Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 2 additions & 10 deletions packages/tui/src/component/dialog-debug.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
import { TextAttributes } from "@opentui/core"
import { createMemo, createSignal, For } from "solid-js"
import { Keymap } from "../context/keymap"
import { useTheme } from "../context/theme"
import { useDialog } from "../ui/dialog"
import { DialogHeader, useDialog } from "../ui/dialog"
import { useRoute } from "../context/route"
import { useLocal } from "../context/local"
import { useClipboard } from "../context/clipboard"
Expand Down Expand Up @@ -54,14 +53,7 @@ export function DialogDebug() {

return (
<box paddingLeft={2} paddingRight={2} gap={1} paddingBottom={1}>
<box flexDirection="row" justifyContent="space-between">
<text fg={theme.text.base} attributes={TextAttributes.BOLD}>
Debug
</text>
<text fg={theme.text.muted} onMouseUp={() => dialog.clear()}>
esc
</text>
</box>
<DialogHeader title="Debug" />
{/* No click-to-copy here: releasing a mouse selection must trigger the
global copy-on-select so users can copy a single value, e.g. the session id. */}
<box>
Expand Down
33 changes: 17 additions & 16 deletions packages/tui/src/component/dialog-error-details.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import { useRoute } from "../context/route"
import { getScrollAcceleration } from "../util/scroll"
import { useTheme } from "../context/theme"
import { emptyPrompt } from "../prompt/history"
import { dialogWidth, useDialog } from "../ui/dialog"
import { DialogHeader, dialogWidth, useDialog } from "../ui/dialog"
import { FilePath } from "../ui/file-path"
import { useToast } from "../ui/toast"
import { errorDetails } from "../util/error-details"
Expand Down Expand Up @@ -73,21 +73,22 @@ export function DialogErrorDetails(props: {
return (
<box paddingLeft={2} paddingRight={2} paddingBottom={1} gap={1}>
<box>
<box flexDirection="row" gap={2}>
<text
attributes={TextAttributes.BOLD}
fg={theme.text.base}
flexGrow={1}
minWidth={0}
wrapMode="none"
truncate
>
{props.title}
</text>
<text fg={theme.text.muted} flexShrink={0} onMouseUp={props.onBack}>
esc
</text>
</box>
<DialogHeader
gap={2}
onClose={props.onBack}
titleView={
<text
attributes={TextAttributes.BOLD}
fg={theme.text.base}
flexGrow={1}
minWidth={0}
wrapMode="none"
truncate
>
{props.title}
</text>
}
/>
<Show when={props.source}>
{(source) => (
<FilePath
Expand Down
11 changes: 2 additions & 9 deletions packages/tui/src/component/dialog-highlights.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { useConfig } from "../config"
import { Keymap } from "../context/keymap"
import type { TuiHighlight } from "../context/runtime"
import { useTheme } from "../context/theme"
import { useDialog } from "../ui/dialog"
import { DialogHeader, useDialog } from "../ui/dialog"
import { getScrollAcceleration } from "../util/scroll"

export function DialogHighlights(props: { version: string; items: ReadonlyArray<TuiHighlight> }) {
Expand Down Expand Up @@ -34,14 +34,7 @@ export function DialogHighlights(props: { version: string; items: ReadonlyArray<

return (
<box gap={1} paddingBottom={1}>
<box flexDirection="row" justifyContent="space-between" paddingLeft={2} paddingRight={2}>
<text attributes={TextAttributes.BOLD} fg={theme.text.base}>
What's new in {props.version}
</text>
<text fg={theme.text.muted} onMouseUp={() => dialog.clear()}>
esc
</text>
</box>
<DialogHeader paddingX={2} title={`What's new in ${props.version}`} />
{/* The band owns the vertical padding so it stays visible while the highlights scroll. */}
<box backgroundColor={overlay.background.raised.high} paddingTop={1} paddingBottom={1}>
<scrollbox
Expand Down
12 changes: 2 additions & 10 deletions packages/tui/src/component/dialog-image-preview.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
import { TextAttributes } from "@opentui/core"
import { useTerminalDimensions } from "@opentui/solid"
import { createMemo, createSignal } from "solid-js"
import { Keymap } from "../context/keymap"
import { useTheme } from "../context/theme"
import { useDialog } from "../ui/dialog"
import { DialogHeader, useDialog } from "../ui/dialog"

type ImagePreviewItem = Readonly<{
uri: string
Expand Down Expand Up @@ -38,14 +37,7 @@ export function DialogImagePreview(props: { images: readonly ImagePreviewItem[];

return (
<box id="prompt-image-viewer" paddingLeft={2} paddingRight={2} paddingBottom={1} gap={1}>
<box flexDirection="row" justifyContent="space-between">
<text attributes={TextAttributes.BOLD} fg={theme.text.base}>
Image {index() + 1} of {props.images.length}
</text>
<text fg={theme.text.muted} onMouseUp={() => dialog.clear()}>
esc
</text>
</box>
<DialogHeader title={`Image ${index() + 1} of ${props.images.length}`} />
<image
id="prompt-image-viewer-image"
source={current().uri}
Expand Down
32 changes: 5 additions & 27 deletions packages/tui/src/component/dialog-integration.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { ScrollBoxRenderable, TextareaRenderable, TextAttributes } from "@opentui/core"
import { ScrollBoxRenderable, TextareaRenderable } from "@opentui/core"
import { useTerminalDimensions } from "@opentui/solid"
import type {
ConnectionInfo,
Expand All @@ -21,7 +21,7 @@ import { useClient } from "../context/client"
import { Keymap } from "../context/keymap"
import { useLocation } from "../context/location"
import { useTheme } from "../context/theme"
import { useDialog } from "../ui/dialog"
import { DialogHeader, useDialog } from "../ui/dialog"
import { DialogPrompt } from "../ui/dialog-prompt"
import { DialogSelect } from "../ui/dialog-select"
import { Link } from "../ui/link"
Expand Down Expand Up @@ -510,14 +510,7 @@ function CommandView(props: { title: string; output: string; message: string })
onMount(() => dialog.setSize("large"))
return (
<box gap={1} paddingBottom={1}>
<box flexDirection="row" justifyContent="space-between" paddingLeft={2} paddingRight={2}>
<text attributes={TextAttributes.BOLD} fg={theme.text.base}>
{props.title}
</text>
<text fg={theme.text.muted} onMouseUp={() => dialog.clear()}>
esc close
</text>
</box>
<DialogHeader paddingX={2} title={props.title} closeLabel="esc close" />
<box
backgroundColor={overlayTheme.background.raised.high}
paddingLeft={2}
Expand Down Expand Up @@ -801,18 +794,10 @@ function OAuthView(props: {
copy?: boolean
open?: boolean
}) {
const dialog = useDialog()
const theme = useTheme().surface("dialog")
return (
<box paddingLeft={2} paddingRight={2} gap={1} paddingBottom={1}>
<box flexDirection="row" justifyContent="space-between">
<text attributes={TextAttributes.BOLD} fg={theme.text.base}>
{props.title}
</text>
<text fg={theme.text.muted} onMouseUp={() => dialog.clear()}>
esc
</text>
</box>
<DialogHeader title={props.title} />
<Show when={props.url}>
{(url) => (
<box gap={1}>
Expand Down Expand Up @@ -986,14 +971,7 @@ function StringChoiceField(props: {
}))
return (
<box paddingLeft={4} paddingRight={4} paddingBottom={1} gap={1}>
<box flexDirection="row" justifyContent="space-between">
<text fg={theme.text.base} attributes={TextAttributes.BOLD}>
{formLabel(props.field)}
</text>
<text fg={theme.text.muted} onMouseUp={() => (store.editing ? back() : dialog.clear())}>
esc
</text>
</box>
<DialogHeader title={formLabel(props.field)} onClose={() => (store.editing ? back() : dialog.clear())} />
<Show when={props.field.description}>{(description) => <text fg={theme.text.muted}>{description()}</text>}</Show>
<scrollbox
gap={1}
Expand Down
11 changes: 2 additions & 9 deletions packages/tui/src/component/dialog-pair.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { createMemo, createResource, createSignal, For, Show } from "solid-js"
import { renderUnicodeCompact } from "uqr"
import { useClient } from "../context/client"
import { useTheme } from "../context/theme"
import { useDialog } from "../ui/dialog"
import { DialogHeader, useDialog } from "../ui/dialog"
import { Link } from "../ui/link"
import { errorMessage } from "../util/error"

Expand Down Expand Up @@ -88,14 +88,7 @@ export function DialogPair() {

return (
<box paddingLeft={2} paddingRight={2} paddingBottom={1} gap={1}>
<box flexDirection="row" justifyContent="space-between">
<text fg={theme.text.base} attributes={TextAttributes.BOLD}>
Pair
</text>
<text fg={theme.text.muted} onMouseUp={() => dialog.clear()}>
esc
</text>
</box>
<DialogHeader title="Pair" />
<Show
when={loadError()}
fallback={
Expand Down
19 changes: 10 additions & 9 deletions packages/tui/src/component/dialog-shell-output.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import stripAnsi from "strip-ansi"
import { useClient } from "../context/client"
import { Keymap } from "../context/keymap"
import { useTheme } from "../context/theme"
import { useDialog } from "../ui/dialog"
import { DialogHeader, useDialog } from "../ui/dialog"

const PAGE_BYTES = 64 * 1024

Expand Down Expand Up @@ -101,15 +101,16 @@ export function DialogShellOutput(props: { shell: ShellInfo; location: LocationR

return (
<box paddingLeft={2} paddingRight={2} paddingBottom={1} gap={1}>
<box flexDirection="row" gap={2}>
<text fg={theme.text.base} attributes={TextAttributes.BOLD} flexGrow={1}>
Shell output
</text>
<DialogHeader
gap={2}
titleView={
<text fg={theme.text.base} attributes={TextAttributes.BOLD} flexGrow={1}>
Shell output
</text>
}
>
<text fg={theme.text.muted}>{status()}</text>
<text fg={theme.text.muted} onMouseUp={() => dialog.clear()}>
esc
</text>
</box>
</DialogHeader>
<text fg={theme.text.muted} maxHeight={3} wrapMode="word">
{props.shell.command}
</text>
Expand Down
13 changes: 2 additions & 11 deletions packages/tui/src/component/dialog-status.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,11 @@
import { TextAttributes } from "@opentui/core"
import { useTheme } from "../context/theme"
import { useDialog } from "../ui/dialog"
import { DialogHeader } from "../ui/dialog"
import { useData } from "../context/data"
import { For, Match, Switch, Show, createMemo } from "solid-js"

export function DialogStatus() {
const data = useData()
const theme = useTheme().surface("dialog")
const dialog = useDialog()

const mcp = createMemo(() => data.location.mcp.server.list() ?? [])
const color = (status: string) => {
Expand All @@ -18,14 +16,7 @@ export function DialogStatus() {
}
return (
<box paddingLeft={2} paddingRight={2} gap={1} paddingBottom={1}>
<box flexDirection="row" justifyContent="space-between">
<text fg={theme.text.base} attributes={TextAttributes.BOLD}>
Status
</text>
<text fg={theme.text.muted} onMouseUp={() => dialog.clear()}>
esc
</text>
</box>
<DialogHeader title="Status" />
<Show when={mcp().length > 0} fallback={<text fg={theme.text.base}>No MCP servers</text>}>
<box>
<text fg={theme.text.base}>
Expand Down
18 changes: 7 additions & 11 deletions packages/tui/src/component/dialog-update.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
import { TextAttributes } from "@opentui/core"
import { createEffect, createMemo, createResource, createSignal, For, Match, onCleanup, Show, Switch } from "solid-js"
import { Keymap } from "../context/keymap"
import { useTheme } from "../context/theme"
import type { UpdateState } from "../context/update-notification"
import { useDialog } from "../ui/dialog"
import { DialogHeader, useDialog } from "../ui/dialog"
import { errorMessage } from "../util/error"
import { Spinner } from "./spinner"

Expand Down Expand Up @@ -87,18 +86,15 @@ export function DialogUpdate(props: {

return (
<box paddingLeft={2} paddingRight={2} gap={1}>
<box flexDirection="row" justifyContent="space-between">
<text attributes={TextAttributes.BOLD} fg={theme.text.base}>
{state().type === "installing"
<DialogHeader
title={
state().type === "installing"
? "Updating OpenCode"
: state().type === "available" || state().type === "failed"
? "Update available"
: "Update"}
</text>
<text fg={theme.text.muted} onMouseUp={() => dialog.clear()}>
esc
</text>
</box>
: "Update"
}
/>
<box paddingBottom={1}>
<Show when={state()} keyed>
{(current) => (
Expand Down
12 changes: 2 additions & 10 deletions packages/tui/src/component/dialog-workspace-file-changes.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
import { TextAttributes } from "@opentui/core"
import { useKeyboard, useTerminalDimensions } from "@opentui/solid"
import type { VcsFileStatus } from "@opencode/client"
import { createMemo, For } from "solid-js"
import { createStore } from "solid-js/store"
import { FilePath } from "../ui/file-path"
import { useTheme } from "../context/theme"
import { useConfig } from "../config"
import { useDialog, type DialogContext } from "../ui/dialog"
import { DialogHeader, useDialog, type DialogContext } from "../ui/dialog"
import { getScrollAcceleration } from "../util/scroll"

const options = ["no", "yes"] as const
Expand Down Expand Up @@ -71,14 +70,7 @@ export function DialogWorkspaceFileChanges(props: {

return (
<box gap={1}>
<box flexDirection="row" justifyContent="space-between" paddingLeft={2} paddingRight={2}>
<text attributes={TextAttributes.BOLD} fg={theme.text.base}>
{props.title ?? "File Changes Found"}
</text>
<text fg={theme.text.muted} onMouseUp={() => dialog.clear()}>
esc
</text>
</box>
<DialogHeader paddingX={2} title={props.title ?? "File Changes Found"} />
<box paddingLeft={2} paddingRight={2}>
<text fg={theme.text.muted} wrapMode="word">
{props.message ?? "Do you want to move these changes with the session?"}
Expand Down
13 changes: 3 additions & 10 deletions packages/tui/src/component/dialog-worktree-name.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { InputRenderable, TextAttributes } from "@opentui/core"
import { InputRenderable } from "@opentui/core"
import { Slug } from "@opencode/core/util/slug"
import { createSignal, onMount } from "solid-js"
import { Keymap } from "../context/keymap"
import { useTheme } from "../context/theme"
import { useDialog, type DialogContext } from "../ui/dialog"
import { DialogHeader, useDialog, type DialogContext } from "../ui/dialog"
import { useConfig } from "../config"

export function DialogWorktreeName(props: { onConfirm: (name: string) => void }) {
Expand Down Expand Up @@ -48,14 +48,7 @@ export function DialogWorktreeName(props: { onConfirm: (name: string) => void })

return (
<box paddingLeft={2} paddingRight={2} gap={1}>
<box flexDirection="row" justifyContent="space-between">
<text attributes={TextAttributes.BOLD} fg={theme.text.base}>
Name worktree
</text>
<text fg={theme.text.muted} onMouseUp={() => dialog.clear()}>
esc
</text>
</box>
<DialogHeader title="Name worktree" />
<input
cursorStyle={config.cursor}
ref={(value: InputRenderable) => {
Expand Down
Loading
Loading