diff --git a/packages/app/src/app/_layout.tsx b/packages/app/src/app/_layout.tsx index 895e5e0aa..9c0894ffc 100644 --- a/packages/app/src/app/_layout.tsx +++ b/packages/app/src/app/_layout.tsx @@ -834,19 +834,23 @@ function FaviconStatusSync() { return null; } +const AGENT_SCREEN_OPTIONS = { gestureEnabled: false }; + function RootStack() { const storeReady = useStoreReady(); const { theme } = useUnistyles(); + const stackScreenOptions = useMemo( + () => ({ + headerShown: false, + animation: "none" as const, + contentStyle: { + backgroundColor: theme.colors.surface0, + }, + }), + [theme.colors.surface0], + ); return ( - + @@ -862,7 +866,7 @@ function RootStack() { outside this route-level native-stack API. */} - + diff --git a/packages/app/src/app/settings/[section].tsx b/packages/app/src/app/settings/[section].tsx index 8afddf1c0..e84d71434 100644 --- a/packages/app/src/app/settings/[section].tsx +++ b/packages/app/src/app/settings/[section].tsx @@ -1,4 +1,5 @@ import { useLocalSearchParams } from "expo-router"; +import { useMemo } from "react"; import SettingsScreen from "@/screens/settings-screen"; import { isSettingsSectionSlug, type SettingsSectionSlug } from "@/utils/host-routes"; @@ -6,6 +7,7 @@ export default function SettingsSectionRoute() { const params = useLocalSearchParams<{ section?: string }>(); const rawSection = typeof params.section === "string" ? params.section : ""; const section: SettingsSectionSlug = isSettingsSectionSlug(rawSection) ? rawSection : "general"; + const view = useMemo(() => ({ kind: "section" as const, section }), [section]); - return ; + return ; } diff --git a/packages/app/src/app/settings/hosts/[serverId].tsx b/packages/app/src/app/settings/hosts/[serverId].tsx index 02260acaa..9a3058c45 100644 --- a/packages/app/src/app/settings/hosts/[serverId].tsx +++ b/packages/app/src/app/settings/hosts/[serverId].tsx @@ -1,14 +1,16 @@ import { useLocalSearchParams } from "expo-router"; +import { useMemo } from "react"; import { HostRouteBootstrapBoundary } from "@/components/host-route-bootstrap-boundary"; import SettingsScreen from "@/screens/settings-screen"; export default function SettingsHostRoute() { const params = useLocalSearchParams<{ serverId?: string }>(); const serverId = typeof params.serverId === "string" ? params.serverId.trim() : ""; + const view = useMemo(() => ({ kind: "host" as const, serverId }), [serverId]); return ( - + ); } diff --git a/packages/app/src/app/settings/index.tsx b/packages/app/src/app/settings/index.tsx index 00e212c2a..09280b5c5 100644 --- a/packages/app/src/app/settings/index.tsx +++ b/packages/app/src/app/settings/index.tsx @@ -3,6 +3,8 @@ import { useIsCompactFormFactor } from "@/constants/layout"; import SettingsScreen from "@/screens/settings-screen"; import { buildSettingsSectionRoute } from "@/utils/host-routes"; +const ROOT_VIEW = { kind: "root" as const }; + export default function SettingsIndexRoute() { const isCompactLayout = useIsCompactFormFactor(); @@ -10,5 +12,5 @@ export default function SettingsIndexRoute() { return ; } - return ; + return ; } diff --git a/packages/app/src/components/adaptive-modal-sheet.tsx b/packages/app/src/components/adaptive-modal-sheet.tsx index c54f2fc2f..2cd7f6f9e 100644 --- a/packages/app/src/components/adaptive-modal-sheet.tsx +++ b/packages/app/src/components/adaptive-modal-sheet.tsx @@ -24,6 +24,7 @@ import { isWeb } from "@/constants/platform"; type EscHandler = () => void; const escStack: EscHandler[] = []; let escListenerAttached = false; +const ABSOLUTE_FILL_STYLE = { ...StyleSheet.absoluteFillObject }; function handleEscKeyDown(event: KeyboardEvent) { if (event.key !== "Escape") return; @@ -191,6 +192,10 @@ export function AdaptiveModalSheet({ const isMobile = useIsCompactFormFactor(); const titleColor = theme.colors.foreground; const resolvedSnapPoints = useMemo(() => snapPoints ?? ["65%", "90%"], [snapPoints]); + const handleIndicatorStyle = useMemo( + () => ({ backgroundColor: theme.colors.surface2 }), + [theme.colors.surface2], + ); const { sheetRef, handleSheetChange } = useIsolatedBottomSheetVisibility({ visible, isEnabled: isMobile, @@ -204,6 +209,12 @@ export function AdaptiveModalSheet({ [], ); + const titleStyle = useMemo(() => [styles.title, { color: titleColor }], [titleColor]); + const desktopCardStyle = useMemo( + () => [styles.desktopCard, desktopMaxWidth != null && { maxWidth: desktopMaxWidth }], + [desktopMaxWidth], + ); + useEffect(() => { if (!isWeb || isMobile || !visible) return; return pushEscHandler(onClose); @@ -220,14 +231,14 @@ export function AdaptiveModalSheet({ backdropComponent={renderBackdrop} enablePanDownToClose backgroundComponent={SheetBackground} - handleIndicatorStyle={{ backgroundColor: theme.colors.surface2 }} + handleIndicatorStyle={handleIndicatorStyle} keyboardBehavior="extend" keyboardBlurBehavior="restore" accessible={false} > - + {title} {subtitle} @@ -256,7 +267,7 @@ export function AdaptiveModalSheet({ <> - + {title} {subtitle} @@ -283,12 +294,8 @@ export function AdaptiveModalSheet({ const desktopContent = ( - - + + {onFilesDropped ? ( {cardInner} ) : ( diff --git a/packages/app/src/components/add-host-modal.tsx b/packages/app/src/components/add-host-modal.tsx index d49f0b232..37f644c87 100644 --- a/packages/app/src/components/add-host-modal.tsx +++ b/packages/app/src/components/add-host-modal.tsx @@ -10,6 +10,8 @@ import { DaemonConnectionTestError, connectToDaemon } from "@/utils/test-daemon- import { AdaptiveModalSheet, AdaptiveTextInput } from "./adaptive-modal-sheet"; import { Button } from "@/components/ui/button"; +const FLEX_ONE_STYLE = { flex: 1 } as const; + const styles = StyleSheet.create((theme) => ({ field: { gap: theme.spacing[2], @@ -274,11 +276,16 @@ export function AddHostModal({ visible, onClose, onCancel, onSaved }: AddHostMod -