diff --git a/apps/mobile/deps/react-native-screens-5.0.0-t3.26.tgz b/apps/mobile/deps/react-native-screens-5.0.0-t3.26.tgz deleted file mode 100644 index ee21d1ffd5c1f15a57326e2508665bcf8050ebb0..0000000000000000000000000000000000000000 Binary files a/apps/mobile/deps/react-native-screens-5.0.0-t3.26.tgz and /dev/null differ diff --git a/apps/mobile/deps/react-native-screens-5.0.0-t3.27.tgz b/apps/mobile/deps/react-native-screens-5.0.0-t3.27.tgz new file mode 100644 index 0000000000000000000000000000000000000000..4aa9184ac209e0c7085265ff9b5f4717efc39fdd Binary files /dev/null and b/apps/mobile/deps/react-native-screens-5.0.0-t3.27.tgz differ diff --git a/apps/mobile/package.json b/apps/mobile/package.json index c4175c317d3b426f85b9da9444f7fcc4656069f2..c7067dfc1e0aa3fae82e43063396414c3970a6c6 100644 --- a/apps/mobile/package.json +++ b/apps/mobile/package.json @@ -126,7 +126,7 @@ "react-native-keyboard-controller": "1.22.6", "react-native-reanimated": "4.7.0", "react-native-safe-area-context": "~5.9.1", - "react-native-screens": "file:deps/react-native-screens-5.0.0-t3.26.tgz", + "react-native-screens": "file:deps/react-native-screens-5.0.0-t3.27.tgz", "react-native-shiki-engine": "^0.3.12", "react-native-svg": "15.15.5", "react-native-webview": "14.0.1", diff --git a/apps/mobile/src/features/pull-requests/PullRequestControls.tsx b/apps/mobile/src/features/pull-requests/PullRequestControls.tsx index cd9b84a2361f25b856647ac4e8e18edefdc6f9a9..5bad565b2a40f35e0bc1a4f03d010219734a359c 100644 --- a/apps/mobile/src/features/pull-requests/PullRequestControls.tsx +++ b/apps/mobile/src/features/pull-requests/PullRequestControls.tsx @@ -4,7 +4,7 @@ import { useNavigation } from "@react-navigation/native"; import type { PullRequestDetail } from "@t3tools/contracts"; import type { ReactNode } from "react"; import { Platform, Pressable, View } from "react-native"; -import { useSafeAreaFrame, useSafeAreaInsets } from "react-native-safe-area-context"; +import { useSafeAreaInsets } from "react-native-safe-area-context"; import { AppText as Text } from "../../components/AppText"; import { SymbolView, type AppSymbolName } from "../../components/AppSymbol"; import { MaterialButton } from "../../components/MaterialButton"; @@ -12,10 +12,7 @@ import { MaterialIconButton } from "../../components/MaterialIconButton"; import { MaterialFloatingToolbar } from "./MaterialFloatingToolbar"; import { ControlPillMenu } from "../../components/ControlPillMenu"; import { NativeHeaderToolbar } from "../../native/StackHeader"; -import { - useNativeColumnLayoutMetrics, - useNativeLayoutMetrics, -} from "../../native/native-layout-metrics"; +import { useNativeLayoutMetrics } from "../../native/native-layout-metrics"; import { type PullRequestParams } from "./usePullRequestDiff"; import { usePullRequestPermissions } from "./usePullRequestPermissions"; import { useAppearancePreferences } from "../settings/appearance/AppearancePreferencesProvider"; @@ -117,8 +114,6 @@ export function PullRequestActionToolbar(props: { const { draft } = usePullRequestReviewDraft(props.params); const { themeVariables: colors } = useAppearancePreferences(); const insets = useSafeAreaInsets(); - const frame = useSafeAreaFrame(); - const columnMetrics = useNativeColumnLayoutMetrics(); const nativeMetrics = useNativeLayoutMetrics(); const verticalControls = nativeMetrics !== null && nativeMetrics.verticalBarEdge !== "none"; const permissions = usePullRequestPermissions(props.params, props.pr); @@ -140,20 +135,6 @@ export function PullRequestActionToolbar(props: { if (!props.pr) return null; const primaryDisabled = pendingReview ? false : agent.disabled; const showPrimary = pendingReview || canOpenThread; - // Match the native phone tab controls; the side rail keeps intrinsic sizing. - const controlSize = verticalControls ? undefined : 60; - // Reserve the native outer margins, custom-button padding, and item gaps. - // UIKit needs this space to keep every action out of its overflow menu. - // Duo's side rail uses an intrinsic icon item instead. - const sideControls = Number(showAgentControls) + 1; - const primaryWidth = verticalControls - ? undefined - : Math.max( - 0, - (columnMetrics?.width ?? frame.width - insets.left - insets.right) - - 58 - - sideControls * (60 + 10 + 16), - ); if (Platform.OS === "android") { const primary = ( ); + if (verticalControls) + return ( + + {filesControl} + {agentControl} + {primaryControl} + + ); return ( - {verticalControls ? filesControl : agentControl} - {verticalControls ? agentControl : primaryControl} - {verticalControls ? primaryControl : filesControl} + {agentControl} + + {primaryControl} + + {filesControl} ); } diff --git a/apps/mobile/src/native/NativeHeaderToolbar.tsx b/apps/mobile/src/native/NativeHeaderToolbar.tsx index b05c498903a4196b0122d1fe522a7b53e82d2455..609e6e090edebc5a9297dda777c9fc3af81d945e 100644 --- a/apps/mobile/src/native/NativeHeaderToolbar.tsx +++ b/apps/mobile/src/native/NativeHeaderToolbar.tsx @@ -41,9 +41,7 @@ type NativeStackHeaderAxisBehavior = Extract< NativeStackHeaderItem, { type: "button" } >["axisBehavior"]; -type NativeToolbarItem = - | (NativeStackHeaderItem & { readonly height?: number }) - | HeaderBarButtonSearchBarPlacementItem; +type NativeToolbarItem = NativeStackHeaderItem | HeaderBarButtonSearchBarPlacementItem; type NativeStackOptionsWithToolbar = NativeStackNavigationOptions & { unstable_headerToolbarItems?: () => NativeToolbarItem[]; }; @@ -162,8 +160,6 @@ function convertToolbarChild(child: ReactNode): NativeToolbarItem | null { : () => undefined, sharesBackground: !child.props.separateBackground, tintColor: child.props.tintColor as ColorValue | undefined, - width: typeof child.props.width === "number" ? child.props.width : undefined, - height: typeof child.props.height === "number" ? child.props.height : undefined, variant: child.props.variant === "done" || child.props.variant === "prominent" ? child.props.variant @@ -189,8 +185,6 @@ function convertToolbarChild(child: ReactNode): NativeToolbarItem | null { }, sharesBackground: !child.props.separateBackground, tintColor: child.props.tintColor as ColorValue | undefined, - width: typeof child.props.width === "number" ? child.props.width : undefined, - height: typeof child.props.height === "number" ? child.props.height : undefined, variant: child.props.variant === "done" || child.props.variant === "prominent" ? child.props.variant @@ -289,8 +283,6 @@ function NativeHeaderToolbarButton(_props: { readonly tintColor?: ColorValue; readonly variant?: "plain" | "done" | "prominent"; readonly identifier?: string; - readonly width?: number; - readonly height?: number; }) { return null; } @@ -308,8 +300,6 @@ function NativeHeaderToolbarMenu(_props: { readonly tintColor?: ColorValue; readonly title?: string; readonly variant?: "plain" | "done" | "prominent"; - readonly width?: number; - readonly height?: number; }) { return null; } diff --git a/apps/mobile/src/native/V5StackHeader.ios.tsx b/apps/mobile/src/native/V5StackHeader.ios.tsx index 5dfa4e90d811624b467314287ee5b2cfd577e6fd..00f674faf30024a15a5607a1f956b533dbc4565e 100644 --- a/apps/mobile/src/native/V5StackHeader.ios.tsx +++ b/apps/mobile/src/native/V5StackHeader.ios.tsx @@ -21,7 +21,7 @@ import { type HeaderItem = NonNullable["leadingItems"]>[number]; type ToolbarItem = - | (NativeStackHeaderItem & { readonly height?: number }) + | NativeStackHeaderItem | HeaderBarButtonMailSearchToolbarItem | HeaderBarButtonSearchBarPlacementItem; type Options = NativeStackNavigationOptions & { @@ -91,10 +91,7 @@ function convertMenu(menu: MenuInput, id: string): StackHeaderMenuIOS { return { id, type: "menu", title: menu.title, children }; } -function convertItems( - items: (NativeStackHeaderItem & { readonly height?: number })[], - prefix: string, -): HeaderItem[] { +function convertItems(items: NativeStackHeaderItem[], prefix: string): HeaderItem[] { return items.map((item, index): HeaderItem => { const id = item.type === "spacing" ? `${prefix}:${index}` : (item.identifier ?? `${prefix}:${index}`); @@ -121,8 +118,6 @@ function convertItems( menu: item.disabled ? undefined : convertMenu(item.menu, `${id}:menu`), variant: item.variant, tintColor: item.tintColor, - width: item.width, - height: item.height, hidesSharedBackground: item.hidesSharedBackground, }; case "button": @@ -136,8 +131,6 @@ function convertItems( onPress: item.disabled ? undefined : item.onPress, variant: item.variant, tintColor: item.tintColor, - width: item.width, - height: item.height, hidesSharedBackground: item.hidesSharedBackground, }; } diff --git a/docs/operations/mobile-screens-fork.md b/docs/operations/mobile-screens-fork.md index 712edaeb11a11c59eb003e91e46c835a0e39d5ea..f9da54a93ab01a7c176fd15eb655015e986e5e9d 100644 --- a/docs/operations/mobile-screens-fork.md +++ b/docs/operations/mobile-screens-fork.md @@ -1,7 +1,7 @@ # Building the mobile Screens dependency The mobile v5 stack uses a committed tarball from the -[T3 Screens fork](https://github.com/pingdotgg/react-native-screens/tree/t3-v5.0.0-t3.26). +[T3 Screens fork](https://github.com/pingdotgg/react-native-screens/tree/t3-v5.0.0-t3.27). The fork owns the integration changes; the app does not patch this package. Each archive includes compiled JavaScript, declarations, native source and `t3-fork.json` recording its version, source commit and upstream base. diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index a944d1fc91e8de7094a358d006e66584879b80ae..70ef13e0c7d89746ecfd5e7df33b4187ebdfdd10 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -348,7 +348,7 @@ importers: version: 7.3.4(react-native@0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6))(react@19.3.0) '@react-navigation/native-stack': specifier: 7.17.6 - version: 7.17.6(patch_hash=d2d52f3776e30765519748fd5e177592dc3b9cc778c52fb00e02674dfa9042c5)(02486f76aa3d9c7d88119682fcbddcde) + version: 7.17.6(patch_hash=d2d52f3776e30765519748fd5e177592dc3b9cc778c52fb00e02674dfa9042c5)(6b53c4f789a319cd2c00cd296dcea732) '@shikijs/core': specifier: 4.2.0 version: 4.2.0 @@ -548,8 +548,8 @@ importers: specifier: ~5.9.1 version: 5.9.1(react-native@0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6))(react@19.3.0) react-native-screens: - specifier: file:deps/react-native-screens-5.0.0-t3.26.tgz - version: file:apps/mobile/deps/react-native-screens-5.0.0-t3.26.tgz(react-native@0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6))(react@19.3.0) + specifier: file:deps/react-native-screens-5.0.0-t3.27.tgz + version: file:apps/mobile/deps/react-native-screens-5.0.0-t3.27.tgz(react-native@0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6))(react@19.3.0) react-native-shiki-engine: specifier: ^0.3.12 version: 0.3.12(react-native@0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6))(react@19.3.0) @@ -10891,9 +10891,9 @@ packages: react: '*' react-native: '*' - react-native-screens@file:apps/mobile/deps/react-native-screens-5.0.0-t3.26.tgz: - resolution: {integrity: sha512-OD1yeZu1HKuvBaroReihFROaofzuF2w4ORtPJXJrpAGk8AgQNusy3KaRRpeiCwIzH2KQU52SnWxrtKaYMzzQ+A==, tarball: file:apps/mobile/deps/react-native-screens-5.0.0-t3.26.tgz} - version: 5.0.0-t3.26 + react-native-screens@file:apps/mobile/deps/react-native-screens-5.0.0-t3.27.tgz: + resolution: {integrity: sha512-krNMVmduM2fXeJYveadSz6NkYI/AFN3hAAirjk42Z9wkBrPtuhmcp3E2+Me95Xdj5LBL3G3dgltUjo5vYeEtLw==, tarball: file:apps/mobile/deps/react-native-screens-5.0.0-t3.27.tgz} + version: 5.0.0-t3.27 peerDependencies: react: '*' react-native: '*' @@ -16096,7 +16096,7 @@ snapshots: optionalDependencies: '@react-native-masked-view/masked-view': 0.3.2(react-native@0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6))(react@19.3.0) - '@react-navigation/native-stack@7.17.6(patch_hash=d2d52f3776e30765519748fd5e177592dc3b9cc778c52fb00e02674dfa9042c5)(02486f76aa3d9c7d88119682fcbddcde)': + '@react-navigation/native-stack@7.17.6(patch_hash=d2d52f3776e30765519748fd5e177592dc3b9cc778c52fb00e02674dfa9042c5)(6b53c4f789a319cd2c00cd296dcea732)': dependencies: '@react-navigation/elements': 2.9.26(83de68753219ecf7f3321e065bd378be) '@react-navigation/native': 7.3.4(react-native@0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6))(react@19.3.0) @@ -16104,7 +16104,7 @@ snapshots: react: 19.3.0 react-native: 0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6) react-native-safe-area-context: 5.9.1(react-native@0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6))(react@19.3.0) - react-native-screens: file:apps/mobile/deps/react-native-screens-5.0.0-t3.26.tgz(react-native@0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6))(react@19.3.0) + react-native-screens: file:apps/mobile/deps/react-native-screens-5.0.0-t3.27.tgz(react-native@0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6))(react@19.3.0) sf-symbols-typescript: 2.2.0 warn-once: 0.1.1 transitivePeerDependencies: @@ -22097,7 +22097,7 @@ snapshots: react: 19.3.0 react-native: 0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6) - react-native-screens@file:apps/mobile/deps/react-native-screens-5.0.0-t3.26.tgz(react-native@0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6))(react@19.3.0): + react-native-screens@file:apps/mobile/deps/react-native-screens-5.0.0-t3.27.tgz(react-native@0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6))(react@19.3.0): dependencies: react: 19.3.0 react-freeze: 1.0.4(react@19.3.0)