import { WorkspaceNoTabs } from "./WorkspaceNoTabs";
import { WORKSPACE_TAB_LABELS, useEnabledNavigationTabs } from "./navigation-tabs";
import { WorkspaceExtraTab } from "./WorkspaceExtraTab";
import { SettingsRouteScreen } from "../settings/SettingsRouteScreen";
import { WorkspaceSectionToolbar } from "./WorkspaceSectionToolbar";
import { useNavigation } from "@react-navigation/native";
import { use } from "react";
import { Platform, View, useWindowDimensions } from "react-native";
import { useKeyboardState } from "react-native-keyboard-controller";
import { SafeAreaInsetsContext, useSafeAreaInsets } from "react-native-safe-area-context";
import { CompactBrandTitle } from "../../components/CompactBrandTitle";
import { AndroidScreenHeader } from "../../components/ui/AndroidScreenHeader";
import { NativeStackScreenOptions } from "../../native/StackHeader";
import { NativePrimaryColumnContext } from "../../native/v5-workspace-context";
import { isDuoDevice } from "../../lib/device-type";
import { NATIVE_LIQUID_GLASS_SUPPORTED } from "../../native/native-glass";
import { useWorkspaceSurface } from "./useWorkspaceSurface";
import {
useDeviceType,
useNativeColumnLayoutMetrics,
useNativeLayoutMetrics,
} from "../../native/native-layout-metrics";
import { HomeRouteScreen } from "../home/HomeRouteScreen";
import { dispatchHardwareKeyboardCommand } from "../keyboard/hardwareKeyboardCommands";
import { WorkspaceConnectionTitle } from "../home/WorkspaceConnectionTitle";
import { useAdaptiveWorkspaceLayout } from "../layout/AdaptiveWorkspaceLayout";
import { PullRequestsScreen } from "../pull-requests/PullRequestsScreen";
import {
WorkspaceTabsContext,
WorkspaceTabsProvider,
useWorkspaceTabs,
} from "./WorkspaceTabsContext";
import { WorkspaceToolbar } from "./WorkspaceToolbar";
import {
WORKSPACE_DOCK,
workspaceDockBottomClearance,
workspaceToolbarHeight,
} from "./workspace-tabs-state";
import { WorkspaceSidebarTabs } from "./WorkspaceSidebarTabs";
import {
useCompactWorkspaceTabs,
useSidebarWorkspaceTabs,
useSystemWorkspaceTabBar,
} from "./useSystemWorkspaceTabBar";
import { openSettings } from "../settings/settings-navigation";
import { useSelectWorkspaceTab } from "./useSelectWorkspaceTab";
const TAB_TITLES = WORKSPACE_TAB_LABELS;
function WorkspaceRootTitle(props: {
readonly maxWidth: number;
readonly onOpenEnvironments: () => void;
}) {
const { state, settingsOpen } = useWorkspaceTabs()!;
const enabled = useEnabledNavigationTabs();
const tabTitle = settingsOpen
? "Settings"
: enabled.length
? TAB_TITLES[state.selectedTab]
: "Navigation";
return (
}
maxWidth={props.maxWidth}
onPress={props.onOpenEnvironments}
/>
);
}
function WorkspaceRootContent() {
const navigation = useNavigation();
const selectTab = useSelectWorkspaceTab();
const { width: windowWidth } = useWindowDimensions();
const { layout, startNewTask } = useAdaptiveWorkspaceLayout();
const primaryColumn = use(NativePrimaryColumnContext);
const columnMetrics = useNativeColumnLayoutMetrics();
const nativeMetrics = useNativeLayoutMetrics();
const deviceType = useDeviceType();
const surface = useWorkspaceSurface();
const systemTabBar = useSystemWorkspaceTabBar();
const compactTabs = useCompactWorkspaceTabs();
const enabled = useEnabledNavigationTabs();
const sidebarTabs = useSidebarWorkspaceTabs();
const sidebarPicker = sidebarTabs === "picker" || (deviceType === "pad" && layout.usesSplitView);
const sidebarNavigation =
primaryColumn !== null &&
(layout.usesSplitView ||
deviceType === "pad" ||
(nativeMetrics !== null && nativeMetrics.verticalBarEdge !== "none"));
const width = columnMetrics?.width ?? windowWidth;
const insets = useSafeAreaInsets();
const keyboardHeight = useKeyboardState((keyboard) => keyboard.height);
const workspace = useWorkspaceTabs()!;
const { state } = workspace;
// Settings is a workspace tab too; its list takes the place of the selected tab's.
const settingsOpen = workspace.settingsOpen;
const renderHeaderTitle = () => (
openSettings(navigation, "SettingsEnvironments")}
/>
);
const tab = state.tabs[settingsOpen ? "settings" : state.selectedTab];
const bottomClearance =
layout.primarySidebarOverlaysContent && state.selectedTab === "usage"
? workspaceDockBottomClearance({ bottomInset: insets.bottom, keyboardHeight })
: Platform.OS === "ios" && isDuoDevice(deviceType)
? // The column's safe area already holds the Duo's search toolbar and keyboard.
Math.max(insets.bottom, keyboardHeight) + 16
: compactTabs || deviceType === "pad"
? workspaceDockBottomClearance({ bottomInset: insets.bottom, keyboardHeight })
: Platform.OS === "ios"
? Math.max(insets.bottom, keyboardHeight) +
(systemTabBar || sidebarTabs || tab.searchMode !== "resting"
? sidebarPicker
? 80
: 16
: WORKSPACE_DOCK.height + WORKSPACE_DOCK.bottomGap + 16)
: keyboardHeight > 0 && tab.searchMode !== "resting"
? keyboardHeight + 64
: Math.max(insets.bottom, 12) + workspaceToolbarHeight(tab.searchMode) + 16;
const context = { ...workspace, bottomClearance };
return (
{Platform.OS === "ios" ? (
[] }
: {}),
unstable_headerLeftItems: () => [],
// Beside a detail column the tab bar names the tab and the detail header the page,
// so the sidebar keeps the brand.
headerTitle:
sidebarNavigation || (!settingsOpen && state.selectedTab !== "usage")
? renderHeaderTitle
: undefined,
}}
/>
) : (
{
dispatchHardwareKeyboardCommand("focusSearch");
},
},
]
: []),
{
accessibilityLabel: "Settings",
icon: "gearshape",
onPress: () => selectTab("settings"),
},
]}
/>
)}
{settingsOpen ? (
) : enabled.length === 0 ? (
) : state.selectedTab === "threads" ? (
) : state.selectedTab === "pullRequests" ? (
) : (
)}
{deviceType !== "pad" && deviceType !== "phone" && sidebarPicker ? (
) : null}
{/* Android's Settings list carries its own search in its app bar. */}
{enabled.length === 0 && !settingsOpen ? null : (
settingsOpen
? Platform.OS === "ios"
: state.selectedTab === "threads" || state.selectedTab === "pullRequests"
) ? (
) : (
)}
);
}
export function WorkspaceRootScreen() {
const { layout } = useAdaptiveWorkspaceLayout();
const workspace = useWorkspaceTabs();
return Platform.OS === "android" && layout.usesSplitView ? (
) : workspace ? (
) : (
);
}