diff --git a/src/components/extra_notifications/extra_notifications.js b/src/components/extra_notifications/extra_notifications.js index ec5ceebe1..31ca57aaa 100644 --- a/src/components/extra_notifications/extra_notifications.js +++ b/src/components/extra_notifications/extra_notifications.js @@ -4,6 +4,7 @@ import { mapGetters } from 'vuex' import { useAnnouncementsStore } from 'src/stores/announcements.js' import { useInterfaceStore } from 'src/stores/interface.js' import { useMergedConfigStore } from 'src/stores/merged_config.js' +import { useSyncConfigStore } from 'src/stores/sync_config.js' import { library } from '@fortawesome/fontawesome-svg-core' import { diff --git a/src/components/post_status_form/post_status_form.js b/src/components/post_status_form/post_status_form.js index 1f92a7e55..7ebbeeaeb 100644 --- a/src/components/post_status_form/post_status_form.js +++ b/src/components/post_status_form/post_status_form.js @@ -325,7 +325,8 @@ const PostStatusForm = { }, hideScopeNotice() { return ( - this.disableNotice || useMergedConfigStore().mergedConfig.hideScopeNotice + this.disableNotice || + useMergedConfigStore().mergedConfig.hideScopeNotice ) }, pollContentError() { diff --git a/src/components/settings_modal/settings_modal.js b/src/components/settings_modal/settings_modal.js index f889cc66f..4ca2857b2 100644 --- a/src/components/settings_modal/settings_modal.js +++ b/src/components/settings_modal/settings_modal.js @@ -10,8 +10,8 @@ import Popover from '../popover/popover.vue' import { useInterfaceStore } from 'src/stores/interface.js' import { useLocalConfigStore } from 'src/stores/local_config.js' -import { useSyncConfigStore } from 'src/stores/sync_config.js' import { useMergedConfigStore } from 'src/stores/merged_config.js' +import { useSyncConfigStore } from 'src/stores/sync_config.js' import { LOCAL_ONLY_KEYS } from 'src/modules/default_config_state.js' import { diff --git a/src/components/status_action_buttons/buttons_definitions.js b/src/components/status_action_buttons/buttons_definitions.js index 01b0e8bdb..cdb49b1ac 100644 --- a/src/components/status_action_buttons/buttons_definitions.js +++ b/src/components/status_action_buttons/buttons_definitions.js @@ -1,9 +1,9 @@ import { useEditStatusStore } from 'src/stores/editStatus.js' import { useInstanceStore } from 'src/stores/instance.js' import { useInstanceCapabilitiesStore } from 'src/stores/instance_capabilities.js' +import { useMergedConfigStore } from 'src/stores/merged_config.js' import { useReportsStore } from 'src/stores/reports.js' import { useStatusHistoryStore } from 'src/stores/statusHistory.js' -import { useMergedConfigStore } from 'src/stores/merged_config.js' const PRIVATE_SCOPES = new Set(['private', 'direct']) const PUBLIC_SCOPES = new Set(['public', 'unlisted']) diff --git a/src/modules/default_config_state.js b/src/modules/default_config_state.js index 5af6f6c5e..3800d4deb 100644 --- a/src/modules/default_config_state.js +++ b/src/modules/default_config_state.js @@ -661,8 +661,8 @@ export const SYNC_DEFAULT_CONFIG_DEFINITIONS = { }, collapseNav: { description: 'Collapse navigation panel to header only', - default: false - } + default: false, + }, } export const SYNC_DEFAULT_CONFIG = convertDefinitions( SYNC_DEFAULT_CONFIG_DEFINITIONS, @@ -675,12 +675,14 @@ export const THEME_CONFIG_DEFINITIONS = { default: null, }, colors: { - description: 'VERY old theme store, just colors of V1, probably not even used anymore', + description: + 'VERY old theme store, just colors of V1, probably not even used anymore', default: {}, }, // V2 customTheme: { - description: '"Snapshot", previously was used as actual theme store for V2 so it\'s still used in case of PleromaFE downgrade event.', + description: + '"Snapshot", previously was used as actual theme store for V2 so it\'s still used in case of PleromaFE downgrade event.', default: null, }, customThemeSource: { @@ -705,9 +707,7 @@ export const THEME_CONFIG_DEFINITIONS = { default: null, }, } -export const THEME_CONFIG = convertDefinitions( - THEME_CONFIG_DEFINITIONS, -) +export const THEME_CONFIG = convertDefinitions(THEME_CONFIG_DEFINITIONS) export const makeUndefined = (c) => Object.fromEntries(Object.keys(c).map((key) => [key, undefined])) diff --git a/src/stores/local_config.js b/src/stores/local_config.js index f8b76a26c..5b15c6ff1 100644 --- a/src/stores/local_config.js +++ b/src/stores/local_config.js @@ -7,8 +7,8 @@ import { useInstanceStore } from 'src/stores/instance' import { LOCAL_DEFAULT_CONFIG, LOCAL_DEFAULT_CONFIG_DEFINITIONS, - validateSetting, makeUndefined, + validateSetting, } from 'src/modules/default_config_state' export const defaultState = { @@ -57,7 +57,9 @@ export const useLocalConfigStore = defineStore('local_config', { persist: { afterLoad(state) { return { - prefsStorage: state.prefsStorage ?? { ...makeUndefined(LOCAL_DEFAULT_CONFIG) }, + prefsStorage: state.prefsStorage ?? { + ...makeUndefined(LOCAL_DEFAULT_CONFIG), + }, tempStorage: { ...makeUndefined(LOCAL_DEFAULT_CONFIG) }, } }, diff --git a/src/stores/merged_config.js b/src/stores/merged_config.js index 80d27fabf..c4f27082c 100644 --- a/src/stores/merged_config.js +++ b/src/stores/merged_config.js @@ -7,8 +7,8 @@ import { useSyncConfigStore } from 'src/stores/sync_config.js' import { INSTANCE_DEFAULT_CONFIG, LOCAL_DEFAULT_CONFIG, - THEME_CONFIG, LOCAL_ONLY_KEYS, + THEME_CONFIG, } from 'src/modules/default_config_state.js' const ROOT_CONFIG = { @@ -35,10 +35,7 @@ export const useMergedConfigStore = defineStore('merged_config', { const getDefault = (k) => instancePrefs[k] ?? ROOT_CONFIG[k] const result = Object.fromEntries( - Object.keys(ROOT_CONFIG).map((k) => [ - k, - getValue(k) ?? getDefault(k), - ]), + Object.keys(ROOT_CONFIG).map((k) => [k, getValue(k) ?? getDefault(k)]), ) return result }, @@ -48,10 +45,7 @@ export const useMergedConfigStore = defineStore('merged_config', { const getDefault = (k) => instancePrefs[k] ?? ROOT_CONFIG[k] const result = Object.fromEntries( - Object.keys(ROOT_CONFIG).map((k) => [ - k, - getDefault(k), - ]), + Object.keys(ROOT_CONFIG).map((k) => [k, getDefault(k)]), ) return result }, @@ -65,10 +59,7 @@ export const useMergedConfigStore = defineStore('merged_config', { tempPrefs[k] ?? localPrefs[k] ?? syncPrefs.simple[k] ?? instancePrefs[k] const result = Object.fromEntries( - Object.keys(ROOT_CONFIG).map(([k, value]) => [ - k, - getValue(k), - ]), + Object.keys(ROOT_CONFIG).map(([k, value]) => [k, getValue(k)]), ) return result }, diff --git a/src/stores/sync_config.js b/src/stores/sync_config.js index a6580b5c7..045579e41 100644 --- a/src/stores/sync_config.js +++ b/src/stores/sync_config.js @@ -24,10 +24,10 @@ import { useLocalConfigStore } from 'src/stores/local_config.js' import { storage } from 'src/lib/storage.js' import { + makeUndefined, ROOT_CONFIG, ROOT_CONFIG_DEFINITIONS, validateSetting, - makeUndefined, } from 'src/modules/default_config_state.js' import { oldDefaultConfigSync } from 'src/modules/old_default_config_state.js' @@ -297,7 +297,7 @@ export const _mergePrefs = (recent, stale) => { ) } switch (operation) { - case 'set': + case 'set': { if (path.startsWith('collections')) { return console.error('Illegal operation "set" on a collection') } @@ -306,8 +306,22 @@ export const _mergePrefs = (recent, stale) => { `Calling set on depth <= 1 (path: ${path}) is not allowed`, ) } - set(resultOutput, path, args[0]) + + const definition = path.startsWith('simple.muteFilters') + ? { default: {} } + : ROOT_CONFIG_DEFINITIONS[path.split('.')[1]] + + const finalValue = validateSetting({ + path: path.split('.')[1], + value: args[0], + definition, + throwError: false, + defaultState: ROOT_CONFIG, + }) + + set(resultOutput, path, finalValue) break + } case 'unset': if (path.startsWith('collections')) { return console.error('Illegal operation "unset" on a collection') @@ -488,8 +502,8 @@ export const useSyncConfigStore = defineStore('sync_config', { } const definition = path.startsWith('simple.muteFilters') - ? { default: {} } - : ROOT_CONFIG_DEFINITIONS[path.split('.')[1]] + ? { default: {} } + : ROOT_CONFIG_DEFINITIONS[path.split('.')[1]] const finalValue = validateSetting({ path: path.split('.')[1], diff --git a/src/stores/user_highlight.js b/src/stores/user_highlight.js index c70c7f57f..3627886ea 100644 --- a/src/stores/user_highlight.js +++ b/src/stores/user_highlight.js @@ -153,8 +153,9 @@ const _mergeJournal = (...journals) => { export const _mergeHighlights = (recent, stale) => { if (!stale) return recent if (!recent) return stale - const { _journal: recentJournal, ...recentData } = recent + const { _journal: recentJournal, highlight: recentHighlight } = recent const { _journal: staleJournal } = stale + console.log(recentHighlight) /** Journal entry format: * user: user to entry in highlight storage * timestamp: timestamp of the change @@ -164,7 +165,7 @@ export const _mergeHighlights = (recent, stale) => { * currently only supported operation type is "set" which just sets the value * to requested one. Intended only to be used with simple preferences (boolean, number) */ - const resultOutput = { ...recentData } + const resultHighlight = { ...recentHighlight } const Journal = _mergeJournal(staleJournal, recentJournal) Journal.forEach(({ user, operation, args }) => { if (user.startsWith('_')) { @@ -174,16 +175,16 @@ export const _mergeHighlights = (recent, stale) => { } switch (operation) { case 'set': - resultOutput[user] = args[0] + resultHighlight[user] = args[0] break case 'unset': - delete resultOutput[user] + delete resultHighlight[user] break default: return console.error(`Unknown journal operation: '${operation}'`) } }) - return { ...resultOutput, _journal: Journal } + return { highlight: resultHighlight, _journal: Journal } } export const useUserHighlightStore = defineStore('user_highlight', { @@ -333,7 +334,6 @@ export const useUserHighlightStore = defineStore('user_highlight', { this.cache._timestamp = Math.min(stale._timestamp, recent._timestamp) } this.highlight = this.cache.highlight - this.pushHighlight() }, pushHighlight({ force = false } = {}) { const needPush = this.dirty || force diff --git a/test/unit/specs/components/draft.spec.js b/test/unit/specs/components/draft.spec.js index 386b2a761..6abf2d75b 100644 --- a/test/unit/specs/components/draft.spec.js +++ b/test/unit/specs/components/draft.spec.js @@ -6,7 +6,7 @@ import { nextTick } from 'vue' import PostStatusForm from 'src/components/post_status_form/post_status_form.vue' import { $t, mountOpts, waitForEvent } from '../../../fixtures/setup_test' -import { useSyncConfigStore } from 'src/stores/sync_config.js' +import { useMergedConfigStore } from 'src/stores/merged_config.js' const autoSaveOrNot = (caseFn, caseTitle, runFn) => { caseFn(`${caseTitle} with auto-save`, function () { @@ -48,7 +48,7 @@ describe('Draft saving', () => { 'should save when the button is clicked', async (autoSave) => { const wrapper = mount(PostStatusForm, mountOpts()) - const store = useSyncConfigStore() + const store = useMergedConfigStore() store.mergedConfig = { autoSaveDraft: autoSave, } @@ -68,7 +68,7 @@ describe('Draft saving', () => { it('should auto-save if it is enabled', async function () { vi.useFakeTimers() const wrapper = mount(PostStatusForm, mountOpts()) - const store = useSyncConfigStore() + const store = useMergedConfigStore() store.mergedConfig = { autoSaveDraft: true, } @@ -91,7 +91,7 @@ describe('Draft saving', () => { }, }), ) - const store = useSyncConfigStore() + const store = useMergedConfigStore() store.mergedConfig = { autoSaveDraft: true, } @@ -112,7 +112,7 @@ describe('Draft saving', () => { }, }), ) - const store = useSyncConfigStore() + const store = useMergedConfigStore() store.mergedConfig = { autoSaveDraft: false, unsavedPostAction: 'save', @@ -134,7 +134,7 @@ describe('Draft saving', () => { }, }), ) - const store = useSyncConfigStore() + const store = useMergedConfigStore() store.mergedConfig = { autoSaveDraft: false, unsavedPostAction: 'discard', @@ -156,7 +156,7 @@ describe('Draft saving', () => { }, }), ) - const store = useSyncConfigStore(createTestingPinia()) + const store = useMergedConfigStore(createTestingPinia()) store.mergedConfig = { autoSaveDraft: false, unsavedPostAction: 'confirm', diff --git a/test/unit/specs/components/emoji_input.spec.js b/test/unit/specs/components/emoji_input.spec.js index 62f90caa4..6a7c67fdb 100644 --- a/test/unit/specs/components/emoji_input.spec.js +++ b/test/unit/specs/components/emoji_input.spec.js @@ -7,7 +7,7 @@ createTestingPinia() import EmojiInput from 'src/components/emoji_input/emoji_input.vue' -import { useSyncConfigStore } from 'src/stores/sync_config.js' +import { useMergedConfigStore } from 'src/stores/merged_config.js' const generateInput = (value, padEmoji = true) => { const wrapper = shallowMount(EmojiInput, { @@ -45,7 +45,7 @@ const generateInput = (value, padEmoji = true) => { describe('EmojiInput', () => { beforeEach(() => { - const store = useSyncConfigStore(createTestingPinia()) + const store = useMergedConfigStore(createTestingPinia()) store.mergedConfig = { padEmoji: true, } @@ -113,7 +113,7 @@ describe('EmojiInput', () => { it('inserts string without any padding if padEmoji setting is set to false', () => { const initialString = 'Eat some spam!' const wrapper = generateInput(initialString, false) - const store = useSyncConfigStore(createTestingPinia()) + const store = useMergedConfigStore(createTestingPinia()) store.mergedConfig = { padEmoji: false, } @@ -152,7 +152,7 @@ describe('EmojiInput', () => { it('correctly sets caret after insertion if padEmoji setting is set to false', async () => { const initialString = '1234' const wrapper = generateInput(initialString, false) - const store = useSyncConfigStore(createTestingPinia()) + const store = useMergedConfigStore(createTestingPinia()) store.mergedConfig = { padEmoji: false, } diff --git a/test/unit/specs/stores/sync_config.spec.js b/test/unit/specs/stores/sync_config.spec.js index eef6e39ac..adf447930 100644 --- a/test/unit/specs/stores/sync_config.spec.js +++ b/test/unit/specs/stores/sync_config.spec.js @@ -1,8 +1,6 @@ import { cloneDeep } from 'lodash' import { createPinia, setActivePinia } from 'pinia' -import { CURRENT_UPDATE_COUNTER } from 'src/components/update_notification/update_notification.js' - import { _getAllFlags, _getRecentData, @@ -75,7 +73,7 @@ describe('The SyncConfig store', () => { _version: VERSION, flagStorage: { ...defaultState.flagStorage, - updateCounter: CURRENT_UPDATE_COUNTER, + updateCounter: 1, }, prefsStorage: { ...defaultState.prefsStorage, @@ -85,7 +83,7 @@ describe('The SyncConfig store', () => { expect(store.flagStorage).to.eql({ ...defaultState.flagStorage, - updateCounter: CURRENT_UPDATE_COUNTER, + updateCounter: 1, }) }) @@ -118,7 +116,7 @@ describe('The SyncConfig store', () => { _version: VERSION, flagStorage: { ...defaultState.flagStorage, - updateCounter: CURRENT_UPDATE_COUNTER, + updateCounter: 1, }, prefsStorage: { ...defaultState.prefsStorage, diff --git a/test/unit/specs/stores/user_highlight.spec.js b/test/unit/specs/stores/user_highlight.spec.js index 742eec522..4e66a9bbb 100644 --- a/test/unit/specs/stores/user_highlight.spec.js +++ b/test/unit/specs/stores/user_highlight.spec.js @@ -3,7 +3,7 @@ import { createPinia, setActivePinia } from 'pinia' import { _getRecentData, - _mergePrefs, + _mergeHighlights, _moveItemInArray, useUserHighlightStore, } from 'src/stores/user_highlight.js' @@ -11,6 +11,15 @@ import { describe('The UserHighlight store', () => { beforeEach(() => { setActivePinia(createPinia()) + window.vuex = { + state: { + users: { + currentUser: { + fqn: 'foo@bar.tld', + }, + }, + }, + } }) describe('mutations', () => { @@ -20,23 +29,23 @@ describe('The UserHighlight store', () => { storage: {}, } - it('should initialize storage if none present', () => { + it('should initialize storage if none present', async () => { const store = useUserHighlightStore() - store.initUserHighlight({ ...user }) + await store.initUserHighlight({ ...user }) expect(store.cache._timestamp).to.be.a('number') expect(store.cache.highlight).to.eql({ _journal: [] }) }) - it('should initialize storage for new users if none present', () => { + it('should initialize storage for new users if none present', async () => { const store = useUserHighlightStore() - store.initUserHighlight({ ...user, created_at: new Date() }) + await store.initUserHighlight({ ...user, created_at: new Date() }) expect(store.cache._timestamp).to.be.a('number') expect(store.cache.highlight).to.eql({ _journal: [] }) }) - it('should use remote version if local missing', () => { + it('should use remote version if local missing', async () => { const store = useUserHighlightStore() - store.initUserHighlight(store, user) + await store.initUserHighlight(store, user) expect(store.cache._timestamp).to.be.a('number') }) }) @@ -161,10 +170,10 @@ describe('The UserHighlight store', () => { }) }) - describe('_mergePrefs', () => { + describe('_mergeHighlights', () => { it('should prefer recent and apply journal to it', () => { expect( - _mergePrefs( + _mergeHighlights( // RECENT { highlight: { @@ -227,7 +236,7 @@ describe('The UserHighlight store', () => { it('should work with objects', () => { expect( - _mergePrefs( + _mergeHighlights( // RECENT { highlight: { 'a@test.xyz': { type: 'foo' } }, @@ -268,7 +277,7 @@ describe('The UserHighlight store', () => { it('should work with unset', () => { expect( - _mergePrefs( + _mergeHighlights( // RECENT { highlight: { 'a@test.xyz': { type: 'foo' } },