From 184732fc2097166921dd46fbb9a8ce433a96b237 Mon Sep 17 00:00:00 2001 From: David Hill <1879069+iamdavidhill@users.noreply.github.com> Date: Thu, 12 Mar 2026 18:26:50 +0000 Subject: [PATCH] fix(app): titlebar cleanup (#17206) --- packages/app/src/components/prompt-input.tsx | 31 -- .../app/src/components/server/server-row.tsx | 14 +- .../src/components/session/session-header.tsx | 283 +------------- .../app/src/components/status-popover.tsx | 12 +- packages/app/src/components/titlebar.tsx | 23 +- .../src/pages/session/message-timeline.tsx | 202 +++++++++- .../src/assets/icons/app/android-studio.svg | 370 +++++++++++++++++- .../ui/src/assets/icons/app/antigravity.svg | 98 ++++- packages/ui/src/assets/icons/app/cursor.svg | 17 +- .../ui/src/assets/icons/app/file-explorer.svg | 21 +- packages/ui/src/assets/icons/app/finder.png | Bin 279917 -> 2127 bytes packages/ui/src/assets/icons/app/ghostty.svg | 14 +- packages/ui/src/assets/icons/app/iterm2.svg | 26 +- .../ui/src/assets/icons/app/powershell.svg | 15 +- .../ui/src/assets/icons/app/sublimetext.svg | 18 +- packages/ui/src/assets/icons/app/terminal.png | Bin 43815 -> 969 bytes packages/ui/src/assets/icons/app/textmate.png | Bin 104374 -> 2900 bytes packages/ui/src/assets/icons/app/vscode.svg | 40 +- packages/ui/src/assets/icons/app/warp.png | Bin 782232 -> 2470 bytes packages/ui/src/assets/icons/app/xcode.png | Bin 866979 -> 3470 bytes packages/ui/src/assets/icons/app/zed-dark.svg | 28 +- packages/ui/src/assets/icons/app/zed.svg | 28 +- packages/ui/src/components/button.css | 12 + packages/ui/src/components/dropdown-menu.css | 10 + packages/ui/src/components/icon.tsx | 22 +- packages/ui/src/components/message-part.css | 3 +- packages/ui/src/styles/tailwind/utilities.css | 5 + 27 files changed, 910 insertions(+), 382 deletions(-) diff --git a/packages/app/src/components/prompt-input.tsx b/packages/app/src/components/prompt-input.tsx index e129b499a..af9c7530f 100644 --- a/packages/app/src/components/prompt-input.tsx +++ b/packages/app/src/components/prompt-input.tsx @@ -26,7 +26,6 @@ import { ProviderIcon } from "@opencode-ai/ui/provider-icon" import { Tooltip, TooltipKeybind } from "@opencode-ai/ui/tooltip" import { IconButton } from "@opencode-ai/ui/icon-button" import { Select } from "@opencode-ai/ui/select" -import { RadioGroup } from "@opencode-ai/ui/radio-group" import { useDialog } from "@opencode-ai/ui/context/dialog" import { ModelSelectorPopover } from "@/components/dialog-select-model" import { DialogSelectModelUnpaid } from "@/components/dialog-select-model-unpaid" @@ -1488,36 +1487,6 @@ export const PromptInput: Component = (props) => { -
- mode} - label={(mode) => ( - - - - )} - onSelect={(mode) => mode && setMode(mode)} - fill - pad="none" - class="w-[68px]" - /> -
diff --git a/packages/app/src/components/server/server-row.tsx b/packages/app/src/components/server/server-row.tsx index 5bb290ec3..8a4b7be4d 100644 --- a/packages/app/src/components/server/server-row.tsx +++ b/packages/app/src/components/server/server-row.tsx @@ -65,22 +65,26 @@ export function ServerRow(props: ServerRowProps) { return (
-
-
- +
+
+ {name()} - + v{props.status?.version} diff --git a/packages/app/src/components/session/session-header.tsx b/packages/app/src/components/session/session-header.tsx index 9476f8b9b..8cb704bf1 100644 --- a/packages/app/src/components/session/session-header.tsx +++ b/packages/app/src/components/session/session-header.tsx @@ -4,9 +4,7 @@ import { DropdownMenu } from "@opencode-ai/ui/dropdown-menu" import { Icon } from "@opencode-ai/ui/icon" import { IconButton } from "@opencode-ai/ui/icon-button" import { Keybind } from "@opencode-ai/ui/keybind" -import { Popover } from "@opencode-ai/ui/popover" import { Spinner } from "@opencode-ai/ui/spinner" -import { TextField } from "@opencode-ai/ui/text-field" import { showToast } from "@opencode-ai/ui/toast" import { Tooltip, TooltipKeybind } from "@opencode-ai/ui/tooltip" import { getFilename } from "@opencode-ai/util/path" @@ -14,12 +12,10 @@ import { createEffect, createMemo, For, onCleanup, Show } from "solid-js" import { createStore } from "solid-js/store" import { Portal } from "solid-js/web" import { useCommand } from "@/context/command" -import { useGlobalSDK } from "@/context/global-sdk" import { useLanguage } from "@/context/language" import { useLayout } from "@/context/layout" import { usePlatform } from "@/context/platform" import { useServer } from "@/context/server" -import { useSync } from "@/context/sync" import { useTerminal } from "@/context/terminal" import { focusTerminalById } from "@/pages/session/helpers" import { useSessionLayout } from "@/pages/session/session-layout" @@ -112,12 +108,6 @@ const LINUX_APPS = [ }, ] as const -type OpenOption = (typeof MAC_APPS)[number] | (typeof WINDOWS_APPS)[number] | (typeof LINUX_APPS)[number] -type OpenIcon = OpenApp | "file-explorer" -const OPEN_ICON_BASE = new Set(["finder", "vscode", "cursor", "zed"]) - -const openIconSize = (id: OpenIcon) => (OPEN_ICON_BASE.has(id) ? "size-4" : "size-[19px]") - const detectOS = (platform: ReturnType): OS => { if (platform.platform === "desktop" && platform.os) return platform.os if (typeof navigator !== "object") return "unknown" @@ -136,98 +126,10 @@ const showRequestError = (language: ReturnType, err: unknown }) } -function useSessionShare(args: { - globalSDK: ReturnType - currentSession: () => - | { - share?: { - url?: string - } - } - | undefined - sessionID: () => string | undefined - projectDirectory: () => string - platform: ReturnType -}) { - const [state, setState] = createStore({ - share: false, - unshare: false, - copied: false, - timer: undefined as number | undefined, - }) - const shareUrl = createMemo(() => args.currentSession()?.share?.url) - - createEffect(() => { - const url = shareUrl() - if (url) return - if (state.timer) window.clearTimeout(state.timer) - setState({ copied: false, timer: undefined }) - }) - - onCleanup(() => { - if (state.timer) window.clearTimeout(state.timer) - }) - - const shareSession = () => { - const sessionID = args.sessionID() - if (!sessionID || state.share) return - setState("share", true) - args.globalSDK.client.session - .share({ sessionID, directory: args.projectDirectory() }) - .catch((error) => { - console.error("Failed to share session", error) - }) - .finally(() => { - setState("share", false) - }) - } - - const unshareSession = () => { - const sessionID = args.sessionID() - if (!sessionID || state.unshare) return - setState("unshare", true) - args.globalSDK.client.session - .unshare({ sessionID, directory: args.projectDirectory() }) - .catch((error) => { - console.error("Failed to unshare session", error) - }) - .finally(() => { - setState("unshare", false) - }) - } - - const copyLink = (onError: (error: unknown) => void) => { - const url = shareUrl() - if (!url) return - navigator.clipboard - .writeText(url) - .then(() => { - if (state.timer) window.clearTimeout(state.timer) - setState("copied", true) - const timer = window.setTimeout(() => { - setState("copied", false) - setState("timer", undefined) - }, 3000) - setState("timer", timer) - }) - .catch(onError) - } - - const viewShare = () => { - const url = shareUrl() - if (!url) return - args.platform.openLink(url) - } - - return { state, shareUrl, shareSession, unshareSession, copyLink, viewShare } -} - export function SessionHeader() { - const globalSDK = useGlobalSDK() const layout = useLayout() const command = useCommand() const server = useServer() - const sync = useSync() const platform = usePlatform() const language = useLanguage() const terminal = useTerminal() @@ -245,10 +147,6 @@ export function SessionHeader() { return getFilename(projectDirectory()) }) const hotkey = createMemo(() => command.keybind("file.open")) - - const currentSession = createMemo(() => (params.id ? sync.session.get(params.id) : undefined)) - const shareEnabled = createMemo(() => sync.data.config.share !== "disabled") - const showShare = createMemo(() => shareEnabled() && !!params.id) const os = createMemo(() => detectOS(platform)) const [exists, setExists] = createStore>>({ @@ -356,14 +254,6 @@ export function SessionHeader() { .catch((err: unknown) => showRequestError(language, err)) } - const share = useSessionShare({ - globalSDK, - currentSession, - sessionID: () => params.id, - projectDirectory, - platform, - }) - const centerMount = createMemo(() => document.getElementById("opencode-titlebar-center")) const rightMount = createMemo(() => document.getElementById("opencode-titlebar-right")) @@ -391,7 +281,9 @@ export function SessionHeader() { {(keybind) => ( - {keybind()} + + {keybind()} + )} @@ -402,7 +294,6 @@ export function SessionHeader() { {(mount) => (
-