From 5e8742f4312a8923f3da92172a7247470ef34516 Mon Sep 17 00:00:00 2001 From: Adam <2363879+adamdotdevin@users.noreply.github.com> Date: Mon, 2 Mar 2026 18:23:59 -0600 Subject: fix(app): timeline jank --- packages/ui/src/components/message-part.tsx | 170 ++++++++++++++++----------- packages/ui/src/hooks/create-auto-scroll.tsx | 5 +- 2 files changed, 108 insertions(+), 67 deletions(-) (limited to 'packages/ui') diff --git a/packages/ui/src/components/message-part.tsx b/packages/ui/src/components/message-part.tsx index b59dd47b8..2490f5c17 100644 --- a/packages/ui/src/components/message-part.tsx +++ b/packages/ui/src/components/message-part.tsx @@ -9,6 +9,7 @@ import { Show, Switch, onCleanup, + Index, type JSX, } from "solid-js" import stripAnsi from "strip-ansi" @@ -458,50 +459,67 @@ export function AssistantParts(props: { const last = createMemo(() => grouped().at(-1)?.key) return ( - - {(entry) => { - if (entry.type === "context") { - const parts = createMemo( - () => - entry.refs - .map((ref) => partByID(list(data.store.part?.[ref.messageID], emptyParts), ref.partID)) - .filter((part): part is ToolPart => !!part && isContextGroupTool(part)), - emptyTools, - { equals: same }, - ) - const busy = createMemo(() => props.working && last() === entry.key) - - return ( - 0}> - - - ) - } - - const message = createMemo(() => props.messages.find((item) => item.id === entry.ref.messageID)) - const part = createMemo(() => - partByID(list(data.store.part?.[entry.ref.messageID], emptyParts), entry.ref.partID), - ) + + {(entryAccessor) => { + const entryType = createMemo(() => entryAccessor().type) return ( - - {(message) => ( - - {(part) => ( - - )} - - )} - + + + {(() => { + const parts = createMemo( + () => { + const entry = entryAccessor() as { type: "context"; refs: PartRef[] } + return entry.refs + .map((ref) => partByID(list(data.store.part?.[ref.messageID], emptyParts), ref.partID)) + .filter((part): part is ToolPart => !!part && isContextGroupTool(part)) + }, + emptyTools, + { equals: same }, + ) + const busy = createMemo(() => props.working && last() === entryAccessor().key) + + return ( + 0}> + + + ) + })()} + + + {(() => { + const message = createMemo(() => { + const entry = entryAccessor() as { type: "part"; ref: PartRef } + return props.messages.find((item) => item.id === entry.ref.messageID) + }) + const part = createMemo(() => { + const entry = entryAccessor() as { type: "part"; ref: PartRef } + return partByID(list(data.store.part?.[entry.ref.messageID], emptyParts), entry.ref.partID) + }) + + return ( + + {(msg) => ( + + {(p) => ( + + )} + + )} + + ) + })()} + + ) }} - + ) } @@ -632,36 +650,56 @@ export function AssistantMessageDisplay(props: { ) return ( - - {(entry) => { - if (entry.type === "context") { - const parts = createMemo( - () => - entry.refs - .map((ref) => partByID(props.parts, ref.partID)) - .filter((part): part is ToolPart => !!part && isContextGroupTool(part)), - emptyTools, - { equals: same }, - ) - - return ( - 0}> - - - ) - } - - const part = createMemo(() => partByID(props.parts, entry.ref.partID)) + + {(entryAccessor) => { + const entryType = createMemo(() => entryAccessor().type) return ( - - {(part) => ( - - )} - + + + {(() => { + const parts = createMemo( + () => { + const entry = entryAccessor() as { type: "context"; refs: PartRef[] } + return entry.refs + .map((ref) => partByID(props.parts, ref.partID)) + .filter((part): part is ToolPart => !!part && isContextGroupTool(part)) + }, + emptyTools, + { equals: same }, + ) + + return ( + 0}> + + + ) + })()} + + + {(() => { + const part = createMemo(() => { + const entry = entryAccessor() as { type: "part"; ref: PartRef } + return partByID(props.parts, entry.ref.partID) + }) + + return ( + + {(p) => ( + + )} + + ) + })()} + + ) }} - + ) } diff --git a/packages/ui/src/hooks/create-auto-scroll.tsx b/packages/ui/src/hooks/create-auto-scroll.tsx index c32017739..8483915a8 100644 --- a/packages/ui/src/hooks/create-auto-scroll.tsx +++ b/packages/ui/src/hooks/create-auto-scroll.tsx @@ -142,7 +142,10 @@ export function createAutoScroll(options: AutoScrollOptions) { const handleInteraction = () => { if (!active()) return - stop() + const selection = window.getSelection() + if (selection && selection.toString().length > 0) { + stop() + } } const updateOverflowAnchor = (el: HTMLElement) => { -- cgit v1.2.3