diff --git a/src/components/settings/settings.js b/src/components/settings/settings.js index b6540d7ec02820a7850b9ee4e90e4af7a61a3cb3..3923fc600b1cd3e07ccf77cfe077e4c21b2902c4 100644 --- a/src/components/settings/settings.js +++ b/src/components/settings/settings.js @@ -5,88 +5,16 @@ 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' const pleromaFeCommitUrl = 'https://git.pleroma.social/pleroma/pleroma-fe/commit/' const pleromaBeCommitUrl = 'https://git.pleroma.social/pleroma/pleroma/commit/' const settings = { data () { - const user = this.$store.state.config const instance = this.$store.state.instance return { - hideAttachmentsLocal: user.hideAttachments, - padEmojiLocal: user.padEmoji, - 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') || @@ -94,8 +22,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 @@ -122,116 +48,46 @@ const settings = { }, backendVersionLink () { return pleromaBeCommitUrl + extractCommit(this.backendVersion) + }, + // Getting localized values for instance-default properties + ...instanceDefaultProperties + .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 }) - }, - padEmojiLocal (value) { - this.$store.dispatch('setOption', { name: 'padEmoji', 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.state.config.notificationVisibility + }) + }, + deep: true } } } diff --git a/src/components/settings/settings.vue b/src/components/settings/settings.vue index 6d87a06031cd04f33e2df6e31761d65529ad255c..261efb7e537834a9af729c3458051d1275d02e16 100644 --- a/src/components/settings/settings.vue +++ b/src/components/settings/settings.vue @@ -38,7 +38,7 @@ <li v-if="instanceSpecificPanelPresent"> <input id="hideISP" - v-model="hideISPLocal" + v-model="hideISP" type="checkbox" > <label for="hideISP">{{ $t('settings.hide_isp') }}</label> @@ -51,35 +51,35 @@ <li> <input id="hideMutedPosts" - v-model="hideMutedPostsLocal" + v-model="hideMutedPosts" type="checkbox" > - <label for="hideMutedPosts">{{ $t('settings.hide_muted_posts') }} {{ $t('settings.instance_default', { value: hideMutedPostsDefault }) }}</label> + <label for="hideMutedPosts">{{ $t('settings.hide_muted_posts') }} {{ $t('settings.instance_default', { value: hideMutedPostsLocalizedValue }) }}</label> </li> <li> <input id="collapseMessageWithSubject" - v-model="collapseMessageWithSubjectLocal" + v-model="collapseMessageWithSubject" type="checkbox" > - <label for="collapseMessageWithSubject">{{ $t('settings.collapse_subject') }} {{ $t('settings.instance_default', { value: collapseMessageWithSubjectDefault }) }}</label> + <label for="collapseMessageWithSubject">{{ $t('settings.collapse_subject') }} {{ $t('settings.instance_default', { value: collapseMessageWithSubjectLocalizedValue }) }}</label> </li> <li> <input id="streaming" - v-model="streamingLocal" + v-model="streaming" type="checkbox" > <label for="streaming">{{ $t('settings.streaming') }}</label> <ul class="setting-list suboptions" - :class="[{disabled: !streamingLocal}]" + :class="[{disabled: !streaming}]" > <li> <input id="pauseOnUnfocused" - v-model="pauseOnUnfocusedLocal" - :disabled="!streamingLocal" + v-model="pauseOnUnfocused" + :disabled="!streaming" type="checkbox" > <label for="pauseOnUnfocused">{{ $t('settings.pause_on_unfocused') }}</label> @@ -89,7 +89,7 @@ <li> <input id="autoload" - v-model="autoLoadLocal" + v-model="autoLoad" type="checkbox" > <label for="autoload">{{ $t('settings.autoload') }}</label> @@ -97,7 +97,7 @@ <li> <input id="hoverPreview" - v-model="hoverPreviewLocal" + v-model="hoverPreview" type="checkbox" > <label for="hoverPreview">{{ $t('settings.reply_link_preview') }}</label> @@ -111,21 +111,21 @@ <li> <input id="scopeCopy" - v-model="scopeCopyLocal" + v-model="scopeCopy" type="checkbox" > <label for="scopeCopy"> - {{ $t('settings.scope_copy') }} {{ $t('settings.instance_default', { value: scopeCopyDefault }) }} + {{ $t('settings.scope_copy') }} {{ $t('settings.instance_default', { value: scopeCopyLocalizedValue }) }} </label> </li> <li> <input id="subjectHide" - v-model="alwaysShowSubjectInputLocal" + v-model="alwaysShowSubjectInput" type="checkbox" > <label for="subjectHide"> - {{ $t('settings.subject_input_always_show') }} {{ $t('settings.instance_default', { value: alwaysShowSubjectInputDefault }) }} + {{ $t('settings.subject_input_always_show') }} {{ $t('settings.instance_default', { value: alwaysShowSubjectInputLocalizedValue }) }} </label> </li> <li> @@ -137,19 +137,19 @@ > <select id="subjectLineBehavior" - v-model="subjectLineBehaviorLocal" + v-model="subjectLineBehavior" > <option value="email"> {{ $t('settings.subject_line_email') }} - {{ subjectLineBehaviorDefault == 'email' ? $t('settings.instance_default_simple') : '' }} + {{ subjectLineBehaviorLocalizedValue == 'email' ? $t('settings.instance_default_simple') : '' }} </option> <option value="masto"> {{ $t('settings.subject_line_mastodon') }} - {{ subjectLineBehaviorDefault == 'mastodon' ? $t('settings.instance_default_simple') : '' }} + {{ subjectLineBehaviorLocalizedValue == 'mastodon' ? $t('settings.instance_default_simple') : '' }} </option> <option value="noop"> {{ $t('settings.subject_line_noop') }} - {{ subjectLineBehaviorDefault == 'noop' ? $t('settings.instance_default_simple') : '' }} + {{ subjectLineBehaviorLocalizedValue == 'noop' ? $t('settings.instance_default_simple') : '' }} </option> </select> <i class="icon-down-open" /> @@ -165,7 +165,7 @@ > <select id="postContentType" - v-model="postContentTypeLocal" + v-model="postContentType" > <option v-for="postFormat in postFormats" @@ -173,7 +173,7 @@ :value="postFormat" > {{ $t(`post_status.content_type["${postFormat}"]`) }} - {{ postContentTypeDefault === postFormat ? $t('settings.instance_default_simple') : '' }} + {{ postContentTypeLocalizedValue === postFormat ? $t('settings.instance_default_simple') : '' }} </option> </select> <i class="icon-down-open" /> @@ -183,17 +183,17 @@ <li> <input id="minimalScopesMode" - v-model="minimalScopesModeLocal" + v-model="minimalScopesMode" type="checkbox" > <label for="minimalScopesMode"> - {{ $t('settings.minimal_scopes_mode') }} {{ $t('settings.instance_default', { value: minimalScopesModeDefault }) }} + {{ $t('settings.minimal_scopes_mode') }} {{ $t('settings.instance_default', { value: minimalScopesModeLocalizedValue }) }} </label> </li> <li> <input id="autohideFloatingPostButton" - v-model="autohideFloatingPostButtonLocal" + v-model="autohideFloatingPostButton" type="checkbox" > <label for="autohideFloatingPostButton">{{ $t('settings.autohide_floating_post_button') }}</label> @@ -201,7 +201,7 @@ <li> <input id="padEmoji" - v-model="padEmojiLocal" + v-model="padEmoji" type="checkbox" > <label for="padEmoji">{{ $t('settings.pad_emoji') }}</label> @@ -215,7 +215,7 @@ <li> <input id="hideAttachments" - v-model="hideAttachmentsLocal" + v-model="hideAttachments" type="checkbox" > <label for="hideAttachments">{{ $t('settings.hide_attachments_in_tl') }}</label> @@ -223,7 +223,7 @@ <li> <input id="hideAttachmentsInConv" - v-model="hideAttachmentsInConvLocal" + v-model="hideAttachmentsInConv" type="checkbox" > <label for="hideAttachmentsInConv">{{ $t('settings.hide_attachments_in_convo') }}</label> @@ -242,7 +242,7 @@ <li> <input id="hideNsfw" - v-model="hideNsfwLocal" + v-model="hideNsfw" type="checkbox" > <label for="hideNsfw">{{ $t('settings.nsfw_clickthrough') }}</label> @@ -252,7 +252,7 @@ <input id="preloadImage" v-model="preloadImage" - :disabled="!hideNsfwLocal" + :disabled="!hideNsfw" type="checkbox" > <label for="preloadImage">{{ $t('settings.preload_images') }}</label> @@ -261,7 +261,7 @@ <input id="useOneClickNsfw" v-model="useOneClickNsfw" - :disabled="!hideNsfwLocal" + :disabled="!hideNsfw" type="checkbox" > <label for="useOneClickNsfw">{{ $t('settings.use_one_click_nsfw') }}</label> @@ -278,19 +278,19 @@ <li> <input id="loopVideo" - v-model="loopVideoLocal" + v-model="loopVideo" type="checkbox" > <label for="loopVideo">{{ $t('settings.loop_video') }}</label> <ul class="setting-list suboptions" - :class="[{disabled: !streamingLocal}]" + :class="[{disabled: !streaming}]" > <li> <input id="loopVideoSilentOnly" - v-model="loopVideoSilentOnlyLocal" - :disabled="!loopVideoLocal || !loopSilentAvailable" + v-model="loopVideoSilentOnly" + :disabled="!loopVideo || !loopSilentAvailable" type="checkbox" > <label for="loopVideoSilentOnly">{{ $t('settings.loop_video_silent_only') }}</label> @@ -328,7 +328,7 @@ <li> <input id="webPushNotifications" - v-model="webPushNotificationsLocal" + v-model="webPushNotifications" type="checkbox" > <label for="webPushNotifications"> @@ -353,7 +353,7 @@ <li> <input id="notification-visibility-likes" - v-model="notificationVisibilityLocal.likes" + v-model="notificationVisibility.likes" type="checkbox" > <label for="notification-visibility-likes"> @@ -363,7 +363,7 @@ <li> <input id="notification-visibility-repeats" - v-model="notificationVisibilityLocal.repeats" + v-model="notificationVisibility.repeats" type="checkbox" > <label for="notification-visibility-repeats"> @@ -373,7 +373,7 @@ <li> <input id="notification-visibility-follows" - v-model="notificationVisibilityLocal.follows" + v-model="notificationVisibility.follows" type="checkbox" > <label for="notification-visibility-follows"> @@ -383,7 +383,7 @@ <li> <input id="notification-visibility-mentions" - v-model="notificationVisibilityLocal.mentions" + v-model="notificationVisibility.mentions" type="checkbox" > <label for="notification-visibility-mentions"> @@ -400,7 +400,7 @@ > <select id="replyVisibility" - v-model="replyVisibilityLocal" + v-model="replyVisibility" > <option value="all" @@ -415,21 +415,21 @@ <div> <input id="hidePostStats" - v-model="hidePostStatsLocal" + v-model="hidePostStats" type="checkbox" > <label for="hidePostStats"> - {{ $t('settings.hide_post_stats') }} {{ $t('settings.instance_default', { value: hidePostStatsDefault }) }} + {{ $t('settings.hide_post_stats') }} {{ $t('settings.instance_default', { value: hidePostStatsLocalizedValue }) }} </label> </div> <div> <input id="hideUserStats" - v-model="hideUserStatsLocal" + v-model="hideUserStats" type="checkbox" > <label for="hideUserStats"> - {{ $t('settings.hide_user_stats') }} {{ $t('settings.instance_default', { value: hideUserStatsDefault }) }} + {{ $t('settings.hide_user_stats') }} {{ $t('settings.instance_default', { value: hideUserStatsLocalizedValue }) }} </label> </div> </div> @@ -444,11 +444,11 @@ <div> <input id="hideFilteredStatuses" - v-model="hideFilteredStatusesLocal" + v-model="hideFilteredStatuses" type="checkbox" > <label for="hideFilteredStatuses"> - {{ $t('settings.hide_filtered_statuses') }} {{ $t('settings.instance_default', { value: hideFilteredStatusesDefault }) }} + {{ $t('settings.hide_filtered_statuses') }} {{ $t('settings.instance_default', { value: hideFilteredStatusesLocalizedValue }) }} </label> </div> </div> diff --git a/src/modules/config.js b/src/modules/config.js index 5245308d4d8c37215a70797e580cb36f7880ba39..78314118417683208d08bcab297616efd0e7c0ce 100644 --- a/src/modules/config.js +++ b/src/modules/config.js @@ -3,8 +3,9 @@ import { setPreset, applyTheme } from '../services/style_setter/style_setter.js' const browserLocale = (window.navigator.language || 'en').split('-')[0] -const defaultState = { +export const defaultState = { colors: {}, + // bad name: actually hides posts of muted USERS hideMutedPosts: undefined, // instance default collapseMessageWithSubject: undefined, // instance default padEmoji: true, @@ -37,7 +38,14 @@ const defaultState = { subjectLineBehavior: undefined, // instance default alwaysShowSubjectInput: undefined, // instance default postContentType: undefined, // instance default - minimalScopesMode: undefined // instance default + minimalScopesMode: undefined, // instance default + // This hides statuses filtered via a word filter + hideFilteredStatuses: undefined, // instance default + playVideosInModal: false, + useOneClickNsfw: false, + useContainFit: false, + hidePostStats: undefined, // instance default + hideUserStats: undefined // instance default } // caching the instance default properties diff --git a/src/modules/instance.js b/src/modules/instance.js index 7d602aa103650952839a21fb84639f7f2a6b42c0..0c1235cafc8fb29fd598fdecb571d661f1bab41d 100644 --- a/src/modules/instance.js +++ b/src/modules/instance.js @@ -1,5 +1,6 @@ import { set } from 'vue' import { setPreset } from '../services/style_setter/style_setter.js' +import { instanceDefaultProperties } from './config.js' const defaultState = { // Stuff from static/config.json and apiConfig @@ -72,6 +73,13 @@ const instance = { } } }, + getters: { + instanceDefaultConfig (state) { + return instanceDefaultProperties + .map(key => [key, state[key]]) + .reduce((acc, [key, value]) => ({ ...acc, [key]: value }), {}) + } + }, actions: { setInstanceOption ({ commit, dispatch }, { name, value }) { commit('setInstanceOption', { name, value })