diff --git a/src/components/quick_filter_settings/quick_filter_settings.js b/src/components/quick_filter_settings/quick_filter_settings.js index 4a8aa34b8..ad28febe2 100644 --- a/src/components/quick_filter_settings/quick_filter_settings.js +++ b/src/components/quick_filter_settings/quick_filter_settings.js @@ -3,8 +3,8 @@ import { mapState } from 'pinia' 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 { useLocalConfigStore } from 'src/stores/local_config.js' import { library } from '@fortawesome/fontawesome-svg-core' import { faFilter, faFont, faWrench } from '@fortawesome/free-solid-svg-icons' diff --git a/src/components/settings_modal/tabs/filtering_tab.js b/src/components/settings_modal/tabs/filtering_tab.js index 067248a30..a0e03d850 100644 --- a/src/components/settings_modal/tabs/filtering_tab.js +++ b/src/components/settings_modal/tabs/filtering_tab.js @@ -93,8 +93,7 @@ const FilteringTab = { computed: { ...SharedComputedObject(), ...mapState(useSyncConfigStore, { - muteFilters: (store) => - Object.entries(store.prefsStorage.simple.muteFilters), + muteFilters: (store) => Object.entries(store.prefsStorage.simple.muteFilters), muteFiltersObject: (store) => store.prefsStorage.simple.muteFilters, }), ...mapState(useInstanceCapabilitiesStore, ['blockExpiration']), diff --git a/src/stores/sync_config.js b/src/stores/sync_config.js index 7a7afe36c..ba4031e9a 100644 --- a/src/stores/sync_config.js +++ b/src/stores/sync_config.js @@ -9,7 +9,6 @@ import { groupBy, isEqual, set, - take, takeRight, uniqWith, unset, @@ -220,7 +219,7 @@ export const _mergeFlags = (recent, stale, allFlagKeys) => { ) } -export const _mergeJournal = (...journals) => { +const _mergeJournal = (...journals) => { // Ignore invalid journal entries const allJournals = flatten( journals.map((j) => (Array.isArray(j) ? j : [])), @@ -268,11 +267,9 @@ export const _mergeJournal = (...journals) => { return journal } }) - - const flat = flatten(trimmedGrouped).sort((a, b) => + return flatten(trimmedGrouped).sort((a, b) => a.timestamp > b.timestamp ? 1 : -1, ) - return take(flat, 500) } export const _mergePrefs = (recent, stale) => { @@ -624,26 +621,12 @@ export const useSyncConfigStore = defineStore('sync_config', { const flagsTemplate = userNew ? newUserFlags : defaultState.flagStorage let dirty = false - if (recent === null) { - console.debug( - `Data is empty, initializing for ${userNew ? 'new' : 'existing'} user`, - ) - recent = _wrapData({ - flagStorage: { ...flagsTemplate }, - prefsStorage: { ...defaultState.prefsStorage }, - }) - } - - recent = recent && (await _doMigrations(recent, this.setPreference)) - stale = stale && (await _doMigrations(stale, this.setPreference)) - - // Various migrations console.debug('Migrating from old config') const vuexState = (await storage.getItem('vuex-lz')) ?? {} vuexState.config = vuexState.config ?? {} const migratedEntries = new Set(vuexState.config._syncMigration ?? []) - console.debug(`Already migrated Values: ${[...migratedEntries].join() || '[none]'}`) + console.debug(`Already migrated Values: ${[...migratedEntries].join()}`) Object.entries(oldDefaultConfigSync).forEach(([key, value]) => { const oldValue = vuexState.config[key] @@ -687,6 +670,19 @@ export const useSyncConfigStore = defineStore('sync_config', { vuexState.config._syncMigration = [...migratedEntries] storage.setItem('vuex-lz', vuexState) + if (recent === null) { + console.debug( + `Data is empty, initializing for ${userNew ? 'new' : 'existing'} user`, + ) + recent = _wrapData({ + flagStorage: { ...flagsTemplate }, + prefsStorage: { ...defaultState.prefsStorage }, + }) + } + + recent = recent && (await _doMigrations(recent, this.setPreference)) + stale = stale && (await _doMigrations(stale, this.setPreference)) + if (!needUpload && recent && stale) { console.debug('Checking if data needs merging...') // discarding timestamps and versions @@ -726,7 +722,6 @@ export const useSyncConfigStore = defineStore('sync_config', { this.flagStorage = this.cache.flagStorage this.prefsStorage = this.cache.prefsStorage this.pushSyncConfig() - console.log('C', this.cache) }, pushSyncConfig({ force = false } = {}) { const needPush = this.dirty || force diff --git a/src/sw.js b/src/sw.js index b7c551480..18c74cae8 100644 --- a/src/sw.js +++ b/src/sw.js @@ -5,10 +5,10 @@ import 'virtual:pleroma-fe/service_worker_env' import { createI18n } from 'vue-i18n' import { storage } from 'src/lib/storage.js' -import { instanceDefaultConfig } from 'src/modules/default_config_state.js' import { parseNotification } from 'src/services/entity_normalizer/entity_normalizer.service.js' import { prepareNotificationObject } from 'src/services/notification_utils/notification_utils.js' import { cacheKey, emojiCacheKey, shouldCache } from 'src/services/sw/sw.js' +import { instanceDefaultConfig } from 'src/modules/default_config_state.js' // Collects all messages for service workers // Needed because service workers cannot use dynamic imports diff --git a/test/unit/specs/stores/sync_config.spec.js b/test/unit/specs/stores/sync_config.spec.js index 8078b5949..9aed6193b 100644 --- a/test/unit/specs/stores/sync_config.spec.js +++ b/test/unit/specs/stores/sync_config.spec.js @@ -15,7 +15,6 @@ import { useSyncConfigStore, VERSION, } from 'src/stores/sync_config.js' -import { CURRENT_UPDATE_COUNTER } from 'src/components/update_notification/update_notification.js' describe('The SyncConfig store', () => { beforeEach(() => { @@ -29,52 +28,40 @@ describe('The SyncConfig store', () => { storage: {}, } - it('should initialize storage if none present', async () => { + it('should initialize storage if none present', () => { const store = useSyncConfigStore() - // PushSyncConfig is very simple but uses vuex to push data - store.pushSyncConfig = () => { - /* no-op */ - } - await store.initSyncConfig({ ...user }) + store.initSyncConfig({ ...user }) expect(store.cache._version).to.eql(VERSION) expect(store.cache._timestamp).to.be.a('number') expect(store.cache.flagStorage).to.eql(defaultState.flagStorage) expect(store.cache.prefsStorage).to.eql(defaultState.prefsStorage) }) - it('should initialize storage with proper flags for new users if none present', async () => { + it('should initialize storage with proper flags for new users if none present', () => { const store = useSyncConfigStore() - // PushSyncConfig is very simple but uses vuex to push data - store.pushSyncConfig = () => { - /* no-op */ - } - await store.initSyncConfig({ ...user, created_at: new Date() }) + store.initSyncConfig({ ...user, created_at: new Date() }) expect(store.cache._version).to.eql(VERSION) expect(store.cache._timestamp).to.be.a('number') expect(store.cache.flagStorage).to.eql(newUserFlags) expect(store.cache.prefsStorage).to.eql(defaultState.prefsStorage) }) - it('should merge flags even if remote timestamp is older', async () => { + it('should merge flags even if remote timestamp is older', () => { const store = useSyncConfigStore() - // PushSyncConfig is very simple but uses vuex to push data - store.pushSyncConfig = () => { - /* no-op */ - } store.cache = { _timestamp: Date.now(), _version: VERSION, ...cloneDeep(defaultState), } - await store.initSyncConfig({ + store.initSyncConfig({ ...user, storage: { _timestamp: 123, _version: VERSION, flagStorage: { ...defaultState.flagStorage, - updateCounter: CURRENT_UPDATE_COUNTER, + updateCounter: 1, }, prefsStorage: { ...defaultState.prefsStorage, @@ -82,62 +69,17 @@ describe('The SyncConfig store', () => { }, }) - expect(store.flagStorage).to.eql({ + expect(store.cache.flagStorage).to.eql({ ...defaultState.flagStorage, - updateCounter: CURRENT_UPDATE_COUNTER, + updateCounter: 1, }) }) - it('should trim journal to 500 entries', async () => { - const store = useSyncConfigStore() - // PushSyncConfig is very simple but uses vuex to push data - store.pushSyncConfig = () => { - /* no-op */ - } - store.cache = { - _timestamp: Date.now(), - _version: VERSION, - ...cloneDeep(defaultState), - } - const largeJournal = [] - for (let value = 0; value < 1000; value++) { - largeJournal.push({ - path: 'simple.testing' + value, - operation: 'set', - args: [value], - // should have A timestamp, we don't really care what it is - timestamp: 123456, - }) - } - - await store.initSyncConfig({ - ...user, - storage: { - _timestamp: 123, - _version: VERSION, - flagStorage: { - ...defaultState.flagStorage, - updateCounter: CURRENT_UPDATE_COUNTER, - }, - prefsStorage: { - ...defaultState.prefsStorage, - _journal: largeJournal, - }, - }, - }) - - expect(store.prefsStorage._journal.length).to.eql(500) - }) - - it('should reset local timestamp to remote if contents are the same', async () => { + it('should reset local timestamp to remote if contents are the same', () => { const store = useSyncConfigStore() store.cache = null - // PushSyncConfig is very simple but uses vuex to push data - store.pushSyncConfig = () => { - /* no-op */ - } - await store.initSyncConfig({ + store.initSyncConfig({ ...user, storage: { _timestamp: 123, @@ -153,13 +95,9 @@ describe('The SyncConfig store', () => { expect(store.cache.flagStorage.updateCounter).to.eql(999) }) - it('should use remote version if local missing', async () => { + it('should use remote version if local missing', () => { const store = useSyncConfigStore() - // PushSyncConfig is very simple but uses vuex to push data - store.pushSyncConfig = () => { - /* no-op */ - } - await store.initSyncConfig(store, user) + store.initSyncConfig(store, user) expect(store.cache._version).to.eql(VERSION) expect(store.cache._timestamp).to.be.a('number') expect(store.cache.flagStorage).to.eql(defaultState.flagStorage) @@ -168,10 +106,6 @@ describe('The SyncConfig store', () => { describe('setPreference', () => { it('should set preference and update journal log accordingly', () => { const store = useSyncConfigStore() - // PushSyncConfig is very simple but uses vuex to push data - store.pushSyncConfig = () => { - /* no-op */ - } store.setPreference({ path: 'simple.testing', value: 1 }) expect(store.prefsStorage.simple.testing).to.eql(1) expect(store.prefsStorage._journal.length).to.eql(1) @@ -186,10 +120,6 @@ describe('The SyncConfig store', () => { it('should keep journal to a minimum', () => { const store = useSyncConfigStore() - // PushSyncConfig is very simple but uses vuex to push data - store.pushSyncConfig = () => { - /* no-op */ - } store.setPreference({ path: 'simple.testing', value: 1 }) store.setPreference({ path: 'simple.testing', value: 2 }) store.addCollectionPreference({ path: 'collections.testing', value: 2 }) @@ -219,10 +149,6 @@ describe('The SyncConfig store', () => { it('should remove duplicate entries from journal', () => { const store = useSyncConfigStore() - // PushSyncConfig is very simple but uses vuex to push data - store.pushSyncConfig = () => { - /* no-op */ - } store.setPreference({ path: 'simple.testing', value: 1 }) store.setPreference({ path: 'simple.testing', value: 1 }) store.addCollectionPreference({ path: 'collections.testing', value: 2 }) @@ -235,10 +161,6 @@ describe('The SyncConfig store', () => { it('should remove depth = 3 set/unset entries from journal', () => { const store = useSyncConfigStore() - // PushSyncConfig is very simple but uses vuex to push data - store.pushSyncConfig = () => { - /* no-op */ - } store.setPreference({ path: 'simple.object.foo', value: 1 }) store.unsetPreference({ path: 'simple.object.foo' }) store.updateCache(store, { username: 'test' }) @@ -248,10 +170,6 @@ describe('The SyncConfig store', () => { it('should not allow unsetting depth <= 2', () => { const store = useSyncConfigStore() - // PushSyncConfig is very simple but uses vuex to push data - store.pushSyncConfig = () => { - /* no-op */ - } store.setPreference({ path: 'simple.object.foo', value: 1 }) expect(() => store.unsetPreference({ path: 'simple' })).to.throw() expect(() => @@ -261,10 +179,6 @@ describe('The SyncConfig store', () => { it('should not allow (un)setting depth > 3', () => { const store = useSyncConfigStore() - // PushSyncConfig is very simple but uses vuex to push data - store.pushSyncConfig = () => { - /* no-op */ - } store.setPreference({ path: 'simple.object', value: {} }) expect(() => store.setPreference({ path: 'simple.object.lv3', value: 1 }),