Fix setting persistence to local browser storage #469

Merged
Oneric merged 1 commit from Oneric/akkoma-fe:fix-settings-local-persistence into develop 2025-12-19 19:20:14 +00:00
Showing only changes of commit d83fd8b1cd - Show all commits

Fix setting persistence to local browser storage

Fixes regression in f2c55423fd.
Ideally, this would only set state for what was actually changed
rather than rewriting the entire storage each time, which would also
have avoided this issue.

The fix is somehwat hacky not working with an empty path list or
parsed/internal fields not at the top-level of a path, but in practice
this seems to be always called with well bheaving paths. Should this ever
become an issue, this should migrating to the overall saner updating
approach described in the preceding paragraph.

Note: the cloneDeep call was originally added in
a97c07bfdf as part of
https://git.pleroma.social/pleroma/pleroma-fe/-/merge_requests/1385
Though it is not clear why setState would mangle its data argument
as it supposedly does to necessitate this copying.
Oneric 2025-12-13 00:00:00 +00:00

View file

@ -4,9 +4,20 @@ import { each, get, set, cloneDeep } from 'lodash'
let loaded = false
// use this to avoid cloning and persisitng private runtime state
// (runtime state can be reconstructed and may include non-cloneable objects like functions)
const clonePublicKeys = (state) => {
const clonedState = {}
for (const key in state) {
if (!key.startsWith('__'))
set(clonedState, key, cloneDeep(state[key]))
}
return clonedState
}
const defaultReducer = (state, paths) => (
paths.length === 0 ? state : paths.reduce((substate, path) => {
set(substate, path, get(state, path))
paths.length === 0 ? clonePublicKeys(state) : paths.reduce((substate, path) => {
set(substate, path, clonePublicKeys(get(state, path)))
return substate
}, {})
)
@ -70,7 +81,7 @@ export default function createPersistedState ({
subscriber(store)((mutation, state) => {
try {
if (saveImmedeatelyActions.includes(mutation.type)) {
setState(key, reducer(cloneDeep(state), paths), storage)
setState(key, reducer(state, paths), storage)
.then(success => {
if (typeof success !== 'undefined') {
if (mutation.type === 'setOption' || mutation.type === 'setCurrentUser') {