refactor scrollCompensation a bit more

This commit is contained in:
midzelis 2025-08-24 18:13:16 +00:00
parent 1dd06fd9ff
commit 3194bf43b1
3 changed files with 21 additions and 19 deletions

View File

@ -88,14 +88,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;
};
@ -163,15 +175,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(() => {
@ -274,7 +277,7 @@
}
onSelect?.(asset);
}}
{onScrollCompensation}
onScrollCompensationMonthInDOM={scrollCompensation}
/>
</div>
{/if}

View File

@ -23,14 +23,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;
@ -43,7 +43,7 @@
showArchiveIcon,
monthGroup,
timelineManager,
onScrollCompensation,
onScrollCompensationMonthInDOM,
onHover,
onAssetOpen,
@ -70,8 +70,7 @@
$effect.root(() => {
if (timelineManager.scrollCompensation.monthGroup === monthGroup) {
onScrollCompensation(timelineManager.scrollCompensation);
timelineManager.clearScrollCompensation();
onScrollCompensationMonthInDOM(timelineManager.scrollCompensation);
}
});
</script>

View File

@ -20,7 +20,7 @@
timelineManager: TimelineManager;
assetInteraction: AssetInteraction;
onSelect?: (isSingleSelect: boolean, asset: TimelineAsset) => void;
onScrollCompensation: (compensation: { heightDelta?: number; scrollTop?: number }) => void;
onScrollCompensationMonthInDOM: (compensation: { heightDelta?: number; scrollTop?: number }) => void;
}
let {
@ -32,7 +32,7 @@
assetInteraction,
timelineManager,
onSelect,
onScrollCompensation,
onScrollCompensationMonthInDOM,
}: Props = $props();
let lastAssetMouseEvent: TimelineAsset | null = $state(null);
@ -248,7 +248,7 @@
{showArchiveIcon}
{monthGroup}
{timelineManager}
{onScrollCompensation}
{onScrollCompensationMonthInDOM}
onHover={handleOnHover}
onAssetOpen={handleOnAssetOpen}
onAssetSelect={handleAssetSelect}