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 943b5d12a8..849011bea4 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 @@ -1,9 +1,10 @@ import { sdkMock } from '$lib/__mocks__/sdk.mock'; +import { eventManager } from '$lib/managers/event-manager.svelte'; import { getMonthGroupByDate } from '$lib/managers/timeline-manager/internal/search-support.svelte'; import { AbortError } from '$lib/utils'; import { fromISODateTimeUTCToObject } from '$lib/utils/timeline-util'; import { AssetVisibility, type AssetResponseDto, type TimeBucketAssetResponseDto } from '@immich/sdk'; -import { timelineAssetFactory, toResponseDto } from '@test-data/factories/asset-factory'; +import { assetFactory, timelineAssetFactory, toResponseDto } from '@test-data/factories/asset-factory'; import { tick } from 'svelte'; import { TimelineManager } from './timeline-manager.svelte'; import type { TimelineAsset } from './types'; @@ -442,6 +443,48 @@ describe('TimelineManager', () => { }); }); + describe('AssetUpdate events', () => { + let timelineManager: TimelineManager; + + beforeEach(async () => { + timelineManager = new TimelineManager(); + sdkMock.getTimeBuckets.mockResolvedValue([]); + + await timelineManager.updateViewport({ width: 1588, height: 1000 }); + await timelineManager.updateOptions({ albumId: 'album-id' }); + }); + + afterEach(() => { + timelineManager.destroy(); + }); + + it('ignores unknown assets for album timelines', () => { + eventManager.emit('AssetUpdate', assetFactory.build()); + + expect(timelineManager.assetCount).toEqual(0); + expect(timelineManager.months).toHaveLength(0); + }); + + it('updates existing assets in the timeline', () => { + const existing = deriveLocalDateTimeFromFileCreatedAt(timelineAssetFactory.build({ isFavorite: false })); + + timelineManager.upsertAssets([existing]); + eventManager.emit( + 'AssetUpdate', + assetFactory.build({ + id: existing.id, + ownerId: existing.ownerId, + isFavorite: true, + isTrashed: existing.isTrashed, + visibility: existing.visibility, + }), + ); + + expect(timelineManager.assetCount).toEqual(1); + expect(timelineManager.months[0].getFirstAsset().isFavorite).toEqual(true); + }); + }); + describe('removeAssets', () => { let timelineManager: TimelineManager; 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 9ab884b059..b5c019d06a 100644 --- a/web/src/lib/managers/timeline-manager/timeline-manager.svelte.ts +++ b/web/src/lib/managers/timeline-manager/timeline-manager.svelte.ts @@ -113,7 +113,7 @@ export class TimelineManager extends VirtualScrollManager { this.#unsubscribes.push( eventManager.on({ - AssetUpdate: (asset: AssetResponseDto) => this.upsertAssets([toTimelineAsset(asset)]), + AssetUpdate: (asset: AssetResponseDto) => this.#updateAssets([toTimelineAsset(asset)]), }), ); }