diff --git a/web/src/lib/components/album-page/album-viewer.svelte b/web/src/lib/components/album-page/album-viewer.svelte index 41cdb7fb07..cfe6c70dd7 100644 --- a/web/src/lib/components/album-page/album-viewer.svelte +++ b/web/src/lib/components/album-page/album-viewer.svelte @@ -449,7 +449,7 @@ {/if} {#if album.assetCount > 0} - + {:else}
diff --git a/web/src/lib/components/asset-viewer/asset-viewer.svelte b/web/src/lib/components/asset-viewer/asset-viewer.svelte index d41419ffc7..e65b45e808 100644 --- a/web/src/lib/components/asset-viewer/asset-viewer.svelte +++ b/web/src/lib/components/asset-viewer/asset-viewer.svelte @@ -30,7 +30,16 @@ export let showNavigation = true; export let sharedLink: SharedLinkResponseDto | undefined = undefined; - const dispatch = createEventDispatcher(); + const dispatch = createEventDispatcher<{ + archived: AssetResponseDto; + unarchived: AssetResponseDto; + favorite: AssetResponseDto; + unfavorite: AssetResponseDto; + close: void; + next: void; + previous: void; + }>(); + let appearsInAlbums: AlbumResponseDto[] = []; let isShowAlbumPicker = false; let isShowDeleteConfirmation = false; @@ -105,18 +114,16 @@ closeViewer(); }; - const closeViewer = () => { - dispatch('close'); - }; + const closeViewer = () => dispatch('close'); const navigateAssetForward = (e?: Event) => { e?.stopPropagation(); - dispatch('navigate-next'); + dispatch('next'); }; const navigateAssetBackward = (e?: Event) => { e?.stopPropagation(); - dispatch('navigate-previous'); + dispatch('previous'); }; const showDetailInfoHandler = () => { @@ -159,7 +166,8 @@ }); asset.isFavorite = data.isFavorite; - assetStore?.updateAsset(asset.id, data.isFavorite); + assetStore?.updateAsset(data); + dispatch(data.isFavorite ? 'favorite' : 'unfavorite', data); notificationController.show({ type: NotificationType.Info, @@ -215,12 +223,8 @@ }); asset.isArchived = data.isArchived; - - if (data.isArchived) { - dispatch('archived', data); - } else { - dispatch('unarchived', data); - } + assetStore?.updateAsset(data); + dispatch(data.isArchived ? 'archived' : 'unarchived', data); notificationController.show({ type: NotificationType.Info, diff --git a/web/src/lib/components/memory-page/memory-viewer.svelte b/web/src/lib/components/memory-page/memory-viewer.svelte index 2e7c6ba878..25dc189b8c 100644 --- a/web/src/lib/components/memory-page/memory-viewer.svelte +++ b/web/src/lib/components/memory-page/memory-viewer.svelte @@ -268,7 +268,7 @@ bottom={-200} >
diff --git a/web/src/lib/components/photos-page/asset-grid.svelte b/web/src/lib/components/photos-page/asset-grid.svelte index 85800471cb..574e2baa23 100644 --- a/web/src/lib/components/photos-page/asset-grid.svelte +++ b/web/src/lib/components/photos-page/asset-grid.svelte @@ -13,7 +13,7 @@ import { browser } from '$app/environment'; import { goto } from '$app/navigation'; - import { AppRoute } from '$lib/constants'; + import { AppRoute, AssetAction } from '$lib/constants'; import type { AssetInteractionStore } from '$lib/stores/asset-interaction.store'; import { BucketPosition, type AssetStore, type Viewport } from '$lib/stores/assets.store'; import { isSearchEnabled } from '$lib/stores/search.store'; @@ -22,6 +22,7 @@ export let isAlbumSelectionMode = false; export let assetStore: AssetStore; export let assetInteractionStore: AssetInteractionStore; + export let removeAction: AssetAction | null = null; const { assetSelectionCandidates, assetSelectionStart, selectedAssets, isMultiSelectState } = assetInteractionStore; const viewport: Viewport = { width: 0, height: 0 }; @@ -81,18 +82,34 @@ element.scrollBy(0, event.detail.heightDelta); } - const navigateToPreviousAsset = async () => { - const prevAsset = await assetStore.getPreviousAssetId($viewingAsset.id); - if (prevAsset) { - assetViewingStore.setAssetId(prevAsset); + const handlePrevious = async () => { + const previousAsset = await assetStore.getPreviousAssetId($viewingAsset.id); + if (previousAsset) { + assetViewingStore.setAssetId(previousAsset); } + + return !!previousAsset; }; - const navigateToNextAsset = async () => { + const handleNext = async () => { const nextAsset = await assetStore.getNextAssetId($viewingAsset.id); if (nextAsset) { assetViewingStore.setAssetId(nextAsset); } + + return !!nextAsset; + }; + + const handleClose = () => assetViewingStore.showAssetViewer(false); + + const handleAction = async (asset: AssetResponseDto, action: AssetAction) => { + if (removeAction === action) { + // find the next asset to show or close the viewer + (await handleNext()) || (await handlePrevious()) || handleClose(); + + // delete after find the next one + assetStore.removeAsset(asset.id); + } }; let animationTick = false; @@ -109,12 +126,6 @@ }); }; - const handleArchiveSuccess = (e: CustomEvent) => { - const asset = e.detail as AssetResponseDto; - navigateToNextAsset(); - assetStore.removeAsset(asset.id); - }; - let lastAssetMouseEvent: AssetResponseDto | null = null; $: if (!lastAssetMouseEvent) { @@ -319,12 +330,13 @@ { - assetViewingStore.showAssetViewer(false); - }} - on:archived={handleArchiveSuccess} + on:previous={() => handlePrevious()} + on:next={() => handleNext()} + on:close={() => handleClose()} + on:archived={({ detail: asset }) => handleAction(asset, AssetAction.ARCHIVE)} + on:unarchived={({ detail: asset }) => handleAction(asset, AssetAction.UNARCHIVE)} + on:favorite={({ detail: asset }) => handleAction(asset, AssetAction.FAVORITE)} + on:unfavorite={({ detail: asset }) => handleAction(asset, AssetAction.UNFAVORITE)} /> {/if} diff --git a/web/src/lib/components/share-page/individual-shared-viewer.svelte b/web/src/lib/components/share-page/individual-shared-viewer.svelte index 10c523ec4d..e3372890f6 100644 --- a/web/src/lib/components/share-page/individual-shared-viewer.svelte +++ b/web/src/lib/components/share-page/individual-shared-viewer.svelte @@ -106,6 +106,6 @@ {/if}
- +
diff --git a/web/src/lib/components/shared-components/gallery-viewer/gallery-viewer.svelte b/web/src/lib/components/shared-components/gallery-viewer/gallery-viewer.svelte index b85c777e91..747da30c56 100644 --- a/web/src/lib/components/shared-components/gallery-viewer/gallery-viewer.svelte +++ b/web/src/lib/components/shared-components/gallery-viewer/gallery-viewer.svelte @@ -1,7 +1,3 @@ - - {#if assets.length > 0} @@ -124,9 +108,8 @@ asset={selectedAsset} publicSharedKey={sharedLink?.key} {sharedLink} - on:navigate-previous={navigateAssetBackward} - on:navigate-next={navigateAssetForward} + on:previous={navigateAssetBackward} + on:next={navigateAssetForward} on:close={closeViewer} - on:unarchived={handleUnarchivedSuccess} /> {/if} diff --git a/web/src/lib/constants.ts b/web/src/lib/constants.ts index ed8e833a59..2242f6c09d 100644 --- a/web/src/lib/constants.ts +++ b/web/src/lib/constants.ts @@ -1,6 +1,13 @@ import { env } from '$env/dynamic/public'; export const loginPageMessage: string | undefined = env.PUBLIC_LOGIN_PAGE_MESSAGE; +export enum AssetAction { + ARCHIVE = 'archive', + UNARCHIVE = 'unarchive', + FAVORITE = 'favorite', + UNFAVORITE = 'unfavorite', +} + export enum AppRoute { ADMIN_USER_MANAGEMENT = '/admin/user-management', ADMIN_SETTINGS = '/admin/system-settings', diff --git a/web/src/lib/stores/archived-asset.store.ts b/web/src/lib/stores/archived-asset.store.ts deleted file mode 100644 index 4e478580de..0000000000 --- a/web/src/lib/stores/archived-asset.store.ts +++ /dev/null @@ -1,4 +0,0 @@ -import type { AssetResponseDto } from '@api'; -import { writable } from 'svelte/store'; - -export const archivedAsset = writable([]); diff --git a/web/src/lib/stores/assets.store.ts b/web/src/lib/stores/assets.store.ts index 2e0f06d9cb..4a5753c06f 100644 --- a/web/src/lib/stores/assets.store.ts +++ b/web/src/lib/stores/assets.store.ts @@ -146,13 +146,14 @@ export class AssetStore { return this.assetToBucket[assetId]?.bucketIndex ?? null; } - updateAsset(assetId: string, isFavorite: boolean) { - const asset = this.assets.find((asset) => asset.id === assetId); + updateAsset(_asset: AssetResponseDto) { + const asset = this.assets.find((asset) => asset.id === _asset.id); if (!asset) { return; } - asset.isFavorite = isFavorite; + Object.assign(asset, _asset); + this.emit(false); } diff --git a/web/src/routes/(user)/archive/+page.svelte b/web/src/routes/(user)/archive/+page.svelte index 13a472e050..fb5e4d8d61 100644 --- a/web/src/routes/(user)/archive/+page.svelte +++ b/web/src/routes/(user)/archive/+page.svelte @@ -11,6 +11,7 @@ import AssetSelectContextMenu from '$lib/components/photos-page/asset-select-context-menu.svelte'; import AssetSelectControlBar from '$lib/components/photos-page/asset-select-control-bar.svelte'; import EmptyPlaceholder from '$lib/components/shared-components/empty-placeholder.svelte'; + import { AssetAction } from '$lib/constants'; import { createAssetInteractionStore } from '$lib/stores/asset-interaction.store'; import { AssetStore } from '$lib/stores/assets.store'; import { api, TimeBucketSize } from '@api'; @@ -53,7 +54,7 @@ {#if assetCount} - + {:else} {/if} diff --git a/web/src/routes/(user)/favorites/+page.svelte b/web/src/routes/(user)/favorites/+page.svelte index 959ab7f81c..2759d9d8e9 100644 --- a/web/src/routes/(user)/favorites/+page.svelte +++ b/web/src/routes/(user)/favorites/+page.svelte @@ -11,6 +11,7 @@ import AssetSelectContextMenu from '$lib/components/photos-page/asset-select-context-menu.svelte'; import AssetSelectControlBar from '$lib/components/photos-page/asset-select-control-bar.svelte'; import EmptyPlaceholder from '$lib/components/shared-components/empty-placeholder.svelte'; + import { AssetAction } from '$lib/constants'; import { createAssetInteractionStore } from '$lib/stores/asset-interaction.store'; import { AssetStore } from '$lib/stores/assets.store'; import { api, TimeBucketSize } from '@api'; @@ -54,7 +55,7 @@ {#if assetCount} - + {:else} {/if} diff --git a/web/src/routes/(user)/map/+page.svelte b/web/src/routes/(user)/map/+page.svelte index 5ca8f94ea2..12aef1a904 100644 --- a/web/src/routes/(user)/map/+page.svelte +++ b/web/src/routes/(user)/map/+page.svelte @@ -143,11 +143,9 @@ 1} - on:navigate-next={navigateNext} - on:navigate-previous={navigatePrevious} - on:close={() => { - assetViewingStore.showAssetViewer(false); - }} + on:next={navigateNext} + on:previous={navigatePrevious} + on:close={() => assetViewingStore.showAssetViewer(false)} /> {/if} diff --git a/web/src/routes/(user)/people/[personId]/+page.svelte b/web/src/routes/(user)/people/[personId]/+page.svelte index 0ccd27e35b..160065513f 100644 --- a/web/src/routes/(user)/people/[personId]/+page.svelte +++ b/web/src/routes/(user)/people/[personId]/+page.svelte @@ -242,7 +242,7 @@
- +
diff --git a/web/src/routes/(user)/photos/+page.svelte b/web/src/routes/(user)/photos/+page.svelte index eb2f82e4f2..caf8c786a9 100644 --- a/web/src/routes/(user)/photos/+page.svelte +++ b/web/src/routes/(user)/photos/+page.svelte @@ -12,6 +12,7 @@ import AssetSelectControlBar from '$lib/components/photos-page/asset-select-control-bar.svelte'; import MemoryLane from '$lib/components/photos-page/memory-lane.svelte'; import EmptyPlaceholder from '$lib/components/shared-components/empty-placeholder.svelte'; + import { AssetAction } from '$lib/constants'; import { createAssetInteractionStore } from '$lib/stores/asset-interaction.store'; import { AssetStore } from '$lib/stores/assets.store'; import { openFileUploadDialog } from '$lib/utils/file-uploader'; @@ -31,7 +32,7 @@ $: isAllFavorite = Array.from($selectedAssets).every((asset) => asset.isFavorite); onMount(async () => { - const { data: stats } = await api.assetApi.getAssetStats(); + const { data: stats } = await api.assetApi.getAssetStats({ isArchived: false }); assetCount = stats.total; }); @@ -57,7 +58,7 @@ {#if assetCount} - + {:else} diff --git a/web/src/routes/(user)/search/+page.svelte b/web/src/routes/(user)/search/+page.svelte index d9ad89ce1f..4853fb4abf 100644 --- a/web/src/routes/(user)/search/+page.svelte +++ b/web/src/routes/(user)/search/+page.svelte @@ -138,12 +138,7 @@
{#if data.results?.assets?.items.length > 0}
- +
{:else}
diff --git a/web/src/routes/(user)/share/[key]/photos/[assetId]/+page.svelte b/web/src/routes/(user)/share/[key]/photos/[assetId]/+page.svelte index 800f1f6fd2..436d15c4be 100644 --- a/web/src/routes/(user)/share/[key]/photos/[assetId]/+page.svelte +++ b/web/src/routes/(user)/share/[key]/photos/[assetId]/+page.svelte @@ -9,9 +9,9 @@ null} - on:navigate-next={() => null} showNavigation={false} + on:previous={() => null} + on:next={() => null} on:close={() => goto(`/share/${data.key}`)} /> {/if}