From f3b7dac768bd3d53a5d95c361a5ef04a46c65fe4 Mon Sep 17 00:00:00 2001 From: Mohamed Boudra Date: Thu, 4 Jun 2026 08:46:47 +0700 Subject: [PATCH] Fix compact provider sheet footer --- .../src/components/adaptive-modal-sheet.tsx | 10 +- .../components/provider-diagnostic-sheet.tsx | 120 ++++++++++++++---- 2 files changed, 102 insertions(+), 28 deletions(-) diff --git a/packages/app/src/components/adaptive-modal-sheet.tsx b/packages/app/src/components/adaptive-modal-sheet.tsx index d7052892b..d27993080 100644 --- a/packages/app/src/components/adaptive-modal-sheet.tsx +++ b/packages/app/src/components/adaptive-modal-sheet.tsx @@ -20,6 +20,7 @@ import { useIsolatedBottomSheetVisibility, } from "@/components/ui/isolated-bottom-sheet-modal"; import { isNative, isWeb } from "@/constants/platform"; +import { useSafeAreaInsets } from "react-native-safe-area-context"; // Horizontal indent token shared by the sheet header (title, back arrow, // leading icon, search input icon) and any row primitive rendered inside the @@ -458,7 +459,12 @@ export function AdaptiveModalSheet({ }: AdaptiveModalSheetProps) { const { theme } = useUnistyles(); const isMobile = useIsCompactFormFactor(); + const insets = useSafeAreaInsets(); const resolvedSnapPoints = useMemo(() => snapPoints ?? ["65%", "90%"], [snapPoints]); + const footerStyle = useMemo( + () => [styles.footer, isMobile ? { paddingBottom: theme.spacing[3] + insets.bottom } : null], + [insets.bottom, isMobile, theme.spacing], + ); const handleIndicatorStyle = useMemo( () => ({ backgroundColor: theme.colors.surface2 }), [theme.colors.surface2], @@ -515,7 +521,7 @@ export function AdaptiveModalSheet({ ) : ( {children} )} - {footer ? {footer} : null} + {footer ? {footer} : null} ); } @@ -534,7 +540,7 @@ export function AdaptiveModalSheet({ ) : ( {children} )} - {footer ? {footer} : null} + {footer ? {footer} : null} ); diff --git a/packages/app/src/components/provider-diagnostic-sheet.tsx b/packages/app/src/components/provider-diagnostic-sheet.tsx index 79abc2487..c7edf1ae2 100644 --- a/packages/app/src/components/provider-diagnostic-sheet.tsx +++ b/packages/app/src/components/provider-diagnostic-sheet.tsx @@ -16,6 +16,7 @@ import { } from "@/components/adaptive-modal-sheet"; import { Button } from "@/components/ui/button"; import { LoadingSpinner } from "@/components/ui/loading-spinner"; +import { useIsCompactFormFactor } from "@/constants/layout"; import { isWeb } from "@/constants/platform"; import { CODE_SURFACE_DATASET } from "@/styles/code-surface"; import { useDaemonConfig } from "@/hooks/use-daemon-config"; @@ -359,6 +360,69 @@ interface ProviderModalBodyProps { theme: { iconSize: { md: number }; colors: { foregroundMuted: string } }; } +interface ProviderSheetFooterInput { + fetchedAtLabel: string | null; + isCompact: boolean; + modelsRefreshing: boolean; + onOpenAddSheet: () => void; + onOpenDiagSheet: () => void; + onRefreshModels: () => void; +} + +function renderProviderSheetFooter({ + fetchedAtLabel, + isCompact, + modelsRefreshing, + onOpenAddSheet, + onOpenDiagSheet, + onRefreshModels, +}: ProviderSheetFooterInput) { + const contentStyle = isCompact ? sheetStyles.compactFooterContent : sheetStyles.footerContent; + const actionsStyle = isCompact ? sheetStyles.compactFooterActions : sheetStyles.footerActions; + const buttonStyle = isCompact ? sheetStyles.compactFooterButton : null; + const metaStyle = isCompact ? COMPACT_FOOTER_META_STYLE : sheetStyles.footerMeta; + + return ( + + {fetchedAtLabel || !isCompact ? ( + + {fetchedAtLabel ? `Updated ${fetchedAtLabel}` : ""} + + ) : null} + + + + + + + ); +} + function ProviderModalBody(props: ProviderModalBodyProps) { const { discoveredCount, @@ -446,6 +510,7 @@ export function ProviderDiagnosticSheet({ serverId, }: ProviderDiagnosticSheetProps) { const { theme } = useUnistyles(); + const isCompact = useIsCompactFormFactor(); const { entries: snapshotEntries, refresh, isRefreshing } = useProvidersSnapshot(serverId); const { config, patchConfig } = useDaemonConfig(serverId); const [query, setQuery] = useState(""); @@ -545,38 +610,20 @@ export function ProviderDiagnosticSheet({ [providerLabel], ); - const footer = ( - <> - - {fetchedAtLabel ? `Updated ${fetchedAtLabel}` : ""} - - - - - - - - ); - return ( <> ({ alignItems: "center", gap: theme.spacing[3], }, + footerContent: { + flex: 1, + flexDirection: "row", + alignItems: "center", + justifyContent: "space-between", + gap: theme.spacing[2], + }, + compactFooterContent: { + flex: 1, + gap: theme.spacing[2], + }, footerMeta: { flex: 1, fontSize: theme.fontSize.xs, color: theme.colors.foregroundMuted, }, + compactFooterMeta: { + flex: 0, + }, footerActions: { flexDirection: "row", alignItems: "center", gap: theme.spacing[2], }, + compactFooterActions: { + gap: theme.spacing[2], + }, + compactFooterButton: { + alignSelf: "stretch", + }, formGroup: { gap: theme.spacing[3], }, @@ -741,6 +808,7 @@ const sheetStyles = StyleSheet.create((theme) => ({ })); const FORM_INPUT_STYLE = [sheetStyles.formInput, isWeb && { outlineStyle: "none" }]; +const COMPACT_FOOTER_META_STYLE = [sheetStyles.footerMeta, sheetStyles.compactFooterMeta]; const MAIN_SNAP_POINTS = ["65%", "92%"]; const ADD_SNAP_POINTS = ["40%"];