Explorar el Código

feat(app): show draft server status in titlebar (#35521)

Brendan Allan hace 2 meses
padre
commit
7f57d2a9ac

+ 2 - 2
packages/app/src/components/session/session-header.tsx

@@ -31,6 +31,7 @@ import { Icon as IconV2 } from "@opencode-ai/ui/v2/icon"
 import { KeybindV2 } from "@opencode-ai/ui/v2/keybind-v2"
 import { TooltipV2 } from "@opencode-ai/ui/v2/tooltip-v2"
 import { reviewTooltipKeybind } from "../command-tooltip-keybind"
+import { useTitlebarRightMount } from "../titlebar"
 
 const OPEN_APPS = [
   "vscode",
@@ -284,10 +285,9 @@ export function SessionHeader() {
   }
 
   const [centerMount, setCenterMount] = createSignal<HTMLElement | null>(null)
-  const [rightMount, setRightMount] = createSignal<HTMLElement | null>(null)
+  const rightMount = useTitlebarRightMount()
   onMount(() => {
     setCenterMount(document.getElementById("opencode-titlebar-center"))
-    setRightMount(document.getElementById("opencode-titlebar-right"))
   })
 
   return (

+ 7 - 1
packages/app/src/components/titlebar.tsx

@@ -1,4 +1,4 @@
-import { createEffect, createMemo, createResource, createSignal, Match, Show, Switch, untrack } from "solid-js"
+import { createEffect, createMemo, createResource, createSignal, Match, onMount, Show, Switch, untrack } from "solid-js"
 import { createStore } from "solid-js/store"
 import { useLocation, useNavigate, useParams } from "@solidjs/router"
 import { IconButton } from "@opencode-ai/ui/icon-button"
@@ -60,6 +60,12 @@ export type TitlebarUpdate = {
   install: () => void
 }
 
+export function useTitlebarRightMount() {
+  const [mount, setMount] = createSignal<HTMLElement | null>(null)
+  onMount(() => setMount(document.getElementById("opencode-titlebar-right")))
+  return mount
+}
+
 export function Titlebar(props: { update?: TitlebarUpdate }) {
   const layout = useLayout()
   const platform = usePlatform()

+ 18 - 0
packages/app/src/pages/new-session.tsx

@@ -1,8 +1,11 @@
 import { Show, createEffect, createMemo, createResource, untrack } from "solid-js"
 import { createStore } from "solid-js/store"
+import { Portal } from "solid-js/web"
 import { useSearchParams } from "@solidjs/router"
+import { Tooltip } from "@opencode-ai/ui/tooltip"
 import { NewSessionDesignView } from "@/components/session"
 import { PromptInput } from "@/components/prompt-input"
+import { StatusPopoverV2 } from "@/components/status-popover"
 import { useSettingsCommand } from "@/components/settings-dialog"
 import {
   PromptProjectAddButton,
@@ -15,11 +18,13 @@ import { useSDK } from "@/context/sdk"
 import { useSync } from "@/context/sync"
 import { useServerSync } from "@/context/server-sync"
 import { useLanguage } from "@/context/language"
+import { useSettings } from "@/context/settings"
 import { createPromptInputController, createPromptProjectControls } from "@/pages/session/composer"
 import { useSessionKey } from "@/pages/session/session-layout"
 import { useComposerCommands } from "@/pages/session/use-composer-commands"
 import { NEW_SESSION_CONTENT_WIDTH } from "@/pages/session/new-session-layout"
 import { PromptWorkspaceSelector } from "@/components/prompt-workspace-selector"
+import { useTitlebarRightMount } from "@/components/titlebar"
 
 const showWorkspaceBar = import.meta.env.VITE_OPENCODE_CHANNEL !== "prod"
 
@@ -35,6 +40,7 @@ export default function NewSessionPage() {
   const serverSync = useServerSync()
   const comments = useComments()
   const language = useLanguage()
+  const settings = useSettings()
   const route = useSessionKey()
   const [searchParams, setSearchParams] = useSearchParams<{ draftId?: string; prompt?: string }>()
 
@@ -55,6 +61,7 @@ export default function NewSessionPage() {
   })
 
   const [store, setStore] = createStore<{ worktree?: string }>({})
+  const rightMount = useTitlebarRightMount()
 
   const newSessionWorktree = createMemo(() => {
     if (store.worktree) return store.worktree
@@ -92,6 +99,17 @@ export default function NewSessionPage() {
 
   return (
     <div class="relative size-full overflow-hidden flex flex-col">
+      <Show when={rightMount()}>
+        {(mount) => (
+          <Portal mount={mount()}>
+            <Show when={settings.visibility.status()}>
+              <Tooltip placement="bottom" value={language.t("status.popover.trigger")}>
+                <StatusPopoverV2 />
+              </Tooltip>
+            </Show>
+          </Portal>
+        )}
+      </Show>
       <div class="flex-1 min-h-0 flex flex-col gap-2 p-2">
         <div class="@container relative flex flex-col min-h-0 h-full flex-1">
           <div class="flex-1 min-h-0 overflow-hidden rounded-[10px]">