diff options
Diffstat (limited to 'apps/mobile')
| -rw-r--r-- | apps/mobile/app.config.js | 4 | ||||
| -rw-r--r-- | apps/mobile/app/_layout.tsx | 79 | ||||
| -rw-r--r-- | apps/mobile/app/sharing.tsx | 12 | ||||
| -rw-r--r-- | apps/mobile/components/ui/Input.tsx | 61 | ||||
| -rw-r--r-- | apps/mobile/package.json | 58 |
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", |
