diff --git a/packages/session-ui/src/timeline/projection.ts b/packages/session-ui/src/timeline/projection.ts index 3802d7db245..a31b0d52a84 100644 --- a/packages/session-ui/src/timeline/projection.ts +++ b/packages/session-ui/src/timeline/projection.ts @@ -8,7 +8,7 @@ import type { SessionStatus, } from "@opencode/client/promise" import { Effect, Option, Predicate, Schema } from "effect" -import { createMemo, mapArray, type Accessor } from "solid-js" +import { createComputed, createMemo, createSignal, mapArray, type Accessor } from "solid-js" import { currentContentDefaultOpen, currentToolFailed, @@ -157,7 +157,15 @@ export function createReactiveTimelineProjection(input: { .flatMap((message) => message.type === "assistant" ? message.content.filter((content) => content.type !== "tool") : [], ), - (content) => [content, createMemo(() => !!content.text.trim())] as const, + (content) => { + // A memo here went stale on every streamed delta, which marked the projection below pending; Solid then + // re-checked each of its thousands of sources to find nothing changed. A signal set from a computation + // notifies only when visibility actually flips. + const [visible, setVisible] = createSignal(false) + createComputed(() => setVisible(!!content.text.trim())) + + return [content, visible] as const + }, ) const textVisible = createMemo(() => new Map>(textParts()))