aboutsummaryrefslogtreecommitdiffstats
path: root/apps/mobile/app
diff options
context:
space:
mode:
authorMohamedBassem <me@mbassem.com>2024-09-14 17:08:40 +0100
committerMohamedBassem <me@mbassem.com>2024-09-14 17:36:03 +0100
commit66fcf022695283268e80855365f10262ae6ec907 (patch)
tree07cc278b1476b9a868f6ecbf8cbfd9ea8ebf56f8 /apps/mobile/app
parentb9c7857c5bb16d024fed6544eebf0ef6cd10390f (diff)
downloadkarakeep-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.tsx8
-rw-r--r--apps/mobile/app/dashboard/(tabs)/settings.tsx33
-rw-r--r--apps/mobile/app/dashboard/_layout.tsx11
-rw-r--r--apps/mobile/app/dashboard/settings/theme.tsx47
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>
+ );
+}