diff --git a/web/src/lib/components/album-page/album-viewer.svelte b/web/src/lib/components/album-page/album-viewer.svelte
index 8c91d29a34..b8f2f5a8a7 100644
--- a/web/src/lib/components/album-page/album-viewer.svelte
+++ b/web/src/lib/components/album-page/album-viewer.svelte
@@ -18,10 +18,10 @@
import { onDestroy } from 'svelte';
import { t } from 'svelte-i18n';
import DownloadAction from '../photos-page/actions/download-action.svelte';
- import AssetGrid from '../photos-page/asset-grid.svelte';
import ControlAppBar from '../shared-components/control-app-bar.svelte';
import ImmichLogoSmallLink from '../shared-components/immich-logo-small-link.svelte';
import ThemeButton from '../shared-components/theme-button.svelte';
+ import AssetGrid from '../timeline-viewer/base-timeline.svelte';
import AlbumSummary from './album-summary.svelte';
interface Props {
diff --git a/web/src/lib/components/asset-viewer/actions/delete-action.svelte b/web/src/lib/components/asset-viewer/actions/delete-action.svelte
index 82b88127f6..25f439246e 100644
--- a/web/src/lib/components/asset-viewer/actions/delete-action.svelte
+++ b/web/src/lib/components/asset-viewer/actions/delete-action.svelte
@@ -1,21 +1,21 @@
id));
+ let isTrashEnabled = $derived($featureFlags.loaded && $featureFlags.trash);
+ let isEmpty = $derived(timelineManager.isInitialized && timelineManager.months.length === 0);
+ let idsSelectedAssets = $derived(assetInteraction.selectedAssets.map(({ id }) => id));
let isShortcutModalOpen = false;
const handleOpenShortcutModal = async () => {
diff --git a/web/src/lib/components/timeline-viewer/base-timeline.svelte b/web/src/lib/components/timeline-viewer/base-timeline.svelte
new file mode 100644
index 0000000000..4dc932dd80
--- /dev/null
+++ b/web/src/lib/components/timeline-viewer/base-timeline.svelte
@@ -0,0 +1,208 @@
+
+
+
+ {#snippet header(handleScrollTop)}
+ {#if timelineManager.months.length > 0}
+ onScrub({ ...args, handleScrollTop })}
+ bind:scrubberWidth
+ />
+ {/if}
+ {/snippet}
+
diff --git a/web/src/lib/components/timeline-viewer/timeline-viewer.svelte b/web/src/lib/components/timeline-viewer/timeline-viewer.svelte
index cfb29d1f88..51b8c437c1 100644
--- a/web/src/lib/components/timeline-viewer/timeline-viewer.svelte
+++ b/web/src/lib/components/timeline-viewer/timeline-viewer.svelte
@@ -2,11 +2,12 @@
import { afterNavigate, beforeNavigate } from '$app/navigation';
import { page } from '$app/stores';
import { resizeObserver, type OnResizeCallback } from '$lib/actions/resize-observer';
- import AssetGridActions from '$lib/components/photos-page/asset-grid-actions.svelte';
+ import AssetGridActions from '$lib/components/timeline-viewer/actions/timeline-keyboard-actions.svelte';
import Skeleton from '$lib/components/timeline-viewer/skeleton.svelte';
import TimelineAssetViewer from '$lib/components/timeline-viewer/timeline-asset-viewer.svelte';
import SelectableTimelineDay from '$lib/components/timeline-viewer/timeline-day/selectable-timeline-day.svelte';
import { AssetAction } from '$lib/constants';
+ 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';
import type { TimelineAsset } from '$lib/managers/timeline-manager/types';
@@ -20,6 +21,7 @@
import Portal from '../shared-components/portal/portal.svelte';
interface Props {
+ customLayout?: Snippet<[TimelineAsset]>;
isSelectionMode?: boolean;
singleSelect?: boolean;
/** `true` if this asset grid is responds to navigation events; if `true`, then look at the
@@ -40,6 +42,7 @@
album?: AlbumResponseDto | null;
person?: PersonResponseDto | null;
isShowDeleteConfirmation?: boolean;
+ onAssetOpen?: (dayGroup: DayGroup, asset: TimelineAsset, defaultAssetOpen: () => void) => void;
onSelect?: (asset: TimelineAsset) => void;
onEscape?: () => void;
header?: Snippet<[handleScrollTop: (top: number) => void]>;
@@ -49,6 +52,7 @@
}
let {
+ customLayout,
isSelectionMode = false,
singleSelect = false,
enableRouting,
@@ -61,6 +65,7 @@
album = null,
person = null,
isShowDeleteConfirmation = $bindable(false),
+ onAssetOpen,
onSelect = (asset: TimelineAsset) => void 0,
onEscape = () => {},
children,
@@ -317,6 +322,7 @@
style:width="100%"
>
void,
- ) => {
+ const handleOnAssetOpen = (dayGroup: DayGroup, asset: TimelineAsset, defaultAssetOpen: () => void) => {
if (hasGps(asset)) {
locationUpdated = true;
setTimeout(() => {
@@ -128,9 +118,9 @@
}, 1500);
location = { latitude: asset.latitude!, longitude: asset.longitude! };
void setQueryValue('at', asset.id);
- } else {
- onClick(timelineManager, dayGroup.getAssets(), dayGroup.groupTitle, asset);
+ return;
}
+ defaultAssetOpen();
};
@@ -193,7 +183,7 @@
removeAction={AssetAction.ARCHIVE}
onEscape={handleEscape}
withStacked
- onThumbnailClick={handleThumbnailClick}
+ onAssetOpen={handleOnAssetOpen}
>
{#snippet customLayout(asset: TimelineAsset)}
{#if hasGps(asset)}