diff options
Diffstat (limited to 'packages/web-util/src/hooks')
-rw-r--r-- | packages/web-util/src/hooks/index.ts | 2 | ||||
-rw-r--r-- | packages/web-util/src/hooks/useLang.ts | 9 | ||||
-rw-r--r-- | packages/web-util/src/hooks/useLocalStorage.ts | 105 |
3 files changed, 39 insertions, 77 deletions
diff --git a/packages/web-util/src/hooks/index.ts b/packages/web-util/src/hooks/index.ts index 393a6fcbb..e5cb54e21 100644 --- a/packages/web-util/src/hooks/index.ts +++ b/packages/web-util/src/hooks/index.ts @@ -1,5 +1,5 @@ export { useLang } from "./useLang.js"; -export { useLocalStorage, useNotNullLocalStorage } from "./useLocalStorage.js"; +export { useLocalStorage } from "./useLocalStorage.js"; export { useAsyncAsHook, HookError, diff --git a/packages/web-util/src/hooks/useLang.ts b/packages/web-util/src/hooks/useLang.ts index 5b02c5255..9888cc51a 100644 --- a/packages/web-util/src/hooks/useLang.ts +++ b/packages/web-util/src/hooks/useLang.ts @@ -14,17 +14,16 @@ GNU Anastasis; see the file COPYING. If not, see <http://www.gnu.org/licenses/> */ -import { useNotNullLocalStorage } from "./useLocalStorage.js"; +import { LocalStorageState, useLocalStorage } from "./useLocalStorage.js"; function getBrowserLang(): string | undefined { + if (typeof window === "undefined") return undefined; if (window.navigator.languages) return window.navigator.languages[0]; if (window.navigator.language) return window.navigator.language; return undefined; } -export function useLang( - initial?: string, -): [string, (s: string) => void, boolean] { +export function useLang(initial?: string): Required<LocalStorageState> { const defaultLang = (getBrowserLang() || initial || "en").substring(0, 2); - return useNotNullLocalStorage("lang-preference", defaultLang); + return useLocalStorage("lang-preference", defaultLang); } diff --git a/packages/web-util/src/hooks/useLocalStorage.ts b/packages/web-util/src/hooks/useLocalStorage.ts index ab786db13..264919d37 100644 --- a/packages/web-util/src/hooks/useLocalStorage.ts +++ b/packages/web-util/src/hooks/useLocalStorage.ts @@ -19,92 +19,55 @@ * @author Sebastian Javier Marchano (sebasjm) */ -import { StateUpdater, useEffect, useState } from "preact/hooks"; +import { useEffect, useState } from "preact/hooks"; +import { localStorageMap, memoryMap } from "../utils/observable.js"; +export interface LocalStorageState { + value?: string; + update: (s: string) => void; + reset: () => void; +} + +const supportLocalStorage = typeof window !== "undefined"; + +const storage = supportLocalStorage ? localStorageMap() : memoryMap<string>(); + +export function useLocalStorage( + key: string, + initialValue: string, +): Required<LocalStorageState>; +export function useLocalStorage(key: string): LocalStorageState; export function useLocalStorage( key: string, initialValue?: string, -): [string | undefined, StateUpdater<string | undefined>] { +): LocalStorageState { const [storedValue, setStoredValue] = useState<string | undefined>( (): string | undefined => { - return typeof window !== "undefined" - ? window.localStorage.getItem(key) || initialValue - : initialValue; + return storage.get(key) ?? initialValue; }, ); useEffect(() => { - const listener = buildListenerForKey(key, (newValue) => { + return storage.onUpdate(key, () => { + const newValue = storage.get(key); + console.log("new value", key, newValue); setStoredValue(newValue ?? initialValue); }); - window.addEventListener("storage", listener); - return () => { - window.removeEventListener("storage", listener); - }; }, []); - const setValue = ( - value?: string | ((val?: string) => string | undefined), - ): void => { - setStoredValue((p) => { - const toStore = value instanceof Function ? value(p) : value; - if (typeof window !== "undefined") { - if (!toStore) { - window.localStorage.removeItem(key); - } else { - window.localStorage.setItem(key, toStore); - } - } - return toStore; - }); - }; - - return [storedValue, setValue]; -} - -function buildListenerForKey( - key: string, - onUpdate: (newValue: string | undefined) => void, -): () => void { - return function listenKeyChange() { - const value = window.localStorage.getItem(key); - onUpdate(value ?? undefined); - }; -} - -//TODO: merge with the above function -export function useNotNullLocalStorage( - key: string, - initialValue: string, -): [string, StateUpdater<string>, boolean] { - const [storedValue, setStoredValue] = useState<string>((): string => { - return typeof window !== "undefined" - ? window.localStorage.getItem(key) || initialValue - : initialValue; - }); - - useEffect(() => { - const listener = buildListenerForKey(key, (newValue) => { - setStoredValue(newValue ?? initialValue); - }); - window.addEventListener("storage", listener); - return () => { - window.removeEventListener("storage", listener); - }; - }); - - const setValue = (value: string | ((val: string) => string)): void => { - const valueToStore = value instanceof Function ? value(storedValue) : value; - setStoredValue(valueToStore); - if (typeof window !== "undefined") { - if (!valueToStore) { - window.localStorage.removeItem(key); - } else { - window.localStorage.setItem(key, valueToStore); - } + const setValue = (value?: string): void => { + if (!value) { + storage.delete(key); + } else { + storage.set(key, value); } }; - const isSaved = window.localStorage.getItem(key) !== null; - return [storedValue, setValue, isSaved]; + return { + value: storedValue, + update: setValue, + reset: () => { + setValue(initialValue); + }, + }; } |