aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--apps/mobile/app/dashboard/(tabs)/index.tsx2
-rw-r--r--apps/mobile/app/dashboard/(tabs)/settings.tsx42
-rw-r--r--apps/mobile/components/ui/PageTitle.tsx13
-rw-r--r--apps/mobile/lib/settings.ts18
-rw-r--r--apps/mobile/package.json1
-rw-r--r--pnpm-lock.yaml20
6 files changed, 84 insertions, 12 deletions
diff --git a/apps/mobile/app/dashboard/(tabs)/index.tsx b/apps/mobile/app/dashboard/(tabs)/index.tsx
index dc9871e7..bd7ce3ea 100644
--- a/apps/mobile/app/dashboard/(tabs)/index.tsx
+++ b/apps/mobile/app/dashboard/(tabs)/index.tsx
@@ -34,7 +34,7 @@ function HeaderRight({
} else if (nativeEvent.event === "library") {
const result = await ImagePicker.launchImageLibraryAsync({
mediaTypes: ImagePicker.MediaTypeOptions.Images,
- quality: 0,
+ quality: settings.imageQuality,
allowsMultipleSelection: false,
});
if (!result.canceled) {
diff --git a/apps/mobile/app/dashboard/(tabs)/settings.tsx b/apps/mobile/app/dashboard/(tabs)/settings.tsx
index 73d1b42d..18d3d243 100644
--- a/apps/mobile/app/dashboard/(tabs)/settings.tsx
+++ b/apps/mobile/app/dashboard/(tabs)/settings.tsx
@@ -1,6 +1,10 @@
+import { useEffect } from "react";
import { Text, View } from "react-native";
+import { Slider } from "react-native-awesome-slider";
+import { useSharedValue } from "react-native-reanimated";
import { Button } from "@/components/ui/Button";
import CustomSafeAreaView from "@/components/ui/CustomSafeAreaView";
+import { Divider } from "@/components/ui/Divider";
import PageTitle from "@/components/ui/PageTitle";
import { useSession } from "@/lib/session";
import useAppSettings from "@/lib/settings";
@@ -8,7 +12,19 @@ import { api } from "@/lib/trpc";
export default function Dashboard() {
const { logout } = useSession();
- const { settings, isLoading: isSettingsLoading } = useAppSettings();
+ const {
+ settings,
+ setSettings,
+ isLoading: isSettingsLoading,
+ } = useAppSettings();
+
+ const imageQuality = useSharedValue(0);
+ const imageQualityMin = useSharedValue(0);
+ const imageQualityMax = useSharedValue(100);
+
+ useEffect(() => {
+ imageQuality.value = settings.imageQuality * 100;
+ }, [settings]);
const { data, error, isLoading } = api.users.whoami.useQuery();
@@ -30,8 +46,30 @@ export default function Dashboard() {
{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">
+ Upload 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">
+ <Text className="text-lg text-accent-foreground">Image Quality</Text>
+ <View className="flex flex-1 flex-row items-center justify-center gap-2">
+ <Text className="text-foreground">
+ {settings.imageQuality * 100}%
+ </Text>
+ <Slider
+ onSlidingComplete={(value) =>
+ setSettings({
+ ...settings,
+ imageQuality: Math.round(value) / 100,
+ })
+ }
+ progress={imageQuality}
+ minimumValue={imageQualityMin}
+ maximumValue={imageQualityMax}
+ />
+ </View>
+ </View>
</View>
</CustomSafeAreaView>
);
diff --git a/apps/mobile/components/ui/PageTitle.tsx b/apps/mobile/components/ui/PageTitle.tsx
index 1c1543ce..dc712379 100644
--- a/apps/mobile/components/ui/PageTitle.tsx
+++ b/apps/mobile/components/ui/PageTitle.tsx
@@ -1,7 +1,16 @@
import { Text } from "react-native";
+import { cx } from "class-variance-authority";
-export default function PageTitle({ title }: { title: string }) {
+export default function PageTitle({
+ title,
+ className,
+}: {
+ title: string;
+ className?: string;
+}) {
return (
- <Text className="p-4 text-4xl font-bold text-foreground">{title}</Text>
+ <Text className={cx("p-4 text-4xl font-bold text-foreground", className)}>
+ {title}
+ </Text>
);
}
diff --git a/apps/mobile/lib/settings.ts b/apps/mobile/lib/settings.ts
index efb5593a..085f4f01 100644
--- a/apps/mobile/lib/settings.ts
+++ b/apps/mobile/lib/settings.ts
@@ -1,13 +1,17 @@
import * as SecureStore from "expo-secure-store";
+import { z } from "zod";
import { create } from "zustand";
const SETTING_NAME = "settings";
-export interface Settings {
- apiKey?: string;
- apiKeyId?: string;
- address: string;
-}
+const zSettingsSchema = z.object({
+ apiKey: z.string().optional(),
+ apiKeyId: z.string().optional(),
+ address: z.string(),
+ imageQuality: z.number().optional().default(0.2),
+});
+
+export type Settings = z.infer<typeof zSettingsSchema>;
interface AppSettingsState {
settings: { isLoading: boolean; settings: Settings };
@@ -18,7 +22,7 @@ interface AppSettingsState {
const useSettings = create<AppSettingsState>((set, get) => ({
settings: {
isLoading: true,
- settings: { address: "" },
+ settings: { address: "", imageQuality: 0.2 },
},
setSettings: async (settings) => {
await SecureStore.setItemAsync(SETTING_NAME, JSON.stringify(settings));
@@ -36,7 +40,7 @@ const useSettings = create<AppSettingsState>((set, get) => ({
return;
}
// TODO Wipe the state if invalid
- const parsed = JSON.parse(strVal) as Settings;
+ const parsed = zSettingsSchema.parse(JSON.parse(strVal));
set((_state) => ({ settings: { isLoading: false, settings: parsed } }));
},
}));
diff --git a/apps/mobile/package.json b/apps/mobile/package.json
index da8ef432..6519692e 100644
--- a/apps/mobile/package.json
+++ b/apps/mobile/package.json
@@ -42,6 +42,7 @@
"nativewind": "^4.0.1",
"react": "^18.2.0",
"react-native": "0.73.4",
+ "react-native-awesome-slider": "^2.5.3",
"react-native-gesture-handler": "~2.14.0",
"react-native-markdown-display": "^7.0.2",
"react-native-reanimated": "^3.8.0",
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index f1fcf9a0..9f0d5901 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -378,6 +378,9 @@ importers:
react-native:
specifier: 0.73.4
version: 0.73.4(@babel/core@7.23.9)(@babel/preset-env@7.24.0(@babel/core@7.23.9))(react@18.2.0)
+ react-native-awesome-slider:
+ specifier: ^2.5.3
+ version: 2.5.3(react-native-gesture-handler@2.14.1(react-native@0.73.4(@babel/core@7.23.9)(@babel/preset-env@7.24.0(@babel/core@7.23.9))(react@18.2.0))(react@18.2.0))(react-native-reanimated@3.8.0(@babel/core@7.23.9)(react-native@0.73.4(@babel/core@7.23.9)(@babel/preset-env@7.24.0(@babel/core@7.23.9))(react@18.2.0))(react@18.2.0))(react-native@0.73.4(@babel/core@7.23.9)(@babel/preset-env@7.24.0(@babel/core@7.23.9))(react@18.2.0))(react@18.2.0)
react-native-gesture-handler:
specifier: ~2.14.0
version: 2.14.1(react-native@0.73.4(@babel/core@7.23.9)(@babel/preset-env@7.24.0(@babel/core@7.23.9))(react@18.2.0))(react@18.2.0)
@@ -10340,6 +10343,15 @@ packages:
peerDependencies:
react: '>=16.0.0'
+ react-native-awesome-slider@2.5.3:
+ resolution: {integrity: sha512-dKgwcKz2hobR1xd0FFdxP99vcPhVJK6sZgTyjwbGBK97cnFB8mB5WhIRXzPLnSgrNMABPS6IbdseLRNhpp57gQ==}
+ engines: {node: '>= 18.0.0'}
+ peerDependencies:
+ react: '*'
+ react-native: '*'
+ react-native-gesture-handler: '>=2.0.0'
+ react-native-reanimated: '>=3.0.0'
+
react-native-css-interop@0.0.36:
resolution: {integrity: sha512-ZWoKQlq6XrI5DB4BdPk5ABvJQsX7zls1SQYWuYXOQB8u5QE0KH3OfOGAGRZPekTjgkhjqGO4Bf8G2JTSWAYMSg==}
engines: {node: '>=18'}
@@ -26521,6 +26533,14 @@ snapshots:
react: 18.2.0
dev: false
+ react-native-awesome-slider@2.5.3(react-native-gesture-handler@2.14.1(react-native@0.73.4(@babel/core@7.23.9)(@babel/preset-env@7.24.0(@babel/core@7.23.9))(react@18.2.0))(react@18.2.0))(react-native-reanimated@3.8.0(@babel/core@7.23.9)(react-native@0.73.4(@babel/core@7.23.9)(@babel/preset-env@7.24.0(@babel/core@7.23.9))(react@18.2.0))(react@18.2.0))(react-native@0.73.4(@babel/core@7.23.9)(@babel/preset-env@7.24.0(@babel/core@7.23.9))(react@18.2.0))(react@18.2.0):
+ dependencies:
+ react: 18.2.0
+ react-native: 0.73.4(@babel/core@7.23.9)(@babel/preset-env@7.24.0(@babel/core@7.23.9))(react@18.2.0)
+ react-native-gesture-handler: 2.14.1(react-native@0.73.4(@babel/core@7.23.9)(@babel/preset-env@7.24.0(@babel/core@7.23.9))(react@18.2.0))(react@18.2.0)
+ react-native-reanimated: 3.8.0(@babel/core@7.23.9)(react-native@0.73.4(@babel/core@7.23.9)(@babel/preset-env@7.24.0(@babel/core@7.23.9))(react@18.2.0))(react@18.2.0)
+ dev: false
+
react-native-css-interop@0.0.36(@babel/core@7.23.9)(react-native-reanimated@3.8.0(@babel/core@7.23.9)(react-native@0.73.4(@babel/core@7.23.9)(@babel/preset-env@7.24.0(@babel/core@7.23.9))(react@18.2.0))(react@18.2.0))(react-native-safe-area-context@4.8.2(react-native@0.73.4(@babel/core@7.23.9)(@babel/preset-env@7.24.0(@babel/core@7.23.9))(react@18.2.0))(react@18.2.0))(react-native-svg@15.1.0(react-native@0.73.4(@babel/core@7.23.9)(@babel/preset-env@7.24.0(@babel/core@7.23.9))(react@18.2.0))(react@18.2.0))(react-native@0.73.4(@babel/core@7.23.9)(@babel/preset-env@7.24.0(@babel/core@7.23.9))(react@18.2.0))(react@18.2.0)(tailwindcss@3.4.1):
dependencies:
'@babel/helper-module-imports': 7.22.15