diff options
Diffstat (limited to 'src/components/settings_modal')
32 files changed, 1081 insertions, 85 deletions
diff --git a/src/components/settings_modal/admin_tabs/emoji_tab.js b/src/components/settings_modal/admin_tabs/emoji_tab.js new file mode 100644 index 00000000..58e1468f --- /dev/null +++ b/src/components/settings_modal/admin_tabs/emoji_tab.js @@ -0,0 +1,257 @@ +import { clone, assign } from 'lodash' +import TabSwitcher from 'src/components/tab_switcher/tab_switcher.jsx' +import StringSetting from '../helpers/string_setting.vue' +import Checkbox from 'components/checkbox/checkbox.vue' +import StillImage from 'components/still-image/still-image.vue' +import Select from 'components/select/select.vue' +import Popover from 'components/popover/popover.vue' +import ConfirmModal from 'components/confirm_modal/confirm_modal.vue' +import ModifiedIndicator from '../helpers/modified_indicator.vue' +import EmojiEditingPopover from '../helpers/emoji_editing_popover.vue' + +const EmojiTab = { + components: { + TabSwitcher, + StringSetting, + Checkbox, + StillImage, + Select, + Popover, + ConfirmModal, + ModifiedIndicator, + EmojiEditingPopover + }, + + data () { + return { + knownLocalPacks: { }, + knownRemotePacks: { }, + editedMetadata: { }, + packName: '', + newPackName: '', + deleteModalVisible: false, + remotePackInstance: '', + remotePackDownloadAs: '' + } + }, + + provide () { + return { emojiAddr: this.emojiAddr } + }, + + computed: { + pack () { + return this.packName !== '' ? this.knownPacks[this.packName] : undefined + }, + packMeta () { + if (this.editedMetadata[this.packName] === undefined) { + this.editedMetadata[this.packName] = clone(this.pack.pack) + } + + return this.editedMetadata[this.packName] + }, + knownPacks () { + // Copy the object itself but not the children, so they are still passed by reference and modified + const result = clone(this.knownLocalPacks) + for (const instName in this.knownRemotePacks) { + for (const instPack in this.knownRemotePacks[instName]) { + result[`${instPack}@${instName}`] = this.knownRemotePacks[instName][instPack] + } + } + + return result + }, + downloadWillReplaceLocal () { + return (this.remotePackDownloadAs.trim() === '' && this.pack.remote && this.pack.remote.baseName in this.knownLocalPacks) || + (this.remotePackDownloadAs in this.knownLocalPacks) + } + }, + + methods: { + reloadEmoji () { + this.$store.state.api.backendInteractor.reloadEmoji() + }, + importFromFS () { + this.$store.state.api.backendInteractor.importEmojiFromFS() + }, + emojiAddr (name) { + if (this.pack.remote !== undefined) { + // Remote pack + return `${this.pack.remote.instance}/emoji/${encodeURIComponent(this.pack.remote.baseName)}/${name}` + } else { + return `${this.$store.state.instance.server}/emoji/${encodeURIComponent(this.packName)}/${name}` + } + }, + + createEmojiPack () { + this.$store.state.api.backendInteractor.createEmojiPack( + { name: this.newPackName } + ).then(resp => resp.json()).then(resp => { + if (resp === 'ok') { + return this.refreshPackList() + } else { + this.displayError(resp.error) + return Promise.reject(resp) + } + }).then(done => { + this.$refs.createPackPopover.hidePopover() + + this.packName = this.newPackName + this.newPackName = '' + }) + }, + deleteEmojiPack () { + this.$store.state.api.backendInteractor.deleteEmojiPack( + { name: this.packName } + ).then(resp => resp.json()).then(resp => { + if (resp === 'ok') { + return this.refreshPackList() + } else { + this.displayError(resp.error) + return Promise.reject(resp) + } + }).then(done => { + delete this.editedMetadata[this.packName] + + this.deleteModalVisible = false + this.packName = '' + }) + }, + + metaEdited (prop) { + if (!this.pack) return + + const def = this.pack.pack[prop] || '' + const edited = this.packMeta[prop] || '' + return edited !== def + }, + savePackMetadata () { + this.$store.state.api.backendInteractor.saveEmojiPackMetadata({ name: this.packName, newData: this.packMeta }).then( + resp => resp.json() + ).then(resp => { + if (resp.error !== undefined) { + this.displayError(resp.error) + return + } + + // Update actual pack data + this.pack.pack = resp + // Delete edited pack data, should auto-update itself + delete this.editedMetadata[this.packName] + }) + }, + + updatePackFiles (newFiles) { + this.pack.files = newFiles + this.sortPackFiles(this.packName) + }, + + loadPacksPaginated (listFunction) { + const pageSize = 25 + const allPacks = {} + + return listFunction({ instance: this.remotePackInstance, page: 1, pageSize: 0 }) + .then(data => data.json()) + .then(data => { + if (data.error !== undefined) { return Promise.reject(data.error) } + + let resultingPromise = Promise.resolve({}) + for (let i = 0; i < Math.ceil(data.count / pageSize); i++) { + resultingPromise = resultingPromise.then(() => listFunction({ instance: this.remotePackInstance, page: i, pageSize }) + ).then(data => data.json()).then(pageData => { + if (pageData.error !== undefined) { return Promise.reject(pageData.error) } + + assign(allPacks, pageData.packs) + }) + } + + return resultingPromise + }) + .then(finished => allPacks) + .catch(data => { + this.displayError(data) + }) + }, + + refreshPackList () { + this.loadPacksPaginated(this.$store.state.api.backendInteractor.listEmojiPacks) + .then(allPacks => { + this.knownLocalPacks = allPacks + for (const name of Object.keys(this.knownLocalPacks)) { + this.sortPackFiles(name) + } + }) + }, + listRemotePacks () { + this.loadPacksPaginated(this.$store.state.api.backendInteractor.listRemoteEmojiPacks) + .then(allPacks => { + let inst = this.remotePackInstance + if (!inst.startsWith('http')) { inst = 'https://' + inst } + const instUrl = new URL(inst) + inst = instUrl.host + + for (const packName in allPacks) { + allPacks[packName].remote = { + baseName: packName, + instance: instUrl.origin + } + } + + this.knownRemotePacks[inst] = allPacks + for (const pack in this.knownRemotePacks[inst]) { + this.sortPackFiles(`${pack}@${inst}`) + } + + this.$refs.remotePackPopover.hidePopover() + }) + .catch(data => { + this.displayError(data) + }) + }, + downloadRemotePack () { + if (this.remotePackDownloadAs.trim() === '') { + this.remotePackDownloadAs = this.pack.remote.baseName + } + + this.$store.state.api.backendInteractor.downloadRemoteEmojiPack({ + instance: this.pack.remote.instance, packName: this.pack.remote.baseName, as: this.remotePackDownloadAs + }) + .then(data => data.json()) + .then(resp => { + if (resp === 'ok') { + this.$refs.dlPackPopover.hidePopover() + + return this.refreshPackList() + } else { + this.displayError(resp.error) + return Promise.reject(resp) + } + }).then(done => { + this.packName = this.remotePackDownloadAs + this.remotePackDownloadAs = '' + }) + }, + displayError (msg) { + this.$store.dispatch('pushGlobalNotice', { + messageKey: 'admin_dash.emoji.error', + messageArgs: [msg], + level: 'error' + }) + }, + sortPackFiles (nameOfPack) { + // Sort by key + const sorted = Object.keys(this.knownPacks[nameOfPack].files).sort().reduce((acc, key) => { + if (key.length === 0) return acc + acc[key] = this.knownPacks[nameOfPack].files[key] + return acc + }, {}) + this.knownPacks[nameOfPack].files = sorted + } + }, + + mounted () { + this.refreshPackList() + } +} + +export default EmojiTab diff --git a/src/components/settings_modal/admin_tabs/emoji_tab.scss b/src/components/settings_modal/admin_tabs/emoji_tab.scss new file mode 100644 index 00000000..3e77e019 --- /dev/null +++ b/src/components/settings_modal/admin_tabs/emoji_tab.scss @@ -0,0 +1,59 @@ +.emoji-tab { + .btn-group .btn:not(:first-child) { + margin-left: 0.5em; + } + + .pack-info-wrapper { + margin-top: 1em; + } + + .emoji-info-input { + width: 100%; + } + + .emoji-data-input { + width: 40%; + margin-left: 0.5em; + margin-right: 0.5em; + } + + .emoji { + width: 32px; + height: 32px; + } + + .emoji-unsaved { + box-shadow: 0 3px 5px var(--cBlue); + } + + .emoji-list { + display: flex; + flex-wrap: wrap; + gap: 1em 1em; + } +} + +.emoji-tab-popover-button:not(:first-child) { + margin-left: 0.5em; +} + +.emoji-tab-popover-input { + margin-bottom: 0.5em; + + label { + display: block; + margin-bottom: 0.5em; + } + + input { + width: 20em; + } + + .emoji-tab-popover-file { + padding-top: 3px; + } + + .warning { + color: var(--cOrange); + } +} diff --git a/src/components/settings_modal/admin_tabs/emoji_tab.vue b/src/components/settings_modal/admin_tabs/emoji_tab.vue new file mode 100644 index 00000000..5742d2ce --- /dev/null +++ b/src/components/settings_modal/admin_tabs/emoji_tab.vue @@ -0,0 +1,358 @@ +<template> + <div + class="emoji-tab" + :label="$t('admin_dash.tabs.emoji')" + > + <div class="setting-item"> + <h2>{{ $t('admin_dash.tabs.emoji') }}</h2> + + <ul class="setting-list"> + <h3>{{ $t('admin_dash.emoji.global_actions') }}</h3> + + <li class="btn-group setting-item"> + <button + class="button button-default btn" + type="button" + @click="reloadEmoji" + > + {{ $t('admin_dash.emoji.reload') }} + </button> + <button + class="button button-default btn" + type="button" + @click="importFromFS" + > + {{ $t('admin_dash.emoji.importFS') }} + </button> + </li> + + <li class="btn-group setting-item"> + <button + class="button button-default btn" + type="button" + @click="$refs.remotePackPopover.showPopover" + > + {{ $t('admin_dash.emoji.remote_packs') }} + + <Popover + ref="remotePackPopover" + popover-class="emoji-tab-edit-popover popover-default" + trigger="click" + placement="bottom" + bound-to-selector=".emoji-tab" + :bound-to="{ x: 'container' }" + :offset="{ y: 5 }" + > + <template #content> + <div class="emoji-tab-popover-input"> + <h3>{{ $t('admin_dash.emoji.remote_pack_instance') }}</h3> + <input + v-model="remotePackInstance" + class="input" + :placeholder="$t('admin_dash.emoji.remote_pack_instance')" + > + <button + class="button button-default btn emoji-tab-popover-button" + type="button" + @click="listRemotePacks" + > + {{ $t('admin_dash.emoji.do_list') }} + </button> + </div> + </template> + </Popover> + </button> + </li> + + <h3>{{ $t('admin_dash.emoji.emoji_packs') }}</h3> + + <li> + <h4>{{ $t('admin_dash.emoji.edit_pack') }}</h4> + + <Select + v-model="packName" + class="form-control" + > + <option + value="" + disabled + hidden + > + {{ $t('admin_dash.emoji.emoji_pack') }} + </option> + <option + v-for="(pack, listPackName) in knownPacks" + :key="listPackName" + :label="listPackName" + > + {{ listPackName }} + </option> + </Select> + + <button + class="button button-default btn emoji-tab-popover-button" + type="button" + @click="$refs.createPackPopover.showPopover" + > + {{ $t('admin_dash.emoji.create_pack') }} + </button> + <Popover + ref="createPackPopover" + popover-class="emoji-tab-edit-popover popover-default" + trigger="click" + placement="bottom" + bound-to-selector=".emoji-tab" + :bound-to="{ x: 'container' }" + :offset="{ y: 5 }" + > + <template #content> + <div class="emoji-tab-popover-input"> + <h3>{{ $t('admin_dash.emoji.new_pack_name') }}</h3> + <input + v-model="newPackName" + :placeholder="$t('admin_dash.emoji.new_pack_name')" + class="input" + > + <button + class="button button-default btn emoji-tab-popover-button" + type="button" + @click="createEmojiPack" + > + {{ $t('admin_dash.emoji.create') }} + </button> + </div> + </template> + </Popover> + </li> + </ul> + + <div v-if="pack"> + <div class="pack-info-wrapper"> + <ul class="setting-list"> + <li> + <label> + {{ $t('admin_dash.emoji.description') }} + <ModifiedIndicator + :changed="metaEdited('description')" + message-key="admin_dash.emoji.metadata_changed" + /> + + <textarea + v-model="packMeta.description" + :disabled="pack.remote !== undefined" + class="bio resize-height input" + /> + </label> + </li> + <li> + <label> + {{ $t('admin_dash.emoji.homepage') }} + <ModifiedIndicator + :changed="metaEdited('homepage')" + message-key="admin_dash.emoji.metadata_changed" + /> + + <input + v-model="packMeta.homepage" + class="emoji-info-input input" + :disabled="pack.remote !== undefined" + > + </label> + </li> + <li> + <label> + {{ $t('admin_dash.emoji.fallback_src') }} + <ModifiedIndicator + :changed="metaEdited('fallback-src')" + message-key="admin_dash.emoji.metadata_changed" + /> + + <input + v-model="packMeta['fallback-src']" + class="emoji-info-input input" + :disabled="pack.remote !== undefined" + > + </label> + </li> + <li> + <label> + {{ $t('admin_dash.emoji.fallback_sha256') }} + + <input + v-model="packMeta['fallback-src-sha256']" + :disabled="true" + class="emoji-info-input input" + > + </label> + </li> + <li> + <Checkbox + v-model="packMeta['share-files']" + :disabled="pack.remote !== undefined" + > + {{ $t('admin_dash.emoji.share') }} + </Checkbox> + + <ModifiedIndicator + :changed="metaEdited('share-files')" + message-key="admin_dash.emoji.metadata_changed" + /> + </li> + <li class="btn-group"> + <button + v-if="pack.remote === undefined" + class="button button-default btn" + type="button" + @click="savePackMetadata" + > + {{ $t('admin_dash.emoji.save_meta') }} + </button> + <button + v-if="pack.remote === undefined" + class="button button-default btn" + type="button" + @click="savePackMetadata" + > + {{ $t('admin_dash.emoji.revert_meta') }} + </button> + + <button + v-if="pack.remote === undefined" + class="button button-default btn" + type="button" + @click="deleteModalVisible = true" + > + {{ $t('admin_dash.emoji.delete_pack') }} + + <ConfirmModal + v-if="deleteModalVisible" + :title="$t('admin_dash.emoji.delete_title')" + :cancel-text="$t('status.delete_confirm_cancel_button')" + :confirm-text="$t('status.delete_confirm_accept_button')" + @cancelled="deleteModalVisible = false" + @accepted="deleteEmojiPack" + > + {{ $t('admin_dash.emoji.delete_confirm', [packName]) }} + </ConfirmModal> + </button> + + <button + v-if="pack.remote !== undefined" + class="button button-default btn" + type="button" + @click="$refs.dlPackPopover.showPopover" + > + {{ $t('admin_dash.emoji.download_pack') }} + + <Popover + ref="dlPackPopover" + trigger="click" + placement="bottom" + bound-to-selector=".emoji-tab" + popover-class="emoji-tab-edit-popover popover-default" + :bound-to="{ x: 'container' }" + :offset="{ y: 5 }" + > + <template #content> + <h3>{{ $t('admin_dash.emoji.downloading_pack', [packName]) }}</h3> + <div> + <div> + <div class="emoji-tab-popover-input"> + <label> + {{ $t('admin_dash.emoji.download_as_name') }} + <input + v-model="remotePackDownloadAs" + class="emoji-data-input input" + :placeholder="$t('admin_dash.emoji.download_as_name_full')" + > + </label> + + <div + v-if="downloadWillReplaceLocal" + class="warning" + > + <em>{{ $t('admin_dash.emoji.replace_warning') }}</em> + </div> + </div> + + <button + class="button button-default btn" + type="button" + @click="downloadRemotePack" + > + {{ $t('admin_dash.emoji.download') }} + </button> + </div> + </div> + </template> + </Popover> + </button> + </li> + </ul> + </div> + + <ul class="setting-list"> + <h4> + {{ $t('admin_dash.emoji.files') }} + + <ModifiedIndicator + v-if="pack" + :changed="$refs.emojiPopovers && $refs.emojiPopovers.some(p => p.isEdited)" + message-key="admin_dash.emoji.emoji_changed" + /> + </h4> + + <div + v-if="pack" + class="emoji-list" + > + <EmojiEditingPopover + v-if="pack.remote === undefined" + placement="bottom" + new-upload + :title="$t('admin_dash.emoji.adding_new')" + :pack-name="packName" + @updatePackFiles="updatePackFiles" + @displayError="displayError" + > + <template #trigger> + <FAIcon + icon="plus" + size="2x" + :title="$t('admin_dash.emoji.add_file')" + /> + </template> + </EmojiEditingPopover> + + <EmojiEditingPopover + v-for="(file, shortcode) in pack.files" + ref="emojiPopovers" + :key="shortcode" + placement="top" + :title="$t('admin_dash.emoji.editing', [shortcode])" + :disabled="pack.remote !== undefined" + :shortcode="shortcode" + :file="file" + :pack-name="packName" + @updatePackFiles="updatePackFiles" + @displayError="displayError" + > + <template #trigger> + <StillImage + class="emoji" + :src="emojiAddr(file)" + :title="`:${shortcode}:`" + :alt="`:${shortcode}:`" + /> + </template> + </EmojiEditingPopover> + </div> + </ul> + </div> + </div> + </div> +</template> + +<script src="./emoji_tab.js"></script> + +<style lang="scss" src="./emoji_tab.scss"></style> diff --git a/src/components/settings_modal/admin_tabs/frontends_tab.js b/src/components/settings_modal/admin_tabs/frontends_tab.js index 8163af59..f57310ee 100644 --- a/src/components/settings_modal/admin_tabs/frontends_tab.js +++ b/src/components/settings_modal/admin_tabs/frontends_tab.js @@ -55,9 +55,13 @@ const FrontendsTab = { return fe.refs.includes(frontend.ref) }, getSuggestedRef (frontend) { - const defaultFe = this.adminDraft[':pleroma'][':frontends'][':primary'] - if (defaultFe?.name === frontend.name && this.canInstall(defaultFe)) { - return defaultFe.ref + if (this.adminDraft) { + const defaultFe = this.adminDraft[':pleroma'][':frontends'][':primary'] + if (defaultFe?.name === frontend.name && this.canInstall(defaultFe)) { + return defaultFe.ref + } else { + return frontend.refs[0] + } } else { return frontend.refs[0] } diff --git a/src/components/settings_modal/admin_tabs/frontends_tab.vue b/src/components/settings_modal/admin_tabs/frontends_tab.vue index dd4c9790..8fb3d399 100644 --- a/src/components/settings_modal/admin_tabs/frontends_tab.vue +++ b/src/components/settings_modal/admin_tabs/frontends_tab.vue @@ -6,7 +6,10 @@ <div class="setting-item"> <h2>{{ $t('admin_dash.tabs.frontends') }}</h2> <p>{{ $t('admin_dash.frontend.wip_notice') }}</p> - <ul class="setting-list"> + <ul + v-if="adminDraft" + class="setting-list" + > <li> <h3>{{ $t('admin_dash.frontend.default_frontend') }}</h3> <p>{{ $t('admin_dash.frontend.default_frontend_tip') }}</p> @@ -23,8 +26,18 @@ </ul> </li> </ul> + <div + v-else + class="setting-list" + > + {{ $t('admin_dash.frontend.default_frontend_unavail') }} + </div> + <div class="setting-list relative"> - <PanelLoading class="overlay" v-if="working"/> + <PanelLoading + v-if="working" + class="overlay" + /> <h3>{{ $t('admin_dash.frontend.available_frontends') }}</h3> <ul class="cards-list"> <li @@ -33,9 +46,9 @@ > <strong>{{ frontend.name }}</strong> {{ ' ' }} - <span v-if="adminDraft[':pleroma'][':frontends'][':primary']?.name === frontend.name"> + <span v-if="adminDraft && adminDraft[':pleroma'][':frontends'][':primary']?.name === frontend.name"> <i18n-t - v-if="adminDraft[':pleroma'][':frontends'][':primary']?.ref === frontend.refs[0]" + v-if="adminDraft && adminDraft[':pleroma'][':frontends'][':primary']?.ref === frontend.refs[0]" keypath="admin_dash.frontend.is_default" /> <i18n-t @@ -43,7 +56,7 @@ keypath="admin_dash.frontend.is_default_custom" > <template #version> - <code>{{ adminDraft[':pleroma'][':frontends'][':primary'].ref }}</code> + <code>{{ adminDraft && adminDraft[':pleroma'][':frontends'][':primary'].ref }}</code> </template> </i18n-t> </span> @@ -103,7 +116,7 @@ <button v-for="ref in frontend.refs" :key="ref" - class="button-default dropdown-item" + class="menu-item dropdown-item" @click.prevent="update(frontend, ref)" @click="close" > @@ -134,7 +147,7 @@ class="button button-default btn" type="button" :disabled=" - adminDraft[':pleroma'][':frontends'][':primary']?.name === frontend.name && + !adminDraft || adminDraft[':pleroma'][':frontends'][':primary']?.name === frontend.name && adminDraft[':pleroma'][':frontends'][':primary']?.ref === frontend.refs[0] " @click="setDefault(frontend)" @@ -160,7 +173,7 @@ <button v-for="ref in frontend.installedRefs || frontend.refs" :key="ref" - class="button-default dropdown-item" + class="menu-item dropdown-item" @click.prevent="setDefault(frontend, ref)" @click="close" > diff --git a/src/components/settings_modal/admin_tabs/instance_tab.vue b/src/components/settings_modal/admin_tabs/instance_tab.vue index a0e3351e..32e8df25 100644 --- a/src/components/settings_modal/admin_tabs/instance_tab.vue +++ b/src/components/settings_modal/admin_tabs/instance_tab.vue @@ -8,7 +8,10 @@ </li> <!-- See https://git.pleroma.social/pleroma/pleroma/-/merge_requests/3963 --> <li v-if="adminDraft[':pleroma'][':instance'][':favicon'] !== undefined"> - <AttachmentSetting compact path=":pleroma.:instance.:favicon" /> + <AttachmentSetting + compact + path=":pleroma.:instance.:favicon" + /> </li> <li> <StringSetting path=":pleroma.:instance.:email" /> @@ -20,7 +23,10 @@ <StringSetting path=":pleroma.:instance.:short_description" /> </li> <li> - <AttachmentSetting compact path=":pleroma.:instance.:instance_thumbnail" /> + <AttachmentSetting + compact + path=":pleroma.:instance.:instance_thumbnail" + /> </li> <li> <AttachmentSetting path=":pleroma.:instance.:background_image" /> diff --git a/src/components/settings_modal/helpers/attachment_setting.vue b/src/components/settings_modal/helpers/attachment_setting.vue index b50231f2..96c80ab1 100644 --- a/src/components/settings_modal/helpers/attachment_setting.vue +++ b/src/components/settings_modal/helpers/attachment_setting.vue @@ -29,7 +29,7 @@ <label for="path">{{ $t('settings.url') }}</label> <input :id="path" - class="string-input" + class="input string-input" :disabled="shouldBeDisabled" :value="realDraftMode ? draft : state" @change="update" diff --git a/src/components/settings_modal/helpers/emoji_editing_popover.vue b/src/components/settings_modal/helpers/emoji_editing_popover.vue new file mode 100644 index 00000000..f0465dd5 --- /dev/null +++ b/src/components/settings_modal/helpers/emoji_editing_popover.vue @@ -0,0 +1,227 @@ +<template> + <Popover + ref="emojiPopover" + trigger="click" + :placement="placement" + bound-to-selector=".emoji-list" + popover-class="emoji-tab-edit-popover popover-default" + :bound-to="{ x: 'container' }" + :offset="{ y: 5 }" + :disabled="disabled" + :class="{'emoji-unsaved': isEdited}" + > + <template #trigger> + <slot name="trigger" /> + </template> + <template #content> + <h3> + {{ title }} + </h3> + + <StillImage + v-if="emojiPreview" + class="emoji" + :src="emojiPreview" + /> + <div + v-else + class="emoji" + /> + + <div + v-if="newUpload" + class="emoji-tab-popover-input" + > + <input + type="file" + accept="image/*" + class="emoji-tab-popover-file input" + @change="uploadFile = $event.target.files" + > + </div> + <div> + <div class="emoji-tab-popover-input"> + <label> + {{ $t('admin_dash.emoji.shortcode') }} + <input + v-model="editedShortcode" + class="emoji-data-input input" + :placeholder="$t('admin_dash.emoji.new_shortcode')" + > + </label> + </div> + + <div class="emoji-tab-popover-input"> + <label> + {{ $t('admin_dash.emoji.filename') }} + + <input + v-model="editedFile" + class="emoji-data-input input" + :placeholder="$t('admin_dash.emoji.new_filename')" + > + </label> + </div> + + <button + class="button button-default btn" + type="button" + :disabled="newUpload ? uploadFile.length == 0 : !isEdited" + @click="newUpload ? uploadEmoji() : saveEditedEmoji()" + > + {{ $t('admin_dash.emoji.save') }} + </button> + + <template v-if="!newUpload"> + <button + class="button button-default btn emoji-tab-popover-button" + type="button" + @click="deleteModalVisible = true" + > + {{ $t('admin_dash.emoji.delete') }} + </button> + <button + class="button button-default btn emoji-tab-popover-button" + type="button" + @click="revertEmoji" + > + {{ $t('admin_dash.emoji.revert') }} + </button> + <ConfirmModal + v-if="deleteModalVisible" + :title="$t('admin_dash.emoji.delete_title')" + :cancel-text="$t('status.delete_confirm_cancel_button')" + :confirm-text="$t('status.delete_confirm_accept_button')" + @cancelled="deleteModalVisible = false" + @accepted="deleteEmoji" + > + {{ $t('admin_dash.emoji.delete_confirm', [shortcode]) }} + </ConfirmModal> + </template> + </div> + </template> + </Popover> +</template> + +<script> +import Popover from 'components/popover/popover.vue' +import ConfirmModal from 'components/confirm_modal/confirm_modal.vue' +import StillImage from 'components/still-image/still-image.vue' + +export default { + components: { Popover, ConfirmModal, StillImage }, + inject: ['emojiAddr'], + props: { + placement: String, + disabled: { + type: Boolean, + default: false + }, + + newUpload: Boolean, + + title: String, + packName: String, + shortcode: { + type: String, + // Only exists when this is not a new upload + default: '' + }, + file: { + type: String, + // Only exists when this is not a new upload + default: '' + } + }, + emits: ['updatePackFiles', 'displayError'], + data () { + return { + uploadFile: [], + editedShortcode: this.shortcode, + editedFile: this.file, + deleteModalVisible: false + } + }, + computed: { + emojiPreview () { + if (this.newUpload && this.uploadFile.length > 0) { + return URL.createObjectURL(this.uploadFile[0]) + } else if (!this.newUpload) { + return this.emojiAddr(this.file) + } + + return null + }, + isEdited () { + return !this.newUpload && (this.editedShortcode !== this.shortcode || this.editedFile !== this.file) + } + }, + methods: { + saveEditedEmoji () { + if (!this.isEdited) return + + this.$store.state.api.backendInteractor.updateEmojiFile( + { packName: this.packName, shortcode: this.shortcode, newShortcode: this.editedShortcode, newFilename: this.editedFile, force: false } + ).then(resp => { + if (resp.error !== undefined) { + this.$emit('displayError', resp.error) + return Promise.reject(resp.error) + } + + return resp.json() + }).then(resp => this.$emit('updatePackFiles', resp)) + }, + uploadEmoji () { + this.$store.state.api.backendInteractor.addNewEmojiFile({ + packName: this.packName, + file: this.uploadFile[0], + shortcode: this.editedShortcode, + filename: this.editedFile + }).then(resp => resp.json()).then(resp => { + if (resp.error !== undefined) { + this.$emit('displayError', resp.error) + return + } + + this.$emit('updatePackFiles', resp) + this.$refs.emojiPopover.hidePopover() + + this.editedFile = '' + this.editedShortcode = '' + this.uploadFile = [] + }) + }, + revertEmoji () { + this.editedFile = this.file + this.editedShortcode = this.shortcode + }, + deleteEmoji () { + this.deleteModalVisible = false + + this.$store.state.api.backendInteractor.deleteEmojiFile( + { packName: this.packName, shortcode: this.shortcode } + ).then(resp => resp.json()).then(resp => { + if (resp.error !== undefined) { + this.$emit('displayError', resp.error) + return + } + + this.$emit('updatePackFiles', resp) + }) + } + } +} +</script> + +<style lang="scss"> + .emoji-tab-edit-popover { + padding-left: 0.5em; + padding-right: 0.5em; + padding-bottom: 0.5em; + + .emoji { + width: 32px; + height: 32px; + } + } +</style> diff --git a/src/components/settings_modal/helpers/modified_indicator.vue b/src/components/settings_modal/helpers/modified_indicator.vue index 45db3fc2..a747cebd 100644 --- a/src/components/settings_modal/helpers/modified_indicator.vue +++ b/src/components/settings_modal/helpers/modified_indicator.vue @@ -15,7 +15,7 @@ </template> <template #content> <div class="modified-tooltip"> - {{ $t('settings.setting_changed') }} + {{ $t(messageKey) }} </div> </template> </Popover> @@ -33,7 +33,13 @@ library.add( export default { components: { Popover }, - props: ['changed'] + props: { + changed: Boolean, + messageKey: { + type: String, + default: 'settings.setting_changed' + } + } } </script> diff --git a/src/components/settings_modal/helpers/number_setting.vue b/src/components/settings_modal/helpers/number_setting.vue index 93f11331..23c1a5dd 100644 --- a/src/components/settings_modal/helpers/number_setting.vue +++ b/src/components/settings_modal/helpers/number_setting.vue @@ -17,7 +17,7 @@ </label> <input :id="path" - class="number-input" + class="input number-input" type="number" :step="step || 1" :disabled="shouldBeDisabled" diff --git a/src/components/settings_modal/helpers/setting.js b/src/components/settings_modal/helpers/setting.js index b3add346..abf9cfdf 100644 --- a/src/components/settings_modal/helpers/setting.js +++ b/src/components/settings_modal/helpers/setting.js @@ -195,7 +195,8 @@ export default { } }, canHardReset () { - return this.realSource === 'admin' && this.$store.state.adminSettings.modifiedPaths.has(this.canonPath.join(' -> ')) + return this.realSource === 'admin' && this.$store.state.adminSettings.modifiedPaths && + this.$store.state.adminSettings.modifiedPaths.has(this.canonPath.join(' -> ')) }, matchesExpertLevel () { return (this.expert || 0) <= this.$store.state.config.expertLevel > 0 diff --git a/src/components/settings_modal/helpers/size_setting.vue b/src/components/settings_modal/helpers/size_setting.vue index 6c3fbaeb..0a2206b2 100644 --- a/src/components/settings_modal/helpers/size_setting.vue +++ b/src/components/settings_modal/helpers/size_setting.vue @@ -11,7 +11,7 @@ </label> <input :id="path" - class="number-input" + class="input number-input" type="number" step="1" :disabled="disabled" diff --git a/src/components/settings_modal/helpers/string_setting.vue b/src/components/settings_modal/helpers/string_setting.vue index 0cfa61ce..7b30d1b9 100644 --- a/src/components/settings_modal/helpers/string_setting.vue +++ b/src/components/settings_modal/helpers/string_setting.vue @@ -17,7 +17,7 @@ </label> <input :id="path" - class="string-input" + class="input string-input" :disabled="shouldBeDisabled" :value="realDraftMode ? draft : state" @change="update" diff --git a/src/components/settings_modal/settings_modal.scss b/src/components/settings_modal/settings_modal.scss index 6bc9459b..d01553db 100644 --- a/src/components/settings_modal/settings_modal.scss +++ b/src/components/settings_modal/settings_modal.scss @@ -1,5 +1,3 @@ -@import "src/variables"; - .settings-modal { overflow: hidden; diff --git a/src/components/settings_modal/settings_modal.vue b/src/components/settings_modal/settings_modal.vue index 4e7fd931..50859c94 100644 --- a/src/components/settings_modal/settings_modal.vue +++ b/src/components/settings_modal/settings_modal.vue @@ -14,7 +14,7 @@ <div v-if="currentSaveStateNotice" class="alert" - :class="{ transparent: !currentSaveStateNotice.error, error: currentSaveStateNotice.error}" + :class="{ success: !currentSaveStateNotice.error, error: currentSaveStateNotice.error}" @click.prevent > {{ currentSaveStateNotice.error ? $t('settings.saving_err') : $t('settings.saving_ok') }} @@ -70,7 +70,7 @@ <template #content="{close}"> <div class="dropdown-menu"> <button - class="button-default dropdown-item dropdown-item-icon" + class="menu-item dropdown-item dropdown-item-icon" @click.prevent="backup" @click="close" > @@ -80,7 +80,7 @@ /><span>{{ $t("settings.file_export_import.backup_settings") }}</span> </button> <button - class="button-default dropdown-item dropdown-item-icon" + class="menu-item dropdown-item dropdown-item-icon" @click.prevent="backupWithTheme" @click="close" > @@ -90,7 +90,7 @@ /><span>{{ $t("settings.file_export_import.backup_settings_theme") }}</span> </button> <button - class="button-default dropdown-item dropdown-item-icon" + class="menu-item dropdown-item dropdown-item-icon" @click.prevent="restore" @click="close" > diff --git a/src/components/settings_modal/settings_modal_admin_content.js b/src/components/settings_modal/settings_modal_admin_content.js index f94721ec..ce835bf2 100644 --- a/src/components/settings_modal/settings_modal_admin_content.js +++ b/src/components/settings_modal/settings_modal_admin_content.js @@ -3,6 +3,7 @@ import TabSwitcher from 'src/components/tab_switcher/tab_switcher.jsx' import InstanceTab from './admin_tabs/instance_tab.vue' import LimitsTab from './admin_tabs/limits_tab.vue' import FrontendsTab from './admin_tabs/frontends_tab.vue' +import EmojiTab from './admin_tabs/emoji_tab.vue' import { library } from '@fortawesome/fontawesome-svg-core' import { @@ -33,7 +34,8 @@ const SettingsModalAdminContent = { InstanceTab, LimitsTab, - FrontendsTab + FrontendsTab, + EmojiTab }, computed: { user () { diff --git a/src/components/settings_modal/settings_modal_admin_content.scss b/src/components/settings_modal/settings_modal_admin_content.scss index c984d703..bd619d7f 100644 --- a/src/components/settings_modal/settings_modal_admin_content.scss +++ b/src/components/settings_modal/settings_modal_admin_content.scss @@ -1,10 +1,8 @@ -@import "src/variables"; - .settings_tab-switcher { height: 100%; .setting-item { - border-bottom: 2px solid var(--fg, $fallback--fg); + border-bottom: 2px solid var(--border); margin: 1em 1em 1.4em; padding-bottom: 1.4em; @@ -45,8 +43,7 @@ .unavailable, .unavailable svg { - color: var(--cRed, $fallback--cRed); - color: $fallback--cRed; + color: var(--cRed); } } } diff --git a/src/components/settings_modal/settings_modal_admin_content.vue b/src/components/settings_modal/settings_modal_admin_content.vue index a7a2ac9a..65e23b7e 100644 --- a/src/components/settings_modal/settings_modal_admin_content.vue +++ b/src/components/settings_modal/settings_modal_admin_content.vue @@ -60,6 +60,14 @@ > <FrontendsTab /> </div> + + <div + :label="$t('admin_dash.tabs.emoji')" + icon="face-smile-beam" + data-tab-name="emoji" + > + <EmojiTab /> + </div> </tab-switcher> </template> diff --git a/src/components/settings_modal/settings_modal_user_content.scss b/src/components/settings_modal/settings_modal_user_content.scss index c984d703..bd619d7f 100644 --- a/src/components/settings_modal/settings_modal_user_content.scss +++ b/src/components/settings_modal/settings_modal_user_content.scss @@ -1,10 +1,8 @@ -@import "src/variables"; - .settings_tab-switcher { height: 100%; .setting-item { - border-bottom: 2px solid var(--fg, $fallback--fg); + border-bottom: 2px solid var(--border); margin: 1em 1em 1.4em; padding-bottom: 1.4em; @@ -45,8 +43,7 @@ .unavailable, .unavailable svg { - color: var(--cRed, $fallback--cRed); - color: $fallback--cRed; + color: var(--cRed); } } } diff --git a/src/components/settings_modal/tabs/filtering_tab.vue b/src/components/settings_modal/tabs/filtering_tab.vue index 89fdef1a..1f2c0363 100644 --- a/src/components/settings_modal/tabs/filtering_tab.vue +++ b/src/components/settings_modal/tabs/filtering_tab.vue @@ -45,13 +45,36 @@ </BooleanSetting> </li> <li> + <BooleanSetting path="muteSensitiveStatuses"> + {{ $t('settings.mute_sensitive_posts') }} + </BooleanSetting> + </li> + <li> + <BooleanSetting path="hideMutedFederationRestrictions"> + {{ $t('settings.hide_muted_federation_restrictions') }} + </BooleanSetting> + <ul + class="setting-list suboptions" + :class="[{disabled: !streaming}]" + > + <li + v-for="item in muteFederationRestrictionsLevels" + :key="'mute_' + item + '_federation_restriction'" + > + <BooleanSetting :path="'muteFederationRestrictions.' + item"> + {{ $t('settings.mute_' + item + '_federation_restriction') }} + </BooleanSetting> + </li> + </ul> + </li> + <li> <BooleanSetting path="hidePostStats"> {{ $t('settings.hide_post_stats') }} </BooleanSetting> </li> <li> <BooleanSetting path="hideBotIndication"> - {{ $t('settings.hide_bot_indication') }} + {{ $t('settings.hide_actor_type_indication') }} </BooleanSetting> </li> <ChoiceSetting @@ -67,7 +90,7 @@ <textarea id="muteWords" v-model="muteWordsString" - class="resize-height" + class="input resize-height" /> <div>{{ $t('settings.filtering_explanation') }}</div> </li> diff --git a/src/components/settings_modal/tabs/general_tab.vue b/src/components/settings_modal/tabs/general_tab.vue index f56fa8e0..424ee7e4 100644 --- a/src/components/settings_modal/tabs/general_tab.vue +++ b/src/components/settings_modal/tabs/general_tab.vue @@ -201,6 +201,14 @@ <h2>{{ $t('settings.post_look_feel') }}</h2> <ul class="setting-list"> <li> + <BooleanSetting + path="forceThemeRecompilation" + :expert="1" + > + {{ $t('settings.force_theme_recompilation_debug') }} + </BooleanSetting> + </li> + <li> <ChoiceSetting id="conversationDisplay" path="conversationDisplay" diff --git a/src/components/settings_modal/tabs/notifications_tab.vue b/src/components/settings_modal/tabs/notifications_tab.vue index 9ace4c36..ca2cf8ad 100644 --- a/src/components/settings_modal/tabs/notifications_tab.vue +++ b/src/components/settings_modal/tabs/notifications_tab.vue @@ -19,7 +19,10 @@ </div> </li> <li> - <BooleanSetting path="unseenAtTop" expert="1"> + <BooleanSetting + path="unseenAtTop" + expert="1" + > {{ $t('settings.notification_setting_unseen_at_top') }} </BooleanSetting> </li> @@ -38,7 +41,9 @@ </li> <li> <h3> {{ $t('settings.notification_visibility') }}</h3> - <p v-if="expertLevel > 0">{{ $t('settings.notification_setting_filters_chrome_push') }}</p> + <p v-if="expertLevel > 0"> + {{ $t('settings.notification_setting_filters_chrome_push') }} + </p> <ul class="setting-list two-column"> <li> <h4> {{ $t('settings.notification_visibility_mentions') }}</h4> diff --git a/src/components/settings_modal/tabs/profile_tab.js b/src/components/settings_modal/tabs/profile_tab.js index eeacad48..dee17450 100644 --- a/src/components/settings_modal/tabs/profile_tab.js +++ b/src/components/settings_modal/tabs/profile_tab.js @@ -9,6 +9,7 @@ import suggestor from 'src/components/emoji_input/suggestor.js' import Autosuggest from 'src/components/autosuggest/autosuggest.vue' import Checkbox from 'src/components/checkbox/checkbox.vue' import InterfaceLanguageSwitcher from 'src/components/interface_language_switcher/interface_language_switcher.vue' +import Select from 'src/components/select/select.vue' import BooleanSetting from '../helpers/boolean_setting.vue' import SharedComputedObject from '../helpers/shared_computed_object.js' import localeService from 'src/services/locale/locale.service.js' @@ -39,6 +40,7 @@ const ProfileTab = { showRole: this.$store.state.users.currentUser.show_role, role: this.$store.state.users.currentUser.role, bot: this.$store.state.users.currentUser.bot, + actorType: this.$store.state.users.currentUser.actor_type, pickAvatarBtnVisible: true, bannerUploading: false, backgroundUploading: false, @@ -57,7 +59,8 @@ const ProfileTab = { ProgressButton, Checkbox, BooleanSetting, - InterfaceLanguageSwitcher + InterfaceLanguageSwitcher, + Select }, computed: { user () { @@ -116,6 +119,12 @@ const ProfileTab = { bannerImgSrc () { const src = this.$store.state.users.currentUser.cover_photo return (!src) ? this.defaultBanner : src + }, + groupActorAvailable () { + return this.$store.state.instance.groupActorAvailable + }, + availableActorTypes () { + return this.groupActorAvailable ? ['Person', 'Service', 'Group'] : ['Person', 'Service'] } }, methods: { @@ -127,7 +136,7 @@ const ProfileTab = { /* eslint-disable camelcase */ display_name: this.newName, fields_attributes: this.newFields.filter(el => el != null), - bot: this.bot, + actor_type: this.actorType, show_role: this.showRole, birthday: this.newBirthday || '', show_birthday: this.showBirthday diff --git a/src/components/settings_modal/tabs/profile_tab.scss b/src/components/settings_modal/tabs/profile_tab.scss index ee253ffe..7eda943b 100644 --- a/src/components/settings_modal/tabs/profile_tab.scss +++ b/src/components/settings_modal/tabs/profile_tab.scss @@ -1,5 +1,3 @@ -@import "../../../variables"; - .profile-tab { .bio { margin: 0; @@ -43,16 +41,14 @@ display: block; width: 100%; height: 100%; - border-radius: $fallback--avatarRadius; - border-radius: var(--avatarRadius, $fallback--avatarRadius); + border-radius: var(--roundness); } .reset-button { position: absolute; top: 0.2em; right: 0.2em; - border-radius: $fallback--tooltipRadius; - border-radius: var(--tooltipRadius, $fallback--tooltipRadius); + border-radius: var(--roundness); background-color: rgb(0 0 0 / 60%); opacity: 0.7; width: 1.5em; diff --git a/src/components/settings_modal/tabs/profile_tab.vue b/src/components/settings_modal/tabs/profile_tab.vue index 1cc850cb..034034a1 100644 --- a/src/components/settings_modal/tabs/profile_tab.vue +++ b/src/components/settings_modal/tabs/profile_tab.vue @@ -12,7 +12,7 @@ <input id="username" v-model="newName" - class="name-changer" + class="input name-changer" v-bind="propsToNative(inputProps)" > </template> @@ -26,7 +26,7 @@ <template #default="inputProps"> <textarea v-model="newBio" - class="bio resize-height" + class="input bio resize-height" v-bind="propsToNative(inputProps)" /> </template> @@ -47,7 +47,7 @@ id="birthday" v-model="newBirthday" type="date" - class="birthday-input" + class="input birthday-input" > <Checkbox v-model="showBirthday"> {{ $t('settings.birthday.show_birthday') }} @@ -71,6 +71,7 @@ v-model="newFields[i].name" :placeholder="$t('settings.profile_fields.name')" v-bind="propsToNative(inputProps)" + class="input" > </template> </EmojiInput> @@ -85,6 +86,7 @@ v-model="newFields[i].value" :placeholder="$t('settings.profile_fields.value')" v-bind="propsToNative(inputProps)" + class="input" > </template> </EmojiInput> @@ -109,10 +111,24 @@ </button> </div> <p> - <Checkbox v-model="bot"> - {{ $t('settings.bot') }} - </Checkbox> + <label> + {{ $t('settings.actor_type') }} + <Select v-model="actorType"> + <option + v-for="option in availableActorTypes" + :key="option" + :value="option" + > + {{ $t('settings.actor_type_' + option) }} + </option> + </Select> + </label> </p> + <div v-if="groupActorAvailable"> + <small> + {{ $t('settings.actor_type_description') }} + </small> + </div> <p> <interface-language-switcher :prompt-text="$t('settings.email_language')" @@ -191,6 +207,7 @@ <div> <input type="file" + class="input" @change="uploadFile('banner', $event)" > </div> @@ -233,6 +250,7 @@ <div> <input type="file" + class="input" @change="uploadFile('background', $event)" > </div> diff --git a/src/components/settings_modal/tabs/security_tab/mfa.vue b/src/components/settings_modal/tabs/security_tab/mfa.vue index ee5b6b13..9421b16e 100644 --- a/src/components/settings_modal/tabs/security_tab/mfa.vue +++ b/src/components/settings_modal/tabs/security_tab/mfa.vue @@ -99,12 +99,14 @@ <input v-model="otpConfirmToken" type="text" + class="input" > <p>{{ $t('settings.enter_current_password_to_confirm') }}:</p> <input v-model="currentPassword" type="password" + class="input" > <div class="confirm-otp-actions"> <button @@ -137,8 +139,6 @@ <script src="./mfa.js"></script> <style lang="scss"> -@import "../../../../variables"; - .mfa-settings { .mfa-heading, .method-item { @@ -149,8 +149,7 @@ } .warning { - color: $fallback--cOrange; - color: var(--cOrange, $fallback--cOrange); + color: var(--cOrange); } .setup-otp { diff --git a/src/components/settings_modal/tabs/security_tab/mfa_backup_codes.vue b/src/components/settings_modal/tabs/security_tab/mfa_backup_codes.vue index 923161b2..32a8a759 100644 --- a/src/components/settings_modal/tabs/security_tab/mfa_backup_codes.vue +++ b/src/components/settings_modal/tabs/security_tab/mfa_backup_codes.vue @@ -21,16 +21,13 @@ </template> <script src="./mfa_backup_codes.js"></script> <style lang="scss"> -@import "../../../../variables"; - .mfa-backup-codes { .warning { - color: $fallback--cOrange; - color: var(--cOrange, $fallback--cOrange); + color: var(--cOrange); } .backup-codes { - font-family: var(--postCodeFont, monospace); + font-family: var(--monoFont); } } </style> diff --git a/src/components/settings_modal/tabs/security_tab/mfa_totp.vue b/src/components/settings_modal/tabs/security_tab/mfa_totp.vue index 8e767bd0..99b66818 100644 --- a/src/components/settings_modal/tabs/security_tab/mfa_totp.vue +++ b/src/components/settings_modal/tabs/security_tab/mfa_totp.vue @@ -30,6 +30,7 @@ <input v-model="currentPassword" type="password" + class="input" > </confirm> <div diff --git a/src/components/settings_modal/tabs/security_tab/security_tab.vue b/src/components/settings_modal/tabs/security_tab/security_tab.vue index d36d478f..74103f6f 100644 --- a/src/components/settings_modal/tabs/security_tab/security_tab.vue +++ b/src/components/settings_modal/tabs/security_tab/security_tab.vue @@ -8,6 +8,7 @@ v-model="newEmail" type="email" autocomplete="email" + class="input" > </div> <div> @@ -16,6 +17,7 @@ v-model="changeEmailPassword" type="password" autocomplete="current-password" + class="input" > </div> <button @@ -40,6 +42,7 @@ <input v-model="changePasswordInputs[0]" type="password" + class="input" > </div> <div> @@ -47,6 +50,7 @@ <input v-model="changePasswordInputs[1]" type="password" + class="input" > </div> <div> @@ -54,6 +58,7 @@ <input v-model="changePasswordInputs[2]" type="password" + class="input" > </div> <button @@ -155,6 +160,7 @@ </i18n-t> <input v-model="addAliasTarget" + class="input" > </div> <button @@ -187,6 +193,7 @@ </i18n-t> <input v-model="moveAccountTarget" + class="input" > </div> <div> @@ -195,6 +202,7 @@ v-model="moveAccountPassword" type="password" autocomplete="current-password" + class="input" > </div> <button @@ -222,6 +230,7 @@ <input v-model="deleteAccountConfirmPasswordInput" type="password" + class="input" > <button class="btn button-default" diff --git a/src/components/settings_modal/tabs/theme_tab/preview.vue b/src/components/settings_modal/tabs/theme_tab/preview.vue index d755279a..1837620f 100644 --- a/src/components/settings_modal/tabs/theme_tab/preview.vue +++ b/src/components/settings_modal/tabs/theme_tab/preview.vue @@ -5,7 +5,7 @@ <div class="panel-heading"> <div class="title"> {{ $t('settings.style.preview.header') }} - <span class="badge badge-notification"> + <span class="badge -notification"> 99 </span> </div> @@ -81,7 +81,7 @@ class="faint" scope="global" > - <a style="color: var(--faintLink);"> + <a style="color: var(--linkFaint);"> {{ $t('settings.style.preview.faint_link') }} </a> </i18n-t> @@ -95,6 +95,7 @@ <input :value="$t('settings.style.preview.input')" type="text" + class="input" > <div class="actions"> @@ -103,6 +104,7 @@ id="preview_checkbox" checked="very yes" type="checkbox" + class="input" > <label for="preview_checkbox">{{ $t('settings.style.preview.checkbox') }}</label> </span> diff --git a/src/components/settings_modal/tabs/theme_tab/theme_tab.js b/src/components/settings_modal/tabs/theme_tab/theme_tab.js index 58f8d44a..11c90b03 100644 --- a/src/components/settings_modal/tabs/theme_tab/theme_tab.js +++ b/src/components/settings_modal/tabs/theme_tab/theme_tab.js @@ -4,15 +4,7 @@ import { getContrastRatioLayers } from 'src/services/color_convert/color_convert.js' import { - DEFAULT_SHADOWS, - generateColors, - generateShadows, - generateRadii, - generateFonts, - composePreset, - getThemes, - shadows2to3, - colors2to3 + getThemes } from 'src/services/style_setter/style_setter.js' import { newImporter, @@ -25,7 +17,15 @@ import { CURRENT_VERSION, OPACITIES, getLayers, - getOpacitySlot + getOpacitySlot, + DEFAULT_SHADOWS, + generateColors, + generateShadows, + generateRadii, + generateFonts, + composePreset, + shadows2to3, + colors2to3 } from 'src/services/theme_data/theme_data.service.js' import ColorInput from 'src/components/color_input/color_input.vue' import RangeInput from 'src/components/range_input/range_input.vue' @@ -514,6 +514,7 @@ export default { this.$store.dispatch('setOption', { name: 'customTheme', value: { + themeFileVersion: this.selectedVersion, themeEngineVersion: CURRENT_VERSION, ...this.previewTheme } @@ -521,6 +522,7 @@ export default { this.$store.dispatch('setOption', { name: 'customThemeSource', value: { + themeFileVersion: this.selectedVersion, themeEngineVersion: CURRENT_VERSION, shadows: this.shadowsLocal, fonts: this.fontsLocal, diff --git a/src/components/settings_modal/tabs/theme_tab/theme_tab.scss b/src/components/settings_modal/tabs/theme_tab/theme_tab.scss index 9935c2e7..5e633120 100644 --- a/src/components/settings_modal/tabs/theme_tab/theme_tab.scss +++ b/src/components/settings_modal/tabs/theme_tab/theme_tab.scss @@ -1,5 +1,3 @@ -@import "src/variables"; - .theme-tab { padding-bottom: 2em; @@ -162,8 +160,7 @@ .preview-container { border-top: 1px dashed; border-bottom: 1px dashed; - border-color: $fallback--border; - border-color: var(--border, $fallback--border); + border-color: var(--border); margin: 1em 0; padding: 1em; background-color: var(--wallpaper); @@ -227,8 +224,6 @@ min-width: 20px; min-height: 20px; line-height: 20px; - border-radius: $fallback--avatarAltRadius; - border-radius: var(--avatarAltRadius, $fallback--avatarAltRadius); } .avatar { @@ -254,8 +249,7 @@ .separator { margin: 1em; border-bottom: 1px solid; - border-color: $fallback--border; - border-color: var(--border, $fallback--border); + border-color: var(--border); } .btn { @@ -296,7 +290,7 @@ border: 0; box-shadow: none; background: transparent; - color: var(--faint, $fallback--faint); + color: var(--textFaint); align-self: stretch; } |
