refactor scrollCompensation a bit more

This commit is contained in:
midzelis 2025-08-24 18:13:16 +00:00
parent 2a55b05a25
commit 88ca63ff47
3 changed files with 21 additions and 19 deletions

View File

@ -96,14 +96,26 @@
updateSlidingWindow();
};
const scrollCompensation = (compensation: { heightDelta?: number; scrollTop?: number }) => {
const { heightDelta, scrollTop } = compensation;
if (heightDelta !== undefined) {
scrollBy(heightDelta);
} else if (scrollTop !== undefined) {
scrollTo(scrollTop);
}
timelineManager.clearScrollCompensation();
};
const getAssetHeight = (assetId: string, monthGroup: MonthGroup) => {
// the following method may trigger any layouts, so need to
// handle any scroll compensation that may have been set
const height = monthGroup!.findAssetAbsolutePosition(assetId);
// this is in a while loop, since scrollCompensations invoke scrolls
// which may load months, triggering more scrollCompensations. Call
// this in a loop, until no more layouts occur.
while (timelineManager.scrollCompensation.monthGroup) {
scrollCompensation(timelineManager.scrollCompensation);
timelineManager.clearScrollCompensation();
}
return height;
};
@ -171,15 +183,6 @@
// Also note: don't throttle, debounce, or otherwise do this function async - it causes flicker
const updateSlidingWindow = () => timelineManager.updateSlidingWindow(element?.scrollTop || 0);
const scrollCompensation = ({ heightDelta, scrollTop }: { heightDelta?: number; scrollTop?: number }) => {
if (heightDelta !== undefined) {
scrollBy(heightDelta);
} else if (scrollTop !== undefined) {
scrollTo(scrollTop);
}
};
const onScrollCompensation = scrollCompensation;
const topSectionResizeObserver: OnResizeCallback = ({ height }) => (timelineManager.topSectionHeight = height);
onMount(() => {
@ -284,7 +287,7 @@
}
onSelect?.(asset);
}}
{onScrollCompensation}
onScrollCompensationMonthInDOM={scrollCompensation}
/>
</div>
{/if}

View File

@ -25,14 +25,14 @@
monthGroup: MonthGroup;
timelineManager: TimelineManager;
onScrollCompensation: (compensation: { heightDelta?: number; scrollTop?: number }) => void;
onScrollCompensationMonthInDOM: (compensation: { heightDelta?: number; scrollTop?: number }) => void;
onHover: (dayGroup: DayGroup, asset: TimelineAsset) => void;
onAssetOpen: (dayGroup: DayGroup, asset: TimelineAsset) => void;
onAssetSelect: (dayGroup: DayGroup, asset: TimelineAsset) => void;
onDayGroupSelect: (dayGroup: DayGroup, assets: TimelineAsset[]) => void;
// these should be replaced with reactive properties in timelinemanager
// these should be replaced with reactive properties in timeline-manager.svelte.ts
isDayGroupSelected: (dayGroup: DayGroup) => boolean;
isAssetSelected: (asset: TimelineAsset) => boolean;
isAssetSelectionCandidate: (asset: TimelineAsset) => boolean;
@ -47,7 +47,7 @@
showArchiveIcon,
monthGroup,
timelineManager,
onScrollCompensation,
onScrollCompensationMonthInDOM,
onHover,
onAssetOpen,
@ -74,8 +74,7 @@
$effect.root(() => {
if (timelineManager.scrollCompensation.monthGroup === monthGroup) {
onScrollCompensation(timelineManager.scrollCompensation);
timelineManager.clearScrollCompensation();
onScrollCompensationMonthInDOM(timelineManager.scrollCompensation);
}
});
</script>

View File

@ -25,7 +25,7 @@
onAssetOpen?: (dayGroup: DayGroup, asset: TimelineAsset, defaultAssetOpen: () => void) => void;
onSelect?: (isSingleSelect: boolean, asset: TimelineAsset) => void;
onScrollCompensation: (compensation: { heightDelta?: number; scrollTop?: number }) => void;
onScrollCompensationMonthInDOM: (compensation: { heightDelta?: number; scrollTop?: number }) => void;
}
let {
@ -39,7 +39,7 @@
timelineManager,
onAssetOpen,
onSelect,
onScrollCompensation,
onScrollCompensationMonthInDOM,
}: Props = $props();
let lastAssetMouseEvent: TimelineAsset | null = $state(null);
@ -264,7 +264,7 @@
{showArchiveIcon}
{monthGroup}
{timelineManager}
{onScrollCompensation}
{onScrollCompensationMonthInDOM}
onHover={handleOnHover}
onAssetOpen={handleOnAssetOpen}
onAssetSelect={handleAssetSelect}