aboutsummaryrefslogtreecommitdiffstats
path: root/packages
diff options
context:
space:
mode:
authorMohamedBassem <me@mbassem.com>2024-03-11 11:05:36 +0000
committerMohamedBassem <me@mbassem.com>2024-03-11 11:05:36 +0000
commit999ed977a588b2c3b2055f18db4218d77882a1a1 (patch)
treebe926d82bcd495878956483ee7b21a172666566a /packages
parente774f1ad01d4755651a82ed100c26587774c8ee0 (diff)
downloadkarakeep-999ed977a588b2c3b2055f18db4218d77882a1a1.tar.zst
mobile: Add support for app settings
Diffstat (limited to 'packages')
-rw-r--r--packages/mobile/app.json3
-rw-r--r--packages/mobile/app/_layout.tsx12
-rw-r--r--packages/mobile/lib/providers.tsx47
-rw-r--r--packages/mobile/lib/settings.ts39
-rw-r--r--packages/mobile/lib/trpc.ts4
-rw-r--r--packages/mobile/package.json6
6 files changed, 104 insertions, 7 deletions
diff --git a/packages/mobile/app.json b/packages/mobile/app.json
index 11455267..cfc42f72 100644
--- a/packages/mobile/app.json
+++ b/packages/mobile/app.json
@@ -38,7 +38,8 @@
"NSExtensionActivationSupportsImageWithMaxCount": 1,
"NSExtensionActivationSupportsMovieWithMaxCount": 1
}
- }]
+ }],
+ "expo-secure-store"
]
}
}
diff --git a/packages/mobile/app/_layout.tsx b/packages/mobile/app/_layout.tsx
index c578d07f..b37585e2 100644
--- a/packages/mobile/app/_layout.tsx
+++ b/packages/mobile/app/_layout.tsx
@@ -7,6 +7,8 @@ import { StatusBar } from "expo-status-bar";
import { useEffect } from "react";
import { View } from "react-native";
+import { Providers } from "@/lib/providers";
+
export default function RootLayout() {
const router = useRouter();
const { hasShareIntent, shareIntent, resetShareIntent } = useShareIntent({
@@ -23,9 +25,11 @@ export default function RootLayout() {
}
}, [hasShareIntent]);
return (
- <View className="h-full w-full bg-white">
- <Slot />
- <StatusBar style="auto" />
- </View>
+ <Providers>
+ <View className="h-full w-full bg-white">
+ <Slot />
+ <StatusBar style="auto" />
+ </View>
+ </Providers>
);
}
diff --git a/packages/mobile/lib/providers.tsx b/packages/mobile/lib/providers.tsx
new file mode 100644
index 00000000..d5638da8
--- /dev/null
+++ b/packages/mobile/lib/providers.tsx
@@ -0,0 +1,47 @@
+import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
+import { httpBatchLink } from "@trpc/client";
+import { useEffect, useState } from "react";
+import superjson from "superjson";
+
+import useAppSettings, { getAppSettings } from "./settings";
+import { api } from "./trpc";
+
+function getTRPCClient(address: string) {
+ return api.createClient({
+ links: [
+ httpBatchLink({
+ url: `${address}/api/trpc`,
+ async headers() {
+ const settings = await getAppSettings();
+ return {
+ Authorization: settings ? `Bearer ${settings.apiKey}` : undefined,
+ };
+ },
+ transformer: superjson,
+ }),
+ ],
+ });
+}
+
+export function Providers({ children }: { children: React.ReactNode }) {
+ const { settings } = useAppSettings();
+ const [queryClient] = useState(() => new QueryClient());
+
+ const [trpcClient, setTrpcClient] = useState<
+ ReturnType<typeof getTRPCClient>
+ >(getTRPCClient(settings.address));
+
+ useEffect(() => {
+ setTrpcClient(getTRPCClient(settings.address));
+ }, [settings.address]);
+
+ return (
+ <api.Provider
+ key={settings.address}
+ client={trpcClient}
+ queryClient={queryClient}
+ >
+ <QueryClientProvider client={queryClient}>{children}</QueryClientProvider>
+ </api.Provider>
+ );
+}
diff --git a/packages/mobile/lib/settings.ts b/packages/mobile/lib/settings.ts
new file mode 100644
index 00000000..85296cfa
--- /dev/null
+++ b/packages/mobile/lib/settings.ts
@@ -0,0 +1,39 @@
+import * as SecureStore from "expo-secure-store";
+import { useEffect, useState } from "react";
+
+const SETTING_NAME = "settings";
+
+export type Settings = {
+ apiKey: string;
+ address: string;
+};
+
+export default function useAppSettings() {
+ const [settings, setSettings] = useState<Settings>({
+ apiKey: "",
+ address: "",
+ });
+
+ useEffect(() => {
+ SecureStore.setItemAsync(SETTING_NAME, JSON.stringify(settings));
+ }, [settings]);
+
+ useEffect(() => {
+ SecureStore.getItemAsync(SETTING_NAME).then((val) => {
+ if (!val) {
+ return;
+ }
+ setSettings(JSON.parse(val));
+ });
+ }, []);
+
+ return { settings, setSettings };
+}
+
+export async function getAppSettings() {
+ const val = await SecureStore.getItemAsync(SETTING_NAME);
+ if (!val) {
+ return null;
+ }
+ return JSON.parse(val) as Settings;
+}
diff --git a/packages/mobile/lib/trpc.ts b/packages/mobile/lib/trpc.ts
new file mode 100644
index 00000000..6b428bd9
--- /dev/null
+++ b/packages/mobile/lib/trpc.ts
@@ -0,0 +1,4 @@
+import type { AppRouter } from "@hoarder/trpc/routers/_app";
+import { createTRPCReact } from "@trpc/react-query";
+
+export const api = createTRPCReact<AppRouter>();
diff --git a/packages/mobile/package.json b/packages/mobile/package.json
index 70054835..bbc0127c 100644
--- a/packages/mobile/package.json
+++ b/packages/mobile/package.json
@@ -4,12 +4,13 @@
"main": "expo-router/entry",
"scripts": {
"start": "expo start",
- "android": "expo start --android",
- "ios": "expo start --ios",
+ "android": "expo run:android",
+ "ios": "expo run:ios",
"web": "expo start --web",
"lint": "eslint ."
},
"dependencies": {
+ "@tanstack/react-query": "^5.24.8",
"class-variance-authority": "^0.7.0",
"clsx": "^2.1.0",
"expo": "~50.0.11",
@@ -18,6 +19,7 @@
"expo-dev-client": "^3.3.9",
"expo-linking": "~6.2.2",
"expo-router": "~3.4.8",
+ "expo-secure-store": "^12.8.1",
"expo-share-intent": "^1.0.1",
"expo-status-bar": "~1.11.1",
"lucide-react-native": "^0.354.0",