Reduce scroll jitter from virtual items
This commit is contained in:
@@ -423,6 +423,7 @@ export default function MessageSection(props: MessageSectionProps) {
|
|||||||
clearQuoteSelection()
|
clearQuoteSelection()
|
||||||
scheduleScrollPersist()
|
scheduleScrollPersist()
|
||||||
})
|
})
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -74,9 +74,6 @@ export const SessionView: Component<SessionViewProps> = (props) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function handleSendMessage(prompt: string, attachments: Attachment[]) {
|
async function handleSendMessage(prompt: string, attachments: Attachment[]) {
|
||||||
if (scrollToBottomHandle && import.meta.env?.DEV) {
|
|
||||||
console.debug("[SessionView] handleSendMessage scroll", props.sessionId)
|
|
||||||
}
|
|
||||||
scheduleScrollToBottom()
|
scheduleScrollToBottom()
|
||||||
await sendMessage(props.instanceId, props.sessionId, prompt, attachments)
|
await sendMessage(props.instanceId, props.sessionId, prompt, attachments)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ import { JSX, Accessor, children as resolveChildren, createEffect, createMemo, c
|
|||||||
const sizeCache = new Map<string, number>()
|
const sizeCache = new Map<string, number>()
|
||||||
const DEFAULT_MARGIN_PX = 600
|
const DEFAULT_MARGIN_PX = 600
|
||||||
const MIN_PLACEHOLDER_HEIGHT = 32
|
const MIN_PLACEHOLDER_HEIGHT = 32
|
||||||
|
const VISIBILITY_BUFFER_PX = 48
|
||||||
|
|
||||||
type ObserverRoot = Element | Document | null
|
type ObserverRoot = Element | Document | null
|
||||||
|
|
||||||
@@ -48,6 +49,19 @@ function createSharedObserver(root: ObserverRoot, margin: number): SharedObserve
|
|||||||
return { observer, listeners }
|
return { observer, listeners }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function shouldRenderEntry(entry: IntersectionObserverEntry) {
|
||||||
|
const rootBounds = entry.rootBounds
|
||||||
|
if (!rootBounds) {
|
||||||
|
return entry.isIntersecting
|
||||||
|
}
|
||||||
|
const distanceAbove = rootBounds.top - entry.boundingClientRect.bottom
|
||||||
|
const distanceBelow = entry.boundingClientRect.top - rootBounds.bottom
|
||||||
|
if (distanceAbove > VISIBILITY_BUFFER_PX || distanceBelow > VISIBILITY_BUFFER_PX) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
function subscribeToSharedObserver(
|
function subscribeToSharedObserver(
|
||||||
target: Element,
|
target: Element,
|
||||||
root: ObserverRoot,
|
root: ObserverRoot,
|
||||||
@@ -224,7 +238,8 @@ export default function VirtualItem(props: VirtualItemProps) {
|
|||||||
}
|
}
|
||||||
const margin = props.threshold ?? DEFAULT_MARGIN_PX
|
const margin = props.threshold ?? DEFAULT_MARGIN_PX
|
||||||
intersectionCleanup = subscribeToSharedObserver(wrapperRef, targetRoot, margin, (entry) => {
|
intersectionCleanup = subscribeToSharedObserver(wrapperRef, targetRoot, margin, (entry) => {
|
||||||
queueVisibility(entry.isIntersecting)
|
const nextVisible = shouldRenderEntry(entry)
|
||||||
|
queueVisibility(nextVisible)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user