diff --git a/web/src/lib/components/timeline/Timeline.svelte b/web/src/lib/components/timeline/Timeline.svelte
index ff8386aae9..f323235a13 100644
--- a/web/src/lib/components/timeline/Timeline.svelte
+++ b/web/src/lib/components/timeline/Timeline.svelte
@@ -2,14 +2,13 @@
import { afterNavigate, beforeNavigate } from '$app/navigation';
import { page } from '$app/stores';
import { resizeObserver, type OnResizeCallback } from '$lib/actions/resize-observer';
- import type { Action } from '$lib/components/asset-viewer/actions/action';
import Scrubber from '$lib/components/timeline/Scrubber.svelte';
+ import TimelineAssetViewer from '$lib/components/timeline/TimelineAssetViewer.svelte';
import TimelineKeyboardActions from '$lib/components/timeline/actions/TimelineKeyboardActions.svelte';
import { AssetAction } from '$lib/constants';
import HotModuleReload from '$lib/elements/HotModuleReload.svelte';
import Portal from '$lib/elements/Portal.svelte';
import Skeleton from '$lib/elements/Skeleton.svelte';
- import { authManager } from '$lib/managers/auth-manager.svelte';
import type { DayGroup } from '$lib/managers/timeline-manager/day-group.svelte';
import type { MonthGroup } from '$lib/managers/timeline-manager/month-group.svelte';
import { TimelineManager } from '$lib/managers/timeline-manager/timeline-manager.svelte';
@@ -19,10 +18,9 @@
import { assetViewingStore } from '$lib/stores/asset-viewing.store';
import { isSelectingAllAssets } from '$lib/stores/assets-store.svelte';
import { mobileDevice } from '$lib/stores/mobile-device.svelte';
- import { updateStackedAssetInTimeline, updateUnstackedAssetInTimeline } from '$lib/utils/actions';
import { navigate } from '$lib/utils/navigation';
- import { getTimes, toTimelineAsset, type ScrubberListener, type TimelineYearMonth } from '$lib/utils/timeline-util';
- import { getAssetInfo, type AlbumResponseDto, type PersonResponseDto } from '@immich/sdk';
+ import { getTimes, type ScrubberListener, type TimelineYearMonth } from '$lib/utils/timeline-util';
+ import { type AlbumResponseDto, type PersonResponseDto } from '@immich/sdk';
import { DateTime } from 'luxon';
import { onMount, type Snippet } from 'svelte';
import type { UpdatePayload } from 'vite';
@@ -89,7 +87,7 @@
onThumbnailClick,
}: Props = $props();
- let { isViewing: showAssetViewer, asset: viewingAsset, preloadAssets, gridScrollTarget, mutex } = assetViewingStore;
+ let { isViewing: showAssetViewer, asset: viewingAsset, gridScrollTarget } = assetViewingStore;
let element: HTMLElement | undefined = $state();
@@ -392,126 +390,6 @@
}
};
- const handlePrevious = async () => {
- const release = await mutex.acquire();
- const laterAsset = await timelineManager.getLaterAsset($viewingAsset);
-
- if (laterAsset) {
- const preloadAsset = await timelineManager.getLaterAsset(laterAsset);
- const asset = await getAssetInfo({ ...authManager.params, id: laterAsset.id });
- assetViewingStore.setAsset(asset, preloadAsset ? [preloadAsset] : []);
- await navigate({ targetRoute: 'current', assetId: laterAsset.id });
- }
-
- release();
- return !!laterAsset;
- };
-
- const handleNext = async () => {
- const release = await mutex.acquire();
- const earlierAsset = await timelineManager.getEarlierAsset($viewingAsset);
-
- if (earlierAsset) {
- const preloadAsset = await timelineManager.getEarlierAsset(earlierAsset);
- const asset = await getAssetInfo({ ...authManager.params, id: earlierAsset.id });
- assetViewingStore.setAsset(asset, preloadAsset ? [preloadAsset] : []);
- await navigate({ targetRoute: 'current', assetId: earlierAsset.id });
- }
-
- release();
- return !!earlierAsset;
- };
-
- const handleRandom = async () => {
- const randomAsset = await timelineManager.getRandomAsset();
-
- if (randomAsset) {
- const asset = await getAssetInfo({ ...authManager.params, id: randomAsset.id });
- assetViewingStore.setAsset(asset);
- await navigate({ targetRoute: 'current', assetId: randomAsset.id });
- return asset;
- }
- };
-
- const handleClose = async (asset: { id: string }) => {
- assetViewingStore.showAssetViewer(false);
- showSkeleton = true;
- $gridScrollTarget = { at: asset.id };
- await navigate({ targetRoute: 'current', assetId: null, assetGridRouteSearchParams: $gridScrollTarget });
- };
-
- const handlePreAction = async (action: Action) => {
- switch (action.type) {
- case removeAction:
- case AssetAction.TRASH:
- case AssetAction.RESTORE:
- case AssetAction.DELETE:
- case AssetAction.ARCHIVE:
- case AssetAction.SET_VISIBILITY_LOCKED:
- case AssetAction.SET_VISIBILITY_TIMELINE: {
- // find the next asset to show or close the viewer
- // eslint-disable-next-line @typescript-eslint/no-unused-expressions
- (await handleNext()) || (await handlePrevious()) || (await handleClose(action.asset));
-
- // delete after find the next one
- timelineManager.removeAssets([action.asset.id]);
- break;
- }
- }
- };
- const handleAction = (action: Action) => {
- switch (action.type) {
- case AssetAction.ARCHIVE:
- case AssetAction.UNARCHIVE:
- case AssetAction.FAVORITE:
- case AssetAction.UNFAVORITE: {
- timelineManager.updateAssets([action.asset]);
- break;
- }
-
- case AssetAction.ADD: {
- timelineManager.addAssets([action.asset]);
- break;
- }
-
- case AssetAction.UNSTACK: {
- updateUnstackedAssetInTimeline(timelineManager, action.assets);
- break;
- }
- case AssetAction.REMOVE_ASSET_FROM_STACK: {
- timelineManager.addAssets([toTimelineAsset(action.asset)]);
- if (action.stack) {
- //Have to unstack then restack assets in timeline in order to update the stack count in the timeline.
- updateUnstackedAssetInTimeline(
- timelineManager,
- action.stack.assets.map((asset) => toTimelineAsset(asset)),
- );
- updateStackedAssetInTimeline(timelineManager, {
- stack: action.stack,
- toDeleteIds: action.stack.assets
- .filter((asset) => asset.id !== action.stack?.primaryAssetId)
- .map((asset) => asset.id),
- });
- }
- break;
- }
- case AssetAction.SET_STACK_PRIMARY_ASSET: {
- //Have to unstack then restack assets in timeline in order for the currently removed new primary asset to be made visible.
- updateUnstackedAssetInTimeline(
- timelineManager,
- action.stack.assets.map((asset) => toTimelineAsset(asset)),
- );
- updateStackedAssetInTimeline(timelineManager, {
- stack: action.stack,
- toDeleteIds: action.stack.assets
- .filter((asset) => asset.id !== action.stack.primaryAssetId)
- .map((asset) => asset.id),
- });
- break;
- }
- }
- };
-
let lastAssetMouseEvent: TimelineAsset | null = $state(null);
let shiftKeyIsDown = $state(false);
@@ -808,22 +686,7 @@
{#if $showAssetViewer}
- {#await import('../asset-viewer/asset-viewer.svelte') then { default: AssetViewer }}
-
- {/await}
+
{/if}
diff --git a/web/src/lib/components/timeline/TimelineAssetViewer.svelte b/web/src/lib/components/timeline/TimelineAssetViewer.svelte
new file mode 100644
index 0000000000..17e3ed06f3
--- /dev/null
+++ b/web/src/lib/components/timeline/TimelineAssetViewer.svelte
@@ -0,0 +1,177 @@
+
+
+{#await import('../asset-viewer/asset-viewer.svelte') then { default: AssetViewer }}
+
+{/await}