aboutsummaryrefslogtreecommitdiffstats
path: root/apps/mobile
diff options
context:
space:
mode:
authorMohamed Bassem <me@mbassem.com>2025-08-20 15:57:34 +0300
committerGitHub <noreply@github.com>2025-08-20 13:57:34 +0100
commitdd53ccb9624e719d019a8fe29fcd66415c1b1528 (patch)
tree5788b06d4280248cf0c0f837318b0722f6d4cdd7 /apps/mobile
parent5f07b5075dd45b4b0f4ab35ee70412f11177eff4 (diff)
downloadkarakeep-dd53ccb9624e719d019a8fe29fcd66415c1b1528.tar.zst
deps: Upgrade expo & nextjs to react 19 (#1565)
* Attempt to upgrade expo 53 * Attempt upgrade nextjs * Fix a bunch of peer deps * upgrade some docs deps * fix typecheck * update the shadcn calendar component * more fixes * more fixes * revert ollama upgrade * update react version to use carets * remove react-select from landing * fix the typescript error caused by customFetch * upgrade the new grid user setting to nextjs 15 * mobile: enable react canary to support react 19.1 * upgrade react native menu * fix navigation context error
Diffstat (limited to 'apps/mobile')
-rw-r--r--apps/mobile/app.config.js4
-rw-r--r--apps/mobile/app/_layout.tsx79
-rw-r--r--apps/mobile/app/sharing.tsx12
-rw-r--r--apps/mobile/components/ui/Input.tsx61
-rw-r--r--apps/mobile/package.json58
5 files changed, 111 insertions, 103 deletions
diff --git a/apps/mobile/app.config.js b/apps/mobile/app.config.js
index 7e8ab546..1b60c74f 100644
--- a/apps/mobile/app.config.js
+++ b/apps/mobile/app.config.js
@@ -9,6 +9,9 @@ export default {
light: "./assets/icon.png",
tinted: "./assets/icon-tinted.png",
},
+ experiments: {
+ reactCanary: true,
+ },
userInterfaceStyle: "automatic",
assetBundlePatterns: ["**/*"],
ios: {
@@ -89,6 +92,7 @@ export default {
},
},
],
+ "expo-web-browser",
],
extra: {
router: {
diff --git a/apps/mobile/app/_layout.tsx b/apps/mobile/app/_layout.tsx
index e1751f1e..ca3da0cb 100644
--- a/apps/mobile/app/_layout.tsx
+++ b/apps/mobile/app/_layout.tsx
@@ -32,42 +32,47 @@ export default function RootLayout() {
}, [settings.theme]);
return (
- <GestureHandlerRootView style={{ flex: 1 }}>
- <ShareIntentProvider>
- <Providers>
- <StyledStack
- contentClassName={cn(
- "w-full flex-1 bg-gray-100 text-foreground dark:bg-background",
- colorScheme == "dark" ? "dark" : "light",
- )}
- screenOptions={{
- headerTitle: "",
- headerTransparent: true,
- }}
- >
- <Stack.Screen name="index" />
- <Stack.Screen
- name="signin"
- options={{
- headerShown: true,
- headerBackVisible: true,
- headerBackTitle: "Back",
- title: "",
- }}
- />
- <Stack.Screen name="sharing" />
- <Stack.Screen
- name="test-connection"
- options={{
- title: "Test Connection",
- headerShown: true,
- presentation: "modal",
- }}
- />
- </StyledStack>
- <StatusBar style="auto" />
- </Providers>
- </ShareIntentProvider>
- </GestureHandlerRootView>
+ <>
+ <StyledStack
+ layout={(props) => {
+ return (
+ <GestureHandlerRootView style={{ flex: 1 }}>
+ <ShareIntentProvider>
+ <Providers>{props.children}</Providers>
+ </ShareIntentProvider>
+ </GestureHandlerRootView>
+ );
+ }}
+ contentClassName={cn(
+ "w-full flex-1 bg-gray-100 text-foreground dark:bg-background",
+ colorScheme == "dark" ? "dark" : "light",
+ )}
+ screenOptions={{
+ headerTitle: "",
+ headerTransparent: true,
+ }}
+ >
+ <Stack.Screen name="index" />
+ <Stack.Screen
+ name="signin"
+ options={{
+ headerShown: true,
+ headerBackVisible: true,
+ headerBackTitle: "Back",
+ title: "",
+ }}
+ />
+ <Stack.Screen name="sharing" />
+ <Stack.Screen
+ name="test-connection"
+ options={{
+ title: "Test Connection",
+ headerShown: true,
+ presentation: "modal",
+ }}
+ />
+ </StyledStack>
+ <StatusBar style="auto" />
+ </>
);
}
diff --git a/apps/mobile/app/sharing.tsx b/apps/mobile/app/sharing.tsx
index 941b4c83..506b5100 100644
--- a/apps/mobile/app/sharing.tsx
+++ b/apps/mobile/app/sharing.tsx
@@ -1,4 +1,4 @@
-import { useEffect, useState } from "react";
+import { useEffect, useRef, useState } from "react";
import { ActivityIndicator, Pressable, Text, View } from "react-native";
import { useRouter } from "expo-router";
import { useShareIntentContext } from "expo-share-intent";
@@ -83,7 +83,7 @@ export default function Sharing() {
const router = useRouter();
const [mode, setMode] = useState<Mode>({ type: "idle" });
- let autoCloseTimeoutId: NodeJS.Timeout | null = null;
+ const autoCloseTimeoutId = useRef<number | null>(null);
let comp;
switch (mode.type) {
@@ -102,8 +102,8 @@ export default function Sharing() {
label="Manage"
onPress={() => {
router.replace(`/dashboard/bookmarks/${mode.bookmarkId}/info`);
- if (autoCloseTimeoutId) {
- clearTimeout(autoCloseTimeoutId);
+ if (autoCloseTimeoutId.current) {
+ clearTimeout(autoCloseTimeoutId.current);
}
}}
/>
@@ -126,11 +126,11 @@ export default function Sharing() {
return;
}
- autoCloseTimeoutId = setTimeout(() => {
+ autoCloseTimeoutId.current = setTimeout(() => {
router.replace("dashboard");
}, 2000);
- return () => clearTimeout(autoCloseTimeoutId!);
+ return () => clearTimeout(autoCloseTimeoutId.current!);
}, [mode.type]);
return (
diff --git a/apps/mobile/components/ui/Input.tsx b/apps/mobile/components/ui/Input.tsx
index dc84f54f..2bd5e190 100644
--- a/apps/mobile/components/ui/Input.tsx
+++ b/apps/mobile/components/ui/Input.tsx
@@ -1,47 +1,46 @@
+import type { TextInputProps } from "react-native";
import { forwardRef } from "react";
import { ActivityIndicator, Text, TextInput, View } from "react-native";
import { cn } from "@/lib/utils";
import { TailwindResolver } from "../TailwindResolver";
-export interface InputProps
- extends React.ComponentPropsWithoutRef<typeof TextInput> {
+export interface InputProps extends TextInputProps {
label?: string;
labelClasses?: string;
inputClasses?: string;
+ loading?: boolean;
}
-const Input = forwardRef<
- React.ElementRef<typeof TextInput>,
- InputProps & { loading?: boolean }
->(
+export const Input = forwardRef<TextInput, InputProps>(
(
{ className, label, labelClasses, inputClasses, loading, ...props },
ref,
- ) => (
- <View className={cn("flex flex-col gap-1.5", className)}>
- {label && <Text className={cn("text-base", labelClasses)}>{label}</Text>}
- <TailwindResolver
- className="text-gray-400"
- comp={(styles) => (
- <TextInput
- placeholderTextColor={styles?.color?.toString()}
- ref={ref}
- className={cn(
- "bg-background text-foreground",
- inputClasses,
- "rounded-lg border border-input px-4 py-2.5",
- )}
- {...props}
- />
+ ) => {
+ return (
+ <View className={cn("flex flex-col gap-1.5", className)}>
+ {label && (
+ <Text className={cn("text-base", labelClasses)}>{label}</Text>
)}
- />
- {loading && (
- <ActivityIndicator className="absolute bottom-0 right-0 p-2" />
- )}
- </View>
- ),
+ <TailwindResolver
+ className="text-gray-400"
+ comp={(styles) => (
+ <TextInput
+ ref={ref}
+ placeholderTextColor={styles?.color?.toString()}
+ className={cn(
+ "bg-background text-foreground",
+ inputClasses,
+ "rounded-lg border border-input px-4 py-2.5",
+ )}
+ {...props}
+ />
+ )}
+ />
+ {loading && (
+ <ActivityIndicator className="absolute bottom-0 right-0 p-2" />
+ )}
+ </View>
+ );
+ },
);
-Input.displayName = "Input";
-
-export { Input };
diff --git a/apps/mobile/package.json b/apps/mobile/package.json
index 80e4ffcb..0ed5668c 100644
--- a/apps/mobile/package.json
+++ b/apps/mobile/package.json
@@ -19,55 +19,55 @@
"@karakeep/shared-react": "workspace:^0.1.0",
"@karakeep/trpc": "workspace:^0.1.0",
"@react-native-async-storage/async-storage": "1.23.1",
- "@react-native-menu/menu": "^1.1.6",
+ "@react-native-menu/menu": "^1.2.4",
"@tanstack/react-query": "^5.80.3",
"class-variance-authority": "^0.7.0",
"clsx": "^2.1.0",
- "expo": "~52.0.46",
- "expo-build-properties": "^0.13.3",
- "expo-checkbox": "^4.0.1",
- "expo-clipboard": "^7.0.1",
- "expo-constants": "~17.0.8",
- "expo-dev-client": "^5.0.20",
+ "expo": "~53.0.11",
+ "expo-build-properties": "^0.14.6",
+ "expo-checkbox": "^4.1.4",
+ "expo-clipboard": "^7.1.4",
+ "expo-constants": "~17.1.6",
+ "expo-dev-client": "^5.2.0",
"expo-file-system": "~18.0.12",
- "expo-haptics": "^14.0.1",
- "expo-image": "^2.0.7",
- "expo-image-picker": "^16.0.6",
- "expo-linking": "~7.0.5",
- "expo-navigation-bar": "^4.0.9",
- "expo-router": "~4.0.21",
- "expo-secure-store": "^14.0.1",
- "expo-share-intent": "3.2.3",
+ "expo-haptics": "^14.1.4",
+ "expo-image": "^2.2.0",
+ "expo-image-picker": "^16.1.4",
+ "expo-linking": "~7.1.5",
+ "expo-navigation-bar": "^4.2.5",
+ "expo-router": "~5.0.7",
+ "expo-secure-store": "^14.2.3",
+ "expo-share-intent": "^4.0.0",
"expo-sharing": "~13.0.1",
- "expo-status-bar": "~2.0.1",
- "expo-system-ui": "^4.0.9",
- "expo-web-browser": "^14.0.2",
- "lucide-react-native": "^0.354.0",
+ "expo-status-bar": "~2.2.3",
+ "expo-system-ui": "^5.0.8",
+ "expo-web-browser": "^14.1.6",
+ "lucide-react-native": "^0.513.0",
"nativewind": "^4.1.23",
- "react": "^18.3.1",
- "react-native": "0.76.9",
+ "react": "^19.1.0",
+ "react-native": "0.79.3",
"react-native-awesome-slider": "^2.5.3",
"react-native-blob-util": "^0.21.2",
- "react-native-gesture-handler": "~2.20.2",
+ "react-native-gesture-handler": "~2.24.0",
"react-native-image-viewing": "^0.2.2",
"react-native-markdown-display": "^7.0.2",
"react-native-pdf": "^6.7.7",
- "react-native-reanimated": "^3.16.2",
- "react-native-safe-area-context": "4.12.0",
- "react-native-screens": "~4.4.0",
- "react-native-svg": "^15.8.0",
- "react-native-webview": "^13.12.5",
+ "react-native-reanimated": "^3.17.5",
+ "react-native-safe-area-context": "5.4.0",
+ "react-native-screens": "~4.11.1",
+ "react-native-svg": "^15.11.2",
+ "react-native-webview": "^13.13.5",
"tailwind-merge": "^2.2.1",
"use-debounce": "^10.0.0",
"zod": "^3.24.2",
- "zustand": "^4.5.1"
+ "zustand": "^5.0.5"
},
"devDependencies": {
"@babel/core": "~7.26.0",
"@karakeep/prettier-config": "workspace:^0.1.0",
"@karakeep/tailwind-config": "workspace:^0.1.0",
"@karakeep/tsconfig": "workspace:^0.1.0",
- "@types/react": "^18.3.12",
+ "@types/react": "^19.1.6",
"ajv": "latest",
"prettier": "^3.4.2",
"tailwindcss": "^3.4.1",