From f3a33d41f155ae68082cf57f172308303cd79caf Mon Sep 17 00:00:00 2001 From: GitHub Action Date: Fri, 12 Dec 2025 20:26:02 +0000 Subject: chore: format code --- packages/ui/src/styles/theme.css | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'packages/ui/src/styles') diff --git a/packages/ui/src/styles/theme.css b/packages/ui/src/styles/theme.css index 98450ff53..2a095b436 100644 --- a/packages/ui/src/styles/theme.css +++ b/packages/ui/src/styles/theme.css @@ -122,7 +122,7 @@ --surface-diff-hidden-weaker: var(--blue-light-1); --surface-diff-hidden-strong: var(--blue-light-5); --surface-diff-hidden-stronger: var(--blue-light-9); - --surface-diff-add-base: #DAFBE0; + --surface-diff-add-base: #dafbe0; --surface-diff-add-weak: var(--mint-light-2); --surface-diff-add-weaker: var(--mint-light-1); --surface-diff-add-strong: var(--mint-light-5); @@ -269,21 +269,21 @@ --syntax-regexp: var(--text-base); --syntax-string: #006656; --syntax-keyword: var(--text-weak); - --syntax-primitive: #FB4804; + --syntax-primitive: #fb4804; --syntax-operator: var(--text-base); --syntax-variable: var(--text-strong); - --syntax-property: #ED6DC8; + --syntax-property: #ed6dc8; --syntax-type: #596600; - --syntax-constant: #007B80; + --syntax-constant: #007b80; --syntax-punctuation: var(--text-base); --syntax-object: var(--text-strong); --syntax-success: var(--apple-light-10); --syntax-warning: var(--amber-light-10); --syntax-critical: var(--ember-light-10); - --syntax-info: #0092A8; + --syntax-info: #0092a8; --syntax-diff-add: var(--mint-light-11); --syntax-diff-delete: var(--ember-light-11); - --syntax-diff-unknown: #FF0000; + --syntax-diff-unknown: #ff0000; --markdown-heading: #d68c27; --markdown-text: #1a1a1a; --markdown-link: #3b7dd8; -- cgit v1.2.3 From 78484f545cd6a0a1d326079907d51bee4e871936 Mon Sep 17 00:00:00 2001 From: Adam <2363879+adamdotdevin@users.noreply.github.com> Date: Fri, 12 Dec 2025 13:27:19 -0600 Subject: chore: cleanup --- packages/ui/src/components/message-progress.css | 50 ------- packages/ui/src/components/message-progress.tsx | 179 ------------------------ packages/ui/src/styles/index.css | 1 - 3 files changed, 230 deletions(-) delete mode 100644 packages/ui/src/components/message-progress.css delete mode 100644 packages/ui/src/components/message-progress.tsx (limited to 'packages/ui/src/styles') diff --git a/packages/ui/src/components/message-progress.css b/packages/ui/src/components/message-progress.css deleted file mode 100644 index 0b84e0393..000000000 --- a/packages/ui/src/components/message-progress.css +++ /dev/null @@ -1,50 +0,0 @@ -[data-component="message-progress"] { - display: flex; - flex-direction: column; - gap: 12px; -} - -[data-component="message-progress"] [data-slot="message-progress-status"] { - display: flex; - align-items: center; - column-gap: 20px; - padding-left: 12px; - border: 1px solid transparent; - color: var(--text-base); -} - -[data-component="message-progress"] [data-slot="message-progress-status-text"] { - font-size: 12px; - font-weight: 500; - line-height: 1.5; -} - -[data-component="message-progress"] [data-slot="message-progress-list-container"] { - height: 120px; - overflow: hidden; - pointer-events: none; - padding-bottom: 4px; - - mask-image: linear-gradient(to bottom, transparent 0%, black 33%, black 95%, transparent 100%); - -webkit-mask-image: linear-gradient(to bottom, transparent 0%, black 33%, black 95%, transparent 100%); -} - -[data-component="message-progress"] [data-slot="message-progress-list"] { - width: 100%; - display: flex; - flex-direction: column; - align-items: flex-start; - align-self: stretch; - gap: 8px; - padding-top: 32px; - padding-bottom: 32px; - - transition: transform 500ms cubic-bezier(0.22, 1, 0.36, 1); -} - -[data-component="message-progress"] [data-slot="message-progress-item"] { - height: 32px; - display: flex; - align-items: center; - width: 100%; -} diff --git a/packages/ui/src/components/message-progress.tsx b/packages/ui/src/components/message-progress.tsx deleted file mode 100644 index a6d56b397..000000000 --- a/packages/ui/src/components/message-progress.tsx +++ /dev/null @@ -1,179 +0,0 @@ -import { For, JSXElement, Match, Show, Switch, createEffect, createMemo, createSignal, onCleanup } from "solid-js" -import { Part } from "./message-part" -import { Spinner } from "./spinner" -import { useData } from "../context/data" -import type { AssistantMessage as AssistantMessageType, ToolPart } from "@opencode-ai/sdk/v2" - -export interface MessageProgressProps { - assistantMessages: () => AssistantMessageType[] - done?: boolean -} - -export function MessageProgress(props: MessageProgressProps) { - const data = useData() - const sanitizer = createMemo(() => (data.directory ? new RegExp(`${data.directory}/`, "g") : undefined)) - const parts = createMemo(() => props.assistantMessages().flatMap((m) => data.store.part[m.id])) - const done = createMemo(() => props.done ?? false) - const currentTask = createMemo( - () => - parts().findLast( - (p) => - p && - p.type === "tool" && - p.tool === "task" && - p.state && - "metadata" in p.state && - p.state.metadata && - p.state.metadata.sessionId && - p.state.status === "running", - ) as ToolPart, - ) - const resolvedParts = createMemo(() => { - let resolved = parts() - const task = currentTask() - if (task && task.state && "metadata" in task.state && task.state.metadata?.sessionId) { - const messages = data.store.message[task.state.metadata.sessionId as string]?.filter( - (m) => m.role === "assistant", - ) - resolved = messages?.flatMap((m) => data.store.part[m.id]) ?? parts() - } - return resolved - }) - - const eligibleItems = createMemo(() => { - return resolvedParts().filter((p) => p?.type === "tool" && p?.state.status === "completed") as ToolPart[] - }) - const finishedItems = createMemo<(JSXElement | ToolPart)[]>(() => [ -
, -
, -
, - ...eligibleItems(), - ...(done() - ? [ -
, -
, -
, - ] - : []), - ]) - - const delay = createMemo(() => (done() ? 220 : 400)) - const [visibleCount, setVisibleCount] = createSignal(eligibleItems().length) - - createEffect(() => { - const total = finishedItems().length - if (total > visibleCount()) { - const timer = setTimeout(() => { - setVisibleCount((prev) => prev + 1) - }, delay()) - onCleanup(() => clearTimeout(timer)) - } else if (total < visibleCount()) { - setVisibleCount(total) - } - }) - - const translateY = createMemo(() => { - const total = visibleCount() - if (total < 2) return "0px" - return `-${(total - 2) * 40 - 8}px` - }) - - const lastPart = createMemo(() => resolvedParts().slice(-1)?.at(0)) - const rawStatus = createMemo(() => { - const last = lastPart() - if (!last) return undefined - - if (last.type === "tool") { - switch (last.tool) { - case "task": - return "Delegating work" - case "todowrite": - case "todoread": - return "Planning next steps" - case "read": - return "Gathering context" - case "list": - case "grep": - case "glob": - return "Searching the codebase" - case "webfetch": - return "Searching the web" - case "edit": - case "write": - return "Making edits" - case "bash": - return "Running commands" - default: - break - } - } else if (last.type === "reasoning") { - return "Thinking" - } else if (last.type === "text") { - return "Gathering thoughts" - } - return undefined - }) - - const [status, setStatus] = createSignal(rawStatus()) - let lastStatusChange = Date.now() - let statusTimeout: number | undefined - - createEffect(() => { - const newStatus = rawStatus() - if (newStatus === status() || !newStatus) return - - const timeSinceLastChange = Date.now() - lastStatusChange - - if (timeSinceLastChange >= 1500) { - setStatus(newStatus) - lastStatusChange = Date.now() - if (statusTimeout) { - clearTimeout(statusTimeout) - statusTimeout = undefined - } - } else { - if (statusTimeout) clearTimeout(statusTimeout) - statusTimeout = setTimeout(() => { - setStatus(rawStatus()) - lastStatusChange = Date.now() - statusTimeout = undefined - }, 1000 - timeSinceLastChange) as unknown as number - } - }) - - return ( -
-
- {status() ?? "Considering next steps..."} -
- 0}> -
-
- - {(part) => ( - - - {(p) => { - const part = p() as ToolPart - const message = createMemo(() => - data.store.message[part.sessionID].find((m) => m.id === part.messageID), - ) - return ( -
- -
- ) - }} -
- -
{part as JSXElement}
-
-
- )} -
-
-
-
-
- ) -} diff --git a/packages/ui/src/styles/index.css b/packages/ui/src/styles/index.css index d60082d93..ba2c954bc 100644 --- a/packages/ui/src/styles/index.css +++ b/packages/ui/src/styles/index.css @@ -26,7 +26,6 @@ @import "../components/logo.css" layer(components); @import "../components/markdown.css" layer(components); @import "../components/message-part.css" layer(components); -@import "../components/message-progress.css" layer(components); @import "../components/message-nav.css" layer(components); @import "../components/progress-circle.css" layer(components); @import "../components/resize-handle.css" layer(components); -- cgit v1.2.3 From 6c3495a75a5cacad78eb908ea9cf5b4fad2d0836 Mon Sep 17 00:00:00 2001 From: Adam <2363879+adamdotdevin@users.noreply.github.com> Date: Fri, 12 Dec 2025 14:59:41 -0600 Subject: fix: desktop layout --- packages/ui/src/components/spinner.tsx | 20 +++++++++++--------- packages/ui/src/components/typewriter.tsx | 13 +++++++++---- packages/ui/src/styles/animations.css | 10 ++++++++++ 3 files changed, 30 insertions(+), 13 deletions(-) (limited to 'packages/ui/src/styles') diff --git a/packages/ui/src/components/spinner.tsx b/packages/ui/src/components/spinner.tsx index 5e787d86b..41f4d9e71 100644 --- a/packages/ui/src/components/spinner.tsx +++ b/packages/ui/src/components/spinner.tsx @@ -1,14 +1,16 @@ import { ComponentProps, For } from "solid-js" -export function Spinner(props: { class?: string; classList?: ComponentProps<"div">["classList"] }) { - const squares = Array.from({ length: 16 }, (_, i) => ({ - id: i, - x: (i % 4) * 4, - y: Math.floor(i / 4) * 4, - delay: Math.random() * 3, - duration: 2 + Math.random() * 2, - })) +const outerIndices = new Set([0, 1, 2, 3, 4, 7, 8, 11, 12, 13, 14, 15]) +const squares = Array.from({ length: 16 }, (_, i) => ({ + id: i, + x: (i % 4) * 4, + y: Math.floor(i / 4) * 4, + delay: Math.random() * 1.5, + duration: 1 + Math.random() * 1, + outer: outerIndices.has(i), +})) +export function Spinner(props: { class?: string; classList?: ComponentProps<"div">["classList"] }) { return ( diff --git a/packages/ui/src/components/typewriter.tsx b/packages/ui/src/components/typewriter.tsx index 2f6ecb016..16c85a110 100644 --- a/packages/ui/src/components/typewriter.tsx +++ b/packages/ui/src/components/typewriter.tsx @@ -1,4 +1,4 @@ -import { createEffect, Show, type ValidComponent } from "solid-js" +import { createEffect, onCleanup, Show, type ValidComponent } from "solid-js" import { createStore } from "solid-js/store" import { Dynamic } from "solid-js/web" @@ -14,6 +14,7 @@ export const Typewriter = (props: { text?: strin if (!text) return let i = 0 + const timeouts: ReturnType[] = [] setStore("typing", true) setStore("displayed", "") setStore("cursor", true) @@ -29,14 +30,18 @@ export const Typewriter = (props: { text?: strin if (i < text.length) { setStore("displayed", text.slice(0, i + 1)) i++ - setTimeout(type, getTypingDelay()) + timeouts.push(setTimeout(type, getTypingDelay())) } else { setStore("typing", false) - setTimeout(() => setStore("cursor", false), 2000) + timeouts.push(setTimeout(() => setStore("cursor", false), 2000)) } } - setTimeout(type, 200) + timeouts.push(setTimeout(type, 200)) + + onCleanup(() => { + for (const timeout of timeouts) clearTimeout(timeout) + }) }) return ( diff --git a/packages/ui/src/styles/animations.css b/packages/ui/src/styles/animations.css index 5fcebb93f..0ae3493eb 100644 --- a/packages/ui/src/styles/animations.css +++ b/packages/ui/src/styles/animations.css @@ -12,6 +12,16 @@ } } +@keyframes pulse-opacity-dim { + 0%, + 100% { + opacity: 0; + } + 50% { + opacity: 0.3; + } +} + @keyframes fadeUp { from { opacity: 0; -- cgit v1.2.3