From ea1aba4192fd356603e807144edf202328008ee6 Mon Sep 17 00:00:00 2001 From: Adam <2363879+adamdotdevin@users.noreply.github.com> Date: Mon, 2 Feb 2026 07:02:40 -0600 Subject: feat(app): project context menu on right-click --- packages/app/src/pages/layout.tsx | 107 +++++++++++++++++++++++++++----------- 1 file changed, 78 insertions(+), 29 deletions(-) (limited to 'packages/app/src') diff --git a/packages/app/src/pages/layout.tsx b/packages/app/src/pages/layout.tsx index a970bf667..5a8dc0f2e 100644 --- a/packages/app/src/pages/layout.tsx +++ b/packages/app/src/pages/layout.tsx @@ -31,6 +31,7 @@ import { Tooltip, TooltipKeybind } from "@opencode-ai/ui/tooltip" import { HoverCard } from "@opencode-ai/ui/hover-card" import { MessageNav } from "@opencode-ai/ui/message-nav" import { DropdownMenu } from "@opencode-ai/ui/dropdown-menu" +import { ContextMenu } from "@opencode-ai/ui/context-menu" import { Collapsible } from "@opencode-ai/ui/collapsible" import { DiffChanges } from "@opencode-ai/ui/diff-changes" import { Spinner } from "@opencode-ai/ui/spinner" @@ -2310,10 +2311,13 @@ export default function Layout(props: ParentProps) { () => props.project.vcs === "git" && layout.sidebar.workspaces(props.project.worktree)(), ) const [open, setOpen] = createSignal(false) + const [menu, setMenu] = createSignal(false) const preview = createMemo(() => !props.mobile && layout.sidebar.opened()) const overlay = createMemo(() => !props.mobile && !layout.sidebar.opened()) - const active = createMemo(() => (preview() ? open() : overlay() && state.hoverProject === props.project.worktree)) + const active = createMemo( + () => menu() || (preview() ? open() : overlay() && state.hoverProject === props.project.worktree), + ) createEffect(() => { if (preview()) return @@ -2352,35 +2356,79 @@ export default function Layout(props: ParentProps) { const projectName = () => props.project.name || getFilename(props.project.worktree) const trigger = ( - + { + if (!overlay()) return + globalSync.child(props.project.worktree) + setState("hoverProject", props.project.worktree) + setState("hoverSession", undefined) + }} + onFocus={() => { + if (!overlay()) return + globalSync.child(props.project.worktree) + setState("hoverProject", props.project.worktree) + setState("hoverSession", undefined) + }} + onClick={() => navigateToProject(props.project.worktree)} + onBlur={() => setOpen(false)} + > + + + + + dialog.show(() => )}> + {language.t("common.edit")} + + { + const enabled = layout.sidebar.workspaces(props.project.worktree)() + if (enabled) { + layout.sidebar.toggleWorkspaces(props.project.worktree) + return + } + if (props.project.vcs !== "git") return + layout.sidebar.toggleWorkspaces(props.project.worktree) + }} + > + + {layout.sidebar.workspaces(props.project.worktree)() + ? language.t("sidebar.workspaces.disable") + : language.t("sidebar.workspaces.enable")} + + + + closeProject(props.project.worktree)} + > + {language.t("common.close")} + + + + ) return ( @@ -2388,13 +2436,14 @@ export default function Layout(props: ParentProps) {
{ + if (menu()) return setOpen(value) if (value) setState("hoverSession", undefined) }} -- cgit v1.2.3