| author | |
| committer | |
| log | 6ae44b418a24dc021cf042cbb1e60ebeb47e160f |
| tree | 7a67bc947abca4ef3af6becd996fb4b29c036489 |
| parent | 4a2f8b04bbce916be166fec96f33a7e1f0df4a9f |
| signature | Signed by PGP key B5690EEEBB952194 |
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Co-authored-by: Julius Marminge <julius0216@outlook.com>5 files changed, 18 insertions(+), 7 deletions(-)
apps/mobile/src/features/files/FileTreeBrowser.tsx+2-1| ... | @@ -8,6 +8,7 @@ import { AppText as Text } from "../../components/AppText"; | ... | @@ -8,6 +8,7 @@ import { AppText as Text } from "../../components/AppText"; |
| 8 | import { PierreEntryIcon } from "../../components/PierreEntryIcon"; | 8 | import { PierreEntryIcon } from "../../components/PierreEntryIcon"; |
| 9 | import { cn } from "../../lib/cn"; | 9 | import { cn } from "../../lib/cn"; |
| 10 | import { useThemeColor } from "../../lib/useThemeColor"; | 10 | import { useThemeColor } from "../../lib/useThemeColor"; |
| 11 | import { IOS_NAV_BAR_HEIGHT } from "../../lib/layoutMetrics"; | ||
| 11 | import { NATIVE_LIQUID_GLASS_SUPPORTED } from "../../native/native-glass"; | 12 | import { NATIVE_LIQUID_GLASS_SUPPORTED } from "../../native/native-glass"; |
| 12 | import { | 13 | import { |
| 13 | buildFileTree, | 14 | buildFileTree, |
| ... | @@ -123,7 +124,7 @@ export function FileTreeBrowser(props: { | ... | @@ -123,7 +124,7 @@ export function FileTreeBrowser(props: { |
| 123 | const insets = useSafeAreaInsets(); | 124 | const insets = useSafeAreaInsets(); |
| 124 | // Native transparent-header height ≈ safe-area top + nav bar (~44). Matches the | 125 | // Native transparent-header height ≈ safe-area top + nav bar (~44). Matches the |
| 125 | // observed adjustedContentInset bottom (~102) seen in the native trace. | 126 | // observed adjustedContentInset bottom (~102) seen in the native trace. |
| 126 | const headerInset = NATIVE_LIQUID_GLASS_SUPPORTED ? insets.top + 44 : 0; | 127 | const headerInset = NATIVE_LIQUID_GLASS_SUPPORTED ? insets.top + IOS_NAV_BAR_HEIGHT : 0; |
| 127 | const iconColor = String(useThemeColor("--color-icon-muted")); | 128 | const iconColor = String(useThemeColor("--color-icon-muted")); |
| 128 | const { onPreviewFile, onSelectFile, selectedPath: controlledSelectedPath } = props; | 129 | const { onPreviewFile, onSelectFile, selectedPath: controlledSelectedPath } = props; |
| 129 | const controlledSelectedPathRef = useRef(controlledSelectedPath); | 130 | const controlledSelectedPathRef = useRef(controlledSelectedPath); |
apps/mobile/src/features/review/ReviewSheet.tsx+5-2| ... | @@ -39,6 +39,7 @@ import { environmentCatalog } from "../../connection/catalog"; | ... | @@ -39,6 +39,7 @@ import { environmentCatalog } from "../../connection/catalog"; |
| 39 | import { useEnvironmentPresentation } from "../../state/presentation"; | 39 | import { useEnvironmentPresentation } from "../../state/presentation"; |
| 40 | import { useAtomCommand } from "../../state/use-atom-command"; | 40 | import { useAtomCommand } from "../../state/use-atom-command"; |
| 41 | import { useThemeColor } from "../../lib/useThemeColor"; | 41 | import { useThemeColor } from "../../lib/useThemeColor"; |
| 42 | import { IOS_NAV_BAR_HEIGHT } from "../../lib/layoutMetrics"; | ||
| 42 | import { useThreadDraftForThread } from "../../state/use-thread-composer-state"; | 43 | import { useThreadDraftForThread } from "../../state/use-thread-composer-state"; |
| 43 | import { EnvironmentConnectionNotice } from "../connection/EnvironmentConnectionNotice"; | 44 | import { EnvironmentConnectionNotice } from "../connection/EnvironmentConnectionNotice"; |
| 44 | import { | 45 | import { |
| ... | @@ -277,9 +278,11 @@ function ReviewFileNavigator({ | ... | @@ -277,9 +278,11 @@ function ReviewFileNavigator({ |
| 277 | // The nested native header is translucent; start the list below it so | 278 | // The nested native header is translucent; start the list below it so |
| 278 | // the scroll-edge effect can sample the content (same treatment as | 279 | // the scroll-edge effect can sample the content (same treatment as |
| 279 | // FileTreeBrowser in the Files pane). | 280 | // FileTreeBrowser in the Files pane). |
| 280 | paddingTop: Platform.OS === "ios" ? insets.top + 44 + 8 : 8, | 281 | paddingTop: Platform.OS === "ios" ? insets.top + IOS_NAV_BAR_HEIGHT + 8 : 8, |
| 281 | }} | 282 | }} |
| 282 | scrollIndicatorInsets={Platform.OS === "ios" ? { top: insets.top + 44 } : undefined} | 283 | scrollIndicatorInsets={ |
| 284 | Platform.OS === "ios" ? { top: insets.top + IOS_NAV_BAR_HEIGHT } : undefined | ||
| 285 | } | ||
| 283 | renderItem={renderFile} | 286 | renderItem={renderFile} |
| 284 | /> | 287 | /> |
| 285 | ); | 288 | ); |
apps/mobile/src/features/threads/ThreadDetailScreen.tsx+2-1| ... | @@ -57,6 +57,7 @@ import type { ComposerEditorHandle } from "../../components/ComposerEditor"; | ... | @@ -57,6 +57,7 @@ import type { ComposerEditorHandle } from "../../components/ComposerEditor"; |
| 57 | import type { StatusTone } from "../../components/StatusPill"; | 57 | import type { StatusTone } from "../../components/StatusPill"; |
| 58 | import type { DraftComposerImageAttachment } from "../../lib/composerImages"; | 58 | import type { DraftComposerImageAttachment } from "../../lib/composerImages"; |
| 59 | import { CHAT_CONTENT_MAX_WIDTH, type LayoutVariant } from "../../lib/layout"; | 59 | import { CHAT_CONTENT_MAX_WIDTH, type LayoutVariant } from "../../lib/layout"; |
| 60 | import { IOS_NAV_BAR_HEIGHT } from "../../lib/layoutMetrics"; | ||
| 60 | import { scopedThreadKey } from "../../lib/scopedEntities"; | 61 | import { scopedThreadKey } from "../../lib/scopedEntities"; |
| 61 | import type { | 62 | import type { |
| 62 | PendingApproval, | 63 | PendingApproval, |
| ... | @@ -249,7 +250,7 @@ export const ThreadDetailScreen = memo(function ThreadDetailScreen(props: Thread | ... | @@ -249,7 +250,7 @@ export const ThreadDetailScreen = memo(function ThreadDetailScreen(props: Thread |
| 249 | } | 250 | } |
| 250 | }, []); | 251 | }, []); |
| 251 | const windowHeight = useWindowDimensions().height; | 252 | const windowHeight = useWindowDimensions().height; |
| 252 | const navigationHeaderHeight = useContext(HeaderHeightContext) || insets.top + 44; | 253 | const navigationHeaderHeight = useContext(HeaderHeightContext) || insets.top + IOS_NAV_BAR_HEIGHT; |
| 253 | const agentLabel = `${props.selectedThread.modelSelection.instanceId} agent`; | 254 | const agentLabel = `${props.selectedThread.modelSelection.instanceId} agent`; |
| 254 | const selectedThreadKey = scopedThreadKey(props.environmentId, props.selectedThread.id); | 255 | const selectedThreadKey = scopedThreadKey(props.environmentId, props.selectedThread.id); |
| 255 | const composerEditorRef = useRef<ComposerEditorHandle>(null); | 256 | const composerEditorRef = useRef<ComposerEditorHandle>(null); |
apps/mobile/src/features/threads/ThreadFeed.tsx+3-2| ... | @@ -47,6 +47,7 @@ import ImageViewing from "react-native-image-viewing"; | ... | @@ -47,6 +47,7 @@ import ImageViewing from "react-native-image-viewing"; |
| 47 | import { useSafeAreaInsets } from "react-native-safe-area-context"; | 47 | import { useSafeAreaInsets } from "react-native-safe-area-context"; |
| 48 | import Animated, { FadeIn, FadeInUp, type SharedValue } from "react-native-reanimated"; | 48 | import Animated, { FadeIn, FadeInUp, type SharedValue } from "react-native-reanimated"; |
| 49 | import { useThemeColor } from "../../lib/useThemeColor"; | 49 | import { useThemeColor } from "../../lib/useThemeColor"; |
| 50 | import { IOS_NAV_BAR_HEIGHT } from "../../lib/layoutMetrics"; | ||
| 50 | import { useFontFamily } from "../../lib/useFontFamily"; | 51 | import { useFontFamily } from "../../lib/useFontFamily"; |
| 51 | import { scopedThreadKey } from "../../lib/scopedEntities"; | 52 | import { scopedThreadKey } from "../../lib/scopedEntities"; |
| 52 | import { copyTextWithHaptic } from "../../lib/copyTextWithHaptic"; | 53 | import { copyTextWithHaptic } from "../../lib/copyTextWithHaptic"; |
| ... | @@ -1396,7 +1397,7 @@ export const ThreadFeed = memo(function ThreadFeed(props: ThreadFeedProps) { | ... | @@ -1396,7 +1397,7 @@ export const ThreadFeed = memo(function ThreadFeed(props: ThreadFeedProps) { |
| 1396 | const userBubbleMaxWidth = contentWidth * 0.85; | 1397 | const userBubbleMaxWidth = contentWidth * 0.85; |
| 1397 | const reviewCommentBubbleWidth = Math.min(Math.max(280, contentWidth * 0.85), contentWidth); | 1398 | const reviewCommentBubbleWidth = Math.min(Math.max(280, contentWidth * 0.85), contentWidth); |
| 1398 | const insets = useSafeAreaInsets(); | 1399 | const insets = useSafeAreaInsets(); |
| 1399 | const topContentInset = props.contentTopInset ?? insets.top + 44; | 1400 | const topContentInset = props.contentTopInset ?? insets.top + IOS_NAV_BAR_HEIGHT; |
| 1400 | const bottomContentInset = props.contentBottomInset ?? 18; | 1401 | const bottomContentInset = props.contentBottomInset ?? 18; |
| 1401 | const usesNativeAutomaticInsets = | 1402 | const usesNativeAutomaticInsets = |
| 1402 | props.usesAutomaticContentInsets === true && Platform.OS === "ios"; | 1403 | props.usesAutomaticContentInsets === true && Platform.OS === "ios"; |
| ... | @@ -1409,7 +1410,7 @@ export const ThreadFeed = memo(function ThreadFeed(props: ThreadFeedProps) { | ... | @@ -1409,7 +1410,7 @@ export const ThreadFeed = memo(function ThreadFeed(props: ThreadFeedProps) { |
| 1409 | // header-providing screen) and fall back to the standard iOS bar height. | 1410 | // header-providing screen) and fall back to the standard iOS bar height. |
| 1410 | const navigationHeaderHeight = useContext(HeaderHeightContext); | 1411 | const navigationHeaderHeight = useContext(HeaderHeightContext); |
| 1411 | const anchorTopInset = usesNativeAutomaticInsets | 1412 | const anchorTopInset = usesNativeAutomaticInsets |
| 1412 | ? navigationHeaderHeight || insets.top + 44 | 1413 | ? navigationHeaderHeight || insets.top + IOS_NAV_BAR_HEIGHT |
| 1413 | : topContentInset; | 1414 | : topContentInset; |
| 1414 | 1415 | ||
| 1415 | const iconSubtleColor = useThemeColor("--color-icon-subtle"); | 1416 | const iconSubtleColor = useThemeColor("--color-icon-subtle"); |
apps/mobile/src/lib/layoutMetrics.ts+6-1| ... | @@ -5,7 +5,12 @@ export const HOME_HORIZONTAL_INSET = 20; | ... | @@ -5,7 +5,12 @@ export const HOME_HORIZONTAL_INSET = 20; |
| 5 | export const IPAD_HOME_TITLE_OFFSET = 10; | 5 | export const IPAD_HOME_TITLE_OFFSET = 10; |
| 6 | 6 | ||
| 7 | /** | 7 | /** |
| 8 | * Height of the app's own header chrome below the safe-area inset, on every | 8 | * Height of the native iOS navigation bar below the safe-area inset, used as |
| 9 | * a fallback when the measured HeaderHeightContext is unavailable. | ||
| 10 | */ | ||
| 11 | export const IOS_NAV_BAR_HEIGHT = 44; | ||
| 12 | |||
| 13 | /* Height of the app's own header chrome below the safe-area inset, on every | ||
| 9 | * platform (matches the `min-h-12` AndroidScreenHeader). Distinct from the | 14 | * platform (matches the `min-h-12` AndroidScreenHeader). Distinct from the |
| 10 | * 44pt native iOS navigation bar. | 15 | * 44pt native iOS navigation bar. |
| 11 | */ | 16 | */ |