diff options
Diffstat (limited to 'src/components/settings')
| -rw-r--r-- | src/components/settings/settings.js | 235 | ||||
| -rw-r--r-- | src/components/settings/settings.vue | 710 |
2 files changed, 419 insertions, 526 deletions
diff --git a/src/components/settings/settings.js b/src/components/settings/settings.js index c4aa45b2..c49083f9 100644 --- a/src/components/settings/settings.js +++ b/src/components/settings/settings.js @@ -5,87 +5,22 @@ import TabSwitcher from '../tab_switcher/tab_switcher.js' import StyleSwitcher from '../style_switcher/style_switcher.vue' import InterfaceLanguageSwitcher from '../interface_language_switcher/interface_language_switcher.vue' import { extractCommit } from '../../services/version/version.service' +import { instanceDefaultProperties, defaultState as configDefaultState } from '../../modules/config.js' +import Checkbox from '../checkbox/checkbox.vue' const pleromaFeCommitUrl = 'https://git.pleroma.social/pleroma/pleroma-fe/commit/' const pleromaBeCommitUrl = 'https://git.pleroma.social/pleroma/pleroma/commit/' +const multiChoiceProperties = [ + 'postContentType', + 'subjectLineBehavior' +] + const settings = { data () { - const user = this.$store.state.config const instance = this.$store.state.instance return { - hideAttachmentsLocal: user.hideAttachments, - hideAttachmentsInConvLocal: user.hideAttachmentsInConv, - maxThumbnails: user.maxThumbnails, - hideNsfwLocal: user.hideNsfw, - useOneClickNsfw: user.useOneClickNsfw, - hideISPLocal: user.hideISP, - preloadImage: user.preloadImage, - - hidePostStatsLocal: typeof user.hidePostStats === 'undefined' - ? instance.hidePostStats - : user.hidePostStats, - hidePostStatsDefault: this.$t('settings.values.' + instance.hidePostStats), - - hideUserStatsLocal: typeof user.hideUserStats === 'undefined' - ? instance.hideUserStats - : user.hideUserStats, - hideUserStatsDefault: this.$t('settings.values.' + instance.hideUserStats), - - hideFilteredStatusesLocal: typeof user.hideFilteredStatuses === 'undefined' - ? instance.hideFilteredStatuses - : user.hideFilteredStatuses, - hideFilteredStatusesDefault: this.$t('settings.values.' + instance.hideFilteredStatuses), - - notificationVisibilityLocal: user.notificationVisibility, - replyVisibilityLocal: user.replyVisibility, - loopVideoLocal: user.loopVideo, - muteWordsString: user.muteWords.join('\n'), - autoLoadLocal: user.autoLoad, - streamingLocal: user.streaming, - pauseOnUnfocusedLocal: user.pauseOnUnfocused, - hoverPreviewLocal: user.hoverPreview, - autohideFloatingPostButtonLocal: user.autohideFloatingPostButton, - - hideMutedPostsLocal: typeof user.hideMutedPosts === 'undefined' - ? instance.hideMutedPosts - : user.hideMutedPosts, - hideMutedPostsDefault: this.$t('settings.values.' + instance.hideMutedPosts), - - collapseMessageWithSubjectLocal: typeof user.collapseMessageWithSubject === 'undefined' - ? instance.collapseMessageWithSubject - : user.collapseMessageWithSubject, - collapseMessageWithSubjectDefault: this.$t('settings.values.' + instance.collapseMessageWithSubject), - - subjectLineBehaviorLocal: typeof user.subjectLineBehavior === 'undefined' - ? instance.subjectLineBehavior - : user.subjectLineBehavior, - subjectLineBehaviorDefault: instance.subjectLineBehavior, - - postContentTypeLocal: typeof user.postContentType === 'undefined' - ? instance.postContentType - : user.postContentType, - postContentTypeDefault: instance.postContentType, - - alwaysShowSubjectInputLocal: typeof user.alwaysShowSubjectInput === 'undefined' - ? instance.alwaysShowSubjectInput - : user.alwaysShowSubjectInput, - alwaysShowSubjectInputDefault: this.$t('settings.values.' + instance.alwaysShowSubjectInput), - - scopeCopyLocal: typeof user.scopeCopy === 'undefined' - ? instance.scopeCopy - : user.scopeCopy, - scopeCopyDefault: this.$t('settings.values.' + instance.scopeCopy), - - minimalScopesModeLocal: typeof user.minimalScopesMode === 'undefined' - ? instance.minimalScopesMode - : user.minimalScopesMode, - minimalScopesModeDefault: this.$t('settings.values.' + instance.minimalScopesMode), - - stopGifs: user.stopGifs, - webPushNotificationsLocal: user.webPushNotifications, - loopVideoSilentOnlyLocal: user.loopVideosSilentOnly, loopSilentAvailable: // Firefox Object.getOwnPropertyDescriptor(HTMLVideoElement.prototype, 'mozHasAudio') || @@ -93,8 +28,6 @@ const settings = { Object.getOwnPropertyDescriptor(HTMLMediaElement.prototype, 'webkitAudioDecodedByteCount') || // Future spec, still not supported in Nightly 63 as of 08/2018 Object.getOwnPropertyDescriptor(HTMLMediaElement.prototype, 'audioTracks'), - playVideosInModal: user.playVideosInModal, - useContainFit: user.useContainFit, backendVersion: instance.backendVersion, frontendVersion: instance.frontendVersion @@ -103,7 +36,8 @@ const settings = { components: { TabSwitcher, StyleSwitcher, - InterfaceLanguageSwitcher + InterfaceLanguageSwitcher, + Checkbox }, computed: { user () { @@ -121,113 +55,56 @@ const settings = { }, backendVersionLink () { return pleromaBeCommitUrl + extractCommit(this.backendVersion) + }, + // Getting localized values for instance-default properties + ...instanceDefaultProperties + .filter(key => multiChoiceProperties.includes(key)) + .map(key => [ + key + 'DefaultValue', + function () { + return this.$store.getters.instanceDefaultConfig[key] + } + ]) + .reduce((acc, [key, value]) => ({ ...acc, [key]: value }), {}), + ...instanceDefaultProperties + .filter(key => !multiChoiceProperties.includes(key)) + .map(key => [ + key + 'LocalizedValue', + function () { + return this.$t('settings.values.' + this.$store.getters.instanceDefaultConfig[key]) + } + ]) + .reduce((acc, [key, value]) => ({ ...acc, [key]: value }), {}), + // Generating computed values for vuex properties + ...Object.keys(configDefaultState) + .map(key => [key, { + get () { return this.$store.getters.mergedConfig[key] }, + set (value) { + this.$store.dispatch('setOption', { name: key, value }) + } + }]) + .reduce((acc, [key, value]) => ({ ...acc, [key]: value }), {}), + // Special cases (need to transform values) + muteWordsString: { + get () { return this.$store.getters.mergedConfig.muteWords.join('\n') }, + set (value) { + this.$store.dispatch('setOption', { + name: 'muteWords', + value: filter(value.split('\n'), (word) => trim(word).length > 0) + }) + } } }, + // Updating nested properties watch: { - hideAttachmentsLocal (value) { - this.$store.dispatch('setOption', { name: 'hideAttachments', value }) - }, - hideAttachmentsInConvLocal (value) { - this.$store.dispatch('setOption', { name: 'hideAttachmentsInConv', value }) - }, - hidePostStatsLocal (value) { - this.$store.dispatch('setOption', { name: 'hidePostStats', value }) - }, - hideUserStatsLocal (value) { - this.$store.dispatch('setOption', { name: 'hideUserStats', value }) - }, - hideFilteredStatusesLocal (value) { - this.$store.dispatch('setOption', { name: 'hideFilteredStatuses', value }) - }, - hideNsfwLocal (value) { - this.$store.dispatch('setOption', { name: 'hideNsfw', value }) - }, - useOneClickNsfw (value) { - this.$store.dispatch('setOption', { name: 'useOneClickNsfw', value }) - }, - preloadImage (value) { - this.$store.dispatch('setOption', { name: 'preloadImage', value }) - }, - hideISPLocal (value) { - this.$store.dispatch('setOption', { name: 'hideISP', value }) - }, - 'notificationVisibilityLocal.likes' (value) { - this.$store.dispatch('setOption', { name: 'notificationVisibility', value: this.$store.state.config.notificationVisibility }) - }, - 'notificationVisibilityLocal.follows' (value) { - this.$store.dispatch('setOption', { name: 'notificationVisibility', value: this.$store.state.config.notificationVisibility }) - }, - 'notificationVisibilityLocal.repeats' (value) { - this.$store.dispatch('setOption', { name: 'notificationVisibility', value: this.$store.state.config.notificationVisibility }) - }, - 'notificationVisibilityLocal.mentions' (value) { - this.$store.dispatch('setOption', { name: 'notificationVisibility', value: this.$store.state.config.notificationVisibility }) - }, - replyVisibilityLocal (value) { - this.$store.dispatch('setOption', { name: 'replyVisibility', value }) - }, - loopVideoLocal (value) { - this.$store.dispatch('setOption', { name: 'loopVideo', value }) - }, - loopVideoSilentOnlyLocal (value) { - this.$store.dispatch('setOption', { name: 'loopVideoSilentOnly', value }) - }, - autoLoadLocal (value) { - this.$store.dispatch('setOption', { name: 'autoLoad', value }) - }, - streamingLocal (value) { - this.$store.dispatch('setOption', { name: 'streaming', value }) - }, - pauseOnUnfocusedLocal (value) { - this.$store.dispatch('setOption', { name: 'pauseOnUnfocused', value }) - }, - hoverPreviewLocal (value) { - this.$store.dispatch('setOption', { name: 'hoverPreview', value }) - }, - autohideFloatingPostButtonLocal (value) { - this.$store.dispatch('setOption', { name: 'autohideFloatingPostButton', value }) - }, - muteWordsString (value) { - value = filter(value.split('\n'), (word) => trim(word).length > 0) - this.$store.dispatch('setOption', { name: 'muteWords', value }) - }, - hideMutedPostsLocal (value) { - this.$store.dispatch('setOption', { name: 'hideMutedPosts', value }) - }, - collapseMessageWithSubjectLocal (value) { - this.$store.dispatch('setOption', { name: 'collapseMessageWithSubject', value }) - }, - scopeCopyLocal (value) { - this.$store.dispatch('setOption', { name: 'scopeCopy', value }) - }, - alwaysShowSubjectInputLocal (value) { - this.$store.dispatch('setOption', { name: 'alwaysShowSubjectInput', value }) - }, - subjectLineBehaviorLocal (value) { - this.$store.dispatch('setOption', { name: 'subjectLineBehavior', value }) - }, - postContentTypeLocal (value) { - this.$store.dispatch('setOption', { name: 'postContentType', value }) - }, - minimalScopesModeLocal (value) { - this.$store.dispatch('setOption', { name: 'minimalScopesMode', value }) - }, - stopGifs (value) { - this.$store.dispatch('setOption', { name: 'stopGifs', value }) - }, - webPushNotificationsLocal (value) { - this.$store.dispatch('setOption', { name: 'webPushNotifications', value }) - if (value) this.$store.dispatch('registerPushNotifications') - }, - playVideosInModal (value) { - this.$store.dispatch('setOption', { name: 'playVideosInModal', value }) - }, - useContainFit (value) { - this.$store.dispatch('setOption', { name: 'useContainFit', value }) - }, - maxThumbnails (value) { - value = this.maxThumbnails = Math.floor(Math.max(value, 0)) - this.$store.dispatch('setOption', { name: 'maxThumbnails', value }) + notificationVisibility: { + handler (value) { + this.$store.dispatch('setOption', { + name: 'notificationVisibility', + value: this.$store.getters.mergedConfig.notificationVisibility + }) + }, + deep: true } } } diff --git a/src/components/settings/settings.vue b/src/components/settings/settings.vue index 920e6e12..a83489d2 100644 --- a/src/components/settings/settings.vue +++ b/src/components/settings/settings.vue @@ -1,373 +1,389 @@ <template> -<div class="settings panel panel-default"> - <div class="panel-heading"> - <div class="title"> - {{$t('settings.settings')}} - </div> + <div class="settings panel panel-default"> + <div class="panel-heading"> + <div class="title"> + {{ $t('settings.settings') }} + </div> - <transition name="fade"> - <template v-if="currentSaveStateNotice"> - <div @click.prevent class="alert error" v-if="currentSaveStateNotice.error"> - {{ $t('settings.saving_err') }} - </div> + <transition name="fade"> + <template v-if="currentSaveStateNotice"> + <div + v-if="currentSaveStateNotice.error" + class="alert error" + @click.prevent + > + {{ $t('settings.saving_err') }} + </div> - <div @click.prevent class="alert transparent" v-if="!currentSaveStateNotice.error"> - {{ $t('settings.saving_ok') }} - </div> - </template> - </transition> - </div> - <div class="panel-body"> -<keep-alive> - <tab-switcher> - <div :label="$t('settings.general')" > - <div class="setting-item"> - <h2>{{ $t('settings.interface') }}</h2> - <ul class="setting-list"> - <li> - <interface-language-switcher /> - </li> - <li v-if="instanceSpecificPanelPresent"> - <input type="checkbox" id="hideISP" v-model="hideISPLocal"> - <label for="hideISP">{{$t('settings.hide_isp')}}</label> - </li> - </ul> - </div> - <div class="setting-item"> - <h2>{{$t('nav.timeline')}}</h2> - <ul class="setting-list"> - <li> - <input type="checkbox" id="hideMutedPosts" v-model="hideMutedPostsLocal"> - <label for="hideMutedPosts">{{$t('settings.hide_muted_posts')}} {{$t('settings.instance_default', { value: hideMutedPostsDefault })}}</label> - </li> - <li> - <input type="checkbox" id="collapseMessageWithSubject" v-model="collapseMessageWithSubjectLocal"> - <label for="collapseMessageWithSubject">{{$t('settings.collapse_subject')}} {{$t('settings.instance_default', { value: collapseMessageWithSubjectDefault })}}</label> - </li> - <li> - <input type="checkbox" id="streaming" v-model="streamingLocal"> - <label for="streaming">{{$t('settings.streaming')}}</label> - <ul class="setting-list suboptions" :class="[{disabled: !streamingLocal}]"> + <div + v-if="!currentSaveStateNotice.error" + class="alert transparent" + @click.prevent + > + {{ $t('settings.saving_ok') }} + </div> + </template> + </transition> + </div> + <div class="panel-body"> + <keep-alive> + <tab-switcher> + <div :label="$t('settings.general')"> + <div class="setting-item"> + <h2>{{ $t('settings.interface') }}</h2> + <ul class="setting-list"> <li> - <input :disabled="!streamingLocal" type="checkbox" id="pauseOnUnfocused" v-model="pauseOnUnfocusedLocal"> - <label for="pauseOnUnfocused">{{$t('settings.pause_on_unfocused')}}</label> + <interface-language-switcher /> + </li> + <li v-if="instanceSpecificPanelPresent"> + <Checkbox v-model="hideISP"> + {{ $t('settings.hide_isp') }} + </Checkbox> </li> </ul> - </li> - <li> - <input type="checkbox" id="autoload" v-model="autoLoadLocal"> - <label for="autoload">{{$t('settings.autoload')}}</label> - </li> - <li> - <input type="checkbox" id="hoverPreview" v-model="hoverPreviewLocal"> - <label for="hoverPreview">{{$t('settings.reply_link_preview')}}</label> - </li> - </ul> - </div> - - <div class="setting-item"> - <h2>{{$t('settings.composing')}}</h2> - <ul class="setting-list"> - <li> - <input type="checkbox" id="scopeCopy" v-model="scopeCopyLocal"> - <label for="scopeCopy"> - {{$t('settings.scope_copy')}} {{$t('settings.instance_default', { value: scopeCopyDefault })}} - </label> - </li> - <li> - <input type="checkbox" id="subjectHide" v-model="alwaysShowSubjectInputLocal"> - <label for="subjectHide"> - {{$t('settings.subject_input_always_show')}} {{$t('settings.instance_default', { value: alwaysShowSubjectInputDefault })}} - </label> - </li> - <li> - <div> - {{$t('settings.subject_line_behavior')}} - <label for="subjectLineBehavior" class="select"> - <select id="subjectLineBehavior" v-model="subjectLineBehaviorLocal"> - <option value="email"> - {{$t('settings.subject_line_email')}} - {{subjectLineBehaviorDefault == 'email' ? $t('settings.instance_default_simple') : ''}} - </option> - <option value="masto"> - {{$t('settings.subject_line_mastodon')}} - {{subjectLineBehaviorDefault == 'mastodon' ? $t('settings.instance_default_simple') : ''}} - </option> - <option value="noop"> - {{$t('settings.subject_line_noop')}} - {{subjectLineBehaviorDefault == 'noop' ? $t('settings.instance_default_simple') : ''}} - </option> - </select> - <i class="icon-down-open"/> - </label> - </div> - </li> - <li> - <div> - {{$t('settings.post_status_content_type')}} - <label for="postContentType" class="select"> - <select id="postContentType" v-model="postContentTypeLocal"> - <option v-for="postFormat in postFormats" :key="postFormat" :value="postFormat"> - {{$t(`post_status.content_type["${postFormat}"]`)}} - {{postContentTypeDefault === postFormat ? $t('settings.instance_default_simple') : ''}} - </option> - </select> - <i class="icon-down-open"/> - </label> - </div> - </li> - <li> - <input type="checkbox" id="minimalScopesMode" v-model="minimalScopesModeLocal"> - <label for="minimalScopesMode"> - {{$t('settings.minimal_scopes_mode')}} {{$t('settings.instance_default', { value: minimalScopesModeDefault })}} - </label> - </li> - <li> - <input type="checkbox" id="autohideFloatingPostButton" v-model="autohideFloatingPostButtonLocal"> - <label for="autohideFloatingPostButton">{{$t('settings.autohide_floating_post_button')}}</label> - </li> - </ul> - </div> + </div> + <div class="setting-item"> + <h2>{{ $t('nav.timeline') }}</h2> + <ul class="setting-list"> + <li> + <Checkbox v-model="hideMutedPosts"> + {{ $t('settings.hide_muted_posts') }} {{ $t('settings.instance_default', { value: hideMutedPostsLocalizedValue }) }} + </Checkbox> + </li> + <li> + <Checkbox v-model="collapseMessageWithSubject"> + {{ $t('settings.collapse_subject') }} {{ $t('settings.instance_default', { value: collapseMessageWithSubjectLocalizedValue }) }} + </Checkbox> + </li> + <li> + <Checkbox v-model="streaming"> + {{ $t('settings.streaming') }} + </Checkbox> + <ul + class="setting-list suboptions" + :class="[{disabled: !streaming}]" + > + <li> + <Checkbox + v-model="pauseOnUnfocused" + :disabled="!streaming" + > + {{ $t('settings.pause_on_unfocused') }} + </Checkbox> + </li> + </ul> + </li> + <li> + <Checkbox v-model="autoLoad"> + {{ $t('settings.autoload') }} + </Checkbox> + </li> + <li> + <Checkbox v-model="hoverPreview"> + {{ $t('settings.reply_link_preview') }} + </Checkbox> + </li> + </ul> + </div> - <div class="setting-item"> - <h2>{{$t('settings.attachments')}}</h2> - <ul class="setting-list"> - <li> - <input type="checkbox" id="hideAttachments" v-model="hideAttachmentsLocal"> - <label for="hideAttachments">{{$t('settings.hide_attachments_in_tl')}}</label> - </li> - <li> - <input type="checkbox" id="hideAttachmentsInConv" v-model="hideAttachmentsInConvLocal"> - <label for="hideAttachmentsInConv">{{$t('settings.hide_attachments_in_convo')}}</label> - </li> - <li> - <label for="maxThumbnails">{{$t('settings.max_thumbnails')}}</label> - <input class="number-input" type="number" id="maxThumbnails" v-model.number="maxThumbnails" min="0" step="1"> - </li> - <li> - <input type="checkbox" id="hideNsfw" v-model="hideNsfwLocal"> - <label for="hideNsfw">{{$t('settings.nsfw_clickthrough')}}</label> - </li> - <ul class="setting-list suboptions" > - <li> - <input :disabled="!hideNsfwLocal" type="checkbox" id="preloadImage" v-model="preloadImage"> - <label for="preloadImage">{{$t('settings.preload_images')}}</label> - </li> - <li> - <input :disabled="!hideNsfwLocal" type="checkbox" id="useOneClickNsfw" v-model="useOneClickNsfw"> - <label for="useOneClickNsfw">{{$t('settings.use_one_click_nsfw')}}</label> - </li> - </ul> - <li> - <input type="checkbox" id="stopGifs" v-model="stopGifs"> - <label for="stopGifs">{{$t('settings.stop_gifs')}}</label> - </li> - <li> - <input type="checkbox" id="loopVideo" v-model="loopVideoLocal"> - <label for="loopVideo">{{$t('settings.loop_video')}}</label> - <ul class="setting-list suboptions" :class="[{disabled: !streamingLocal}]"> + <div class="setting-item"> + <h2>{{ $t('settings.composing') }}</h2> + <ul class="setting-list"> + <li> + <Checkbox v-model="scopeCopy"> + {{ $t('settings.scope_copy') }} {{ $t('settings.instance_default', { value: scopeCopyLocalizedValue }) }} + </Checkbox> + </li> <li> - <input :disabled="!loopVideoLocal || !loopSilentAvailable" type="checkbox" id="loopVideoSilentOnly" v-model="loopVideoSilentOnlyLocal"> - <label for="loopVideoSilentOnly">{{$t('settings.loop_video_silent_only')}}</label> - <div v-if="!loopSilentAvailable" class="unavailable"> - <i class="icon-globe"/>! {{$t('settings.limited_availability')}} + <Checkbox v-model="alwaysShowSubjectInput"> + {{ $t('settings.subject_input_always_show') }} {{ $t('settings.instance_default', { value: alwaysShowSubjectInputLocalizedValue }) }} + </Checkbox> + </li> + <li> + <div> + {{ $t('settings.subject_line_behavior') }} + <label + for="subjectLineBehavior" + class="select" + > + <select + id="subjectLineBehavior" + v-model="subjectLineBehavior" + > + <option value="email"> + {{ $t('settings.subject_line_email') }} + {{ subjectLineBehaviorDefaultValue == 'email' ? $t('settings.instance_default_simple') : '' }} + </option> + <option value="masto"> + {{ $t('settings.subject_line_mastodon') }} + {{ subjectLineBehaviorDefaultValue == 'mastodon' ? $t('settings.instance_default_simple') : '' }} + </option> + <option value="noop"> + {{ $t('settings.subject_line_noop') }} + {{ subjectLineBehaviorDefaultValue == 'noop' ? $t('settings.instance_default_simple') : '' }} + </option> + </select> + <i class="icon-down-open" /> + </label> </div> </li> + <li v-if="postFormats.length > 0"> + <div> + {{ $t('settings.post_status_content_type') }} + <label + for="postContentType" + class="select" + > + <select + id="postContentType" + v-model="postContentType" + > + <option + v-for="postFormat in postFormats" + :key="postFormat" + :value="postFormat" + > + {{ $t(`post_status.content_type["${postFormat}"]`) }} + {{ postContentTypeDefaultValue === postFormat ? $t('settings.instance_default_simple') : '' }} + </option> + </select> + <i class="icon-down-open" /> + </label> + </div> + </li> + <li> + <Checkbox v-model="minimalScopesMode"> + {{ $t('settings.minimal_scopes_mode') }} {{ $t('settings.instance_default', { value: minimalScopesModeLocalizedValue }) }} + </Checkbox> + </li> + <li> + <Checkbox v-model="autohideFloatingPostButton"> + {{ $t('settings.autohide_floating_post_button') }} + </Checkbox> + </li> + <li> + <Checkbox v-model="padEmoji"> + {{ $t('settings.pad_emoji') }} + </Checkbox> + </li> </ul> - </li> - <li> - <input type="checkbox" id="playVideosInModal" v-model="playVideosInModal"> - <label for="playVideosInModal">{{$t('settings.play_videos_in_modal')}}</label> - </li> - <li> - <input type="checkbox" id="useContainFit" v-model="useContainFit"> - <label for="useContainFit">{{$t('settings.use_contain_fit')}}</label> - </li> - </ul> - </div> - - <div class="setting-item"> - <h2>{{$t('settings.notifications')}}</h2> - <ul class="setting-list"> - <li> - <input type="checkbox" id="webPushNotifications" v-model="webPushNotificationsLocal"> - <label for="webPushNotifications"> - {{$t('settings.enable_web_push_notifications')}} - </label> - </li> - </ul> - </div> - </div> + </div> - <div :label="$t('settings.theme')" > - <div class="setting-item"> - <style-switcher></style-switcher> - </div> - </div> + <div class="setting-item"> + <h2>{{ $t('settings.attachments') }}</h2> + <ul class="setting-list"> + <li> + <Checkbox v-model="hideAttachments"> + {{ $t('settings.hide_attachments_in_tl') }} + </Checkbox> + </li> + <li> + <Checkbox v-model="hideAttachmentsInConv"> + {{ $t('settings.hide_attachments_in_convo') }} + </Checkbox> + </li> + <li> + <label for="maxThumbnails"> + {{ $t('settings.max_thumbnails') }} + </label> + <input + id="maxThumbnails" + v-model.number="maxThumbnails" + class="number-input" + type="number" + min="0" + step="1" + > + </li> + <li> + <Checkbox v-model="hideNsfw"> + {{ $t('settings.nsfw_clickthrough') }} + </Checkbox> + </li> + <ul class="setting-list suboptions"> + <li> + <Checkbox + v-model="preloadImage" + :disabled="!hideNsfw" + > + {{ $t('settings.preload_images') }} + </Checkbox> + </li> + <li> + <Checkbox + v-model="useOneClickNsfw" + :disabled="!hideNsfw" + > + {{ $t('settings.use_one_click_nsfw') }} + </Checkbox> + </li> + </ul> + <li> + <Checkbox v-model="stopGifs"> + {{ $t('settings.stop_gifs') }} + </Checkbox> + </li> + <li> + <Checkbox v-model="loopVideo"> + {{ $t('settings.loop_video') }} + </Checkbox> + <ul + class="setting-list suboptions" + :class="[{disabled: !streaming}]" + > + <li> + <Checkbox + v-model="loopVideoSilentOnly" + :disabled="!loopVideo || !loopSilentAvailable" + > + {{ $t('settings.loop_video_silent_only') }} + </Checkbox> + <div + v-if="!loopSilentAvailable" + class="unavailable" + > + <i class="icon-globe" />! {{ $t('settings.limited_availability') }} + </div> + </li> + </ul> + </li> + <li> + <Checkbox v-model="playVideosInModal"> + {{ $t('settings.play_videos_in_modal') }} + </Checkbox> + </li> + <li> + <Checkbox v-model="useContainFit"> + {{ $t('settings.use_contain_fit') }} + </Checkbox> + </li> + </ul> + </div> - <div :label="$t('settings.filtering')" > - <div class="setting-item"> - <div class="select-multiple"> - <span class="label">{{$t('settings.notification_visibility')}}</span> - <ul class="option-list"> - <li> - <input type="checkbox" id="notification-visibility-likes" v-model="notificationVisibilityLocal.likes"> - <label for="notification-visibility-likes"> - {{$t('settings.notification_visibility_likes')}} - </label> - </li> - <li> - <input type="checkbox" id="notification-visibility-repeats" v-model="notificationVisibilityLocal.repeats"> - <label for="notification-visibility-repeats"> - {{$t('settings.notification_visibility_repeats')}} - </label> - </li> - <li> - <input type="checkbox" id="notification-visibility-follows" v-model="notificationVisibilityLocal.follows"> - <label for="notification-visibility-follows"> - {{$t('settings.notification_visibility_follows')}} - </label> - </li> - <li> - <input type="checkbox" id="notification-visibility-mentions" v-model="notificationVisibilityLocal.mentions"> - <label for="notification-visibility-mentions"> - {{$t('settings.notification_visibility_mentions')}} - </label> - </li> - </ul> - </div> - <div> - {{$t('settings.replies_in_timeline')}} - <label for="replyVisibility" class="select"> - <select id="replyVisibility" v-model="replyVisibilityLocal"> - <option value="all" selected>{{$t('settings.reply_visibility_all')}}</option> - <option value="following">{{$t('settings.reply_visibility_following')}}</option> - <option value="self">{{$t('settings.reply_visibility_self')}}</option> - </select> - <i class="icon-down-open"/> - </label> - </div> - <div> - <input type="checkbox" id="hidePostStats" v-model="hidePostStatsLocal"> - <label for="hidePostStats"> - {{$t('settings.hide_post_stats')}} {{$t('settings.instance_default', { value: hidePostStatsDefault })}} - </label> - </div> - <div> - <input type="checkbox" id="hideUserStats" v-model="hideUserStatsLocal"> - <label for="hideUserStats"> - {{$t('settings.hide_user_stats')}} {{$t('settings.instance_default', { value: hideUserStatsDefault })}} - </label> + <div class="setting-item"> + <h2>{{ $t('settings.notifications') }}</h2> + <ul class="setting-list"> + <li> + <Checkbox v-model="webPushNotifications"> + {{ $t('settings.enable_web_push_notifications') }} + </Checkbox> + </li> + </ul> + </div> </div> - </div> - <div class="setting-item"> - <div> - <p>{{$t('settings.filtering_explanation')}}</p> - <textarea id="muteWords" v-model="muteWordsString"></textarea> + + <div :label="$t('settings.theme')"> + <div class="setting-item"> + <style-switcher /> + </div> </div> - <div> - <input type="checkbox" id="hideFilteredStatuses" v-model="hideFilteredStatusesLocal"> - <label for="hideFilteredStatuses"> - {{$t('settings.hide_filtered_statuses')}} {{$t('settings.instance_default', { value: hideFilteredStatusesDefault })}} - </label> + + <div :label="$t('settings.filtering')"> + <div class="setting-item"> + <div class="select-multiple"> + <span class="label">{{ $t('settings.notification_visibility') }}</span> + <ul class="option-list"> + <li> + <Checkbox v-model="notificationVisibility.likes"> + {{ $t('settings.notification_visibility_likes') }} + </Checkbox> + </li> + <li> + <Checkbox v-model="notificationVisibility.repeats"> + {{ $t('settings.notification_visibility_repeats') }} + </Checkbox> + </li> + <li> + <Checkbox v-model="notificationVisibility.follows"> + {{ $t('settings.notification_visibility_follows') }} + </Checkbox> + </li> + <li> + <Checkbox v-model="notificationVisibility.mentions"> + {{ $t('settings.notification_visibility_mentions') }} + </Checkbox> + </li> + </ul> + </div> + <div> + {{ $t('settings.replies_in_timeline') }} + <label + for="replyVisibility" + class="select" + > + <select + id="replyVisibility" + v-model="replyVisibility" + > + <option + value="all" + selected + >{{ $t('settings.reply_visibility_all') }}</option> + <option value="following">{{ $t('settings.reply_visibility_following') }}</option> + <option value="self">{{ $t('settings.reply_visibility_self') }}</option> + </select> + <i class="icon-down-open" /> + </label> + </div> + <div> + <Checkbox v-model="hidePostStats"> + {{ $t('settings.hide_post_stats') }} {{ $t('settings.instance_default', { value: hidePostStatsLocalizedValue }) }} + </Checkbox> + </div> + <div> + <Checkbox v-model="hideUserStats"> + {{ $t('settings.hide_user_stats') }} {{ $t('settings.instance_default', { value: hideUserStatsLocalizedValue }) }} + </Checkbox> + </div> + </div> + <div class="setting-item"> + <div> + <p>{{ $t('settings.filtering_explanation') }}</p> + <textarea + id="muteWords" + v-model="muteWordsString" + /> + </div> + <div> + <Checkbox v-model="hideFilteredStatuses"> + {{ $t('settings.hide_filtered_statuses') }} {{ $t('settings.instance_default', { value: hideFilteredStatusesLocalizedValue }) }} + </Checkbox> + </div> + </div> </div> - </div> - </div> - <div :label="$t('settings.version.title')" > - <div class="setting-item"> - <ul class="setting-list"> - <li> - <p>{{$t('settings.version.backend_version')}}</p> - <ul class="option-list"> + <div :label="$t('settings.version.title')"> + <div class="setting-item"> + <ul class="setting-list"> <li> - <a :href="backendVersionLink" target="_blank">{{backendVersion}}</a> + <p>{{ $t('settings.version.backend_version') }}</p> + <ul class="option-list"> + <li> + <a + :href="backendVersionLink" + target="_blank" + >{{ backendVersion }}</a> + </li> + </ul> </li> - </ul> - </li> - <li> - <p>{{$t('settings.version.frontend_version')}}</p> - <ul class="option-list"> <li> - <a :href="frontendVersionLink" target="_blank">{{frontendVersion}}</a> + <p>{{ $t('settings.version.frontend_version') }}</p> + <ul class="option-list"> + <li> + <a + :href="frontendVersionLink" + target="_blank" + >{{ frontendVersion }}</a> + </li> + </ul> </li> </ul> - </li> - </ul> - </div> - </div> - </tab-switcher> -</keep-alive> + </div> + </div> + </tab-switcher> + </keep-alive> + </div> </div> -</div> </template> <script src="./settings.js"> </script> - -<style lang="scss"> -@import '../../_variables.scss'; - -.setting-item { - border-bottom: 2px solid var(--fg, $fallback--fg); - margin: 1em 1em 1.4em; - padding-bottom: 1.4em; - - > div { - margin-bottom: .5em; - &:last-child { - margin-bottom: 0; - } - } - - &:last-child { - border-bottom: none; - padding-bottom: 0; - margin-bottom: 1em; - } - - select { - min-width: 10em; - } - - - textarea { - width: 100%; - max-width: 100%; - height: 100px; - } - - .unavailable, - .unavailable i { - color: var(--cRed, $fallback--cRed); - color: $fallback--cRed; - } - - .btn { - min-height: 28px; - min-width: 10em; - padding: 0 2em; - } - - .number-input { - max-width: 6em; - } -} -.select-multiple { - display: flex; - .option-list { - margin: 0; - padding-left: .5em; - } -} -.setting-list, -.option-list{ - list-style-type: none; - padding-left: 2em; - li { - margin-bottom: 0.5em; - } - .suboptions { - margin-top: 0.3em - } -} -</style> |
