parent
5b7c653874
commit
dbfca224d8
@ -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 |
Loading…
Reference in new issue