diff --git a/src/App.js b/src/App.js index 19d28f843..4fcfaf2c6 100644 --- a/src/App.js +++ b/src/App.js @@ -156,7 +156,7 @@ export default { } } }, - shoutJoined() { + shout() { return useShoutStore().joined }, isChats() { diff --git a/src/App.vue b/src/App.vue index f432d8bc4..e5e088bc3 100644 --- a/src/App.vue +++ b/src/App.vue @@ -60,8 +60,8 @@ /> - - + {{ ' ' }} @@ -100,7 +99,7 @@ override-backend-description override-backend-description-label override-available-options - :options="[...limitLocalContentOptions]" + :options="limitLocalContentOptions" path=":pleroma.:instance.:limit_to_local_content" /> diff --git a/src/components/settings_modal/helpers/attachment_setting.js b/src/components/settings_modal/helpers/attachment_setting.js index cbcd4abf8..7ba910950 100644 --- a/src/components/settings_modal/helpers/attachment_setting.js +++ b/src/components/settings_modal/helpers/attachment_setting.js @@ -29,7 +29,7 @@ export default { // The "server" part is primarily for local dev, but could be useful for alt-domain or multiuser usage. const url = path.includes('://') ? path : useInstanceStore().server + path return { - type: fileTypeExt(url), + mimetype: fileTypeExt(url), url, } }, diff --git a/src/components/settings_modal/helpers/color_setting.vue b/src/components/settings_modal/helpers/color_setting.vue index f8f3b9427..26789ee09 100644 --- a/src/components/settings_modal/helpers/color_setting.vue +++ b/src/components/settings_modal/helpers/color_setting.vue @@ -20,7 +20,6 @@ {{ ' ' }} - - - {{ ' ' }} - @@ -36,6 +29,13 @@ :value="realDraftMode ? draft :state" @change="update" > + {{ ' ' }} + + +

diff --git a/src/components/settings_modal/tabs/clutter_tab.vue b/src/components/settings_modal/tabs/clutter_tab.vue index 8ae416ff8..fe75582ed 100644 --- a/src/components/settings_modal/tabs/clutter_tab.vue +++ b/src/components/settings_modal/tabs/clutter_tab.vue @@ -62,18 +62,12 @@

  • - + {{ $t('settings.hide_attachments_in_tl') }}
  • - + {{ $t('settings.hide_attachments_in_convo') }}
  • diff --git a/src/components/settings_modal/tabs/composing_tab.js b/src/components/settings_modal/tabs/composing_tab.js index b2ddbe54a..908582659 100644 --- a/src/components/settings_modal/tabs/composing_tab.js +++ b/src/components/settings_modal/tabs/composing_tab.js @@ -12,7 +12,6 @@ import SharedComputedObject from '../helpers/shared_computed_object.js' import UnitSetting from '../helpers/unit_setting.vue' import { useInstanceStore } from 'src/stores/instance.js' -import { useInstanceCapabilitiesStore } from 'src/stores/instance_capabilities.js' import { useSyncConfigStore } from 'src/stores/sync_config.js' import localeService from 'src/services/locale/locale.service.js' @@ -105,7 +104,7 @@ const ComposingTab = { }, computed: { postFormats() { - return useInstanceCapabilitiesStore().postFormats + return useInstanceStore().postFormats || [] }, postContentOptions() { return this.postFormats.map((format) => ({ diff --git a/src/components/settings_modal/tabs/composing_tab.vue b/src/components/settings_modal/tabs/composing_tab.vue index 755539096..4b6c0bb51 100644 --- a/src/components/settings_modal/tabs/composing_tab.vue +++ b/src/components/settings_modal/tabs/composing_tab.vue @@ -29,7 +29,6 @@ id="postContentType" path="postContentType" :options="postContentOptions" - :local="true" > {{ $t('settings.default_post_status_content_type') }} @@ -91,7 +90,6 @@
  • {{ $t('settings.image_compression') }} @@ -100,7 +98,6 @@
  • diff --git a/src/components/settings_modal/tabs/general_tab.vue b/src/components/settings_modal/tabs/general_tab.vue index a3cb5be07..905a2baec 100644 --- a/src/components/settings_modal/tabs/general_tab.vue +++ b/src/components/settings_modal/tabs/general_tab.vue @@ -68,6 +68,7 @@ name="ui" :label="$t('settings.style.fonts.components_inline.interface')" :fallback="{ family: 'sans-serif' }" + :is-local="true" no-inherit="1" @update:model-value="v => updateFont('interface', v)" /> @@ -76,6 +77,7 @@ {{ $t('settings.emoji_reactions_scale') }} diff --git a/src/components/settings_modal/tabs/layout_tab.vue b/src/components/settings_modal/tabs/layout_tab.vue index ca514e0cb..acae859a0 100644 --- a/src/components/settings_modal/tabs/layout_tab.vue +++ b/src/components/settings_modal/tabs/layout_tab.vue @@ -40,7 +40,6 @@
  • @@ -84,18 +83,12 @@
  • - + {{ $t('settings.right_sidebar') }}
  • - + {{ $t('settings.navbar_column_stretch') }}
  • diff --git a/src/components/user_avatar/user_avatar.js b/src/components/user_avatar/user_avatar.js index d484303c1..fdf766f58 100644 --- a/src/components/user_avatar/user_avatar.js +++ b/src/components/user_avatar/user_avatar.js @@ -37,7 +37,7 @@ const UserAvatar = { data() { return { showPlaceholder: false, - defaultAvatar: `${useInstanceStore().server + useInstanceStore().instanceIdentity.defaultAvatar}`, + defaultAvatar: `${useInstanceStore().server + useInstanceStore().defaultAvatar}`, betterShadow: useInterfaceStore().browserSupport.cssFilter, } }, diff --git a/src/modules/api.js b/src/modules/api.js index 6f4b8b15f..d6bf27f23 100644 --- a/src/modules/api.js +++ b/src/modules/api.js @@ -345,7 +345,7 @@ const api = { // Set up websocket connection const token = state.wsToken if ( - useInstanceCapabilitiesStore().shoutAvailable && + useInstanceStore().shoutAvailable && typeof token !== 'undefined' && state.socket === null ) { diff --git a/src/modules/default_config_state.js b/src/modules/default_config_state.js index fbfaf08a3..af2f60ac4 100644 --- a/src/modules/default_config_state.js +++ b/src/modules/default_config_state.js @@ -45,6 +45,7 @@ export const instanceDefaultConfig = { muteSensitiveStatuses: false, collapseMessageWithSubject: false, padEmoji: true, + hideAttachments: false, hideAttachmentsInConv: false, hideScrobbles: false, hideScrobblesAfter: '2d', @@ -94,9 +95,12 @@ export const instanceDefaultConfig = { webPushAlwaysShowNotifications: false, interfaceLanguage: browserLocale, hideScopeNotice: false, + useStreamingApi: false, + sidebarRight: false, scopeCopy: true, subjectLineBehavior: 'email', alwaysShowSubjectInput: true, + postContentType: 'text/plain', minimalScopesMode: false, // This hides statuses filtered via a word filter @@ -129,8 +133,19 @@ export const instanceDefaultConfig = { userPopoverOverlay: false, userCardLeftJustify: false, userCardHidePersonalMarks: false, + sidebarColumnWidth: '25rem', + contentColumnWidth: '45rem', + notifsColumnWidth: '25rem', + themeEditorMinWidth: '0rem', + emojiReactionsScale: 0.5, + textSize: '1rem', + emojiSize: '2.2rem', + navbarSize: '3.5rem', + panelHeaderSize: '3.2rem', forcedRoundness: -1, + navbarColumnStretch: false, greentext: false, + mentionLinkDisplay: 'short', mentionLinkShowTooltip: true, mentionLinkShowAvatar: false, mentionLinkFadeDomain: true, @@ -160,27 +175,8 @@ export const instanceDefaultConfig = { useAbsoluteTimeFormat: false, absoluteTimeFormatMinAge: '0d', absoluteTime12h: '24h', -} - -export const defaultConfigLocal = { - hideAttachments: false, - hideAttachmentsInConv: false, - postContentType: 'text/plain', - sidebarRight: false, - sidebarColumnWidth: '25rem', - contentColumnWidth: '45rem', - notifsColumnWidth: '25rem', - themeEditorMinWidth: '0rem', - emojiReactionsScale: 0.5, - textSize: '1rem', - emojiSize: '2.2rem', - navbarSize: '3.5rem', - panelHeaderSize: '3.2rem', - navbarColumnStretch: false, - mentionLinkDisplay: 'short', - alwaysUseJpeg: false, imageCompression: true, - useStreamingApi: false, + alwaysUseJpeg: false, } export const makeUndefined = (c) => diff --git a/src/modules/old_default_config_state.js b/src/modules/old_default_config_state.js index e53cafe29..3977a5d89 100644 --- a/src/modules/old_default_config_state.js +++ b/src/modules/old_default_config_state.js @@ -1,187 +1,129 @@ // this is a snapshot of config keys used prior to sync config. // used to migrate from old config. +export const defaultStateKeys = [ + 'expertLevel', + 'hideISP', + 'hideInstanceWallpaper', + 'hideShoutbox', + 'hideMutedPosts', + 'hideMutedThreads', + 'hideWordFilteredPosts', + 'muteBotStatuses', + 'muteSensitiveStatuses', + 'collapseMessageWithSubject', + 'padEmoji', + 'hideAttachments', + 'hideAttachmentsInConv', + 'hideScrobbles', + 'hideScrobblesAfter', + 'maxThumbnails', + 'hideNsfw', + 'preloadImage', + 'loopVideo', + 'loopVideoSilentOnly', + 'streaming', + 'emojiReactionsOnTimeline', + 'alwaysShowNewPostButton', + 'autohideFloatingPostButton', + 'pauseOnUnfocused', + 'stopGifs', + 'replyVisibility', + 'thirdColumnMode', + 'notificationVisibility', + 'notificationNative', + 'webPushNotifications', + 'webPushAlwaysShowNotifications', + 'interfaceLanguage', + 'hideScopeNotice', + 'useStreamingApi', + 'sidebarRight', + 'scopeCopy', + 'subjectLineBehavior', + 'alwaysShowSubjectInput', + 'postContentType', + 'minimalScopesMode', + 'hideFilteredStatuses', + 'modalOnRepeat', + 'modalOnUnfollow', + 'modalOnBlock', + 'modalOnMute', + 'modalOnMuteConversation', + 'modalOnMuteDomain', + 'modalOnDelete', + 'modalOnLogout', + 'modalOnApproveFollow', + 'modalOnDenyFollow', + 'modalOnRemoveUserFromFollowers', + 'onMuteDefaultAction', + 'onBlockDefaultAction', + 'modalMobileCenter', + 'playVideosInModal', + 'useOneClickNsfw', + 'useContainFit', + 'disableStickyHeaders', + 'showScrollbars', + 'userPopoverAvatarAction', + 'userPopoverOverlay', + 'userCardLeftJustify', + 'userCardHidePersonalMarks', + 'sidebarColumnWidth', + 'contentColumnWidth', + 'notifsColumnWidth', + 'themeEditorMinWidth', + 'emojiReactionsScale', + 'textSize', + 'emojiSize', + 'navbarSize', + 'panelHeaderSize', + 'forcedRoundness', + 'navbarColumnStretch', + 'greentext', + 'mentionLinkDisplay', + 'mentionLinkShowTooltip', + 'mentionLinkShowAvatar', + 'mentionLinkFadeDomain', + 'mentionLinkShowYous', + 'mentionLinkBoldenYou', + 'hidePostStats', + 'hideBotIndication', + 'hideUserStats', + 'virtualScrolling', + 'sensitiveByDefault', + 'conversationDisplay', + 'conversationTreeAdvanced', + 'conversationOtherRepliesButton', + 'conversationTreeFadeAncestors', + 'showExtraNotifications', + 'showExtraNotificationsTip', + 'showChatsInExtraNotifications', + 'showAnnouncementsInExtraNotifications', + 'showFollowRequestsInExtraNotifications', + 'maxDepthInThread', + 'autocompleteSelect', + 'closingDrawerMarksAsSeen', + 'unseenAtTop', + 'ignoreInactionableSeen', + 'unsavedPostAction', + 'autoSaveDraft', + 'useAbsoluteTimeFormat', + 'absoluteTimeFormatMinAge', + 'absoluteTime12h', + 'imageCompression', + 'alwaysUseJpeg', + 'theme', -// commented entries are unsynced stuff -export const defaultConfigSync = { - expertLevel: 0, // used to track which settings to show and hide - hideISP: false, - hideInstanceWallpaper: false, - hideShoutbox: false, - // bad name: actually hides posts of muted USERS - hideMutedPosts: false, - hideMutedThreads: true, - hideWordFilteredPosts: false, - muteBotStatuses: false, - muteSensitiveStatuses: false, - collapseMessageWithSubject: false, - padEmoji: true, - hideScrobbles: false, - hideScrobblesAfter: '2d', - maxThumbnails: 16, - hideNsfw: true, - preloadImage: true, - loopVideo: true, - loopVideoSilentOnly: true, - /// This is not the streaming API configuration, but rather an option - /// for automatically loading new posts into the timeline without - /// the user clicking the Show New button. - streaming: false, - emojiReactionsOnTimeline: true, - alwaysShowNewPostButton: false, - autohideFloatingPostButton: false, - pauseOnUnfocused: true, - stopGifs: true, - replyVisibility: 'all', - thirdColumnMode: 'notifications', - notificationVisibility: { - follows: true, - mentions: true, - statuses: true, - likes: true, - repeats: true, - moves: true, - emojiReactions: true, - followRequest: true, - reports: true, - chatMention: true, - polls: true, - }, - notificationNative: { - follows: true, - mentions: true, - statuses: true, - likes: false, - repeats: false, - moves: false, - emojiReactions: false, - followRequest: true, - reports: true, - chatMention: true, - polls: true, - }, - webPushNotifications: false, - webPushAlwaysShowNotifications: false, - //interfaceLanguage: '', - hideScopeNotice: false, - useStreamingApi: false, - sidebarRight: false, - scopeCopy: true, - subjectLineBehavior: 'email', - alwaysShowSubjectInput: true, - postContentType: 'text/plain', - minimalScopesMode: false, + 'colors', - // This hides statuses filtered via a word filter - hideFilteredStatuses: false, + 'customTheme', + 'customThemeSource', - // Confirmations - modalOnRepeat: false, - modalOnUnfollow: false, - modalOnBlock: true, - modalOnMute: false, - modalOnMuteConversation: false, - modalOnMuteDomain: true, - modalOnDelete: true, - modalOnLogout: true, - modalOnApproveFollow: false, - modalOnDenyFollow: false, - modalOnRemoveUserFromFollowers: false, - - // Expiry confirmations/default actions - onMuteDefaultAction: 'ask', - onBlockDefaultAction: 'ask', - - modalMobileCenter: false, - playVideosInModal: false, - useOneClickNsfw: false, - useContainFit: true, - disableStickyHeaders: false, - showScrollbars: false, - userPopoverAvatarAction: 'open', - userPopoverOverlay: false, - userCardLeftJustify: false, - userCardHidePersonalMarks: false, - forcedRoundness: -1, - greentext: false, - mentionLinkShowTooltip: true, - mentionLinkShowAvatar: false, - mentionLinkFadeDomain: true, - mentionLinkShowYous: false, - mentionLinkBoldenYou: true, - hidePostStats: false, - hideBotIndication: false, - hideUserStats: false, - virtualScrolling: true, - sensitiveByDefault: false, - conversationDisplay: 'linear', - conversationTreeAdvanced: false, - conversationOtherRepliesButton: 'below', - conversationTreeFadeAncestors: false, - showExtraNotifications: true, - showExtraNotificationsTip: true, - showChatsInExtraNotifications: true, - showAnnouncementsInExtraNotifications: true, - showFollowRequestsInExtraNotifications: true, - maxDepthInThread: 6, - autocompleteSelect: false, - closingDrawerMarksAsSeen: true, - unseenAtTop: false, - ignoreInactionableSeen: false, - unsavedPostAction: 'confirm', - autoSaveDraft: false, - useAbsoluteTimeFormat: false, - absoluteTimeFormatMinAge: '0d', - absoluteTime12h: '24h', - theme3hacks: { - // Hacks, user overrides that are independent of theme used - underlay: 'none', - fonts: { - interface: undefined, - input: undefined, - post: undefined, - monospace: undefined, - }, - }, - // Special processing - // Theme stuff - theme: undefined, // Very old theme store, stores preset name, still in use - - // V1 - colors: {}, // VERY old theme store, just colors of V1, probably not even used anymore - - // V2 - customTheme: undefined, // "snapshot", previously was used as actual theme store for V2 so it's still used in case of PleromaFE downgrade event. - customThemeSource: undefined, // "source", stores original theme data - - // V3 - style: null, - styleCustomData: null, - palette: null, - paletteCustomData: null, - themeDebug: false, // debug mode that uses computed backgrounds instead of real ones to debug contrast functions - forceThemeRecompilation: false, // flag that forces recompilation on boot even if cache exists - - // Those are handled outside config now - // muteWords: [], - // highlight: {}, -} - -export const defaultConfigLocal = { - hideAttachments: false, - hideAttachmentsInConv: false, - sidebarColumnWidth: '25rem', - contentColumnWidth: '45rem', - notifsColumnWidth: '25rem', - themeEditorMinWidth: '0rem', - emojiReactionsScale: 0.5, - textSize: '1rem', - emojiSize: '2.2rem', - navbarSize: '3.5rem', - panelHeaderSize: '3.2rem', - navbarColumnStretch: false, - mentionLinkDisplay: 'short', - imageCompression: true, - alwaysUseJpeg: false, - imageCompression: true, - alwaysUseJpeg: false, -} + 'style', + 'styleCustomData', + 'palette', + 'paletteCustomData', + 'themeDebug', + 'forceThemeRecompilation', + 'theme3hacks', + // 'muteWords', // mutes migrated separately + // 'highlight', // highlight migration is done separately +] diff --git a/src/stores/sync_config.js b/src/stores/sync_config.js index e43356e8e..c460b38b0 100644 --- a/src/stores/sync_config.js +++ b/src/stores/sync_config.js @@ -22,7 +22,7 @@ import { useLocalConfigStore } from 'src/stores/local_config.js' import { storage } from 'src/lib/storage.js' import { defaultState as configDefaultState } from 'src/modules/default_config_state.js' -import { defaultConfigSync } from 'src/modules/old_default_config_state.js' +import { defaultStateKeys } from 'src/modules/old_default_config_state.js' export const VERSION = 2 export const NEW_USER_DATE = new Date('2022-08-04') // date of writing this, basically @@ -38,6 +38,7 @@ export const defaultState = { // storage of flags - stuff that can only be set and incremented flagStorage: { updateCounter: 0, // Counter for most recent update notification seen + configMigration: 0, // Counter for config -> server-side migrations reset: 0, // special flag that can be used to force-reset all data, debug purposes only // special reset codes: // 1000: trim keys to those known by currently running FE @@ -416,6 +417,14 @@ export const _doMigrations = async (data, setPreference) => { console.debug( 'Data has older version, seeing if there any migrations that can be applied', ) + + if (data._version === 1) { + // Migrate old config to sync config + const vuexState = await storage.getItem('vuex-lz') + defaultStateKeys.forEach((key) => { + setPreference({ path: `simple.${key}`, value: vuexState.config[key] }) + }) + } } if (data._version > VERSION) { @@ -614,31 +623,6 @@ export const useSyncConfigStore = defineStore('sync_config', { const flagsTemplate = userNew ? newUserFlags : defaultState.flagStorage let dirty = false - console.debug('Migrating from old config') - const vuexState = await storage.getItem('vuex-lz') - const { config } = vuexState - - const migratedEntries = new Set(config._syncMigration ?? []) - console.debug(`Already migrated Values: ${[...migratedEntries].join()}`) - - Object.entries(defaultConfigSync).forEach(([key, value]) => { - const oldValue = config[key] - const defaultValue = value - - const present = oldValue !== undefined - const migrated = migratedEntries.has(key) - const different = !isEqual(oldValue, defaultValue) - - if (present && !migrated && different) { - console.debug(`Migrating config ${key}: ${oldValue}`,) - this.setPreference({ path: `simple.${key}`, oldValue }) - migratedEntries.add(key) - needUpload = true - } - }) - vuexState.config._syncMigration = [...migratedEntries] - storage.setItem('vuex-lz', vuexState) - if (recent === null) { console.debug( `Data is empty, initializing for ${userNew ? 'new' : 'existing'} user`, @@ -657,12 +641,7 @@ export const useSyncConfigStore = defineStore('sync_config', { // discarding timestamps and versions const { _timestamp: _0, _version: _1, ...recentData } = recent const { _timestamp: _2, _version: _3, ...staleData } = stale - dirty = !isEqual( - // Something wrong happens if we compare both objects directly - // or with cloneDeep() - JSON.parse(JSON.stringify(recentData)), - JSON.parse(JSON.stringify(staleData)), - ) + dirty = !isEqual(recentData, staleData) console.debug(`Data ${dirty ? 'needs' : "doesn't need"} merging`) }