diff options
Diffstat (limited to 'src/modules')
| -rw-r--r-- | src/modules/serverSideStorage.js | 158 | ||||
| -rw-r--r-- | src/modules/users.js | 2 |
2 files changed, 160 insertions, 0 deletions
diff --git a/src/modules/serverSideStorage.js b/src/modules/serverSideStorage.js new file mode 100644 index 00000000..5ebe17fd --- /dev/null +++ b/src/modules/serverSideStorage.js @@ -0,0 +1,158 @@ +import { toRaw } from 'vue' + +const VERSION = 1 +const NEW_USER_DATE = new Date('04-08-2022') // date of writing this, basically + +const COMMAND_TRIM_FLAGS = 1000 +const COMMAND_TRIM_FLAGS_AND_RESET = 1001 + +const defaultState = { + // last timestamp + timestamp: 0, + // need to update server + dirty: false, + // storage of flags - stuff that can only be set and incremented + flagStorage: { + updateCounter: 0, // Counter for most recent update notification seen + // TODO move to prefsStorage when that becomes a thing since only way + // this can be reset is by complete reset of all flags + dontShowUpdateNotifs: 0, // if user chose to not show update notifications ever again + reset: 0 // special flag that can be used to force-reset all flags, debug purposes only + // special reset codes: + // 1000: trim keys to those known by currently running FE + // 1001: same as above + reset everything to 0 + }, + // raw data + raw: null, + // local cache + cache: null +} + +const newUserFlags = { + ...defaultState.flagStorage, + updateCounter: 1 // new users don't need to see update notification +} + +const serverSideStorage = { + state: { + ...defaultState + }, + mutations: { + setServerSideStorage (state, userData) { + const live = userData.storage + const userNew = userData.created_at > NEW_USER_DATE + const flagsTemplate = userNew ? newUserFlags : defaultState.defaultState + state.raw = live + console.log(1111, live._timestamp) + let recent = null + const cache = state.cache || {} + const cacheValid = cache._timestamp > 0 && cache._version > 0 + const liveValid = live._timestamp > 0 && live._version > 0 + if (!liveValid) { + state.dirty = true + console.debug('Nothing valid stored on server, assuming cache to be source of truth') + if (cacheValid) { + recent = cache + } else { + console.debug(`Local cache is empty, initializing for ${userNew ? 'new' : 'existing'} user`) + + recent = { + _timestamp: Date.now(), + _version: VERSION, + flagStorage: { ...flagsTemplate } + } + } + } else if (!cacheValid) { + console.debug('Valid storage on server found, no local cache found, using live as source of truth') + recent = live + } else { + console.debug('Both sources have valid data, figuring things out...') + console.log(live._timestamp, cache._timestamp) + if (live._timestamp === cache._timestamp && live._version === cache._version) { + console.debug('Same version/timestamp on both source, source of truth irrelevant') + recent = cache + } else { + state.dirty = true + console.debug('Different timestamp, figuring out which one is more recent') + let stale + if (live._timestamp < cache._timestamp) { + recent = cache + stale = live + } else { + recent = live + stale = cache + } + + // Merge the flags + console.debug('Merging the flags...') + recent.flagStorage = recent.flagStorage || { ...flagsTemplate } + stale.flagStorage = stale.flagStorage || { ...flagsTemplate } + const allFlags = Array.from(new Set([ + ...Object.keys(toRaw(recent.flagStorage)), + ...Object.keys(toRaw(stale.flagStorage)) + ])) + + const totalFlags = Object.fromEntries(allFlags.map(flag => { + const recentFlag = recent.flagStorage[flag] + const staleFlag = stale.flagStorage[flag] + // use flag that is of higher value + return [flag, recentFlag > staleFlag ? recentFlag : staleFlag] + })) + + console.debug('AAA', totalFlags) + // flag reset functionality + if (totalFlags.reset >= COMMAND_TRIM_FLAGS && totalFlags.reset <= COMMAND_TRIM_FLAGS_AND_RESET) { + console.debug('Received command to trim the flags') + const knownKeys = new Set(Object.keys(defaultState.flagStorage)) + allFlags.forEach(flag => { + if (!knownKeys.has(flag)) { + delete totalFlags[flag] + } + }) + if (totalFlags.reset === COMMAND_TRIM_FLAGS_AND_RESET) { + // 1001 - and reset everything to 0 + console.debug('Received command to reset the flags') + allFlags.forEach(flag => { totalFlags[flag] = 0 }) + } else { + // reset the reset 0 + totalFlags.reset = 0 + } + } else if (totalFlags.reset > 0 && totalFlags.reset < 9000) { + console.debug('Received command to reset the flags') + allFlags.forEach(flag => { totalFlags[flag] = 0 }) + // for good luck + totalFlags.reset = 0 + } + console.log('AAAA', totalFlags) + state.cache.flagStorage = totalFlags + } + } + state.cache = recent + state.flagStorage = state.cache.flagStorage + }, + setFlag (state, { flag, value }) { + state.flagStorage[flag] = value + state.dirty = true + } + }, + actions: { + pushServerSideStorage ({ state, rootState, commit }, { force = false } = {}) { + console.log('PUSH') + const needPush = state.dirty || force + if (!needPush) return + state.cache = { + _timestamp: Date.now(), + _version: VERSION, + flagStorage: toRaw(state.flagStorage) + } + console.log('YES') + const params = { pleroma_settings_store: { 'pleroma-fe': state.cache } } + rootState.api.backendInteractor + .updateProfile({ params }) + .then((user) => commit('setServerSideStorage', user)) + state.dirty = false + } + } +} + +export default serverSideStorage diff --git a/src/modules/users.js b/src/modules/users.js index 13d4e318..b6fb9746 100644 --- a/src/modules/users.js +++ b/src/modules/users.js @@ -525,6 +525,7 @@ const users = { user.muteIds = [] user.domainMutes = [] commit('setCurrentUser', user) + commit('setServerSideStorage', user) commit('addNewUsers', [user]) store.dispatch('fetchEmoji') @@ -534,6 +535,7 @@ const users = { // Set our new backend interactor commit('setBackendInteractor', backendInteractorService(accessToken)) + store.dispatch('pushServerSideStorage') if (user.token) { store.dispatch('setWsToken', user.token) |
