diff options
| author | MohamedBassem <me@mbassem.com> | 2024-03-11 12:24:51 +0000 |
|---|---|---|
| committer | MohamedBassem <me@mbassem.com> | 2024-03-11 12:33:31 +0000 |
| commit | c87db85815d84ddf907d0a1d26226a2ab911181b (patch) | |
| tree | c909031a7c9b525871fc8938e98c38da4741bde9 /packages/mobile/lib/storage-state.ts | |
| parent | 999ed977a588b2c3b2055f18db4218d77882a1a1 (diff) | |
| download | karakeep-c87db85815d84ddf907d0a1d26226a2ab911181b.tar.zst | |
mobile: An ugly yet functional signin workflow
Diffstat (limited to 'packages/mobile/lib/storage-state.ts')
| -rw-r--r-- | packages/mobile/lib/storage-state.ts | 50 |
1 files changed, 50 insertions, 0 deletions
diff --git a/packages/mobile/lib/storage-state.ts b/packages/mobile/lib/storage-state.ts new file mode 100644 index 00000000..09917c79 --- /dev/null +++ b/packages/mobile/lib/storage-state.ts @@ -0,0 +1,50 @@ +import * as SecureStore from "expo-secure-store"; +import * as React from "react"; + +type UseStateHook<T> = [[boolean, T | null], (value: T | null) => void]; + +function useAsyncState<T>( + initialValue: [boolean, T | null] = [true, null], +): UseStateHook<T> { + return React.useReducer( + ( + state: [boolean, T | null], + action: T | null = null, + ): [boolean, T | null] => [false, action], + initialValue, + ) as UseStateHook<T>; +} + +export async function setStorageItemAsync(key: string, value: string | null) { + if (value == null) { + await SecureStore.deleteItemAsync(key); + } else { + await SecureStore.setItemAsync(key, value); + } +} + +export function useStorageState<T>(key: string): UseStateHook<T> { + // Public + const [state, setState] = useAsyncState<T>(); + + // Get + React.useEffect(() => { + SecureStore.getItemAsync(key).then((value) => { + if (!value) { + return null; + } + setState(JSON.parse(value)); + }); + }, [key]); + + // Set + const setValue = React.useCallback( + (value: T | null) => { + setState(value); + setStorageItemAsync(key, JSON.stringify(value)); + }, + [key], + ); + + return [state, setValue]; +} |
