diff options
| author | Adam <[email protected]> | 2025-12-12 10:45:02 -0600 |
|---|---|---|
| committer | Adam <[email protected]> | 2025-12-12 10:45:34 -0600 |
| commit | 9629f7464b3a1a6077e7c6b04923c4c13993ac08 (patch) | |
| tree | d803cca8c47b65c199c00d68c406a80452831d10 /packages/desktop/src/components | |
| parent | 9017d103031fa252f5b3fce23df651d1b4ef5bc5 (diff) | |
| download | opencode-9629f7464b3a1a6077e7c6b04923c4c13993ac08.tar.gz opencode-9629f7464b3a1a6077e7c6b04923c4c13993ac08.zip | |
chore: cleanup
Diffstat (limited to 'packages/desktop/src/components')
| -rw-r--r-- | packages/desktop/src/components/header.tsx | 113 |
1 files changed, 113 insertions, 0 deletions
diff --git a/packages/desktop/src/components/header.tsx b/packages/desktop/src/components/header.tsx new file mode 100644 index 000000000..cc4d01816 --- /dev/null +++ b/packages/desktop/src/components/header.tsx @@ -0,0 +1,113 @@ +import { useGlobalSync } from "@/context/global-sync" +import { useLayout } from "@/context/layout" +import { Session } from "@opencode-ai/sdk/v2/client" +import { Button } from "@opencode-ai/ui/button" +import { Icon } from "@opencode-ai/ui/icon" +import { Mark } from "@opencode-ai/ui/logo" +import { Select } from "@opencode-ai/ui/select" +import { Tooltip } from "@opencode-ai/ui/tooltip" +import { base64Decode } from "@opencode-ai/util/encode" +import { getFilename } from "@opencode-ai/util/path" +import { A, useParams } from "@solidjs/router" +import { createMemo, Show } from "solid-js" + +export function Header(props: { + navigateToProject: (directory: string) => void + navigateToSession: (session: Session | undefined) => void +}) { + const globalSync = useGlobalSync() + const layout = useLayout() + const params = useParams() + const currentDirectory = createMemo(() => base64Decode(params.dir ?? "")) + const store = createMemo(() => globalSync.child(currentDirectory())[0]) + const sessions = createMemo(() => store().session ?? []) + const currentSession = createMemo(() => sessions().find((s) => s.id === params.id)) + + return ( + <header class="h-12 shrink-0 bg-background-base border-b border-border-weak-base flex" data-tauri-drag-region> + <A + href="/" + classList={{ + "w-12 shrink-0 px-4 py-3.5": true, + "flex items-center justify-start self-stretch": true, + "border-r border-border-weak-base": true, + }} + style={{ width: layout.sidebar.opened() ? `${layout.sidebar.width()}px` : undefined }} + data-tauri-drag-region + > + <Mark class="shrink-0" /> + </A> + <div class="pl-4 px-6 flex items-center justify-between gap-4 w-full"> + <Show when={params.dir && layout.projects.list().length > 0}> + <div class="flex items-center gap-3"> + <div class="flex items-center gap-2"> + <Select + options={layout.projects.list().map((project) => project.worktree)} + current={currentDirectory()} + label={(x) => getFilename(x)} + onSelect={(x) => (x ? props.navigateToProject(x) : undefined)} + class="text-14-regular text-text-base" + variant="ghost" + > + {/* @ts-ignore */} + {(i) => ( + <div class="flex items-center gap-2"> + <Icon name="folder" size="small" /> + <div class="text-text-strong">{getFilename(i)}</div> + </div> + )} + </Select> + <div class="text-text-weaker">/</div> + <Select + options={sessions()} + current={currentSession()} + placeholder="New session" + label={(x) => x.title} + value={(x) => x.id} + onSelect={props.navigateToSession} + class="text-14-regular text-text-base max-w-md" + variant="ghost" + /> + </div> + <Show when={currentSession()}> + <Button as={A} href={`/${params.dir}/session`} icon="plus-small"> + New session + </Button> + </Show> + </div> + <div class="flex items-center gap-4"> + <Tooltip + class="shrink-0" + value={ + <div class="flex items-center gap-2"> + <span>Toggle terminal</span> + <span class="text-icon-base text-12-medium">Ctrl `</span> + </div> + } + > + <Button variant="ghost" class="group/terminal-toggle size-6 p-0" onClick={layout.terminal.toggle}> + <div class="relative flex items-center justify-center size-4 [&>*]:absolute [&>*]:inset-0"> + <Icon + size="small" + name={layout.terminal.opened() ? "layout-bottom-full" : "layout-bottom"} + class="group-hover/terminal-toggle:hidden" + /> + <Icon + size="small" + name="layout-bottom-partial" + class="hidden group-hover/terminal-toggle:inline-block" + /> + <Icon + size="small" + name={layout.terminal.opened() ? "layout-bottom" : "layout-bottom-full"} + class="hidden group-active/terminal-toggle:inline-block" + /> + </div> + </Button> + </Tooltip> + </div> + </Show> + </div> + </header> + ) +} |
