diff --git a/packages/app/src/components/session/session-header.tsx b/packages/app/src/components/session/session-header.tsx index 1c2cf47a7664..411b44c96f1c 100644 --- a/packages/app/src/components/session/session-header.tsx +++ b/packages/app/src/components/session/session-header.tsx @@ -27,6 +27,7 @@ import { Persist, persisted } from "@/utils/persist" import { StatusPopover, StatusPopoverV2 } from "../status-popover" import { IconButtonV2 } from "@opencode-ai/ui/v2/components/icon-button-v2.jsx" import { Icon as IconV2 } from "@opencode-ai/ui/v2/components/icon.jsx" +import { MenuV2 } from "@opencode-ai/ui/v2/components/menu-v2.jsx" const OPEN_APPS = [ "vscode", @@ -233,15 +234,6 @@ export function SessionHeader() { const tint = createMemo(() => messageAgentColor(params.id ? sync.data.message[params.id] : undefined, sync.data.agent), ) - const v2ActionsState = createMemo(() => ({ - statusVisible: status(), - statusLabel: language.t("status.popover.trigger"), - reviewLabel: language.t("command.review.toggle"), - reviewKeybind: command.keybind("review.toggle"), - reviewOpened: view().reviewPanel.opened(), - onReviewToggle: () => view().reviewPanel.toggle(), - })) - const selectApp = (app: OpenApp) => { if (!options().some((item) => item.id === app)) return setPrefs("app", app) @@ -279,6 +271,32 @@ export function SessionHeader() { .catch((err: unknown) => showRequestError(language, err)) } + const v2ActionsState = createMemo(() => ({ + statusVisible: status(), + statusLabel: language.t("status.popover.trigger"), + reviewLabel: language.t("command.review.toggle"), + reviewKeybind: command.keybind("review.toggle"), + reviewOpened: view().reviewPanel.opened(), + onReviewToggle: () => view().reviewPanel.toggle(), + projectDirectory: projectDirectory(), + canOpen: canOpen(), + opening: opening(), + currentIcon: current().icon, + currentLabel: current().label, + tint: tint(), + options: options(), + currentId: current().id, + menuOpen: menu.open, + openInLabel: language.t("session.header.openIn"), + copyPathLabel: language.t("session.header.open.copyPath"), + openMenuLabel: language.t("session.header.open.menu"), + ariaLabel: language.t("session.header.open.ariaLabel", { app: current().label }), + onOpenDir: openDir, + onSelectApp: selectApp, + onCopyPath: copyPath, + onMenuOpenChange: (open: boolean) => setMenu("open", open), + })) + const [centerMount, setCenterMount] = createSignal(null) const [rightMount, setRightMount] = createSignal(null) onMount(() => { @@ -526,11 +544,116 @@ type SessionHeaderV2ActionsState = { reviewKeybind: string reviewOpened: boolean onReviewToggle: () => void + projectDirectory: string + canOpen: boolean + opening: boolean + currentIcon: string + currentLabel: string + tint: string | undefined + options: readonly { id: string; label: string; icon: string }[] + currentId: string + menuOpen: boolean + openInLabel: string + copyPathLabel: string + openMenuLabel: string + ariaLabel: string + onOpenDir: (app: string) => void + onSelectApp: (app: string) => void + onCopyPath: () => void + onMenuOpenChange: (open: boolean) => void } function SessionHeaderV2Actions(props: { state: SessionHeaderV2ActionsState }) { return (
+ +
+ props.state.onOpenDir(props.state.currentId)} + aria-label={props.state.ariaLabel} + icon={ + + +
+ } + > + +
+ } + /> + + } + /> + + + + {props.state.openInLabel} + { + if (!OPEN_APPS.includes(value as OpenApp)) return + props.state.onSelectApp(value) + }} + > + + {(o) => ( + { + props.state.onMenuOpenChange(false) + props.state.onOpenDir(o.id) + }} + > +
+ +
+ {o.label} +
+ )} +
+
+
+ + { + props.state.onMenuOpenChange(false) + props.state.onCopyPath() + }} + > +
+ +
+ {props.state.copyPathLabel} +
+
+
+
+
+ diff --git a/packages/ui/src/v2/components/icon.tsx b/packages/ui/src/v2/components/icon.tsx index 09aaea2e59b0..ec9d866d2b2c 100644 --- a/packages/ui/src/v2/components/icon.tsx +++ b/packages/ui/src/v2/components/icon.tsx @@ -57,6 +57,10 @@ const icons = { viewBox: "0 0 16 16", body: ``, }, + copy: { + viewBox: "0 0 16 16", + body: ``, + }, } const spriteID = "opencode-v2-icon-sprite"