Fix local/session storage parsing/stringifying values
The old logic stringifyed all values, including strings, which caused problems with reading external stored values (e.g., mui-mode) via the "useStorage" hook.
This commit is contained in:
@@ -30,10 +30,11 @@
|
||||
<script type="module" src="./src/index.tsx"></script>
|
||||
<script>
|
||||
const backgroundColor = (() => {
|
||||
const storageValue = window.localStorage.getItem("theme_background")
|
||||
try {
|
||||
return JSON.parse(window.localStorage.getItem("theme_background"))
|
||||
return JSON.parse(storageValue)
|
||||
} catch (e) {
|
||||
return null
|
||||
return storageValue
|
||||
}
|
||||
})();
|
||||
|
||||
|
||||
@@ -26,7 +26,7 @@ export class Storage {
|
||||
return this.parseValue(this.getItem(key), defaultValue);
|
||||
}
|
||||
|
||||
setItem(key: string, value: unknown, emitEvent: boolean = true, stringify: boolean = true): void {
|
||||
setItem(key: string, value: unknown, emitEvent: boolean = true): void {
|
||||
const currentValue = this.getItem(key);
|
||||
|
||||
const fireEvent = (valueToStore: string | undefined) => {
|
||||
@@ -49,9 +49,10 @@ export class Storage {
|
||||
return;
|
||||
}
|
||||
|
||||
const stringify = typeof value !== 'string';
|
||||
const valueToStore = stringify ? JSON.stringify(value) : value;
|
||||
|
||||
this.storage.setItem(key, valueToStore as string);
|
||||
this.storage.setItem(key, valueToStore);
|
||||
fireEvent(valueToStore as string);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
|
||||
import { Dispatch, Reducer, SetStateAction, useCallback, useMemo, useReducer, useSyncExternalStore } from 'react';
|
||||
import { AppStorage, Storage } from '@/lib/storage/AppStorage.ts';
|
||||
import { jsonSaveParse } from '@/lib/HelperFunctions.ts';
|
||||
|
||||
const subscribeToStorageUpdates = (callback: () => void) => {
|
||||
window.addEventListener('storage', callback);
|
||||
@@ -31,16 +32,29 @@ function useStorage<T>(
|
||||
const setValue = useCallback<React.Dispatch<React.SetStateAction<T | undefined>>>(
|
||||
(value) => {
|
||||
// Allow value to be a function so we have same API as useState
|
||||
const valueToStore = value instanceof Function ? value(storage.getItemParsed(key, initialState)) : value;
|
||||
const valueToStore = (() => {
|
||||
if (value instanceof Function) {
|
||||
const previousValue =
|
||||
jsonSaveParse(storage.getItem(key) ?? '') ?? storage.getItemParsed(key, initialState);
|
||||
|
||||
return value(previousValue);
|
||||
}
|
||||
|
||||
return value;
|
||||
})();
|
||||
|
||||
storage.setItem(key, valueToStore);
|
||||
},
|
||||
[key],
|
||||
);
|
||||
|
||||
const storedValue = useMemo(
|
||||
() => (storedValueRaw !== null ? JSON.parse(storedValueRaw) : initialState),
|
||||
[storedValueRaw, key],
|
||||
);
|
||||
const storedValue = useMemo(() => {
|
||||
if (storedValueRaw === null) {
|
||||
return initialState;
|
||||
}
|
||||
|
||||
return jsonSaveParse(storedValueRaw) ?? storedValueRaw;
|
||||
}, [storedValueRaw, key]);
|
||||
|
||||
return [storedValue, setValue];
|
||||
}
|
||||
|
||||
@@ -86,7 +86,7 @@ export const Appearance = () => {
|
||||
setThemeMode(newMode as ThemeMode);
|
||||
setMode(newMode);
|
||||
// in case a non "colorSchemes" mui theme is active, "setMode" does not update the mode ("mui-mode") value
|
||||
AppStorage.local.setItem('mui-mode', newMode, true, false);
|
||||
AppStorage.local.setItem('mui-mode', newMode, true);
|
||||
}}
|
||||
>
|
||||
<MenuItem key={ThemeMode.SYSTEM} value={ThemeMode.SYSTEM}>
|
||||
|
||||
Reference in New Issue
Block a user