1import { requireOptionalNativeModule } from "expo";
2import { useEffect, useState } from "react";
3import { Platform } from "react-native";
4import { useNativeLayoutMetrics } from "./native-layout-metrics";
5
6const nativeControls = requireOptionalNativeModule<{
7 readonly supportsWorkspaceColumns?: boolean;
8 readonly ViewPrototypes?: { readonly T3NativeControls_LayoutMetrics?: unknown };
9}>("T3NativeControls");
10export const NATIVE_WORKSPACE_COLUMNS_SUPPORTED =
11 Platform.OS === "ios" && Platform.isPad && nativeControls?.supportsWorkspaceColumns === true;
12
13// Binaries without the native no-hinge fallback never report metrics on ordinary
14// iPhones running iOS 27.1 or later. Use the compact navigator rather than staying blank.
15const NATIVE_METRICS_TIMEOUT_MS = 1000;
16
17export function useNativeWorkspaceColumnsReady() {
18 const metrics = useNativeLayoutMetrics();
19 const [timedOut, setTimedOut] = useState(false);
20 // Choose the phone's native host before attaching any screens. Older clients
21 // without the observer can immediately use the compact navigator.
22 const waiting =
23 !(Platform.OS === "ios" && Platform.isPad) &&
24 !!nativeControls?.ViewPrototypes?.T3NativeControls_LayoutMetrics &&
25 metrics === null;
26
27 useEffect(() => {
28 if (!waiting) return;
29 const timeout = setTimeout(() => setTimedOut(true), NATIVE_METRICS_TIMEOUT_MS);
30 return () => clearTimeout(timeout);
31 }, [waiting]);
32
33 return !waiting || timedOut;
34}
35
36export function useNativeWorkspaceColumnsSupported() {
37 const metrics = useNativeLayoutMetrics();
38 return (
39 NATIVE_WORKSPACE_COLUMNS_SUPPORTED ||
40 (nativeControls?.supportsWorkspaceColumns === true && metrics?.hasHinge === true)
41 );
42}