From aa559f0b30e674899d22f575f098f71c20c86b5c Mon Sep 17 00:00:00 2001 From: midzelis Date: Thu, 18 Sep 2025 14:38:09 +0000 Subject: [PATCH] refactor(web): rename loadMonthGroup to loadSegment API --- .../lib/components/timeline/Timeline.svelte | 4 +- .../internal/intersection-support.svelte.ts | 6 +-- .../timeline-manager/month-group.svelte.ts | 10 ++++- .../timeline-manager.svelte.spec.ts | 40 +++++++++---------- .../timeline-manager.svelte.ts | 10 ++--- web/src/lib/utils/asset-utils.ts | 2 +- 6 files changed, 38 insertions(+), 34 deletions(-) diff --git a/web/src/lib/components/timeline/Timeline.svelte b/web/src/lib/components/timeline/Timeline.svelte index 2849b50815..cfdd4c1621 100644 --- a/web/src/lib/components/timeline/Timeline.svelte +++ b/web/src/lib/components/timeline/Timeline.svelte @@ -670,7 +670,7 @@ break; } if (started) { - await timelineManager.loadMonthGroup(monthGroup.yearMonth); + await timelineManager.loadSegment(monthGroup.yearMonth); for (const asset of monthGroup.assetsIterator()) { if (deselect) { assetInteraction.removeAssetFromMultiselectGroup(asset.id); @@ -811,7 +811,7 @@ $effect(() => { if ($showAssetViewer) { const { localDateTime } = getTimes($viewingAsset.fileCreatedAt, DateTime.local().offset / 60); - void timelineManager.loadMonthGroup({ year: localDateTime.year, month: localDateTime.month }); + void timelineManager.loadSegment({ year: localDateTime.year, month: localDateTime.month }); } }); diff --git a/web/src/lib/managers/timeline-manager/internal/intersection-support.svelte.ts b/web/src/lib/managers/timeline-manager/internal/intersection-support.svelte.ts index 185d74e0b0..db3d31fc84 100644 --- a/web/src/lib/managers/timeline-manager/internal/intersection-support.svelte.ts +++ b/web/src/lib/managers/timeline-manager/internal/intersection-support.svelte.ts @@ -17,11 +17,7 @@ export function updateIntersectionMonthGroup(timelineManager: TimelineManager, m INTERSECTION_EXPAND_BOTTOM, ); } - month.intersecting = actuallyIntersecting || preIntersecting; - month.actuallyIntersecting = actuallyIntersecting; - if (preIntersecting || actuallyIntersecting) { - timelineManager.clearDeferredLayout(month); - } + month.updateIntersection({ intersecting: actuallyIntersecting || preIntersecting, actuallyIntersecting }); } /** diff --git a/web/src/lib/managers/timeline-manager/month-group.svelte.ts b/web/src/lib/managers/timeline-manager/month-group.svelte.ts index e406972900..c38ccb29c4 100644 --- a/web/src/lib/managers/timeline-manager/month-group.svelte.ts +++ b/web/src/lib/managers/timeline-manager/month-group.svelte.ts @@ -81,7 +81,7 @@ export class MonthGroup { } this.#intersecting = newValue; if (newValue) { - void this.timelineManager.loadMonthGroup(this.yearMonth); + void this.timelineManager.loadSegment(this.yearMonth); } else { this.cancel(); } @@ -374,4 +374,12 @@ export class MonthGroup { cancel() { this.loader?.cancel(); } + + updateIntersection({ intersecting, actuallyIntersecting }: { intersecting: boolean; actuallyIntersecting: boolean }) { + this.intersecting = intersecting; + this.actuallyIntersecting = actuallyIntersecting; + if (intersecting) { + this.timelineManager.clearDeferredLayout(this); + } + } } diff --git a/web/src/lib/managers/timeline-manager/timeline-manager.svelte.spec.ts b/web/src/lib/managers/timeline-manager/timeline-manager.svelte.spec.ts index f845caa119..632b0efd81 100644 --- a/web/src/lib/managers/timeline-manager/timeline-manager.svelte.spec.ts +++ b/web/src/lib/managers/timeline-manager/timeline-manager.svelte.spec.ts @@ -92,7 +92,7 @@ describe('TimelineManager', () => { }); }); - describe('loadMonthGroup', () => { + describe('loadSegment', () => { let timelineManager: TimelineManager; const bucketAssets: Record = { '2024-01-03T00:00:00.000Z': timelineAssetFactory.buildList(1).map((asset) => @@ -129,46 +129,46 @@ describe('TimelineManager', () => { it('loads a month', async () => { expect(getMonthGroupByDate(timelineManager, { year: 2024, month: 1 })?.getAssets().length).toEqual(0); - await timelineManager.loadMonthGroup({ year: 2024, month: 1 }); + await timelineManager.loadSegment({ year: 2024, month: 1 }); expect(sdkMock.getTimeBucket).toBeCalledTimes(1); expect(getMonthGroupByDate(timelineManager, { year: 2024, month: 1 })?.getAssets().length).toEqual(3); }); it('ignores invalid months', async () => { - await timelineManager.loadMonthGroup({ year: 2023, month: 1 }); + await timelineManager.loadSegment({ year: 2023, month: 1 }); expect(sdkMock.getTimeBucket).toBeCalledTimes(0); }); it('cancels month loading', async () => { const month = getMonthGroupByDate(timelineManager, { year: 2024, month: 1 })!; - void timelineManager.loadMonthGroup({ year: 2024, month: 1 }); + void timelineManager.loadSegment({ year: 2024, month: 1 }); const abortSpy = vi.spyOn(month!.loader!.cancelToken!, 'abort'); month?.cancel(); expect(abortSpy).toBeCalledTimes(1); - await timelineManager.loadMonthGroup({ year: 2024, month: 1 }); + await timelineManager.loadSegment({ year: 2024, month: 1 }); expect(getMonthGroupByDate(timelineManager, { year: 2024, month: 1 })?.getAssets().length).toEqual(3); }); it('prevents loading months multiple times', async () => { await Promise.all([ - timelineManager.loadMonthGroup({ year: 2024, month: 1 }), - timelineManager.loadMonthGroup({ year: 2024, month: 1 }), + timelineManager.loadSegment({ year: 2024, month: 1 }), + timelineManager.loadSegment({ year: 2024, month: 1 }), ]); expect(sdkMock.getTimeBucket).toBeCalledTimes(1); - await timelineManager.loadMonthGroup({ year: 2024, month: 1 }); + await timelineManager.loadSegment({ year: 2024, month: 1 }); expect(sdkMock.getTimeBucket).toBeCalledTimes(1); }); it('allows loading a canceled month', async () => { const month = getMonthGroupByDate(timelineManager, { year: 2024, month: 1 })!; - const loadPromise = timelineManager.loadMonthGroup({ year: 2024, month: 1 }); + const loadPromise = timelineManager.loadSegment({ year: 2024, month: 1 }); month.cancel(); await loadPromise; expect(month?.getAssets().length).toEqual(0); - await timelineManager.loadMonthGroup({ year: 2024, month: 1 }); + await timelineManager.loadSegment({ year: 2024, month: 1 }); expect(month!.getAssets().length).toEqual(3); }); }); @@ -477,7 +477,7 @@ describe('TimelineManager', () => { }); it('returns previous assetId', async () => { - await timelineManager.loadMonthGroup({ year: 2024, month: 1 }); + await timelineManager.loadSegment({ year: 2024, month: 1 }); const month = getMonthGroupByDate(timelineManager, { year: 2024, month: 1 }); const a = month!.getAssets()[0]; @@ -487,8 +487,8 @@ describe('TimelineManager', () => { }); it('returns previous assetId spanning multiple months', async () => { - await timelineManager.loadMonthGroup({ year: 2024, month: 2 }); - await timelineManager.loadMonthGroup({ year: 2024, month: 3 }); + await timelineManager.loadSegment({ year: 2024, month: 2 }); + await timelineManager.loadSegment({ year: 2024, month: 3 }); const month = getMonthGroupByDate(timelineManager, { year: 2024, month: 2 }); const previousMonth = getMonthGroupByDate(timelineManager, { year: 2024, month: 3 }); @@ -499,23 +499,23 @@ describe('TimelineManager', () => { }); it('loads previous month', async () => { - await timelineManager.loadMonthGroup({ year: 2024, month: 2 }); + await timelineManager.loadSegment({ year: 2024, month: 2 }); const month = getMonthGroupByDate(timelineManager, { year: 2024, month: 2 }); const previousMonth = getMonthGroupByDate(timelineManager, { year: 2024, month: 3 }); const a = month!.getFirstAsset(); const b = previousMonth!.getFirstAsset(); - const loadMonthGroupSpy = vi.spyOn(month!.loader!, 'execute'); + const loadSegmentSpy = vi.spyOn(month!.loader!, 'execute'); const previousMonthSpy = vi.spyOn(previousMonth!.loader!, 'execute'); const previous = await timelineManager.getLaterAsset(a); expect(previous).toEqual(b); - expect(loadMonthGroupSpy).toBeCalledTimes(0); + expect(loadSegmentSpy).toBeCalledTimes(0); expect(previousMonthSpy).toBeCalledTimes(0); }); it('skips removed assets', async () => { - await timelineManager.loadMonthGroup({ year: 2024, month: 1 }); - await timelineManager.loadMonthGroup({ year: 2024, month: 2 }); - await timelineManager.loadMonthGroup({ year: 2024, month: 3 }); + await timelineManager.loadSegment({ year: 2024, month: 1 }); + await timelineManager.loadSegment({ year: 2024, month: 2 }); + await timelineManager.loadSegment({ year: 2024, month: 3 }); const [assetOne, assetTwo, assetThree] = await getAssets(timelineManager); timelineManager.removeAssets([assetTwo.id]); @@ -523,7 +523,7 @@ describe('TimelineManager', () => { }); it('returns null when no more assets', async () => { - await timelineManager.loadMonthGroup({ year: 2024, month: 3 }); + await timelineManager.loadSegment({ year: 2024, month: 3 }); expect(await timelineManager.getLaterAsset(timelineManager.months[0].getFirstAsset())).toBeUndefined(); }); }); 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 172cd07a02..68bf740b76 100644 --- a/web/src/lib/managers/timeline-manager/timeline-manager.svelte.ts +++ b/web/src/lib/managers/timeline-manager/timeline-manager.svelte.ts @@ -198,7 +198,7 @@ export class TimelineManager { const direction = options?.direction ?? 'earlier'; let { startDayGroup, startAsset } = options ?? {}; for (const monthGroup of this.monthGroupIterator({ direction, startMonthGroup: options?.startMonthGroup })) { - await this.loadMonthGroup(monthGroup.yearMonth, { cancelable: false }); + await this.loadSegment(monthGroup.yearMonth, { cancelable: false }); yield* monthGroup.assetsIterator({ startDayGroup, startAsset, direction }); startDayGroup = startAsset = undefined; } @@ -387,7 +387,7 @@ export class TimelineManager { }; } - async loadMonthGroup(yearMonth: TimelineYearMonth, options?: { cancelable: boolean }): Promise { + async loadSegment(yearMonth: TimelineYearMonth, options?: { cancelable: boolean }): Promise { let cancelable = true; if (options) { cancelable = options.cancelable; @@ -442,7 +442,7 @@ export class TimelineManager { } async #loadMonthGroupAtTime(yearMonth: TimelineYearMonth, options?: { cancelable: boolean }) { - await this.loadMonthGroup(yearMonth, options); + await this.loadSegment(yearMonth, options); return getMonthGroupByDate(this, yearMonth); } @@ -454,7 +454,7 @@ export class TimelineManager { async getRandomMonthGroup() { const random = Math.floor(Math.random() * this.months.length); const month = this.months[random]; - await this.loadMonthGroup(month.yearMonth, { cancelable: false }); + await this.loadSegment(month.yearMonth, { cancelable: false }); return month; } @@ -527,7 +527,7 @@ export class TimelineManager { if (!monthGroup) { return; } - await this.loadMonthGroup(dateTime, { cancelable: false }); + await this.loadSegment(dateTime, { cancelable: false }); const asset = monthGroup.findClosest(dateTime); if (asset) { return asset; diff --git a/web/src/lib/utils/asset-utils.ts b/web/src/lib/utils/asset-utils.ts index 1e6295242a..b24e7782e4 100644 --- a/web/src/lib/utils/asset-utils.ts +++ b/web/src/lib/utils/asset-utils.ts @@ -513,7 +513,7 @@ export const selectAllAssets = async (timelineManager: TimelineManager, assetInt try { for (const monthGroup of timelineManager.months) { - await timelineManager.loadMonthGroup(monthGroup.yearMonth); + await timelineManager.loadSegment(monthGroup.yearMonth); if (!get(isSelectingAllAssets)) { assetInteraction.clearMultiselect();