From 56c30b26906f3210084e31387e72c964c4069a71 Mon Sep 17 00:00:00 2001 From: im-adithya Date: Mon, 28 Oct 2024 20:42:41 +0530 Subject: [PATCH 1/2] fix: store theme in app store and secure storage --- app/_layout.tsx | 15 ++++++++++++--- lib/state/appStore.ts | 18 ++++++++++++++---- pages/settings/Settings.tsx | 7 ++++++- 3 files changed, 32 insertions(+), 8 deletions(-) diff --git a/app/_layout.tsx b/app/_layout.tsx index 25f4a13..e604862 100644 --- a/app/_layout.tsx +++ b/app/_layout.tsx @@ -41,7 +41,8 @@ export const unstable_settings = { }; export default function RootLayout() { - const { isDarkColorScheme } = useColorScheme(); + const { isDarkColorScheme, setColorScheme } = useColorScheme(); + const [themeLoaded, setThemeLoaded] = React.useState(false); const [fontsLoaded, setFontsLoaded] = React.useState(false); useConnectionChecker(); @@ -64,9 +65,17 @@ export default function RootLayout() { } } + const loadTheme = React.useCallback((): void => { + const theme = useAppStore.getState().theme as "light" | "dark" | "system"; + setColorScheme(theme); + + setThemeLoaded(true); + }, [setColorScheme]); + React.useEffect(() => { const init = async () => { try { + loadTheme(); await Promise.all([loadFonts(), checkBiometricStatus()]); } finally { SplashScreen.hideAsync(); @@ -74,9 +83,9 @@ export default function RootLayout() { }; init(); - }, []); + }, [loadTheme]); - if (!fontsLoaded) { + if (!fontsLoaded || !themeLoaded) { return null; } diff --git a/lib/state/appStore.ts b/lib/state/appStore.ts index 7284ba2..cefc4e0 100644 --- a/lib/state/appStore.ts +++ b/lib/state/appStore.ts @@ -12,7 +12,9 @@ interface AppState { readonly addressBookEntries: AddressBookEntry[]; readonly isSecurityEnabled: boolean; readonly isOnboarded: boolean; + readonly theme: string; setUnlocked: (unlocked: boolean) => void; + setTheme: (theme: string) => void; setOnboarded: (isOnboarded: boolean) => void; setNWCClient: (nwcClient: NWCClient | undefined) => void; updateCurrentWallet(wallet: Partial): void; @@ -33,7 +35,8 @@ const selectedWalletIdKey = "selectedWalletId"; const fiatCurrencyKey = "fiatCurrency"; const hasOnboardedKey = "hasOnboarded"; const lastAlbyPaymentKey = "lastAlbyPayment"; -export const isSecurityEnabledKey = "isSecurityEnabled"; +const themeKey = "theme"; +const isSecurityEnabledKey = "isSecurityEnabled"; export const lastActiveTimeKey = "lastActiveTime"; type Wallet = { @@ -139,17 +142,20 @@ export const useAppStore = create()((set, get) => { secureStorage.getItem(selectedWalletIdKey) || "0" ); - const iSecurityEnabled = + const isSecurityEnabled = secureStorage.getItem(isSecurityEnabledKey) === "true"; + const theme = secureStorage.getItem(themeKey) || "system"; + const initialWallets = loadWallets(); return { - unlocked: !iSecurityEnabled, + unlocked: !isSecurityEnabled, addressBookEntries: loadAddressBookEntries(), wallets: initialWallets, nwcClient: getNWCClient(initialSelectedWalletId), fiatCurrency: secureStorage.getItem(fiatCurrencyKey) || "", - isSecurityEnabled: iSecurityEnabled, + isSecurityEnabled, + theme, isOnboarded: secureStorage.getItem(hasOnboardedKey) === "true", selectedWalletId: initialSelectedWalletId, updateCurrentWallet, @@ -157,6 +163,10 @@ export const useAppStore = create()((set, get) => { setUnlocked: (unlocked) => { set({ unlocked }); }, + setTheme: (theme) => { + secureStorage.setItem(themeKey, theme); + set({ theme }); + }, setOnboarded: (isOnboarded) => { if (isOnboarded) { secureStorage.setItem(hasOnboardedKey, "true"); diff --git a/pages/settings/Settings.tsx b/pages/settings/Settings.tsx index 151543e..2eb2188 100644 --- a/pages/settings/Settings.tsx +++ b/pages/settings/Settings.tsx @@ -72,7 +72,12 @@ export function Settings() { { + useAppStore + .getState() + .setTheme(colorScheme === "light" ? "dark" : "light"); + toggleColorScheme(); + }} > Theme From f8cb24acdd9a8b62203f892eae951d5fac4d2dac Mon Sep 17 00:00:00 2001 From: im-adithya Date: Tue, 29 Oct 2024 19:53:53 +0530 Subject: [PATCH 2/2] chore: fixes --- app/_layout.tsx | 22 ++++++++++------------ lib/state/appStore.ts | 8 +++++--- lib/useColorScheme.tsx | 18 +++++++++++++++--- pages/settings/Settings.tsx | 7 +------ 4 files changed, 31 insertions(+), 24 deletions(-) diff --git a/app/_layout.tsx b/app/_layout.tsx index e604862..f1ea3c4 100644 --- a/app/_layout.tsx +++ b/app/_layout.tsx @@ -42,8 +42,7 @@ export const unstable_settings = { export default function RootLayout() { const { isDarkColorScheme, setColorScheme } = useColorScheme(); - const [themeLoaded, setThemeLoaded] = React.useState(false); - const [fontsLoaded, setFontsLoaded] = React.useState(false); + const [resourcesLoaded, setResourcesLoaded] = React.useState(false); useConnectionChecker(); @@ -54,8 +53,6 @@ export default function RootLayout() { "OpenRunde-Semibold": require("./../assets/fonts/OpenRunde-Semibold.otf"), "OpenRunde-Bold": require("./../assets/fonts/OpenRunde-Bold.otf"), }); - - setFontsLoaded(true); } async function checkBiometricStatus() { @@ -65,19 +62,20 @@ export default function RootLayout() { } } - const loadTheme = React.useCallback((): void => { - const theme = useAppStore.getState().theme as "light" | "dark" | "system"; - setColorScheme(theme); - - setThemeLoaded(true); + const loadTheme = React.useCallback((): Promise => { + return new Promise((resolve) => { + const theme = useAppStore.getState().theme; + setColorScheme(theme); + resolve(); + }); }, [setColorScheme]); React.useEffect(() => { const init = async () => { try { - loadTheme(); - await Promise.all([loadFonts(), checkBiometricStatus()]); + await Promise.all([loadTheme(), loadFonts(), checkBiometricStatus()]); } finally { + setResourcesLoaded(true); SplashScreen.hideAsync(); } }; @@ -85,7 +83,7 @@ export default function RootLayout() { init(); }, [loadTheme]); - if (!fontsLoaded || !themeLoaded) { + if (!resourcesLoaded) { return null; } diff --git a/lib/state/appStore.ts b/lib/state/appStore.ts index cefc4e0..dfcc173 100644 --- a/lib/state/appStore.ts +++ b/lib/state/appStore.ts @@ -12,9 +12,9 @@ interface AppState { readonly addressBookEntries: AddressBookEntry[]; readonly isSecurityEnabled: boolean; readonly isOnboarded: boolean; - readonly theme: string; + readonly theme: Theme; setUnlocked: (unlocked: boolean) => void; - setTheme: (theme: string) => void; + setTheme: (theme: Theme) => void; setOnboarded: (isOnboarded: boolean) => void; setNWCClient: (nwcClient: NWCClient | undefined) => void; updateCurrentWallet(wallet: Partial): void; @@ -39,6 +39,8 @@ const themeKey = "theme"; const isSecurityEnabledKey = "isSecurityEnabled"; export const lastActiveTimeKey = "lastActiveTime"; +export type Theme = "system" | "light" | "dark"; + type Wallet = { name?: string; nostrWalletConnectUrl?: string; @@ -145,7 +147,7 @@ export const useAppStore = create()((set, get) => { const isSecurityEnabled = secureStorage.getItem(isSecurityEnabledKey) === "true"; - const theme = secureStorage.getItem(themeKey) || "system"; + const theme = (secureStorage.getItem(themeKey) as Theme) || "system"; const initialWallets = loadWallets(); return { diff --git a/lib/useColorScheme.tsx b/lib/useColorScheme.tsx index df75499..a4a7e17 100644 --- a/lib/useColorScheme.tsx +++ b/lib/useColorScheme.tsx @@ -1,11 +1,23 @@ import { useColorScheme as useNativewindColorScheme } from "nativewind"; +import { useAppStore } from "~/lib/state/appStore"; export function useColorScheme() { - const { colorScheme, setColorScheme, toggleColorScheme } = - useNativewindColorScheme(); + const { + colorScheme, + setColorScheme, + toggleColorScheme: _toggleColorScheme, + } = useNativewindColorScheme(); + + const isDarkColorScheme = colorScheme === "dark"; + + const toggleColorScheme = () => { + _toggleColorScheme(); + useAppStore.getState().setTheme(isDarkColorScheme ? "light" : "dark"); + }; + return { colorScheme: colorScheme ?? "dark", - isDarkColorScheme: colorScheme === "dark", + isDarkColorScheme, setColorScheme, toggleColorScheme, }; diff --git a/pages/settings/Settings.tsx b/pages/settings/Settings.tsx index 2eb2188..151543e 100644 --- a/pages/settings/Settings.tsx +++ b/pages/settings/Settings.tsx @@ -72,12 +72,7 @@ export function Settings() { { - useAppStore - .getState() - .setTheme(colorScheme === "light" ? "dark" : "light"); - toggleColorScheme(); - }} + onPress={toggleColorScheme} > Theme