diff options
| author | MohamedBassem <me@mbassem.com> | 2024-09-14 17:08:40 +0100 |
|---|---|---|
| committer | MohamedBassem <me@mbassem.com> | 2024-09-14 17:36:03 +0100 |
| commit | 66fcf022695283268e80855365f10262ae6ec907 (patch) | |
| tree | 07cc278b1476b9a868f6ecbf8cbfd9ea8ebf56f8 /apps/mobile/app | |
| parent | b9c7857c5bb16d024fed6544eebf0ef6cd10390f (diff) | |
| download | karakeep-66fcf022695283268e80855365f10262ae6ec907.tar.zst | |
feature(mobile): Add settings page for configuring the theme
Diffstat (limited to 'apps/mobile/app')
| -rw-r--r-- | apps/mobile/app/_layout.tsx | 8 | ||||
| -rw-r--r-- | apps/mobile/app/dashboard/(tabs)/settings.tsx | 33 | ||||
| -rw-r--r-- | apps/mobile/app/dashboard/_layout.tsx | 11 | ||||
| -rw-r--r-- | apps/mobile/app/dashboard/settings/theme.tsx | 47 |
4 files changed, 92 insertions, 7 deletions
diff --git a/apps/mobile/app/_layout.tsx b/apps/mobile/app/_layout.tsx index 0f38165b..41186842 100644 --- a/apps/mobile/app/_layout.tsx +++ b/apps/mobile/app/_layout.tsx @@ -10,6 +10,7 @@ import { ShareIntentProvider, useShareIntent } from "expo-share-intent"; import { StatusBar } from "expo-status-bar"; import { StyledStack } from "@/components/navigation/stack"; import { Providers } from "@/lib/providers"; +import useAppSettings from "@/lib/settings"; import { cn } from "@/lib/utils"; import { BottomSheetModalProvider } from "@gorhom/bottom-sheet"; import { useColorScheme } from "nativewind"; @@ -17,7 +18,8 @@ import { useColorScheme } from "nativewind"; export default function RootLayout() { const router = useRouter(); const { hasShareIntent } = useShareIntent(); - const { colorScheme } = useColorScheme(); + const { colorScheme, setColorScheme } = useColorScheme(); + const { settings } = useAppSettings(); useEffect(() => { if (hasShareIntent) { @@ -27,6 +29,10 @@ export default function RootLayout() { } }, [hasShareIntent]); + useEffect(() => { + setColorScheme(settings.theme); + }, [settings.theme]); + return ( <ShareIntentProvider> <Providers> diff --git a/apps/mobile/app/dashboard/(tabs)/settings.tsx b/apps/mobile/app/dashboard/(tabs)/settings.tsx index 18d3d243..db118df8 100644 --- a/apps/mobile/app/dashboard/(tabs)/settings.tsx +++ b/apps/mobile/app/dashboard/(tabs)/settings.tsx @@ -1,7 +1,8 @@ import { useEffect } from "react"; -import { Text, View } from "react-native"; +import { Pressable, Text, View } from "react-native"; import { Slider } from "react-native-awesome-slider"; import { useSharedValue } from "react-native-reanimated"; +import { Link } from "expo-router"; import { Button } from "@/components/ui/Button"; import CustomSafeAreaView from "@/components/ui/CustomSafeAreaView"; import { Divider } from "@/components/ui/Divider"; @@ -9,6 +10,7 @@ import PageTitle from "@/components/ui/PageTitle"; import { useSession } from "@/lib/session"; import useAppSettings from "@/lib/settings"; import { api } from "@/lib/trpc"; +import { ChevronRight } from "lucide-react-native"; export default function Dashboard() { const { logout } = useSession(); @@ -36,18 +38,35 @@ export default function Dashboard() { <CustomSafeAreaView> <PageTitle title="Settings" /> <View className="flex h-full w-full items-center gap-3 px-4 py-2"> - <View className="w-full rounded-lg bg-white px-4 py-2 dark:bg-accent"> + <View className="flex w-full gap-3 rounded-lg bg-white px-4 py-2 dark:bg-accent"> <Text className="text-lg text-accent-foreground"> {isSettingsLoading ? "Loading ..." : settings.address} </Text> - </View> - <View className="w-full rounded-lg bg-white px-4 py-2 dark:bg-accent"> + <Divider orientation="horizontal" /> <Text className="text-lg text-accent-foreground"> {isLoading ? "Loading ..." : data?.email} </Text> </View> - <Button className="w-full" label="Log Out" onPress={logout} /> - <Divider orientation="horizontal" /> + <Text className="w-full p-1 text-2xl font-bold text-foreground"> + App Settings + </Text> + <View className="flex w-full flex-row items-center justify-between gap-8 rounded-lg bg-white px-4 py-2 dark:bg-accent"> + <Link asChild href="/dashboard/settings/theme" className="flex-1"> + <Pressable className="flex flex-row justify-between"> + <Text className="text-lg text-accent-foreground">Theme</Text> + <View className="flex flex-row items-center gap-2"> + <Text className="text-lg text-muted-foreground"> + { + { light: "Light", dark: "Dark", system: "System" }[ + settings.theme + ] + } + </Text> + <ChevronRight color="rgb(0, 122, 255)" /> + </View> + </Pressable> + </Link> + </View> <Text className="w-full p-1 text-2xl font-bold text-foreground"> Upload Settings </Text> @@ -70,6 +89,8 @@ export default function Dashboard() { /> </View> </View> + <Divider orientation="horizontal" /> + <Button className="w-full" label="Log Out" onPress={logout} /> </View> </CustomSafeAreaView> ); diff --git a/apps/mobile/app/dashboard/_layout.tsx b/apps/mobile/app/dashboard/_layout.tsx index db4fd251..22d1ed07 100644 --- a/apps/mobile/app/dashboard/_layout.tsx +++ b/apps/mobile/app/dashboard/_layout.tsx @@ -33,6 +33,9 @@ export default function Dashboard() { <StyledStack contentClassName="bg-gray-100 dark:bg-background" headerClassName="bg-gray-100 dark:bg-background text-foreground" + screenOptions={{ + headerTransparent: true, + }} > <Stack.Screen name="(tabs)" @@ -54,6 +57,14 @@ export default function Dashboard() { headerTransparent: true, }} /> + <Stack.Screen + name="settings/theme" + options={{ + title: "Theme", + headerTitle: "Theme", + headerBackTitle: "Back", + }} + /> </StyledStack> ); } diff --git a/apps/mobile/app/dashboard/settings/theme.tsx b/apps/mobile/app/dashboard/settings/theme.tsx new file mode 100644 index 00000000..dc7ba367 --- /dev/null +++ b/apps/mobile/app/dashboard/settings/theme.tsx @@ -0,0 +1,47 @@ +import { Pressable, Text, View } from "react-native"; +import CustomSafeAreaView from "@/components/ui/CustomSafeAreaView"; +import { Divider } from "@/components/ui/Divider"; +import useAppSettings from "@/lib/settings"; +import { Check } from "lucide-react-native"; + +export default function ThemePage() { + const { settings, setSettings } = useAppSettings(); + + const options = (["light", "dark", "system"] as const) + .map((theme) => { + const isChecked = settings.theme === theme; + return [ + <Pressable + onPress={() => setSettings({ ...settings, theme })} + className="flex flex-row justify-between" + key={theme} + > + <Text className="text-lg text-accent-foreground"> + { + { light: "Light Mode", dark: "Dark Mode", system: "System" }[ + theme + ] + } + </Text> + {isChecked && <Check />} + </Pressable>, + <Divider + key={theme + "-divider"} + orientation="horizontal" + className="my-3 h-0.5 w-full" + />, + ]; + }) + .flat(); + options.pop(); + + return ( + <CustomSafeAreaView> + <View className="flex h-full w-full items-center px-4 py-2"> + <View className="w-full rounded-lg bg-white px-4 py-2 dark:bg-accent"> + {options} + </View> + </View> + </CustomSafeAreaView> + ); +} |
