Add spinner animation for Task tool (#11725)
This commit is contained in:
@@ -10,7 +10,7 @@ import { useSDK } from "../context/sdk"
|
|||||||
import { DialogSessionRename } from "./dialog-session-rename"
|
import { DialogSessionRename } from "./dialog-session-rename"
|
||||||
import { useKV } from "../context/kv"
|
import { useKV } from "../context/kv"
|
||||||
import { createDebouncedSignal } from "../util/signal"
|
import { createDebouncedSignal } from "../util/signal"
|
||||||
import "opentui-spinner/solid"
|
import { Spinner } from "./spinner"
|
||||||
|
|
||||||
export function DialogSessionList() {
|
export function DialogSessionList() {
|
||||||
const dialog = useDialog()
|
const dialog = useDialog()
|
||||||
@@ -32,8 +32,6 @@ export function DialogSessionList() {
|
|||||||
|
|
||||||
const currentSessionID = createMemo(() => (route.data.type === "session" ? route.data.sessionID : undefined))
|
const currentSessionID = createMemo(() => (route.data.type === "session" ? route.data.sessionID : undefined))
|
||||||
|
|
||||||
const spinnerFrames = ["⠋", "⠙", "⠹", "⠸", "⠼", "⠴", "⠦", "⠧", "⠇", "⠏"]
|
|
||||||
|
|
||||||
const sessions = createMemo(() => searchResults() ?? sync.data.session)
|
const sessions = createMemo(() => searchResults() ?? sync.data.session)
|
||||||
|
|
||||||
const options = createMemo(() => {
|
const options = createMemo(() => {
|
||||||
@@ -56,11 +54,7 @@ export function DialogSessionList() {
|
|||||||
value: x.id,
|
value: x.id,
|
||||||
category,
|
category,
|
||||||
footer: Locale.time(x.time.updated),
|
footer: Locale.time(x.time.updated),
|
||||||
gutter: isWorking ? (
|
gutter: isWorking ? <Spinner /> : undefined,
|
||||||
<Show when={kv.get("animations_enabled", true)} fallback={<text fg={theme.textMuted}>[⋯]</text>}>
|
|
||||||
<spinner frames={spinnerFrames} interval={80} color={theme.primary} />
|
|
||||||
</Show>
|
|
||||||
) : undefined,
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|||||||
24
packages/opencode/src/cli/cmd/tui/component/spinner.tsx
Normal file
24
packages/opencode/src/cli/cmd/tui/component/spinner.tsx
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
import { Show } from "solid-js"
|
||||||
|
import { useTheme } from "../context/theme"
|
||||||
|
import { useKV } from "../context/kv"
|
||||||
|
import type { JSX } from "@opentui/solid"
|
||||||
|
import type { RGBA } from "@opentui/core"
|
||||||
|
import "opentui-spinner/solid"
|
||||||
|
|
||||||
|
const frames = ["⠋", "⠙", "⠹", "⠸", "⠼", "⠴", "⠦", "⠧", "⠇", "⠏"]
|
||||||
|
|
||||||
|
export function Spinner(props: { children?: JSX.Element; color?: RGBA }) {
|
||||||
|
const { theme } = useTheme()
|
||||||
|
const kv = useKV()
|
||||||
|
const color = () => props.color ?? theme.textMuted
|
||||||
|
return (
|
||||||
|
<Show when={kv.get("animations_enabled", true)} fallback={<text fg={color()}>⋯ {props.children}</text>}>
|
||||||
|
<box flexDirection="row" gap={1}>
|
||||||
|
<spinner frames={frames} interval={80} color={color()} />
|
||||||
|
<Show when={props.children}>
|
||||||
|
<text fg={color()}>{props.children}</text>
|
||||||
|
</Show>
|
||||||
|
</box>
|
||||||
|
</Show>
|
||||||
|
)
|
||||||
|
}
|
||||||
@@ -16,6 +16,7 @@ import path from "path"
|
|||||||
import { useRoute, useRouteData } from "@tui/context/route"
|
import { useRoute, useRouteData } from "@tui/context/route"
|
||||||
import { useSync } from "@tui/context/sync"
|
import { useSync } from "@tui/context/sync"
|
||||||
import { SplitBorder } from "@tui/component/border"
|
import { SplitBorder } from "@tui/component/border"
|
||||||
|
import { Spinner } from "@tui/component/spinner"
|
||||||
import { useTheme } from "@tui/context/theme"
|
import { useTheme } from "@tui/context/theme"
|
||||||
import {
|
import {
|
||||||
BoxRenderable,
|
BoxRenderable,
|
||||||
@@ -1559,7 +1560,13 @@ function InlineTool(props: {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
function BlockTool(props: { title: string; children: JSX.Element; onClick?: () => void; part?: ToolPart }) {
|
function BlockTool(props: {
|
||||||
|
title: string
|
||||||
|
children: JSX.Element
|
||||||
|
onClick?: () => void
|
||||||
|
part?: ToolPart
|
||||||
|
spinner?: boolean
|
||||||
|
}) {
|
||||||
const { theme } = useTheme()
|
const { theme } = useTheme()
|
||||||
const renderer = useRenderer()
|
const renderer = useRenderer()
|
||||||
const [hover, setHover] = createSignal(false)
|
const [hover, setHover] = createSignal(false)
|
||||||
@@ -1582,9 +1589,16 @@ function BlockTool(props: { title: string; children: JSX.Element; onClick?: () =
|
|||||||
props.onClick?.()
|
props.onClick?.()
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<text paddingLeft={3} fg={theme.textMuted}>
|
<Show
|
||||||
{props.title}
|
when={props.spinner}
|
||||||
</text>
|
fallback={
|
||||||
|
<text paddingLeft={3} fg={theme.textMuted}>
|
||||||
|
{props.title}
|
||||||
|
</text>
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<Spinner color={theme.textMuted}>{props.title.replace(/^# /, "")}</Spinner>
|
||||||
|
</Show>
|
||||||
{props.children}
|
{props.children}
|
||||||
<Show when={error()}>
|
<Show when={error()}>
|
||||||
<text fg={theme.error}>{error()}</text>
|
<text fg={theme.error}>{error()}</text>
|
||||||
@@ -1813,6 +1827,8 @@ function Task(props: ToolProps<typeof TaskTool>) {
|
|||||||
|
|
||||||
const current = createMemo(() => tools().findLast((x) => x.state.status !== "pending"))
|
const current = createMemo(() => tools().findLast((x) => x.state.status !== "pending"))
|
||||||
|
|
||||||
|
const isRunning = createMemo(() => props.part.state.status === "running")
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Switch>
|
<Switch>
|
||||||
<Match when={props.input.description || props.input.subagent_type}>
|
<Match when={props.input.description || props.input.subagent_type}>
|
||||||
@@ -1824,6 +1840,7 @@ function Task(props: ToolProps<typeof TaskTool>) {
|
|||||||
: undefined
|
: undefined
|
||||||
}
|
}
|
||||||
part={props.part}
|
part={props.part}
|
||||||
|
spinner={isRunning()}
|
||||||
>
|
>
|
||||||
<box>
|
<box>
|
||||||
<text style={{ fg: theme.textMuted }}>
|
<text style={{ fg: theme.textMuted }}>
|
||||||
|
|||||||
Reference in New Issue
Block a user