Apply restored scroll position only once

This commit is contained in:
Rūdolfs Ošiņš
2026-07-03 11:33:14 +02:00
parent 9bd20fa15c
commit b01ba37f7e
5 changed files with 26 additions and 2 deletions
+5
View File
@@ -31,6 +31,9 @@
// Restore a previously-captured scroll position (used on history nav).
initialCache?: ListCacheSnapshot;
initialScrollOffset?: number;
// Called once the restore has been applied, so the provider can stop
// handing out the (now stale) values to later remounts of this list.
onRestored?: () => void;
// Reports the current scroll position so callers can persist it.
onState?: (state: {
scrollOffset: number;
@@ -59,6 +62,7 @@
prefetchPx = 800,
initialCache = undefined,
initialScrollOffset = undefined,
onRestored = undefined,
onState = undefined,
onScrollState = undefined,
}: Props = $props();
@@ -134,6 +138,7 @@
if (initialScrollOffset) {
handle.scrollTo(initialScrollOffset);
}
onRestored?.();
});
function reportState() {
+18 -2
View File
@@ -181,6 +181,15 @@ export function createPaginatedList<T>(opts: PaginatedListOptions<T>) {
});
}
// The restore values are handed out once: VirtualList applies them on its
// first mount and reports back via consumeRestoredScroll. A later remount
// of the same list (e.g. the empty-fuzzy-filter branch swapping it out and
// back) must start fresh instead of re-applying a stale offset against
// items that may have changed since.
let restoredScroll = restored
? { scrollOffset: restored.scrollOffset, cache: restored.cache }
: undefined;
return {
get items() {
return items;
@@ -191,8 +200,15 @@ export function createPaginatedList<T>(opts: PaginatedListOptions<T>) {
get loadingMore() {
return loadingMore;
},
initialScrollOffset: restored?.scrollOffset,
initialCache: restored?.cache,
get initialScrollOffset() {
return restoredScroll?.scrollOffset;
},
get initialCache() {
return restoredScroll?.cache;
},
consumeRestoredScroll() {
restoredScroll = undefined;
},
loadMore,
revalidate,
persistScroll,
+1
View File
@@ -315,6 +315,7 @@
getKey={result => result.obj.issue.id}
initialCache={list.initialCache}
initialScrollOffset={list.initialScrollOffset}
onRestored={list.consumeRestoredScroll}
onState={list.persistScroll}>
{#snippet row(result)}
<div class="row">
+1
View File
@@ -343,6 +343,7 @@
getKey={result => result.obj.patch.id}
initialCache={list.initialCache}
initialScrollOffset={list.initialScrollOffset}
onRestored={list.consumeRestoredScroll}
onState={list.persistScroll}>
{#snippet row(result)}
<div class="row">
+1
View File
@@ -274,6 +274,7 @@
r.type === "header" ? `h:${r.key}` : `c:${r.commit.id}`}
initialCache={list.initialCache}
initialScrollOffset={list.initialScrollOffset}
onRestored={list.consumeRestoredScroll}
onState={list.persistScroll}>
{#snippet row(item)}
{#if item.type === "header"}