Skip to content

Commit 97f5c1d

Browse files
Merge branch 'dev' into fix-post-install-instruction-ask-user
2 parents d9b03ad + 13006d6 commit 97f5c1d

269 files changed

Lines changed: 37291 additions & 2211 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/TEAM_MEMBERS

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,3 +14,4 @@ rekram1-node
1414
thdxr
1515
simonklee
1616
vimtor
17+
starptech

.opencode/tool/github-triage.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@ import { tool } from "@opencode-ai/plugin"
44
const TEAM = {
55
tui: ["kommander", "simonklee"],
66
desktop_web: ["Hona", "Brendonovich"],
7-
core: ["jlongster", "rekram1-node", "nexxeln", "kitlangton"],
8-
inference: ["fwang", "MrMushrooooom"],
7+
core: ["jlongster", "rekram1-node", "nexxeln", "kitlangton", "starptech"],
8+
inference: ["fwang", "MrMushrooooom", "starptech"],
99
windows: ["Hona"],
1010
} as const
1111

packages/app/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
"type": "module",
66
"exports": {
77
".": "./src/index.ts",
8+
"./desktop-menu": "./src/desktop-menu.ts",
89
"./vite": "./vite.js",
910
"./index.css": "./src/index.css"
1011
},

packages/app/src/components/titlebar.tsx

Lines changed: 363 additions & 139 deletions
Large diffs are not rendered by default.
Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
import { Show, type JSX } from "solid-js"
2+
import { DropdownMenu } from "@opencode-ai/ui/dropdown-menu"
3+
import { Icon } from "@opencode-ai/ui/icon"
4+
import { IconButton } from "@opencode-ai/ui/icon-button"
5+
6+
import { useCommand } from "@/context/command"
7+
import { DESKTOP_MENU, desktopMenuVisible, type DesktopMenuAction, type DesktopMenuEntry } from "@/desktop-menu"
8+
import { usePlatform } from "@/context/platform"
9+
10+
export function WindowsAppMenu(props: {
11+
command: ReturnType<typeof useCommand>
12+
platform: ReturnType<typeof usePlatform>
13+
}) {
14+
let lastFocused: HTMLElement | undefined
15+
16+
const rememberFocus = () => {
17+
const active = document.activeElement
18+
lastFocused = active instanceof HTMLElement ? active : undefined
19+
}
20+
const commandDisabled = (id: string) => {
21+
const option = props.command.options.find((option) => option.id === id)
22+
if (!option) return true
23+
return option.disabled ?? false
24+
}
25+
const runCommand = (id: string) => {
26+
if (commandDisabled(id)) return
27+
props.command.trigger(id)
28+
}
29+
const runAction = (action: DesktopMenuAction) => {
30+
if (action.startsWith("edit.") && lastFocused?.isConnected) lastFocused.focus({ preventScroll: true })
31+
void props.platform.runDesktopMenuAction?.(action)
32+
}
33+
const runEntry = (entry: DesktopMenuEntry) => {
34+
if (entry.type === "separator") return
35+
if (entry.command) {
36+
runCommand(entry.command)
37+
return
38+
}
39+
if (entry.action) {
40+
runAction(entry.action)
41+
return
42+
}
43+
if (entry.href) props.platform.openLink(entry.href)
44+
}
45+
46+
return (
47+
<DropdownMenu gutter={4} modal={false} placement="bottom-start">
48+
<DropdownMenu.Trigger
49+
as={IconButton}
50+
icon="menu"
51+
variant="ghost"
52+
class="titlebar-icon rounded-md shrink-0"
53+
aria-label="OpenCode menu"
54+
onPointerDown={rememberFocus}
55+
onKeyDown={rememberFocus}
56+
/>
57+
<DropdownMenu.Portal>
58+
<DropdownMenu.Content class="desktop-app-menu">
59+
<DropdownMenu.Group>
60+
<DropdownMenu.GroupLabel class="desktop-app-menu-heading">OpenCode</DropdownMenu.GroupLabel>
61+
{DESKTOP_MENU.filter((menu) => desktopMenuVisible(menu, "windows")).map((menu) => (
62+
<DesktopMenuSubmenu label={menu.label}>
63+
{menu.items
64+
?.filter((entry) => desktopMenuVisible(entry, "windows"))
65+
.map((entry) =>
66+
entry.type === "separator" ? (
67+
<DropdownMenu.Separator />
68+
) : (
69+
<DesktopMenuItem
70+
label={entry.label ?? ""}
71+
keybind={entry.command ? props.command.keybind(entry.command) : entry.accelerator?.windows}
72+
disabled={entry.command ? commandDisabled(entry.command) : false}
73+
onSelect={() => runEntry(entry)}
74+
/>
75+
),
76+
)}
77+
</DesktopMenuSubmenu>
78+
))}
79+
</DropdownMenu.Group>
80+
</DropdownMenu.Content>
81+
</DropdownMenu.Portal>
82+
</DropdownMenu>
83+
)
84+
}
85+
86+
function DesktopMenuSubmenu(props: { label: string; children: JSX.Element }) {
87+
return (
88+
<DropdownMenu.Sub>
89+
<DropdownMenu.SubTrigger>
90+
<span data-slot="dropdown-menu-item-label">{props.label}</span>
91+
<span data-slot="desktop-app-menu-chevron">
92+
<Icon name="chevron-right" size="small" />
93+
</span>
94+
</DropdownMenu.SubTrigger>
95+
<DropdownMenu.Portal>
96+
<DropdownMenu.SubContent class="desktop-app-menu">{props.children}</DropdownMenu.SubContent>
97+
</DropdownMenu.Portal>
98+
</DropdownMenu.Sub>
99+
)
100+
}
101+
102+
function DesktopMenuItem(props: { label: string; keybind?: string; disabled?: boolean; onSelect: () => void }) {
103+
return (
104+
<DropdownMenu.Item disabled={props.disabled} onSelect={props.onSelect}>
105+
<DropdownMenu.ItemLabel>{props.label}</DropdownMenu.ItemLabel>
106+
<Show when={props.keybind}>
107+
<span data-slot="desktop-app-menu-keybind">{props.keybind}</span>
108+
</Show>
109+
</DropdownMenu.Item>
110+
)
111+
}

0 commit comments

Comments
 (0)