diff --git a/web/src/lib/components/timeline/Timeline.svelte b/web/src/lib/components/timeline/Timeline.svelte index 622d89b773..0a209fcde3 100644 --- a/web/src/lib/components/timeline/Timeline.svelte +++ b/web/src/lib/components/timeline/Timeline.svelte @@ -176,12 +176,24 @@ }; const scrollAndLoadAsset = async (assetId: string) => { - const monthGroup = await timelineManager.findMonthGroupForAsset(assetId); - if (!monthGroup) { - return false; + try { + // This flag prevents layout deferral to fix scroll positioning issues. + // When layouts are deferred and we scroll to an asset at the end of the timeline, + // we can calculate the asset's position, but the scrollableElement's scrollHeight + // hasn't been updated yet to reflect the new layout. This creates a mismatch that + // breaks scroll positioning. By disabling layout deferral in this case, we maintain + // the performance benefits of deferred layouts while still supporting deep linking + // to assets at the end of the timeline. + timelineManager.isScrollingOnLoad = true; + const monthGroup = await timelineManager.findMonthGroupForAsset(assetId); + if (!monthGroup) { + return false; + } + scrollToAssetPosition(assetId, monthGroup); + return true; + } finally { + timelineManager.isScrollingOnLoad = false; } - scrollToAssetPosition(assetId, monthGroup); - return true; }; const scrollToAsset = (asset: TimelineAsset) => { diff --git a/web/src/lib/managers/timeline-manager/day-group.svelte.ts b/web/src/lib/managers/timeline-manager/day-group.svelte.ts index a3d3194dd2..934ca1d4ff 100644 --- a/web/src/lib/managers/timeline-manager/day-group.svelte.ts +++ b/web/src/lib/managers/timeline-manager/day-group.svelte.ts @@ -140,7 +140,7 @@ export class DayGroup { } layout(options: CommonLayoutOptions, noDefer: boolean) { - if (!noDefer && !this.monthGroup.intersecting) { + if (!noDefer && !this.monthGroup.intersecting && !this.monthGroup.timelineManager.isScrollingOnLoad) { this.#deferredLayout = true; return; } diff --git a/web/src/lib/managers/timeline-manager/timeline-manager.svelte.ts b/web/src/lib/managers/timeline-manager/timeline-manager.svelte.ts index d2340224a2..24523ce9e7 100644 --- a/web/src/lib/managers/timeline-manager/timeline-manager.svelte.ts +++ b/web/src/lib/managers/timeline-manager/timeline-manager.svelte.ts @@ -61,6 +61,7 @@ export class TimelineManager extends VirtualScrollManager { }); isInitialized = $state(false); + isScrollingOnLoad = false; months: MonthGroup[] = $state([]); albumAssets: Set = new SvelteSet(); scrubberMonths: ScrubberMonth[] = $state([]);