perf(app): better session stream rendering
This commit is contained in:
@@ -316,12 +316,22 @@ export default function Page() {
|
||||
return sync.session.history.loading(id)
|
||||
})
|
||||
const emptyUserMessages: UserMessage[] = []
|
||||
const userMessages = createMemo(() => messages().filter((m) => m.role === "user") as UserMessage[], emptyUserMessages)
|
||||
const visibleUserMessages = createMemo(() => {
|
||||
const revert = revertMessageID()
|
||||
if (!revert) return userMessages()
|
||||
return userMessages().filter((m) => m.id < revert)
|
||||
}, emptyUserMessages)
|
||||
const userMessages = createMemo(
|
||||
() => messages().filter((m) => m.role === "user") as UserMessage[],
|
||||
emptyUserMessages,
|
||||
{ equals: same },
|
||||
)
|
||||
const visibleUserMessages = createMemo(
|
||||
() => {
|
||||
const revert = revertMessageID()
|
||||
if (!revert) return userMessages()
|
||||
return userMessages().filter((m) => m.id < revert)
|
||||
},
|
||||
emptyUserMessages,
|
||||
{
|
||||
equals: same,
|
||||
},
|
||||
)
|
||||
const lastUserMessage = createMemo(() => visibleUserMessages().at(-1))
|
||||
|
||||
createEffect(
|
||||
@@ -347,13 +357,19 @@ export default function Page() {
|
||||
promptHeight: 0,
|
||||
})
|
||||
|
||||
const renderedUserMessages = createMemo(() => {
|
||||
const msgs = visibleUserMessages()
|
||||
const start = store.turnStart
|
||||
if (start <= 0) return msgs
|
||||
if (start >= msgs.length) return emptyUserMessages
|
||||
return msgs.slice(start)
|
||||
}, emptyUserMessages)
|
||||
const renderedUserMessages = createMemo(
|
||||
() => {
|
||||
const msgs = visibleUserMessages()
|
||||
const start = store.turnStart
|
||||
if (start <= 0) return msgs
|
||||
if (start >= msgs.length) return emptyUserMessages
|
||||
return msgs.slice(start)
|
||||
},
|
||||
emptyUserMessages,
|
||||
{
|
||||
equals: same,
|
||||
},
|
||||
)
|
||||
|
||||
const newSessionWorktree = createMemo(() => {
|
||||
if (store.newSessionWorktree === "create") return "create"
|
||||
|
||||
@@ -457,9 +457,16 @@ export function SessionTurn(
|
||||
})
|
||||
|
||||
createEffect(() => {
|
||||
const timer = setInterval(() => {
|
||||
const update = () => {
|
||||
setStore("duration", duration())
|
||||
}, 1000)
|
||||
}
|
||||
|
||||
update()
|
||||
|
||||
// Only keep ticking while the active (in-progress) turn is running.
|
||||
if (!working()) return
|
||||
|
||||
const timer = setInterval(update, 1000)
|
||||
onCleanup(() => clearInterval(timer))
|
||||
})
|
||||
|
||||
@@ -495,6 +502,11 @@ export function SessionTurn(
|
||||
}
|
||||
})
|
||||
|
||||
onCleanup(() => {
|
||||
if (!statusTimeout) return
|
||||
clearTimeout(statusTimeout)
|
||||
})
|
||||
|
||||
return (
|
||||
<div data-component="session-turn" class={props.classes?.root} ref={setRootRef}>
|
||||
<div
|
||||
|
||||
@@ -15,7 +15,6 @@ export function createAutoScroll(options: AutoScrollOptions) {
|
||||
let settleTimer: ReturnType<typeof setTimeout> | undefined
|
||||
let autoTimer: ReturnType<typeof setTimeout> | undefined
|
||||
let cleanup: (() => void) | undefined
|
||||
let resizeFrame: number | undefined
|
||||
let auto: { top: number; time: number } | undefined
|
||||
|
||||
const threshold = () => options.bottomThreshold ?? 10
|
||||
@@ -152,11 +151,10 @@ export function createAutoScroll(options: AutoScrollOptions) {
|
||||
() => {
|
||||
if (!active()) return
|
||||
if (store.userScrolled) return
|
||||
if (resizeFrame !== undefined) return
|
||||
resizeFrame = requestAnimationFrame(() => {
|
||||
resizeFrame = undefined
|
||||
scrollToBottom(false)
|
||||
})
|
||||
// ResizeObserver fires after layout, before paint.
|
||||
// Keep the bottom locked in the same frame to avoid visible
|
||||
// "jump up then catch up" artifacts while streaming content.
|
||||
scrollToBottom(false)
|
||||
},
|
||||
)
|
||||
|
||||
@@ -190,7 +188,6 @@ export function createAutoScroll(options: AutoScrollOptions) {
|
||||
onCleanup(() => {
|
||||
if (settleTimer) clearTimeout(settleTimer)
|
||||
if (autoTimer) clearTimeout(autoTimer)
|
||||
if (resizeFrame !== undefined) cancelAnimationFrame(resizeFrame)
|
||||
if (cleanup) cleanup()
|
||||
})
|
||||
|
||||
|
||||
Reference in New Issue
Block a user