diff --git a/web/src/lib/components/album-page/album-viewer.svelte b/web/src/lib/components/album-page/album-viewer.svelte index 71cd9de932..0866d38557 100644 --- a/web/src/lib/components/album-page/album-viewer.svelte +++ b/web/src/lib/components/album-page/album-viewer.svelte @@ -4,15 +4,16 @@ import AlbumMap from '$lib/components/album-page/album-map.svelte'; import SelectAllAssets from '$lib/components/photos-page/actions/select-all-assets.svelte'; import AssetSelectControlBar from '$lib/components/photos-page/asset-select-control-bar.svelte'; + import { TimelineManager } from '$lib/managers/timeline-manager/timeline-manager.svelte'; import { AssetInteraction } from '$lib/stores/asset-interaction.svelte'; import { assetViewingStore } from '$lib/stores/asset-viewing.store'; - import { AssetStore } from '$lib/managers/timeline-manager/asset-store.svelte'; import { dragAndDropFilesStore } from '$lib/stores/drag-and-drop-files.store'; import { featureFlags } from '$lib/stores/server-config.store'; import { handlePromiseError } from '$lib/utils'; import { cancelMultiselect, downloadAlbum } from '$lib/utils/asset-utils'; import { fileUploadHandler, openFileUploadDialog } from '$lib/utils/file-uploader'; import type { AlbumResponseDto, SharedLinkResponseDto, UserResponseDto } from '@immich/sdk'; + import { IconButton } from '@immich/ui'; import { mdiFileImagePlusOutline, mdiFolderDownloadOutline } from '@mdi/js'; import { onDestroy } from 'svelte'; import { t } from 'svelte-i18n'; @@ -22,7 +23,6 @@ import ImmichLogoSmallLink from '../shared-components/immich-logo-small-link.svelte'; import ThemeButton from '../shared-components/theme-button.svelte'; import AlbumSummary from './album-summary.svelte'; - import { IconButton } from '@immich/ui'; interface Props { sharedLink: SharedLinkResponseDto; @@ -35,9 +35,9 @@ let { isViewing: showAssetViewer } = assetViewingStore; - const assetStore = new AssetStore(); - $effect(() => void assetStore.updateOptions({ albumId: album.id, order: album.order })); - onDestroy(() => assetStore.destroy()); + const timelineManager = new TimelineManager(); + $effect(() => void timelineManager.updateOptions({ albumId: album.id, order: album.order })); + onDestroy(() => timelineManager.destroy()); const assetInteraction = new AssetInteraction(); @@ -61,7 +61,7 @@ />
- +

assetInteraction.clearMultiselect()} > - + {#if sharedLink.allowDownload} {/if} diff --git a/web/src/lib/components/photos-page/actions/archive-action.svelte b/web/src/lib/components/photos-page/actions/archive-action.svelte index e36038972f..150e7c201f 100644 --- a/web/src/lib/components/photos-page/actions/archive-action.svelte +++ b/web/src/lib/components/photos-page/actions/archive-action.svelte @@ -2,11 +2,11 @@ import type { OnArchive } from '$lib/utils/actions'; import { archiveAssets } from '$lib/utils/asset-utils'; import { AssetVisibility } from '@immich/sdk'; + import { IconButton } from '@immich/ui'; import { mdiArchiveArrowDownOutline, mdiArchiveArrowUpOutline, mdiTimerSand } from '@mdi/js'; import { t } from 'svelte-i18n'; import MenuOption from '../../shared-components/context-menu/menu-option.svelte'; import { getAssetControlContext } from '../asset-select-control-bar.svelte'; - import { IconButton } from '@immich/ui'; interface Props { onArchive?: OnArchive; diff --git a/web/src/lib/components/photos-page/actions/focus-actions.ts b/web/src/lib/components/photos-page/actions/focus-actions.ts index 3a75820cd8..f0f9e2e50c 100644 --- a/web/src/lib/components/photos-page/actions/focus-actions.ts +++ b/web/src/lib/components/photos-page/actions/focus-actions.ts @@ -1,4 +1,4 @@ -import { AssetStore } from '$lib/managers/timeline-manager/asset-store.svelte'; +import { TimelineManager } from '$lib/managers/timeline-manager/timeline-manager.svelte'; import type { TimelineAsset } from '$lib/managers/timeline-manager/types'; import { moveFocus } from '$lib/utils/focus-util'; import { InvocationTracker } from '$lib/utils/invocationTracker'; @@ -31,7 +31,7 @@ export const setFocusToAsset = (scrollToAsset: (asset: TimelineAsset) => boolean export const setFocusTo = async ( scrollToAsset: (asset: TimelineAsset) => boolean, - store: AssetStore, + store: TimelineManager, direction: 'earlier' | 'later', interval: 'day' | 'month' | 'year' | 'asset', ) => { diff --git a/web/src/lib/components/photos-page/actions/select-all-assets.svelte b/web/src/lib/components/photos-page/actions/select-all-assets.svelte index d8a5ab2fdf..883ec1d54e 100644 --- a/web/src/lib/components/photos-page/actions/select-all-assets.svelte +++ b/web/src/lib/components/photos-page/actions/select-all-assets.svelte @@ -1,6 +1,6 @@ -{#each filterIntersecting(bucket.dateGroups) as dateGroup, groupIndex (dateGroup.day)} - {@const absoluteWidth = dateGroup.left} +{#each filterIntersecting(monthGroup.dayGroups) as dayGroup, groupIndex (dayGroup.day)} + {@const absoluteWidth = dayGroup.left}
{ isMouseOverGroup = true; - assetMouseEventHandler(dateGroup.groupTitle, null); + assetMouseEventHandler(dayGroup.groupTitle, null); }} onmouseleave={() => { isMouseOverGroup = false; - assetMouseEventHandler(dateGroup.groupTitle, null); + assetMouseEventHandler(dayGroup.groupTitle, null); }} >
- {#if !singleSelect && ((hoveredDateGroup === dateGroup.groupTitle && isMouseOverGroup) || assetInteraction.selectedGroup.has(dateGroup.groupTitle))} + {#if !singleSelect && ((hoveredDayGroup === dayGroup.groupTitle && isMouseOverGroup) || assetInteraction.selectedGroup.has(dayGroup.groupTitle))}
handleSelectGroup(dateGroup.groupTitle, assetsSnapshot(dateGroup.getAssets()))} - onkeydown={() => handleSelectGroup(dateGroup.groupTitle, assetsSnapshot(dateGroup.getAssets()))} + onclick={() => handleSelectGroup(dayGroup.groupTitle, assetsSnapshot(dayGroup.getAssets()))} + onkeydown={() => handleSelectGroup(dayGroup.groupTitle, assetsSnapshot(dayGroup.getAssets()))} > - {#if assetInteraction.selectedGroup.has(dateGroup.groupTitle)} + {#if assetInteraction.selectedGroup.has(dayGroup.groupTitle)} {:else} @@ -150,8 +157,8 @@
{/if} - - {dateGroup.groupTitle} + + {dayGroup.groupTitle}
@@ -159,14 +166,14 @@
- {#each filterIntersecting(dateGroup.intersectingAssets) as intersectingAsset (intersectingAsset.id)} - {@const position = intersectingAsset.position!} - {@const asset = intersectingAsset.asset!} + {#each filterIntersecting(dayGroup.viewerAssets) as viewerAsset (viewerAsset.id)} + {@const position = viewerAsset.position!} + {@const asset = viewerAsset.asset!} - +
onClick(assetStore, dateGroup.getAssets(), dateGroup.groupTitle, asset)} - onSelect={(asset) => assetSelectHandler(assetStore, asset, dateGroup.getAssets(), dateGroup.groupTitle)} - onMouseEvent={() => assetMouseEventHandler(dateGroup.groupTitle, assetSnapshot(asset))} - selected={assetInteraction.hasSelectedAsset(asset.id) || dateGroup.bucket.store.albumAssets.has(asset.id)} + onClick={(asset) => onClick(timelineManager, dayGroup.getAssets(), dayGroup.groupTitle, asset)} + onSelect={(asset) => assetSelectHandler(timelineManager, asset, dayGroup.getAssets(), dayGroup.groupTitle)} + onMouseEvent={() => assetMouseEventHandler(dayGroup.groupTitle, assetSnapshot(asset))} + selected={assetInteraction.hasSelectedAsset(asset.id) || + dayGroup.monthGroup.timelineManager.albumAssets.has(asset.id)} selectionCandidate={assetInteraction.hasSelectionCandidate(asset.id)} - disabled={dateGroup.bucket.store.albumAssets.has(asset.id)} + disabled={dayGroup.monthGroup.timelineManager.albumAssets.has(asset.id)} thumbnailWidth={position.width} thumbnailHeight={position.height} /> diff --git a/web/src/lib/components/photos-page/asset-grid.svelte b/web/src/lib/components/photos-page/asset-grid.svelte index 1b96353d37..2dd9ef3ac7 100644 --- a/web/src/lib/components/photos-page/asset-grid.svelte +++ b/web/src/lib/components/photos-page/asset-grid.svelte @@ -15,18 +15,18 @@ import { albumMapViewManager } from '$lib/managers/album-view-map.manager.svelte'; import { authManager } from '$lib/managers/auth-manager.svelte'; import { modalManager } from '$lib/managers/modal-manager.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'; + import { assetsSnapshot } from '$lib/managers/timeline-manager/utils.svelte'; import ShortcutsModal from '$lib/modals/ShortcutsModal.svelte'; import type { AssetInteraction } from '$lib/stores/asset-interaction.svelte'; import { assetViewingStore } from '$lib/stores/asset-viewing.store'; import { isSelectingAllAssets } from '$lib/stores/assets-store.svelte'; - import { AssetStore } from '$lib/managers/timeline-manager/asset-store.svelte'; - import type { TimelineAsset } from '$lib/managers/timeline-manager/types'; - import { assetsSnapshot } from '$lib/managers/timeline-manager/utils.svelte'; import { mobileDevice } from '$lib/stores/mobile-device.svelte'; import { showDeleteModal } from '$lib/stores/preferences.store'; import { searchStore } from '$lib/stores/search.svelte'; import { featureFlags } from '$lib/stores/server-config.store'; - import type { AssetBucket } from '$lib/managers/timeline-manager/asset-bucket.svelte'; import { handlePromiseError } from '$lib/utils'; import { deleteAssets, updateStackedAssetInTimeline, updateUnstackedAssetInTimeline } from '$lib/utils/actions'; import { archiveAssets, cancelMultiselect, selectAllAssets, stackAssets } from '$lib/utils/asset-utils'; @@ -47,7 +47,7 @@ `AssetViewingStore.gridScrollTarget` and load and scroll to the asset specified, and additionally, update the page location/url with the asset as the asset-grid is scrolled */ enableRouting: boolean; - assetStore: AssetStore; + timelineManager: TimelineManager; assetInteraction: AssetInteraction; removeAction?: | AssetAction.UNARCHIVE @@ -72,7 +72,7 @@ isSelectionMode = false, singleSelect = false, enableRouting, - assetStore = $bindable(), + timelineManager = $bindable(), assetInteraction, removeAction = null, withStacked = false, @@ -94,8 +94,8 @@ let timelineElement: HTMLElement | undefined = $state(); let showSkeleton = $state(true); let isShowSelectDate = $state(false); - let scrubBucketPercent = $state(0); - let scrubBucket: TimelinePlainYearMonth | undefined = $state(); + let scrubberMonthPercent = $state(0); + let scrubberMonth: { year: number; month: number } | undefined = $state(undefined); let scrubOverallPercent: number = $state(0); let scrubberWidth = $state(0); @@ -116,7 +116,7 @@ rowHeight: 235, headerHeight: 48, }; - assetStore.setLayoutOptions(layoutOptions); + timelineManager.setLayoutOptions(layoutOptions); }); const scrollTo = (top: number) => { @@ -138,35 +138,35 @@ scrollTo(0); }; - const getAssetHeight = (assetId: string, bucket: AssetBucket) => { + 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 = bucket!.findAssetAbsolutePosition(assetId); + const height = monthGroup!.findAssetAbsolutePosition(assetId); - while (assetStore.scrollCompensation.bucket) { - handleScrollCompensation(assetStore.scrollCompensation); - assetStore.clearScrollCompensation(); + while (timelineManager.scrollCompensation.monthGroup) { + handleScrollCompensation(timelineManager.scrollCompensation); + timelineManager.clearScrollCompensation(); } return height; }; const scrollToAssetId = async (assetId: string) => { - const bucket = await assetStore.findBucketForAsset(assetId); - if (!bucket) { + const monthGroup = await timelineManager.findMonthGroupForAsset(assetId); + if (!monthGroup) { return false; } - const height = getAssetHeight(assetId, bucket); + const height = getAssetHeight(assetId, monthGroup); scrollTo(height); updateSlidingWindow(); return true; }; const scrollToAsset = (asset: TimelineAsset) => { - const bucket = assetStore.getBucketIndexByAssetId(asset.id); - if (!bucket) { + const monthGroup = timelineManager.getMonthGroupByAssetId(asset.id); + if (!monthGroup) { return false; } - const height = getAssetHeight(asset.id, bucket); + const height = getAssetHeight(asset.id, monthGroup); scrollTo(height); updateSlidingWindow(); return true; @@ -185,7 +185,7 @@ showSkeleton = false; }; - beforeNavigate(() => (assetStore.suspendTransitions = true)); + beforeNavigate(() => (timelineManager.suspendTransitions = true)); afterNavigate((nav) => { const { complete } = nav; @@ -224,7 +224,7 @@ import.meta.hot?.on('vite:beforeUpdate', (payload) => { const assetGridUpdate = payload.updates.some((update) => update.path.endsWith('asset-grid.svelte')); if (assetGridUpdate) { - assetStore.destroy(); + timelineManager.destroy(); } }); @@ -233,9 +233,9 @@ return () => void 0; }; - const updateIsScrolling = () => (assetStore.scrolling = true); + const updateIsScrolling = () => (timelineManager.scrolling = true); // note: don't throttle, debounch, or otherwise do this function async - it causes flicker - const updateSlidingWindow = () => assetStore.updateSlidingWindow(element?.scrollTop || 0); + const updateSlidingWindow = () => timelineManager.updateSlidingWindow(element?.scrollTop || 0); const handleScrollCompensation = ({ heightDelta, scrollTop }: { heightDelta?: number; scrollTop?: number }) => { if (heightDelta !== undefined) { @@ -245,12 +245,12 @@ } // Yes, updateSlideWindow() is called by the onScroll event triggered as a result of // the above calls. However, this delay is enough time to set the intersecting property - // of the bucket to false, then true, which causes the DOM nodes to be recreated, + // of the monthGroup to false, then true, which causes the DOM nodes to be recreated, // causing bad perf, and also, disrupting focus of those elements. updateSlidingWindow(); }; - const topSectionResizeObserver: OnResizeCallback = ({ height }) => (assetStore.topSectionHeight = height); + const topSectionResizeObserver: OnResizeCallback = ({ height }) => (timelineManager.topSectionHeight = height); onMount(() => { if (!enableRouting) { @@ -263,21 +263,23 @@ }); const getMaxScrollPercent = () => { - const totalHeight = assetStore.timelineHeight + bottomSectionHeight + assetStore.topSectionHeight; - return (totalHeight - assetStore.viewportHeight) / totalHeight; + const totalHeight = timelineManager.timelineHeight + bottomSectionHeight + timelineManager.topSectionHeight; + return (totalHeight - timelineManager.viewportHeight) / totalHeight; }; const getMaxScroll = () => { if (!element || !timelineElement) { return 0; } - return assetStore.topSectionHeight + bottomSectionHeight + (timelineElement.clientHeight - element.clientHeight); + return ( + timelineManager.topSectionHeight + bottomSectionHeight + (timelineElement.clientHeight - element.clientHeight) + ); }; - const scrollToBucketAndOffset = (bucket: AssetBucket, bucketScrollPercent: number) => { - const topOffset = bucket.top; + const scrollToMonthGroupAndOffset = (monthGroup: MonthGroup, monthGroupScrollPercent: number) => { + const topOffset = monthGroup.top; const maxScrollPercent = getMaxScrollPercent(); - const delta = bucket.bucketHeight * bucketScrollPercent; + const delta = monthGroup.height * monthGroupScrollPercent; const scrollToTop = (topOffset + delta) * maxScrollPercent; scrollTop(scrollToTop); @@ -285,23 +287,23 @@ // note: don't throttle, debounch, or otherwise make this function async - it causes flicker const onScrub: ScrubberListener = ( - bucketDate: { year: number; month: number } | undefined, - scrollPercent: number, - bucketScrollPercent: number, + scrubMonth: { year: number; month: number }, + overallScrollPercent: number, + scrubberMonthScrollPercent: number, ) => { - if (!bucketDate || assetStore.timelineHeight < assetStore.viewportHeight * 2) { + if (!scrubMonth || timelineManager.timelineHeight < timelineManager.viewportHeight * 2) { // edge case - scroll limited due to size of content, must adjust - use use the overall percent instead const maxScroll = getMaxScroll(); - const offset = maxScroll * scrollPercent; + const offset = maxScroll * overallScrollPercent; scrollTop(offset); } else { - const bucket = assetStore.buckets.find( - (bucket) => bucket.yearMonth.year === bucketDate.year && bucket.yearMonth.month === bucketDate.month, + const monthGroup = timelineManager.months.find( + ({ yearMonth: { year, month } }) => year === scrubMonth.year && month === scrubMonth.month, ); - if (!bucket) { + if (!monthGroup) { return; } - scrollToBucketAndOffset(bucket, bucketScrollPercent); + scrollToMonthGroupAndOffset(monthGroup, scrubberMonthScrollPercent); } }; @@ -313,19 +315,19 @@ return; } - if (assetStore.timelineHeight < assetStore.viewportHeight * 2) { + if (timelineManager.timelineHeight < timelineManager.viewportHeight * 2) { // edge case - scroll limited due to size of content, must adjust - use the overall percent instead const maxScroll = getMaxScroll(); scrubOverallPercent = Math.min(1, element.scrollTop / maxScroll); - scrubBucket = undefined; - scrubBucketPercent = 0; + scrubberMonth = undefined; + scrubberMonthPercent = 0; } else { let top = element.scrollTop; - if (top < assetStore.topSectionHeight) { + if (top < timelineManager.topSectionHeight) { // in the lead-in area - scrubBucket = undefined; - scrubBucketPercent = 0; + scrubberMonth = undefined; + scrubberMonthPercent = 0; const maxScroll = getMaxScroll(); scrubOverallPercent = Math.min(1, element.scrollTop / maxScroll); @@ -335,33 +337,33 @@ let maxScrollPercent = getMaxScrollPercent(); let found = false; - const bucketsLength = assetStore.buckets.length; - for (let i = -1; i < bucketsLength + 1; i++) { - let bucket: TimelinePlainYearMonth | undefined; - let bucketHeight = 0; + const monthsLength = timelineManager.months.length; + for (let i = -1; i < monthsLength + 1; i++) { + let monthGroup: TimelinePlainYearMonth | undefined; + let monthGroupHeight = 0; if (i === -1) { // lead-in - bucketHeight = assetStore.topSectionHeight; - } else if (i === bucketsLength) { + monthGroupHeight = timelineManager.topSectionHeight; + } else if (i === monthsLength) { // lead-out - bucketHeight = bottomSectionHeight; + monthGroupHeight = bottomSectionHeight; } else { - bucket = assetStore.buckets[i].yearMonth; - bucketHeight = assetStore.buckets[i].bucketHeight; + monthGroup = timelineManager.months[i].yearMonth; + monthGroupHeight = timelineManager.months[i].height; } - let next = top - bucketHeight * maxScrollPercent; + let next = top - monthGroupHeight * maxScrollPercent; // instead of checking for < 0, add a little wiggle room for subpixel resolution - if (next < -1 && bucket) { - scrubBucket = bucket; + if (next < -1 && monthGroup) { + scrubberMonth = monthGroup; // allowing next to be at least 1 may cause percent to go negative, so ensure positive percentage - scrubBucketPercent = Math.max(0, top / (bucketHeight * maxScrollPercent)); + scrubberMonthPercent = Math.max(0, top / (monthGroupHeight * maxScrollPercent)); // compensate for lost precision/rounding errors advance to the next bucket, if present - if (scrubBucketPercent > 0.9999 && i + 1 < bucketsLength - 1) { - scrubBucket = assetStore.buckets[i + 1].yearMonth; - scrubBucketPercent = 0; + if (scrubberMonthPercent > 0.9999 && i + 1 < monthsLength - 1) { + scrubberMonth = timelineManager.months[i + 1].yearMonth; + scrubberMonthPercent = 0; } found = true; @@ -371,8 +373,8 @@ } if (!found) { leadout = true; - scrubBucket = undefined; - scrubBucketPercent = 0; + scrubberMonth = undefined; + scrubberMonthPercent = 0; scrubOverallPercent = 1; } } @@ -382,9 +384,9 @@ isShowDeleteConfirmation = false; await deleteAssets( !(isTrashEnabled && !force), - (assetIds) => assetStore.removeAssets(assetIds), + (assetIds) => timelineManager.removeAssets(assetIds), assetInteraction.selectedAssets, - !isTrashEnabled || force ? undefined : (assets) => assetStore.addAssets(assets), + !isTrashEnabled || force ? undefined : (assets) => timelineManager.addAssets(assets), ); assetInteraction.clearMultiselect(); }; @@ -410,31 +412,32 @@ const onStackAssets = async () => { const result = await stackAssets(assetInteraction.selectedAssets); - updateStackedAssetInTimeline(assetStore, result); + updateStackedAssetInTimeline(timelineManager, result); onEscape(); }; const toggleArchive = async () => { - await archiveAssets( - assetInteraction.selectedAssets, - assetInteraction.isAllArchived ? AssetVisibility.Timeline : AssetVisibility.Archive, - ); - assetStore.updateAssets(assetInteraction.selectedAssets); + const visibility = assetInteraction.isAllArchived ? AssetVisibility.Timeline : AssetVisibility.Archive; + const ids = await archiveAssets(assetInteraction.selectedAssets, visibility); + timelineManager.updateAssetOperation(ids, (asset) => { + asset.visibility = visibility; + return { remove: false }; + }); deselectAllAssets(); }; const handleSelectAsset = (asset: TimelineAsset) => { - if (!assetStore.albumAssets.has(asset.id)) { + if (!timelineManager.albumAssets.has(asset.id)) { assetInteraction.selectAsset(asset); } }; const handlePrevious = async () => { - const laterAsset = await assetStore.getLaterAsset($viewingAsset); + const laterAsset = await timelineManager.getLaterAsset($viewingAsset); if (laterAsset) { - const preloadAsset = await assetStore.getLaterAsset(laterAsset); + const preloadAsset = await timelineManager.getLaterAsset(laterAsset); const asset = await getAssetInfo({ id: laterAsset.id, key: authManager.key }); assetViewingStore.setAsset(asset, preloadAsset ? [preloadAsset] : []); await navigate({ targetRoute: 'current', assetId: laterAsset.id }); @@ -444,9 +447,9 @@ }; const handleNext = async () => { - const earlierAsset = await assetStore.getEarlierAsset($viewingAsset); + const earlierAsset = await timelineManager.getEarlierAsset($viewingAsset); if (earlierAsset) { - const preloadAsset = await assetStore.getEarlierAsset(earlierAsset); + const preloadAsset = await timelineManager.getEarlierAsset(earlierAsset); const asset = await getAssetInfo({ id: earlierAsset.id, key: authManager.key }); assetViewingStore.setAsset(asset, preloadAsset ? [preloadAsset] : []); await navigate({ targetRoute: 'current', assetId: earlierAsset.id }); @@ -456,7 +459,7 @@ }; const handleRandom = async () => { - const randomAsset = await assetStore.getRandomAsset(); + const randomAsset = await timelineManager.getRandomAsset(); if (randomAsset) { const asset = await getAssetInfo({ id: randomAsset.id, key: authManager.key }); @@ -487,7 +490,7 @@ (await handleNext()) || (await handlePrevious()) || (await handleClose(action.asset)); // delete after find the next one - assetStore.removeAssets([action.asset.id]); + timelineManager.removeAssets([action.asset.id]); break; } } @@ -498,26 +501,26 @@ case AssetAction.UNARCHIVE: case AssetAction.FAVORITE: case AssetAction.UNFAVORITE: { - assetStore.updateAssets([action.asset]); + timelineManager.updateAssets([action.asset]); break; } case AssetAction.ADD: { - assetStore.addAssets([action.asset]); + timelineManager.addAssets([action.asset]); break; } case AssetAction.UNSTACK: { - updateUnstackedAssetInTimeline(assetStore, action.assets); + updateUnstackedAssetInTimeline(timelineManager, action.assets); 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( - assetStore, + timelineManager, action.stack.assets.map((asset) => toTimelineAsset(asset)), ); - updateStackedAssetInTimeline(assetStore, { + updateStackedAssetInTimeline(timelineManager, { stack: action.stack, toDeleteIds: action.stack.assets .filter((asset) => asset.id !== action.stack.primaryAssetId) @@ -565,7 +568,7 @@ lastAssetMouseEvent = asset; }; - const handleGroupSelect = (assetStore: AssetStore, group: string, assets: TimelineAsset[]) => { + const handleGroupSelect = (timelineManager: TimelineManager, group: string, assets: TimelineAsset[]) => { if (assetInteraction.selectedGroup.has(group)) { assetInteraction.removeGroupFromMultiselectGroup(group); for (const asset of assets) { @@ -578,7 +581,7 @@ } } - if (assetStore.count == assetInteraction.selectedAssets.length) { + if (timelineManager.assetCount == assetInteraction.selectedAssets.length) { isSelectingAllAssets.set(true); } else { isSelectingAllAssets.set(false); @@ -615,8 +618,8 @@ assetInteraction.clearAssetSelectionCandidates(); if (assetInteraction.assetSelectionStart && rangeSelection) { - let startBucket = assetStore.getBucketIndexByAssetId(assetInteraction.assetSelectionStart.id); - let endBucket = assetStore.getBucketIndexByAssetId(asset.id); + let startBucket = timelineManager.getMonthGroupByAssetId(assetInteraction.assetSelectionStart.id); + let endBucket = timelineManager.getMonthGroupByAssetId(asset.id); if (startBucket === null || endBucket === null) { return; @@ -624,13 +627,13 @@ // Select/deselect assets in range (start,end) let started = false; - for (const bucket of assetStore.buckets) { - if (bucket === endBucket) { + for (const monthGroup of timelineManager.months) { + if (monthGroup === endBucket) { break; } if (started) { - await assetStore.loadBucket(bucket.yearMonth); - for (const asset of bucket.assetsIterator()) { + await timelineManager.loadMonthGroup(monthGroup.yearMonth); + for (const asset of monthGroup.assetsIterator()) { if (deselect) { assetInteraction.removeAssetFromMultiselectGroup(asset.id); } else { @@ -638,29 +641,29 @@ } } } - if (bucket === startBucket) { + if (monthGroup === startBucket) { started = true; } } // Update date group selection in range [start,end] started = false; - for (const bucket of assetStore.buckets) { - if (bucket === startBucket) { + for (const monthGroup of timelineManager.months) { + if (monthGroup === startBucket) { started = true; } if (started) { - // Split bucket into date groups and check each group - for (const dateGroup of bucket.dateGroups) { - const dateGroupTitle = dateGroup.groupTitle; - if (dateGroup.getAssets().every((a) => assetInteraction.hasSelectedAsset(a.id))) { - assetInteraction.addGroupToMultiselectGroup(dateGroupTitle); + // Split month group into day groups and check each group + for (const dayGroup of monthGroup.dayGroups) { + const dayGroupTitle = dayGroup.groupTitle; + if (dayGroup.getAssets().every((a) => assetInteraction.hasSelectedAsset(a.id))) { + assetInteraction.addGroupToMultiselectGroup(dayGroupTitle); } else { - assetInteraction.removeGroupFromMultiselectGroup(dateGroupTitle); + assetInteraction.removeGroupFromMultiselectGroup(dayGroupTitle); } } } - if (bucket === endBucket) { + if (monthGroup === endBucket) { break; } } @@ -679,7 +682,7 @@ return; } - const assets = assetsSnapshot(await assetStore.retrieveRange(startAsset, endAsset)); + const assets = assetsSnapshot(await timelineManager.retrieveRange(startAsset, endAsset)); assetInteraction.setAssetSelectionCandidates(assets); }; @@ -690,7 +693,7 @@ }; let isTrashEnabled = $derived($featureFlags.loaded && $featureFlags.trash); - let isEmpty = $derived(assetStore.isInitialized && assetStore.buckets.length === 0); + let isEmpty = $derived(timelineManager.isInitialized && timelineManager.months.length === 0); let idsSelectedAssets = $derived(assetInteraction.selectedAssets.map(({ id }) => id)); let isShortcutModalOpen = false; @@ -710,7 +713,7 @@ } }); - const setFocusTo = setFocusToInit.bind(undefined, scrollToAsset, assetStore); + const setFocusTo = setFocusToInit.bind(undefined, scrollToAsset, timelineManager); const setFocusAsset = setFocusAssetInit.bind(undefined, scrollToAsset); let shortcutList = $derived( @@ -723,7 +726,7 @@ { shortcut: { key: 'Escape' }, onShortcut: onEscape }, { shortcut: { key: '?', shift: true }, onShortcut: handleOpenShortcutModal }, { shortcut: { key: '/' }, onShortcut: () => goto(AppRoute.EXPLORE) }, - { shortcut: { key: 'A', ctrl: true }, onShortcut: () => selectAllAssets(assetStore, assetInteraction) }, + { shortcut: { key: 'A', ctrl: true }, onShortcut: () => selectAllAssets(timelineManager, assetInteraction) }, { shortcut: { key: 'ArrowRight' }, onShortcut: () => setFocusTo('earlier', 'asset') }, { shortcut: { key: 'ArrowLeft' }, onShortcut: () => setFocusTo('later', 'asset') }, { shortcut: { key: 'D' }, onShortcut: () => setFocusTo('earlier', 'day') }, @@ -785,7 +788,9 @@ timezoneInput={false} onConfirm={async (dateString: string) => { isShowSelectDate = false; - const asset = await assetStore.getClosestAssetToDate((DateTime.fromISO(dateString) as DateTime).toObject()); + const asset = await timelineManager.getClosestAssetToDate( + (DateTime.fromISO(dateString) as DateTime).toObject(), + ); if (asset) { setFocusAsset(asset); } @@ -794,16 +799,16 @@ /> {/if} -{#if assetStore.buckets.length > 0} +{#if timelineManager.months.length > 0} { @@ -824,14 +829,14 @@ /> {/if} - +
((assetStore.viewportWidth = v), updateSlidingWindow())} + bind:clientHeight={timelineManager.viewportHeight} + bind:clientWidth={null, (v) => ((timelineManager.viewportWidth = v), updateSlidingWindow())} bind:this={element} onscroll={() => (handleTimelineScroll(), updateSlidingWindow(), updateIsScrolling())} > @@ -839,7 +844,7 @@ bind:this={timelineElement} id="virtual-timeline" class:invisible={showSkeleton} - style:height={assetStore.timelineHeight + 'px'} + style:height={timelineManager.timelineHeight + 'px'} >
- {#each assetStore.buckets as bucket (bucket.viewId)} - {@const display = bucket.intersecting} - {@const absoluteHeight = bucket.top} + {#each timelineManager.months as monthGroup (monthGroup.viewId)} + {@const display = monthGroup.intersecting} + {@const absoluteHeight = monthGroup.top} - {#if !bucket.isLoaded} + {#if !monthGroup.isLoaded}
- +
{:else if display}
handleGroupSelect(assetStore, title, assets)} + {monthGroup} + onSelect={({ title, assets }) => handleGroupSelect(timelineManager, title, assets)} onSelectAssetCandidates={handleSelectAssetCandidates} onSelectAssets={handleSelectAssets} onScrollCompensation={handleScrollCompensation} @@ -898,7 +906,7 @@ style:position="absolute" style:left="0" style:right="0" - style:transform={`translate3d(0,${assetStore.timelineHeight}px,0)`} + style:transform={`translate3d(0,${timelineManager.timelineHeight}px,0)`} >
@@ -932,7 +940,7 @@ scrollbar-width: none; } - .bucket { + .month-group { contain: layout size paint; transform-style: flat; backface-visibility: hidden; diff --git a/web/src/lib/components/shared-components/scrubber/scrubber.svelte b/web/src/lib/components/shared-components/scrubber/scrubber.svelte index 93cfa13521..c65dbc258b 100644 --- a/web/src/lib/components/shared-components/scrubber/scrubber.svelte +++ b/web/src/lib/components/shared-components/scrubber/scrubber.svelte @@ -1,7 +1,7 @@ @@ -49,7 +49,7 @@ - assetStore.updateAssetOperation(ids, (asset) => { + timelineManager.updateAssetOperation(ids, (asset) => { asset.visibility = visibility; return { remove: false }; })} /> - + @@ -82,7 +82,7 @@ - assetStore.updateAssetOperation(ids, (asset) => { + timelineManager.updateAssetOperation(ids, (asset) => { asset.isFavorite = isFavorite; return { remove: false }; })} @@ -90,7 +90,7 @@ - assetStore.removeAssets(assetIds)} /> + timelineManager.removeAssets(assetIds)} /> {/if} diff --git a/web/src/routes/(user)/favorites/[[photos=photos]]/[[assetId=id]]/+page.svelte b/web/src/routes/(user)/favorites/[[photos=photos]]/[[assetId=id]]/+page.svelte index fe42d079f8..ae24a82da7 100644 --- a/web/src/routes/(user)/favorites/[[photos=photos]]/[[assetId=id]]/+page.svelte +++ b/web/src/routes/(user)/favorites/[[photos=photos]]/[[assetId=id]]/+page.svelte @@ -17,8 +17,8 @@ import ButtonContextMenu from '$lib/components/shared-components/context-menu/button-context-menu.svelte'; import EmptyPlaceholder from '$lib/components/shared-components/empty-placeholder.svelte'; import { AssetAction } from '$lib/constants'; + import { TimelineManager } from '$lib/managers/timeline-manager/timeline-manager.svelte'; import { AssetInteraction } from '$lib/stores/asset-interaction.svelte'; - import { AssetStore } from '$lib/managers/timeline-manager/asset-store.svelte'; import { preferences } from '$lib/stores/user.store'; import { mdiDotsVertical, mdiPlus } from '@mdi/js'; import { onDestroy } from 'svelte'; @@ -31,9 +31,9 @@ let { data }: Props = $props(); - const assetStore = new AssetStore(); - void assetStore.updateOptions({ isFavorite: true, withStacked: true }); - onDestroy(() => assetStore.destroy()); + const timelineManager = new TimelineManager(); + void timelineManager.updateOptions({ isFavorite: true, withStacked: true }); + onDestroy(() => timelineManager.destroy()); const assetInteraction = new AssetInteraction(); @@ -45,7 +45,7 @@ }; const handleSetVisibility = (assetIds: string[]) => { - assetStore.removeAssets(assetIds); + timelineManager.removeAssets(assetIds); assetInteraction.clearMultiselect(); }; @@ -54,7 +54,7 @@ assetInteraction.clearMultiselect()} > - assetStore.removeAssets(assetIds)} /> + timelineManager.removeAssets(assetIds)} /> - + @@ -86,7 +86,7 @@ assetStore.removeAssets(assetIds)} + onArchive={(assetIds) => timelineManager.removeAssets(assetIds)} /> {#if $preferences.tags.enabled} @@ -94,8 +94,8 @@ assetStore.removeAssets(assetIds)} - onUndoDelete={(assets) => assetStore.addAssets(assets)} + onAssetDelete={(assetIds) => timelineManager.removeAssets(assetIds)} + onUndoDelete={(assets) => timelineManager.addAssets(assets)} /> diff --git a/web/src/routes/(user)/locked/[[photos=photos]]/[[assetId=id]]/+page.svelte b/web/src/routes/(user)/locked/[[photos=photos]]/[[assetId=id]]/+page.svelte index e1a80ab95f..733e93db71 100644 --- a/web/src/routes/(user)/locked/[[photos=photos]]/[[assetId=id]]/+page.svelte +++ b/web/src/routes/(user)/locked/[[photos=photos]]/[[assetId=id]]/+page.svelte @@ -12,8 +12,8 @@ import ButtonContextMenu from '$lib/components/shared-components/context-menu/button-context-menu.svelte'; import EmptyPlaceholder from '$lib/components/shared-components/empty-placeholder.svelte'; import { AppRoute, AssetAction } from '$lib/constants'; + import { TimelineManager } from '$lib/managers/timeline-manager/timeline-manager.svelte'; import { AssetInteraction } from '$lib/stores/asset-interaction.svelte'; - import { AssetStore } from '$lib/managers/timeline-manager/asset-store.svelte'; import { AssetVisibility, lockAuthSession } from '@immich/sdk'; import { Button } from '@immich/ui'; import { mdiDotsVertical, mdiLockOutline } from '@mdi/js'; @@ -27,9 +27,9 @@ let { data }: Props = $props(); - const assetStore = new AssetStore(); - void assetStore.updateOptions({ visibility: AssetVisibility.Locked }); - onDestroy(() => assetStore.destroy()); + const timelineManager = new TimelineManager(); + void timelineManager.updateOptions({ visibility: AssetVisibility.Locked }); + onDestroy(() => timelineManager.destroy()); const assetInteraction = new AssetInteraction(); @@ -42,7 +42,7 @@ const handleMoveOffLockedFolder = (assetIds: string[]) => { assetInteraction.clearMultiselect(); - assetStore.removeAssets(assetIds); + timelineManager.removeAssets(assetIds); }; const handleLock = async () => { @@ -60,7 +60,7 @@ assetInteraction.clearMultiselect()} > - + - assetStore.removeAssets(assetIds)} /> + timelineManager.removeAssets(assetIds)} /> {/if} diff --git a/web/src/routes/(user)/partners/[userId]/[[photos=photos]]/[[assetId=id]]/+page.svelte b/web/src/routes/(user)/partners/[userId]/[[photos=photos]]/[[assetId=id]]/+page.svelte index 16cf6ffceb..50d792c12b 100644 --- a/web/src/routes/(user)/partners/[userId]/[[photos=photos]]/[[assetId=id]]/+page.svelte +++ b/web/src/routes/(user)/partners/[userId]/[[photos=photos]]/[[assetId=id]]/+page.svelte @@ -8,8 +8,8 @@ import ButtonContextMenu from '$lib/components/shared-components/context-menu/button-context-menu.svelte'; import ControlAppBar from '$lib/components/shared-components/control-app-bar.svelte'; import { AppRoute } from '$lib/constants'; + import { TimelineManager } from '$lib/managers/timeline-manager/timeline-manager.svelte'; import { AssetInteraction } from '$lib/stores/asset-interaction.svelte'; - import { AssetStore } from '$lib/managers/timeline-manager/asset-store.svelte'; import { AssetVisibility } from '@immich/sdk'; import { mdiArrowLeft, mdiPlus } from '@mdi/js'; import { onDestroy } from 'svelte'; @@ -22,16 +22,16 @@ let { data }: Props = $props(); - const assetStore = new AssetStore(); + const timelineManager = new TimelineManager(); $effect( () => - void assetStore.updateOptions({ + void timelineManager.updateOptions({ userId: data.partner.id, visibility: AssetVisibility.Timeline, withStacked: true, }), ); - onDestroy(() => assetStore.destroy()); + onDestroy(() => timelineManager.destroy()); const assetInteraction = new AssetInteraction(); const handleEscape = () => { @@ -43,7 +43,7 @@
- + {#if assetInteraction.selectionActive} void assetStore.updateOptions({ visibility: AssetVisibility.Timeline, personId: data.person.id })); - onDestroy(() => assetStore.destroy()); + const timelineManager = new TimelineManager(); + $effect(() => void timelineManager.updateOptions({ visibility: AssetVisibility.Timeline, personId: data.person.id })); + onDestroy(() => timelineManager.destroy()); const assetInteraction = new AssetInteraction(); @@ -152,7 +152,7 @@ }); const handleUnmerge = () => { - assetStore.removeAssets(assetInteraction.selectedAssets.map((a) => a.id)); + timelineManager.removeAssets(assetInteraction.selectedAssets.map((a) => a.id)); assetInteraction.clearMultiselect(); viewMode = PersonPageViewMode.VIEW_ASSETS; }; @@ -348,12 +348,12 @@ }; const handleDeleteAssets = async (assetIds: string[]) => { - assetStore.removeAssets(assetIds); + timelineManager.removeAssets(assetIds); await updateAssetCount(); }; const handleUndoDeleteAssets = async (assets: TimelineAsset[]) => { - assetStore.addAssets(assets); + timelineManager.addAssets(assets); await updateAssetCount(); }; @@ -368,7 +368,7 @@ }); const handleSetVisibility = (assetIds: string[]) => { - assetStore.removeAssets(assetIds); + timelineManager.removeAssets(assetIds); assetInteraction.clearMultiselect(); }; @@ -386,7 +386,7 @@ assetInteraction.clearMultiselect()} > - + @@ -514,7 +514,7 @@ - assetStore.updateAssetOperation(ids, (asset) => { + timelineManager.updateAssetOperation(ids, (asset) => { asset.isFavorite = isFavorite; return { remove: false }; })} @@ -532,7 +532,7 @@ assetStore.removeAssets(assetIds)} + onArchive={(assetIds) => timelineManager.removeAssets(assetIds)} /> {#if $preferences.tags.enabled && assetInteraction.isAllUserOwned} diff --git a/web/src/routes/(user)/photos/[[assetId=id]]/+page.svelte b/web/src/routes/(user)/photos/[[assetId=id]]/+page.svelte index 49b6790756..0098667873 100644 --- a/web/src/routes/(user)/photos/[[assetId=id]]/+page.svelte +++ b/web/src/routes/(user)/photos/[[assetId=id]]/+page.svelte @@ -22,9 +22,9 @@ import ButtonContextMenu from '$lib/components/shared-components/context-menu/button-context-menu.svelte'; import EmptyPlaceholder from '$lib/components/shared-components/empty-placeholder.svelte'; import { AssetAction } from '$lib/constants'; + import { TimelineManager } from '$lib/managers/timeline-manager/timeline-manager.svelte'; import { AssetInteraction } from '$lib/stores/asset-interaction.svelte'; import { assetViewingStore } from '$lib/stores/asset-viewing.store'; - import { AssetStore } from '$lib/managers/timeline-manager/asset-store.svelte'; import { isFaceEditMode } from '$lib/stores/face-edit.svelte'; import { preferences, user } from '$lib/stores/user.store'; import { @@ -41,9 +41,9 @@ import { t } from 'svelte-i18n'; let { isViewing: showAssetViewer } = assetViewingStore; - const assetStore = new AssetStore(); - void assetStore.updateOptions({ visibility: AssetVisibility.Timeline, withStacked: true, withPartners: true }); - onDestroy(() => assetStore.destroy()); + const timelineManager = new TimelineManager(); + void timelineManager.updateOptions({ visibility: AssetVisibility.Timeline, withStacked: true, withPartners: true }); + onDestroy(() => timelineManager.destroy()); const assetInteraction = new AssetInteraction(); @@ -69,17 +69,17 @@ }; const handleLink: OnLink = ({ still, motion }) => { - assetStore.removeAssets([motion.id]); - assetStore.updateAssets([still]); + timelineManager.removeAssets([motion.id]); + timelineManager.updateAssets([still]); }; const handleUnlink: OnUnlink = ({ still, motion }) => { - assetStore.addAssets([motion]); - assetStore.updateAssets([still]); + timelineManager.addAssets([motion]); + timelineManager.updateAssets([still]); }; const handleSetVisibility = (assetIds: string[]) => { - assetStore.removeAssets(assetIds); + timelineManager.removeAssets(assetIds); assetInteraction.clearMultiselect(); }; @@ -91,7 +91,7 @@ assetInteraction.clearMultiselect()} > - + @@ -121,7 +121,7 @@ - assetStore.updateAssetOperation(ids, (asset) => { + timelineManager.updateAssetOperation(ids, (asset) => { asset.isFavorite = isFavorite; return { remove: false }; })} @@ -131,8 +131,8 @@ {#if assetInteraction.selectedAssets.length > 1 || isAssetStackSelected} updateStackedAssetInTimeline(assetStore, result)} - onUnstack={(assets) => updateUnstackedAssetInTimeline(assetStore, assets)} + onStack={(result) => updateStackedAssetInTimeline(timelineManager, result)} + onUnstack={(assets) => updateUnstackedAssetInTimeline(timelineManager, assets)} /> {/if} {#if isLinkActionAvailable} @@ -146,14 +146,14 @@ - assetStore.removeAssets(assetIds)} /> + timelineManager.removeAssets(assetIds)} /> {#if $preferences.tags.enabled} {/if} assetStore.removeAssets(assetIds)} - onUndoDelete={(assets) => assetStore.addAssets(assets)} + onAssetDelete={(assetIds) => timelineManager.removeAssets(assetIds)} + onUndoDelete={(assets) => timelineManager.addAssets(assets)} />
diff --git a/web/src/routes/(user)/search/[[photos=photos]]/[[assetId=id]]/+page.svelte b/web/src/routes/(user)/search/[[photos=photos]]/[[assetId=id]]/+page.svelte index f3c90ee4b0..092eb3b0d4 100644 --- a/web/src/routes/(user)/search/[[photos=photos]]/[[assetId=id]]/+page.svelte +++ b/web/src/routes/(user)/search/[[photos=photos]]/[[assetId=id]]/+page.svelte @@ -23,10 +23,10 @@ import LoadingSpinner from '$lib/components/shared-components/loading-spinner.svelte'; import SearchBar from '$lib/components/shared-components/search-bar/search-bar.svelte'; import { AppRoute, QueryParameter } from '$lib/constants'; + import { TimelineManager } from '$lib/managers/timeline-manager/timeline-manager.svelte'; + import type { TimelineAsset, Viewport } from '$lib/managers/timeline-manager/types'; import { AssetInteraction } from '$lib/stores/asset-interaction.svelte'; import { assetViewingStore } from '$lib/stores/asset-viewing.store'; - import { AssetStore } from '$lib/managers/timeline-manager/asset-store.svelte'; - import type { TimelineAsset, Viewport } from '$lib/managers/timeline-manager/types'; import { lang, locale } from '$lib/stores/preferences.store'; import { featureFlags } from '$lib/stores/server-config.store'; import { preferences } from '$lib/stores/user.store'; @@ -81,7 +81,7 @@ }); }); - let assetStore = new AssetStore(); + let timelineManager = new TimelineManager(); const onEscape = () => { if ($showAssetViewer) { @@ -131,7 +131,7 @@ }; const handleSetVisibility = (assetIds: string[]) => { - assetStore.removeAssets(assetIds); + timelineManager.removeAssets(assetIds); assetInteraction.clearMultiselect(); onAssetDelete(assetIds); }; diff --git a/web/src/routes/(user)/tags/[[photos=photos]]/[[assetId=id]]/+page.svelte b/web/src/routes/(user)/tags/[[photos=photos]]/[[assetId=id]]/+page.svelte index e344c448b0..27c42076ca 100644 --- a/web/src/routes/(user)/tags/[[photos=photos]]/[[assetId=id]]/+page.svelte +++ b/web/src/routes/(user)/tags/[[photos=photos]]/[[assetId=id]]/+page.svelte @@ -14,7 +14,7 @@ import Sidebar from '$lib/components/sidebar/sidebar.svelte'; import { AppRoute, AssetAction, QueryParameter, SettingInputFieldType } from '$lib/constants'; import { modalManager } from '$lib/managers/modal-manager.svelte'; - import { AssetStore } from '$lib/managers/timeline-manager/asset-store.svelte'; + import { TimelineManager } from '$lib/managers/timeline-manager/timeline-manager.svelte'; import { AssetInteraction } from '$lib/stores/asset-interaction.svelte'; import { joinPaths, TreeNode } from '$lib/utils/tree-utils'; import { deleteTag, getAllTags, updateTag, upsertTags, type TagResponseDto } from '@immich/sdk'; @@ -32,9 +32,9 @@ const assetInteraction = new AssetInteraction(); - const assetStore = new AssetStore(); - $effect(() => void assetStore.updateOptions({ deferInit: !tag, tagId: tag.id })); - onDestroy(() => assetStore.destroy()); + const timelineManager = new TimelineManager(); + $effect(() => void timelineManager.updateOptions({ deferInit: !tag, tagId: tag?.id })); + onDestroy(() => timelineManager.destroy()); let tags = $derived(data.tags); const tree = $derived(TreeNode.fromTags(tags)); @@ -157,7 +157,7 @@
{#if tag.hasAssets} - + {#snippet empty()} {/snippet} diff --git a/web/src/routes/(user)/trash/[[photos=photos]]/[[assetId=id]]/+page.svelte b/web/src/routes/(user)/trash/[[photos=photos]]/[[assetId=id]]/+page.svelte index 37c1a5b46c..bae1786891 100644 --- a/web/src/routes/(user)/trash/[[photos=photos]]/[[assetId=id]]/+page.svelte +++ b/web/src/routes/(user)/trash/[[photos=photos]]/[[assetId=id]]/+page.svelte @@ -14,8 +14,8 @@ } from '$lib/components/shared-components/notification/notification'; import { AppRoute } from '$lib/constants'; import { modalManager } from '$lib/managers/modal-manager.svelte'; + import { TimelineManager } from '$lib/managers/timeline-manager/timeline-manager.svelte'; import { AssetInteraction } from '$lib/stores/asset-interaction.svelte'; - import { AssetStore } from '$lib/managers/timeline-manager/asset-store.svelte'; import { featureFlags, serverConfig } from '$lib/stores/server-config.store'; import { handlePromiseError } from '$lib/utils'; import { handleError } from '$lib/utils/handle-error'; @@ -36,9 +36,9 @@ handlePromiseError(goto(AppRoute.PHOTOS)); } - const assetStore = new AssetStore(); - void assetStore.updateOptions({ isTrashed: true }); - onDestroy(() => assetStore.destroy()); + const timelineManager = new TimelineManager(); + void timelineManager.updateOptions({ isTrashed: true }); + onDestroy(() => timelineManager.destroy()); const assetInteraction = new AssetInteraction(); @@ -75,8 +75,8 @@ // reset asset grid (TODO fix in asset store that it should reset when it is empty) // note - this is still a problem, but updateOptions with the same value will not // do anything, so need to flip it for it to reload/reinit - // await assetStore.updateOptions({ deferInit: true, isTrashed: true }); - // await assetStore.updateOptions({ deferInit: false, isTrashed: true }); + // await timelineManager.updateOptions({ deferInit: true, isTrashed: true }); + // await timelineManager.updateOptions({ deferInit: false, isTrashed: true }); } catch (error) { handleError(error, $t('errors.unable_to_restore_trash')); } @@ -117,7 +117,7 @@ {/snippet} - +

{$t('trashed_items_will_be_permanently_deleted_after', { values: { days: $serverConfig.trashDays } })}

@@ -133,8 +133,8 @@ assets={assetInteraction.selectedAssets} clearSelect={() => assetInteraction.clearMultiselect()} > - - assetStore.removeAssets(assetIds)} /> - assetStore.removeAssets(assetIds)} /> + + timelineManager.removeAssets(assetIds)} /> + timelineManager.removeAssets(assetIds)} /> {/if}