import { useCallback, useMemo, useRef } from "react"; import { Pressable, View, type PressableStateCallbackType } from "react-native"; import { useQueryClient } from "@tanstack/react-query"; import { ChevronDown, GitBranch } from "lucide-react-native"; import { StyleSheet, useUnistyles } from "react-native-unistyles"; import { Combobox, ComboboxItem } from "@/components/ui/combobox"; import type { ComboboxProps } from "@/components/ui/combobox"; import { useIsCompactFormFactor } from "@/constants/layout"; import { useHostRuntimeClient, useHostRuntimeIsConnected } from "@/runtime/host-runtime"; import { useToast } from "@/contexts/toast-context"; import { useBranchSwitcher } from "@/hooks/use-branch-switcher"; import { ScreenTitle } from "@/components/headers/screen-title"; interface BranchSwitcherProps { currentBranchName: string | null; title: string; serverId: string; workspaceId: string; isGitCheckout: boolean; } export function BranchSwitcher({ currentBranchName, title, serverId, workspaceId, isGitCheckout, }: BranchSwitcherProps) { const { theme } = useUnistyles(); const isCompact = useIsCompactFormFactor(); const anchorRef = useRef(null); const client = useHostRuntimeClient(serverId); const isConnected = useHostRuntimeIsConnected(serverId); const toast = useToast(); const queryClient = useQueryClient(); const { branchOptions, isOpen, setIsOpen, handleBranchSelect } = useBranchSwitcher({ client, normalizedServerId: serverId, normalizedWorkspaceId: workspaceId, currentBranchName, isGitCheckout, isConnected, toast, queryClient, }); const titleContent = ( {isGitCheckout ? : null} {title} ); const handleOpen = useCallback(() => setIsOpen(true), [setIsOpen]); const triggerStyle = useCallback( ({ hovered = false, pressed }: PressableStateCallbackType & { hovered?: boolean }) => [ styles.branchSwitcherTrigger, (Boolean(hovered) || pressed) && styles.branchSwitcherTriggerHovered, ], [], ); const branchLeadingSlot = useMemo( () => , [theme.colors.foregroundMuted], ); const renderBranchOption = useCallback>( ({ option, selected, active, onPress }) => ( ), [branchLeadingSlot], ); if (!currentBranchName) { return {titleContent}; } return ( {titleContent} {!isCompact ? : null} ); } const styles = StyleSheet.create((theme) => ({ branchSwitcherTrigger: { flexDirection: "row", alignItems: "center", gap: theme.spacing[1], minWidth: 0, marginLeft: { xs: -theme.spacing[2], md: 0, }, paddingVertical: { xs: 0, md: theme.spacing[1], }, paddingHorizontal: theme.spacing[2], borderRadius: theme.borderRadius.md, flexShrink: 1, }, branchSwitcherTriggerHovered: { backgroundColor: theme.colors.surface1, }, titleRow: { flexDirection: "row", alignItems: "center", gap: theme.spacing[1], minWidth: 0, overflow: "hidden", }, }));