summaryrefslogtreecommitdiffhomepage
path: root/packages
diff options
context:
space:
mode:
Diffstat (limited to 'packages')
-rw-r--r--packages/app/package.json1
-rw-r--r--packages/app/src/pages/session/message-timeline.tsx55
2 files changed, 19 insertions, 37 deletions
diff --git a/packages/app/package.json b/packages/app/package.json
index 8181825c0..61265c28a 100644
--- a/packages/app/package.json
+++ b/packages/app/package.json
@@ -51,6 +51,7 @@
"@solid-primitives/resize-observer": "2.1.3",
"@solid-primitives/scroll": "2.1.3",
"@solid-primitives/storage": "catalog:",
+ "@solid-primitives/timer": "1.4.4",
"@solid-primitives/websocket": "1.3.1",
"@solidjs/meta": "catalog:",
"@solidjs/router": "catalog:",
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]"