From 5c632f6c460a0d459704dab7f7b3c28e520a6551 Mon Sep 17 00:00:00 2001 From: Jai Radhakrishnan Date: Wed, 1 Apr 2026 09:02:16 -0700 Subject: [PATCH] feat: replace external spinner with custom implementation --- .../cli/cmd/tui/component/prompt/index.tsx | 25 ++---------------- .../src/cli/cmd/tui/component/spinner.tsx | 26 ++++++++++++++++--- 2 files changed, 24 insertions(+), 27 deletions(-) diff --git a/packages/opencode/src/cli/cmd/tui/component/prompt/index.tsx b/packages/opencode/src/cli/cmd/tui/component/prompt/index.tsx index 96563b884ede..78190b7d4a00 100644 --- a/packages/opencode/src/cli/cmd/tui/component/prompt/index.tsx +++ b/packages/opencode/src/cli/cmd/tui/component/prompt/index.tsx @@ -1,6 +1,5 @@ import { BoxRenderable, TextareaRenderable, MouseEvent, PasteEvent, decodePasteBytes, t, dim, fg } from "@opentui/core" import { createEffect, createMemo, type JSX, onMount, createSignal, onCleanup, on, Show, Switch, Match } from "solid-js" -import "opentui-spinner/solid" import path from "path" import { Filesystem } from "@/util/filesystem" import { useLocal } from "@tui/context/local" @@ -27,7 +26,6 @@ import { TuiEvent } from "../../event" import { iife } from "@/util/iife" import { Locale } from "@/util/locale" import { formatDuration } from "@/util/format" -import { createColors, createFrames } from "../../ui/spinner.ts" import { useDialog } from "@tui/ui/dialog" import { DialogProvider as DialogProviderConnect } from "../dialog-provider" import { DialogAlert } from "../../ui/dialog-alert" @@ -35,6 +33,7 @@ import { useToast } from "../../ui/toast" import { useKV } from "../../context/kv" import { useTextareaKeybindings } from "../textarea-keybindings" import { DialogSkill } from "../dialog-skill" +import { Spinner } from "../spinner" export type PromptProps = { sessionID?: string @@ -820,26 +819,6 @@ export function Prompt(props: PromptProps) { return `Ask anything... "${list()[store.placeholder % list().length]}"` }) - const spinnerDef = createMemo(() => { - const color = local.agent.color(local.agent.current().name) - return { - frames: createFrames({ - color, - style: "blocks", - inactiveFactor: 0.6, - // enableFading: false, - minAlpha: 0.3, - }), - color: createColors({ - color, - style: "blocks", - inactiveFactor: 0.6, - // enableFading: false, - minAlpha: 0.3, - }), - } - }) - return ( <> [⋯]}> - + diff --git a/packages/opencode/src/cli/cmd/tui/component/spinner.tsx b/packages/opencode/src/cli/cmd/tui/component/spinner.tsx index 8dc54555043b..4563057a1b2e 100644 --- a/packages/opencode/src/cli/cmd/tui/component/spinner.tsx +++ b/packages/opencode/src/cli/cmd/tui/component/spinner.tsx @@ -1,9 +1,8 @@ -import { Show } from "solid-js" +import { Show, createSignal, onCleanup, onMount } 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 = ["⠋", "⠙", "⠹", "⠸", "⠼", "⠴", "⠦", "⠧", "⠇", "⠏"] @@ -11,10 +10,29 @@ export function Spinner(props: { children?: JSX.Element; color?: RGBA }) { const { theme } = useTheme() const kv = useKV() const color = () => props.color ?? theme.textMuted + const [idx, setIdx] = createSignal(0) + + onMount(() => { + const id = setInterval(() => { + setIdx((v) => (v + 1) % frames.length) + }, 80) + onCleanup(() => clearInterval(id)) + }) + return ( - ⋯ {props.children}}> + + + + {props.children} + + + } + > - + {frames[idx()]} {props.children}