Page Menu
Home
Phorge
Search
Configure Global Search
Log In
Files
F85649676
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Award Token
Flag For Later
Size
23 KB
Referenced Files
None
Subscribers
None
View Options
diff --git a/src/components/color_input/color_input.vue b/src/components/color_input/color_input.vue
index a6fc2047be..6f236d35fc 100644
--- a/src/components/color_input/color_input.vue
+++ b/src/components/color_input/color_input.vue
@@ -1,158 +1,158 @@
<template>
<div
class="color-input style-control"
:class="{ disabled: !present || disabled, '-compact': compact }"
>
<label
:for="name"
class="label"
:class="{ faint: !present || disabled }"
>
{{ label }}
</label>
<Checkbox
v-if="typeof fallback !== 'undefined' && showOptionalCheckbox && !hideOptionalCheckbox"
:model-value="present"
:disabled="disabled"
class="opt"
@update:model-value="updateValue(typeof modelValue === 'undefined' ? fallback : undefined)"
/>
<div
class="input color-input-field"
:class="{ disabled: !present || disabled, unstyled }"
>
<input
:id="name + '-t'"
class="textColor unstyled"
:class="{ disabled: !present || disabled }"
type="text"
:value="modelValue ?? fallback"
:disabled="!present || disabled"
@input="updateValue($event.target.value)"
>
<div
v-if="validColor"
class="validIndicator"
:style="{backgroundColor: modelValue || fallback}"
/>
<div
v-else-if="transparentColor"
class="transparentIndicator"
/>
<div
v-else-if="computedColor"
class="computedIndicator"
:style="{backgroundColor: fallback}"
/>
<div
v-else
class="invalidIndicator"
/>
<label class="nativeColor">
<FAIcon icon="eye-dropper" />
<input
:id="name"
class="unstyled"
type="color"
:value="modelValue || fallback"
:disabled="!present || disabled"
:class="{ disabled: !present || disabled }"
@input="updateValue($event.target.value)"
>
</label>
</div>
</div>
</template>
<script>
import { throttle } from 'lodash'
import { hex2rgb } from '../../services/color_convert/color_convert.js'
import Checkbox from '../checkbox/checkbox.vue'
import { library } from '@fortawesome/fontawesome-svg-core'
import { faEyeDropper } from '@fortawesome/free-solid-svg-icons'
library.add(faEyeDropper)
export default {
components: {
Checkbox,
},
props: {
// Name of color, used for identifying
name: {
required: true,
type: String,
},
// Readable label
label: {
- required: true,
+ required: false,
type: String,
},
// use unstyled, uh, style
unstyled: {
required: false,
type: Boolean,
},
// Color value, should be required but vue cannot tell the difference
// between "property missing" and "property set to undefined"
modelValue: {
required: false,
type: String,
default: undefined,
},
// Color fallback to use when value is not defeind
fallback: {
required: false,
type: String,
default: undefined,
},
// Disable the control
disabled: {
required: false,
type: Boolean,
default: false,
},
// Show "optional" tickbox, for when value might become mandatory
showOptionalCheckbox: {
required: false,
type: Boolean,
default: true,
},
// Force "optional" tickbox to hide
hideOptionalCheckbox: {
required: false,
type: Boolean,
default: false,
},
compact: {
required: false,
type: Boolean,
},
},
emits: ['update:modelValue'],
computed: {
present() {
return typeof this.modelValue !== 'undefined'
},
validColor() {
return hex2rgb(this.modelValue || this.fallback)
},
transparentColor() {
return this.modelValue === 'transparent'
},
computedColor() {
return (
this.modelValue &&
(this.modelValue.startsWith('--') || this.modelValue.startsWith('$'))
)
},
},
methods: {
updateValue: throttle(function (value) {
this.$emit('update:modelValue', value)
}, 100),
},
}
</script>
<style lang="scss" src="./color_input.scss"></style>
diff --git a/src/components/settings_modal/admin_tabs/instance_tab.vue b/src/components/settings_modal/admin_tabs/instance_tab.vue
index 585fe303c9..144958fa4f 100644
--- a/src/components/settings_modal/admin_tabs/instance_tab.vue
+++ b/src/components/settings_modal/admin_tabs/instance_tab.vue
@@ -1,191 +1,192 @@
<template>
<div :label="$t('admin_dash.tabs.instance')">
<div class="setting-section">
<h3>{{ $t('admin_dash.instance.instance') }}</h3>
<ul class="setting-list">
<li>
<StringSetting path=":pleroma.:instance.:name" />
</li>
<li>
<StringSetting path=":pleroma.:instance.:contact_username" />
</li>
<li>
<StringSetting path=":pleroma.:instance.:email" />
</li>
<li>
<StringSetting path=":pleroma.:instance.:description" />
</li>
<li>
<StringSetting path=":pleroma.:instance.:short_description" />
</li>
<li>
<ListSetting
force-new
ignore-suggestions
path=":pleroma.:instance.:languages"
/>
</li>
<li>
<StringSetting path=":pleroma.:instance.:status_page" />
</li>
</ul>
<h3>{{ $t('admin_dash.instance.branding') }}</h3>
<ul class="setting-list">
<!-- See https://git.pleroma.social/pleroma/pleroma/-/merge_requests/3963 -->
<li v-if="adminDraft[':pleroma'][':instance'][':favicon'] !== undefined">
<AttachmentSetting
compact
path=":pleroma.:instance.:favicon"
/>
</li>
<li>
<AttachmentSetting
compact
path=":pleroma.:instance.:instance_thumbnail"
/>
</li>
<h4>{{ $t('admin_dash.instance.pwa.manifest') }}</H4>
<li>
<PWAManifestIconsSetting path=":pleroma.:manifest.:icons" />
</li>
<li>
<ColorSetting
hide-draft-buttons
+ label=""
path=":pleroma.:manifest.:theme_color"
/>
</li>
<li>
<ColorSetting
hide-draft-buttons
path=":pleroma.:manifest.:background_color"
/>
</li>
<li>
<GroupSetting path=":pleroma.:manifest" />
</li>
<h4>{{ $t('admin_dash.instance.misc_brand') }}</H4>
<li>
<AttachmentSetting path=":pleroma.:instance.:background_image" />
</li>
</ul>
<h3>{{ $t('admin_dash.instance.rich_metadata') }}</h3>
<ul class="setting-list">
<li>
<ListSetting
override-available-options
:options="providersOptions"
:path="[':pleroma','Pleroma.Web.Metadata', ':providers']"
/>
</li>
<li>
<BooleanSetting
:path="[':pleroma','Pleroma.Web.Metadata', ':unfurl_nsfw']"
/>
</li>
</ul>
</div>
<div class="setting-section">
<h3>{{ $t('admin_dash.instance.access') }}</h3>
<ul class="setting-list">
<li>
<BooleanSetting
override-backend-description
override-backend-description-label
path=":pleroma.:instance.:public"
/>
</li>
<li>
<ChoiceSetting
override-backend-description
override-backend-description-label
override-available-options
- :options="limitLocalContentOptions"
+ :options="[...limitLocalContentOptions]"
path=":pleroma.:instance.:limit_to_local_content"
/>
</li>
<li v-if="expertLevel">
<h3>{{ $t('admin_dash.instance.restrict.header') }}</h3>
<p>
{{ $t('admin_dash.instance.restrict.description') }}
</p>
<ul class="setting-list">
<li>
<h4>{{ $t('admin_dash.instance.restrict.timelines') }}</h4>
<ul class="setting-list">
<li>
<BooleanSetting
path=":pleroma.:restrict_unauthenticated.:timelines.:local"
indeterminate-state=":if_instance_is_private"
swap-description-and-label
hide-description
/>
</li>
<li>
<BooleanSetting
path=":pleroma.:restrict_unauthenticated.:timelines.:federated"
indeterminate-state=":if_instance_is_private"
swap-description-and-label
hide-description
/>
</li>
<li>
<GroupSetting path=":pleroma.:restrict_unauthenticated.:timelines" />
</li>
</ul>
</li>
<li>
<h4>{{ $t('admin_dash.instance.restrict.profiles') }}</h4>
<ul class="setting-list">
<li>
<BooleanSetting
path=":pleroma.:restrict_unauthenticated.:profiles.:local"
indeterminate-state=":if_instance_is_private"
swap-description-and-label
hide-description
/>
</li>
<li>
<BooleanSetting
path=":pleroma.:restrict_unauthenticated.:profiles.:remote"
indeterminate-state=":if_instance_is_private"
swap-description-and-label
hide-description
/>
</li>
<li>
<GroupSetting path=":pleroma.:restrict_unauthenticated.:profiles" />
</li>
</ul>
</li>
<li>
<h4>{{ $t('admin_dash.instance.restrict.activities') }}</h4>
<ul class="setting-list">
<li>
<BooleanSetting
path=":pleroma.:restrict_unauthenticated.:activities.:local"
indeterminate-state=":if_instance_is_private"
swap-description-and-label
hide-description
/>
</li>
<li>
<BooleanSetting
path=":pleroma.:restrict_unauthenticated.:activities.:remote"
indeterminate-state=":if_instance_is_private"
swap-description-and-label
hide-description
/>
</li>
<li>
<GroupSetting path=":pleroma.:restrict_unauthenticated.:activities" />
</li>
</ul>
</li>
</ul>
</li>
</ul>
</div>
</div>
</template>
<script src="./instance_tab.js"></script>
diff --git a/src/components/settings_modal/helpers/attachment_setting.js b/src/components/settings_modal/helpers/attachment_setting.js
index 7ba9109503..cbcd4abf8d 100644
--- a/src/components/settings_modal/helpers/attachment_setting.js
+++ b/src/components/settings_modal/helpers/attachment_setting.js
@@ -1,47 +1,47 @@
import Attachment from 'src/components/attachment/attachment.vue'
import MediaUpload from 'src/components/media_upload/media_upload.vue'
import Setting from './setting.js'
import { useInstanceStore } from 'src/stores/instance.js'
import { fileTypeExt } from 'src/services/file_type/file_type.service.js'
export default {
...Setting,
props: {
...Setting.props,
compact: Boolean,
acceptTypes: {
type: String,
required: false,
default: 'image/*',
},
},
components: {
...Setting.components,
MediaUpload,
Attachment,
},
computed: {
...Setting.computed,
attachment() {
const path = this.realDraftMode ? this.draft : this.state
// The "server" part is primarily for local dev, but could be useful for alt-domain or multiuser usage.
const url = path.includes('://') ? path : useInstanceStore().server + path
return {
- mimetype: fileTypeExt(url),
+ type: fileTypeExt(url),
url,
}
},
},
methods: {
...Setting.methods,
setMediaFile(fileInfo) {
if (this.realDraftMode) {
this.draft = fileInfo.url
} else {
this.configSink(this.path, fileInfo.url)
}
},
},
}
diff --git a/src/components/settings_modal/helpers/color_setting.vue b/src/components/settings_modal/helpers/color_setting.vue
index 6813bb2a25..c996dc02f3 100644
--- a/src/components/settings_modal/helpers/color_setting.vue
+++ b/src/components/settings_modal/helpers/color_setting.vue
@@ -1,71 +1,72 @@
<template>
<label
v-if="matchesExpertLevel"
class="ColorSetting setting-item"
>
<label
v-if="!hideLabel"
:for="path"
class="setting-label"
:class="{ 'faint': shouldBeDisabled }"
>
<template v-if="backendDescriptionLabel">
{{ backendDescriptionLabel + ' ' }}
</template>
<template v-else-if="source === 'admin'">
MISSING LABEL FOR {{ path }}
</template>
<slot v-else />
</label>
{{ ' ' }}
<ColorInput
:id="path"
+ :name="path"
class="setting-control color-setting-input"
:class="{ disabled: shouldBeDisabled }"
:disabled="shouldBeDisabled"
:placeholder="backendDescriptionSuggestions"
:model-value="realDraftMode ? draft : state"
@update:model-value="update"
/>
{{ ' ' }}
<ModifiedIndicator
:changed="isChanged"
:onclick="reset"
/>
<ProfileSettingIndicator :is-profile="isProfileSetting" />
<DraftButtons v-if="!hideDraftButtons" />
<p
v-if="backendDescriptionDescription"
class="setting-description"
:class="{ 'faint': shouldBeDisabled }"
>
{{ backendDescriptionDescription + ' ' }}
</p>
</label>
</template>
<script src="./color_setting.js"></script>
<style lang="scss">
.ColorSetting {
&.setting-item {
display: grid;
grid-template-areas:
"label control"
". desc"
". draft";
.setting-label {
text-align: right;
align-self: center;
}
.setting-control {
align-self: end;
}
}
.color-setting-input {
align-self: baseline;
}
}
</style>
diff --git a/src/components/settings_modal/helpers/pwa_manifest_icons_setting.js b/src/components/settings_modal/helpers/pwa_manifest_icons_setting.js
index 5d90ccb1e8..0af54d3dfe 100644
--- a/src/components/settings_modal/helpers/pwa_manifest_icons_setting.js
+++ b/src/components/settings_modal/helpers/pwa_manifest_icons_setting.js
@@ -1,102 +1,102 @@
import { clone } from 'lodash'
import Attachment from 'src/components/attachment/attachment.vue'
import MediaUpload from 'src/components/media_upload/media_upload.vue'
import Select from 'src/components/select/select.vue'
import Setting from './setting.js'
import { useInstanceStore } from 'src/stores/instance.js'
import { fileTypeExt } from 'src/services/file_type/file_type.service.js'
export default {
...Setting,
components: {
...Setting.components,
Select,
Attachment,
MediaUpload,
},
computed: {
...Setting.computed,
purposeOptions() {
return ['any', 'monochrome', 'maskable'].map((value) => ({
value,
key: value,
label: this.$t('admin_dash.instance.pwa.icon.' + value),
}))
},
},
methods: {
...Setting.methods,
attachment(e) {
const path = e[':src']
if (!path) {
return {
- mimetype: '',
+ type: '',
url: '',
}
}
const url = path.includes('://') ? path : useInstanceStore().server + path
return {
- mimetype: fileTypeExt(url),
+ type: fileTypeExt(url),
url,
}
},
setMediaFile({ event, index }) {
this.update({
event: {
target: {
value: event.url,
},
},
index,
eventType: 'edit',
field: ':src',
})
},
setPurpose({ event, index }) {
this.update({
event: {
target: {
value: event,
},
},
index,
eventType: 'edit',
field: ':purpose',
})
},
getValue({ event, field, index, eventType }) {
switch (eventType) {
case 'add': {
const res = [...this.visibleState, {}]
return res
}
case 'remove': {
const pre = this.visibleState.slice(0, index)
const post = this.visibleState.slice(index + 1)
return [...pre, ...post]
}
case 'edit': {
const pre = this.visibleState.slice(0, index)
const post = this.visibleState.slice(index + 1)
const item = clone(this.visibleState[index])
const string = event.target.value
if (!string) {
delete item[field]
} else {
item[field] = string
}
return [...pre, item, ...post]
}
}
},
},
}
diff --git a/src/components/settings_modal/helpers/pwa_manifest_icons_setting.vue b/src/components/settings_modal/helpers/pwa_manifest_icons_setting.vue
index f8054d266c..6dc8ac3278 100644
--- a/src/components/settings_modal/helpers/pwa_manifest_icons_setting.vue
+++ b/src/components/settings_modal/helpers/pwa_manifest_icons_setting.vue
@@ -1,226 +1,226 @@
<template>
<div
v-if="matchesExpertLevel"
class="PWAManifestIconsSetting setting-item"
>
<label
class="pwa-label setting-label"
:class="{ 'faint': shouldBeDisabled }"
>
<ModifiedIndicator
:changed="isChanged"
:onclick="reset"
/>
<ProfileSettingIndicator :is-profile="isProfileSetting" />
{{ ' ' }}
<template v-if="backendDescriptionLabel">
{{ backendDescriptionLabel + ' ' }}
</template>
<template v-else-if="source === 'admin'">
MISSING LABEL FOR {{ path }}
</template>
<slot v-else />
</label>
<p
v-if="backendDescriptionDescription"
class="setting-description"
:class="{ 'faint': shouldBeDisabled }"
>
{{ backendDescriptionDescription + ' ' }}
</p>
<div class="setting-control">
<ul class="item-list">
<li
v-if="visibleState.length === 0"
class="no_items"
>
{{ $t('admin_dash.instance.pwa.no_icons') }}
<button
v-if="visibleState.length === 0"
class="button-default add-button"
@click="e => update({ eventType: 'add' })"
>
<FAIcon icon="plus" />
</button>
</li>
<li
v-for="(item, index) in visibleState"
:key="index"
>
<div class="icon-element">
<div class="src-field">
<Attachment
class="src-attachment"
- :compact="compact"
+ :compact="true"
:attachment="attachment(item)"
size="small"
hide-description
/>
<div class="src-url">
<label for="path">{{ $t('settings.url') }}</label>
<input
:id="path"
class="input string-input"
:disabled="shouldBeDisabled"
:value="item[':src']"
@change="event => update({ event, index, eventType: 'edit', field: ':src' })"
>
</div>
<MediaUpload
ref="mediaUpload"
class="src-upload media-upload-icon"
:class="{ disabled: shouldBeDisabled }"
normal-button
- :accept-types="acceptTypes"
+ accept-types="image"
@uploaded="event => setMediaFile({ event, index })"
/>
</div>
<dl>
<dt>{{ $t('admin_dash.instance.pwa.icon.purpose') }}</dt>
<dd>
<Select
:class="{ disabled: shouldBeDisabled }"
:disabled="shouldBeDisabled"
:model-value="item[':purpose']"
@update:model-value="event => setPurpose({ event, index })"
>
<option
v-for="(purpose, index2) in purposeOptions"
:key="index2"
:value="purpose.value"
>
{{ purpose.label }}
</option>
</Select>
</dd>
<dt><code>sizes</code>{{ $t('admin_dash.instance.pwa.optional') }}</dt>
<dd>
<input
class="input string-input"
:class="{ disabled: shouldBeDisabled }"
:value="item[':sizes']"
@change="e => update({ event: e, index, eventType: 'edit', field: ':sizes' })"
>
</dd>
<dt><code>type</code>{{ $t('admin_dash.instance.pwa.optional') }}</dt>
<dd>
<input
class="input string-input"
:class="{ disabled: shouldBeDisabled }"
:value="item[':type']"
@change="e => update({ event: e, index, eventType: 'edit', field: ':type' })"
>
</dd>
</dl>
<div class="buttons">
<button
v-if="index === visibleState.length - 1"
class="button-default add-button"
@click="e => update({ eventType: 'add' })"
>
<FAIcon icon="plus" />
</button>
<button
class="button-default delete-button"
@click="e => update({ index, eventType: 'remove' })"
>
<FAIcon icon="times" />
</button>
</div>
</div>
</li>
</ul>
</div>
</div>
</template>
<script src="./pwa_manifest_icons_setting.js"></script>
<style lang="scss">
div.PWAManifestIconsSetting {
margin-left: 3em;
&.setting-item {
display: grid;
grid-template-areas:
"label"
"desc"
"control"
"draft";
grid-template-rows: 2em auto 1fr;
grid-template-columns: 1fr;
}
.pwa-label.setting-label {
align-self: end;
text-align: left;
}
.buttons {
display: flex;
gap: 0.5em;
justify-content: right;
margin-top: 0.5em;
button {
line-height: 2;
}
}
ul {
list-style: none;
display: grid;
grid-template-columns: repeat(auto-fit, 12em);
grid-gap: 2em;
}
dl {
display: grid;
grid-template-columns: 1fr;
margin-top: 0.5em;
gap: 0.25em;
align-items: baseline;
dt {
font-weight: 800;
&::after {
content: ':'
}
}
dd {
margin: 0
}
}
.src-field {
display: grid;
grid-template-columns: auto;
justify-items: center;
gap: 0.5em;
.src-attachment {
width: 10em;
height: 10em;
display: block;
margin-bottom: 0.5em;
}
.src-upload {
display: block;
width: 100%;
}
.src-url {
display: flex;
flex-direction: column;
gap: 0.25em;
width: 100%;
label {
display: block;
}
}
}
}
</style>
File Metadata
Details
Attached
Mime Type
text/x-diff
Expires
Sat, Aug 29, 6:26 PM (1 d, 17 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
1737246
Default Alt Text
(23 KB)
Attached To
Mode
rPUFE pleroma-fe-upstream
Attached
Detach File
Event Timeline
Log In to Comment