Adam 2 месяцев назад
Родитель
Сommit
78484f545c

+ 0 - 50
packages/ui/src/components/message-progress.css

@@ -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%;
-}

+ 0 - 179
packages/ui/src/components/message-progress.tsx

@@ -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)[]>(() => [
-    <div data-slot="message-progress-item" />,
-    <div data-slot="message-progress-item" />,
-    <div data-slot="message-progress-item" />,
-    ...eligibleItems(),
-    ...(done()
-      ? [
-          <div data-slot="message-progress-item" />,
-          <div data-slot="message-progress-item" />,
-          <div data-slot="message-progress-item" />,
-        ]
-      : []),
-  ])
-
-  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 (
-    <div data-component="message-progress">
-      <div data-slot="message-progress-status">
-        <Spinner /> <span data-slot="message-progress-status-text">{status() ?? "Considering next steps..."}</span>
-      </div>
-      <Show when={eligibleItems().length > 0}>
-        <div data-slot="message-progress-list-container">
-          <div data-slot="message-progress-list" style={{ transform: `translateY(${translateY()})` }}>
-            <For each={finishedItems()}>
-              {(part) => (
-                <Switch>
-                  <Match when={part && typeof part === "object" && "type" in part && part}>
-                    {(p) => {
-                      const part = p() as ToolPart
-                      const message = createMemo(() =>
-                        data.store.message[part.sessionID].find((m) => m.id === part.messageID),
-                      )
-                      return (
-                        <div data-slot="message-progress-item">
-                          <Part message={message()!} part={part} sanitize={sanitizer()} />
-                        </div>
-                      )
-                    }}
-                  </Match>
-                  <Match when={true}>
-                    <div data-slot="message-progress-item">{part as JSXElement}</div>
-                  </Match>
-                </Switch>
-              )}
-            </For>
-          </div>
-        </div>
-      </Show>
-    </div>
-  )
-}

+ 0 - 1
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);