diff options
| author | Brendan Allan <[email protected]> | 2026-03-23 18:34:32 +0800 |
|---|---|---|
| committer | GitHub <[email protected]> | 2026-03-23 10:34:32 +0000 |
| commit | 8e1b53b32c2f74c4983e0762cd90f4c2ecc7fda8 (patch) | |
| tree | 8365c03d364c60348c4d7fc7494f14804dd6a84a /packages/app/src | |
| parent | 0a7dfc03ee1dbc29d65605e8ca37ed9d137bd2ec (diff) | |
| download | opencode-8e1b53b32c2f74c4983e0762cd90f4c2ecc7fda8.tar.gz opencode-8e1b53b32c2f74c4983e0762cd90f4c2ecc7fda8.zip | |
fix(app): handle session busy state better (#18758)
Diffstat (limited to 'packages/app/src')
| -rw-r--r-- | packages/app/src/pages/session/message-timeline.tsx | 55 |
1 files changed, 18 insertions, 37 deletions
diff --git a/packages/app/src/pages/session/message-timeline.tsx b/packages/app/src/pages/session/message-timeline.tsx index 7ced21353..fe61f1685 100644 --- a/packages/app/src/pages/session/message-timeline.tsx +++ b/packages/app/src/pages/session/message-timeline.tsx @@ -1,4 +1,4 @@ -import { For, createEffect, createMemo, on, onCleanup, Show, Index, type JSX } from "solid-js" +import { For, createEffect, createMemo, on, onCleanup, Show, Index, type JSX, createSignal } from "solid-js" import { createStore, produce } from "solid-js/store" import { useNavigate } from "@solidjs/router" import { useMutation } from "@tanstack/solid-query" @@ -30,6 +30,7 @@ import { useSDK } from "@/context/sdk" import { useSync } from "@/context/sync" import { messageAgentColor } from "@/utils/agent" import { parseCommentNote, readCommentMetadata } from "@/utils/comment-note" +import { makeTimer } from "@solid-primitives/timer" type MessageComment = { path: string @@ -250,38 +251,21 @@ export function MessageTimeline(props: { const working = createMemo(() => !!pending() || sessionStatus().type !== "idle") const tint = createMemo(() => messageAgentColor(sessionMessages(), sync.data.agent)) - const [slot, setSlot] = createStore({ - open: false, - show: false, - fade: false, + const [timeoutDone, setTimeoutDone] = createSignal(true) + + const workingStatus = createMemo<"hidden" | "showing" | "hiding">((prev) => { + if (working()) return "showing" + if (prev === "showing" || !timeoutDone()) return "hiding" + return "hidden" }) - let f: number | undefined - const clear = () => { - if (f !== undefined) window.clearTimeout(f) - f = undefined - } + createEffect(() => { + if (workingStatus() !== "hiding") return + + setTimeoutDone(false) + makeTimer(() => setTimeoutDone(true), 260, setTimeout) + }) - onCleanup(clear) - createEffect( - on( - working, - (on, prev) => { - clear() - if (on) { - setSlot({ open: true, show: true, fade: false }) - return - } - if (prev) { - setSlot({ open: false, show: true, fade: true }) - f = window.setTimeout(() => setSlot({ show: false, fade: false }), 260) - return - } - setSlot({ open: false, show: false, fade: false }) - }, - { defer: true }, - ), - ) const activeMessageID = createMemo(() => { const parentID = pending()?.parentID if (parentID) { @@ -676,17 +660,15 @@ export function MessageTimeline(props: { <div class="shrink-0 flex items-center justify-center overflow-hidden transition-[width,margin] duration-300 ease-[cubic-bezier(0.22,1,0.36,1)]" style={{ - width: slot.open ? "16px" : "0px", - "margin-right": slot.open ? "8px" : "0px", + width: working() ? "16px" : "0px", + "margin-right": working() ? "8px" : "0px", }} aria-hidden="true" > - <Show when={slot.show}> + <Show when={workingStatus() !== "hidden"}> <div class="transition-opacity duration-200 ease-out" - classList={{ - "opacity-0": slot.fade, - }} + classList={{ "opacity-0": workingStatus() === "hiding" }} > <Spinner class="size-4" style={{ color: tint() ?? "var(--icon-interactive-base)" }} /> </div> @@ -912,7 +894,6 @@ export function MessageTimeline(props: { </div> </div> </Show> - <div role="log" class="flex flex-col gap-12 items-start justify-start pb-16 transition-[margin]" |
