fix: map settings no longer revert/lose in-flight edits when profile refetches (dirty-flag guards hydrate clobber)
This commit is contained in:
@@ -41,10 +41,24 @@ export const useMapSettingsStore = create((set, get) => ({
|
||||
keys: cache0.keys || {},
|
||||
defaultThunderforestKey: cache0.defaultThunderforestKey || '',
|
||||
hydrated: false,
|
||||
dirty: false, // true while a local change is unsaved; blocks hydrate clobber
|
||||
|
||||
// Populate from the server profile. Only marks the store ready to persist
|
||||
// after this runs, so we never clobber the server with stale cache values.
|
||||
// While `dirty`, an unsaved local edit exists, so we must NOT overwrite the
|
||||
// user's choice from the (possibly stale) profile cache — a refetch landing
|
||||
// mid-edit would otherwise revert it. We still record the server default key
|
||||
// and that we've hydrated.
|
||||
hydrate: (server, defaultKey) => set((s) => {
|
||||
if (s.dirty) {
|
||||
const next = {
|
||||
...s,
|
||||
defaultThunderforestKey: defaultKey || s.defaultThunderforestKey || '',
|
||||
hydrated: true,
|
||||
}
|
||||
writeCache(next)
|
||||
return next
|
||||
}
|
||||
const ms = server || {}
|
||||
const provider = MAP_PROVIDERS[ms.provider] ? ms.provider : s.provider
|
||||
const style = MAP_PROVIDERS[provider]?.styles[ms.style] ? ms.style
|
||||
@@ -63,25 +77,34 @@ export const useMapSettingsStore = create((set, get) => ({
|
||||
|
||||
// Debounced persist of the full settings to the user record.
|
||||
_save: () => {
|
||||
const s = get()
|
||||
if (!s.hydrated) return
|
||||
if (!get().hydrated) return
|
||||
clearTimeout(saveTimer)
|
||||
saveTimer = setTimeout(() => {
|
||||
api.put('/profile/map-settings', { provider: s.provider, style: s.style, keys: s.keys })
|
||||
const snap = get()
|
||||
const payload = { provider: snap.provider, style: snap.style, keys: snap.keys }
|
||||
api.put('/profile/map-settings', payload)
|
||||
.then(() => {
|
||||
// Clear `dirty` only if nothing changed since this save was dispatched,
|
||||
// so a newer unsaved edit isn't wrongly treated as saved (and revertable).
|
||||
const cur = get()
|
||||
if (cur.provider === payload.provider && cur.style === payload.style && cur.keys === payload.keys) {
|
||||
set({ dirty: false })
|
||||
}
|
||||
})
|
||||
.catch(() => { /* non-fatal; cache keeps the local choice */ })
|
||||
}, 600)
|
||||
},
|
||||
|
||||
setProvider: (provider) => {
|
||||
set((s) => { const next = { ...s, provider, style: firstStyle(provider) }; writeCache(next); return next })
|
||||
set((s) => { const next = { ...s, provider, style: firstStyle(provider), dirty: true }; writeCache(next); return next })
|
||||
get()._save()
|
||||
},
|
||||
setStyle: (style) => {
|
||||
set((s) => { const next = { ...s, style }; writeCache(next); return next })
|
||||
set((s) => { const next = { ...s, style, dirty: true }; writeCache(next); return next })
|
||||
get()._save()
|
||||
},
|
||||
setKey: (provider, value) => {
|
||||
set((s) => { const next = { ...s, keys: { ...s.keys, [provider]: value } }; writeCache(next); return next })
|
||||
set((s) => { const next = { ...s, keys: { ...s.keys, [provider]: value }, dirty: true }; writeCache(next); return next })
|
||||
get()._save()
|
||||
},
|
||||
}))
|
||||
|
||||
Reference in New Issue
Block a user