mirror of
https://github.com/multica-ai/multica.git
synced 2026-07-26 20:45:37 +02:00
fix(views): anchor newest-first live transcript across prepends
Virtuoso items opt out of native scroll anchoring, so in newest-first sort every live flush prepended rows and shifted the reading position. Compensate with a counting-down firstItemIndex (Virtuoso's prepend contract); sort/filter/task changes remount the list via an epoch key so the value never increases within one instance. scrollToIndex keeps data-relative indices — verified against scrollToIndexSystem, which never reads firstItemIndex. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -287,6 +287,20 @@ export function AgentTranscriptDialog({
|
||||
const isAntigravityLiveEmpty =
|
||||
isLive && displayItems.length === 0 && runtimeInfo?.provider === "antigravity";
|
||||
|
||||
// Newest-first shows live events as PREPENDS, and Virtuoso items opt out of
|
||||
// native scroll anchoring (`overflow-anchor: none`), so without compensation
|
||||
// every 500ms flush shifts the reading position. Virtuoso's contract: a
|
||||
// decrease of firstItemIndex by N anchors the viewport across an N-item
|
||||
// prepend, and the value must never increase within an instance — counting
|
||||
// down from a large base satisfies that while the list only grows. Sort,
|
||||
// filter, or task changes can shrink the list, so `listEpoch` remounts the
|
||||
// instance (fresh at top) instead of letting firstItemIndex climb.
|
||||
// `scrollToIndex`/`computeItemKey` are unaffected: indices stay data-relative
|
||||
// (verified against scrollToIndexSystem — it never reads firstItemIndex).
|
||||
const firstItemIndex =
|
||||
sortDirection === "newest_first" ? 1_000_000 - displayItems.length : 0;
|
||||
const listEpoch = `${task.id}:${sortDirection}:${activeFilterKeys.join(",")}`;
|
||||
|
||||
const detailSeqs = useMemo(
|
||||
() => displayItems.filter(hasEventDetail).map((item) => item.seq),
|
||||
[displayItems],
|
||||
@@ -758,9 +772,11 @@ export function AgentTranscriptDialog({
|
||||
// of DOM rows (#5733). Rows expand/collapse to variable heights;
|
||||
// Virtuoso re-measures them via ResizeObserver.
|
||||
<Virtuoso
|
||||
key={listEpoch}
|
||||
ref={virtuosoRef}
|
||||
style={{ height: "100%" }}
|
||||
data={displayItems}
|
||||
firstItemIndex={firstItemIndex}
|
||||
computeItemKey={(_, item) => item.seq}
|
||||
components={LIST_COMPONENTS}
|
||||
itemContent={(_, item) => (
|
||||
|
||||
Reference in New Issue
Block a user