| 1 | import { Keyboard, Pressable, View } from "react-native"; |
| 2 | |
| 3 | import { SymbolView } from "../../components/AppSymbol"; |
| 4 | import { GlassSurface } from "../../components/GlassSurface"; |
| 5 | import { useWorkspaceTabs } from "./WorkspaceTabsContext"; |
| 6 | import { WORKSPACE_DOCK } from "./workspace-tabs-state"; |
| 7 | |
| 8 | /** Equal-sized glass controls share a baseline without resizing the native tab controller. */ |
| 9 | export function WorkspaceDock(props: { readonly onNewTask: () => void }) { |
| 10 | const workspace = useWorkspaceTabs()!; |
| 11 | return ( |
| 12 | <View |
| 13 | className="w-full flex-row items-center justify-between" |
| 14 | style={{ gap: WORKSPACE_DOCK.gap }} |
| 15 | > |
| 16 | <GlassSurface |
| 17 | style={{ |
| 18 | width: WORKSPACE_DOCK.tabsWidth, |
| 19 | height: WORKSPACE_DOCK.height, |
| 20 | borderRadius: WORKSPACE_DOCK.height / 2, |
| 21 | }} |
| 22 | > |
| 23 | <View className="flex-1 flex-row p-1" accessibilityRole="tablist"> |
| 24 | {(["threads", "pullRequests"] as const).map((tab) => { |
| 25 | const selected = workspace.state.selectedTab === tab; |
| 26 | return ( |
| 27 | <Pressable |
| 28 | key={tab} |
| 29 | accessibilityRole="tab" |
| 30 | accessibilityLabel={tab === "threads" ? "Threads" : "Pull requests"} |
| 31 | accessibilityState={{ selected }} |
| 32 | onPress={() => { |
| 33 | if (selected) return; |
| 34 | Keyboard.dismiss(); |
| 35 | workspace.dispatch({ type: "select", tab }); |
| 36 | }} |
| 37 | className={ |
| 38 | selected |
| 39 | ? "flex-1 items-center justify-center rounded-full bg-subtle-strong" |
| 40 | : "flex-1 items-center justify-center rounded-full" |
| 41 | } |
| 42 | > |
| 43 | <SymbolView |
| 44 | name={tab === "threads" ? "text.bubble" : "arrow.triangle.pull"} |
| 45 | size={23} |
| 46 | tintColorClassName={selected ? "accent-focus" : "accent-icon"} |
| 47 | /> |
| 48 | </Pressable> |
| 49 | ); |
| 50 | })} |
| 51 | </View> |
| 52 | </GlassSurface> |
| 53 | <GlassSurface |
| 54 | style={{ |
| 55 | width: WORKSPACE_DOCK.height, |
| 56 | height: WORKSPACE_DOCK.height, |
| 57 | borderRadius: WORKSPACE_DOCK.height / 2, |
| 58 | }} |
| 59 | > |
| 60 | <Pressable |
| 61 | accessibilityRole="button" |
| 62 | accessibilityLabel="New chat" |
| 63 | onPress={props.onNewTask} |
| 64 | className="flex-1 items-center justify-center" |
| 65 | > |
| 66 | <SymbolView name="square.and.pencil" size={23} tintColorClassName="accent-icon" /> |
| 67 | </Pressable> |
| 68 | </GlassSurface> |
| 69 | </View> |
| 70 | ); |
| 71 | } |