mirror of
https://github.com/immich-app/immich.git
synced 2025-05-31 04:05:39 -04:00
feat(web): Slideshow is enabled everywhere. It no longer needs assetStore. (#15077)
Slideshow no longer needs assetStore. It is enabled everywhere Co-authored-by: Alex <alex.tran1502@gmail.com>
This commit is contained in:
parent
f70ee3f350
commit
4279cd6e1e
@ -8,7 +8,6 @@
|
|||||||
import { updateNumberOfComments } from '$lib/stores/activity.store';
|
import { updateNumberOfComments } from '$lib/stores/activity.store';
|
||||||
import { closeEditorCofirm } from '$lib/stores/asset-editor.store';
|
import { closeEditorCofirm } from '$lib/stores/asset-editor.store';
|
||||||
import { assetViewingStore } from '$lib/stores/asset-viewing.store';
|
import { assetViewingStore } from '$lib/stores/asset-viewing.store';
|
||||||
import type { AssetStore } from '$lib/stores/assets.store';
|
|
||||||
import { isShowDetail } from '$lib/stores/preferences.store';
|
import { isShowDetail } from '$lib/stores/preferences.store';
|
||||||
import { SlideshowNavigation, SlideshowState, slideshowStore } from '$lib/stores/slideshow.store';
|
import { SlideshowNavigation, SlideshowState, slideshowStore } from '$lib/stores/slideshow.store';
|
||||||
import { user } from '$lib/stores/user.store';
|
import { user } from '$lib/stores/user.store';
|
||||||
@ -49,8 +48,9 @@
|
|||||||
import VideoViewer from './video-wrapper-viewer.svelte';
|
import VideoViewer from './video-wrapper-viewer.svelte';
|
||||||
import ImagePanoramaViewer from './image-panorama-viewer.svelte';
|
import ImagePanoramaViewer from './image-panorama-viewer.svelte';
|
||||||
|
|
||||||
|
type HasAsset = boolean;
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
assetStore?: AssetStore | null;
|
|
||||||
asset: AssetResponseDto;
|
asset: AssetResponseDto;
|
||||||
preloadAssets?: AssetResponseDto[];
|
preloadAssets?: AssetResponseDto[];
|
||||||
showNavigation?: boolean;
|
showNavigation?: boolean;
|
||||||
@ -61,13 +61,13 @@
|
|||||||
onAction?: OnAction | undefined;
|
onAction?: OnAction | undefined;
|
||||||
reactions?: ActivityResponseDto[];
|
reactions?: ActivityResponseDto[];
|
||||||
onClose: (dto: { asset: AssetResponseDto }) => void;
|
onClose: (dto: { asset: AssetResponseDto }) => void;
|
||||||
onNext: () => void;
|
onNext: () => Promise<HasAsset>;
|
||||||
onPrevious: () => void;
|
onPrevious: () => Promise<HasAsset>;
|
||||||
|
onRandom: () => Promise<AssetResponseDto | null>;
|
||||||
copyImage?: () => Promise<void>;
|
copyImage?: () => Promise<void>;
|
||||||
}
|
}
|
||||||
|
|
||||||
let {
|
let {
|
||||||
assetStore = null,
|
|
||||||
asset = $bindable(),
|
asset = $bindable(),
|
||||||
preloadAssets = $bindable([]),
|
preloadAssets = $bindable([]),
|
||||||
showNavigation = true,
|
showNavigation = true,
|
||||||
@ -80,6 +80,7 @@
|
|||||||
onClose,
|
onClose,
|
||||||
onNext,
|
onNext,
|
||||||
onPrevious,
|
onPrevious,
|
||||||
|
onRandom,
|
||||||
copyImage = $bindable(),
|
copyImage = $bindable(),
|
||||||
}: Props = $props();
|
}: Props = $props();
|
||||||
|
|
||||||
@ -271,22 +272,6 @@
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const navigateAssetRandom = async () => {
|
|
||||||
if (!assetStore) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const asset = await assetStore.getRandomAsset();
|
|
||||||
if (!asset) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
slideshowHistory.queue(asset);
|
|
||||||
|
|
||||||
setAsset(asset);
|
|
||||||
$restartSlideshowProgress = true;
|
|
||||||
};
|
|
||||||
|
|
||||||
const navigateAsset = async (order?: 'previous' | 'next', e?: Event) => {
|
const navigateAsset = async (order?: 'previous' | 'next', e?: Event) => {
|
||||||
if (!order) {
|
if (!order) {
|
||||||
if ($slideshowState === SlideshowState.PlaySlideshow) {
|
if ($slideshowState === SlideshowState.PlaySlideshow) {
|
||||||
@ -296,23 +281,30 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
e?.stopPropagation();
|
||||||
|
|
||||||
|
let hasNext = false;
|
||||||
|
|
||||||
if ($slideshowState === SlideshowState.PlaySlideshow && $slideshowNavigation === SlideshowNavigation.Shuffle) {
|
if ($slideshowState === SlideshowState.PlaySlideshow && $slideshowNavigation === SlideshowNavigation.Shuffle) {
|
||||||
return (order === 'previous' ? slideshowHistory.previous() : slideshowHistory.next()) || navigateAssetRandom();
|
hasNext = order === 'previous' ? slideshowHistory.previous() : slideshowHistory.next();
|
||||||
|
if (!hasNext) {
|
||||||
|
const asset = await onRandom();
|
||||||
|
if (asset) {
|
||||||
|
slideshowHistory.queue(asset);
|
||||||
|
hasNext = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
hasNext = order === 'previous' ? await onPrevious() : await onNext();
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($slideshowState === SlideshowState.PlaySlideshow && assetStore) {
|
if ($slideshowState === SlideshowState.PlaySlideshow) {
|
||||||
const hasNext =
|
|
||||||
order === 'previous' ? await assetStore.getPreviousAsset(asset) : await assetStore.getNextAsset(asset);
|
|
||||||
if (hasNext) {
|
if (hasNext) {
|
||||||
$restartSlideshowProgress = true;
|
$restartSlideshowProgress = true;
|
||||||
} else {
|
} else {
|
||||||
await handleStopSlideshow();
|
await handleStopSlideshow();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
e?.stopPropagation();
|
|
||||||
// eslint-disable-next-line @typescript-eslint/no-unused-expressions
|
|
||||||
order === 'previous' ? onPrevious() : onNext();
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// const showEditorHandler = () => {
|
// const showEditorHandler = () => {
|
||||||
@ -435,7 +427,7 @@
|
|||||||
{person}
|
{person}
|
||||||
{stack}
|
{stack}
|
||||||
showDetailButton={enableDetailPanel}
|
showDetailButton={enableDetailPanel}
|
||||||
showSlideshow={!!assetStore}
|
showSlideshow={true}
|
||||||
onZoomImage={zoomToggle}
|
onZoomImage={zoomToggle}
|
||||||
onCopyImage={copyImage}
|
onCopyImage={copyImage}
|
||||||
onAction={handleAction}
|
onAction={handleAction}
|
||||||
|
@ -527,6 +527,18 @@
|
|||||||
return !!nextAsset;
|
return !!nextAsset;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const handleRandom = async () => {
|
||||||
|
const randomAsset = await $assetStore.getRandomAsset();
|
||||||
|
|
||||||
|
if (randomAsset) {
|
||||||
|
const preloadAsset = await $assetStore.getNextAsset(randomAsset);
|
||||||
|
assetViewingStore.setAsset(randomAsset, preloadAsset ? [preloadAsset] : []);
|
||||||
|
await navigate({ targetRoute: 'current', assetId: randomAsset.id });
|
||||||
|
}
|
||||||
|
|
||||||
|
return randomAsset;
|
||||||
|
};
|
||||||
|
|
||||||
const handleClose = async ({ asset }: { asset: AssetResponseDto }) => {
|
const handleClose = async ({ asset }: { asset: AssetResponseDto }) => {
|
||||||
assetViewingStore.showAssetViewer(false);
|
assetViewingStore.showAssetViewer(false);
|
||||||
showSkeleton = true;
|
showSkeleton = true;
|
||||||
@ -911,7 +923,6 @@
|
|||||||
{#await import('../asset-viewer/asset-viewer.svelte') then { default: AssetViewer }}
|
{#await import('../asset-viewer/asset-viewer.svelte') then { default: AssetViewer }}
|
||||||
<AssetViewer
|
<AssetViewer
|
||||||
{withStacked}
|
{withStacked}
|
||||||
{assetStore}
|
|
||||||
asset={$viewingAsset}
|
asset={$viewingAsset}
|
||||||
preloadAssets={$preloadAssets}
|
preloadAssets={$preloadAssets}
|
||||||
{isShared}
|
{isShared}
|
||||||
@ -920,6 +931,7 @@
|
|||||||
onAction={handleAction}
|
onAction={handleAction}
|
||||||
onPrevious={handlePrevious}
|
onPrevious={handlePrevious}
|
||||||
onNext={handleNext}
|
onNext={handleNext}
|
||||||
|
onRandom={handleRandom}
|
||||||
onClose={handleClose}
|
onClose={handleClose}
|
||||||
/>
|
/>
|
||||||
{/await}
|
{/await}
|
||||||
|
@ -34,6 +34,7 @@
|
|||||||
isShowDeleteConfirmation?: boolean;
|
isShowDeleteConfirmation?: boolean;
|
||||||
onPrevious?: (() => Promise<AssetResponseDto | undefined>) | undefined;
|
onPrevious?: (() => Promise<AssetResponseDto | undefined>) | undefined;
|
||||||
onNext?: (() => Promise<AssetResponseDto | undefined>) | undefined;
|
onNext?: (() => Promise<AssetResponseDto | undefined>) | undefined;
|
||||||
|
onRandom?: (() => Promise<AssetResponseDto | undefined>) | undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
let {
|
let {
|
||||||
@ -47,6 +48,7 @@
|
|||||||
isShowDeleteConfirmation = $bindable(false),
|
isShowDeleteConfirmation = $bindable(false),
|
||||||
onPrevious = undefined,
|
onPrevious = undefined,
|
||||||
onNext = undefined,
|
onNext = undefined,
|
||||||
|
onRandom = undefined,
|
||||||
}: Props = $props();
|
}: Props = $props();
|
||||||
|
|
||||||
let { isViewing: isViewerOpen, asset: viewingAsset, setAsset } = assetViewingStore;
|
let { isViewing: isViewerOpen, asset: viewingAsset, setAsset } = assetViewingStore;
|
||||||
@ -202,35 +204,71 @@
|
|||||||
})(),
|
})(),
|
||||||
);
|
);
|
||||||
|
|
||||||
const handleNext = async () => {
|
const handleNext = async (): Promise<boolean> => {
|
||||||
try {
|
try {
|
||||||
let asset: AssetResponseDto | undefined;
|
let asset: AssetResponseDto | undefined;
|
||||||
if (onNext) {
|
if (onNext) {
|
||||||
asset = await onNext();
|
asset = await onNext();
|
||||||
} else {
|
} else {
|
||||||
currentViewAssetIndex = Math.min(currentViewAssetIndex + 1, assets.length - 1);
|
currentViewAssetIndex = currentViewAssetIndex + 1;
|
||||||
asset = assets[currentViewAssetIndex];
|
asset = currentViewAssetIndex < assets.length ? assets[currentViewAssetIndex] : undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!asset) {
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
await navigateToAsset(asset);
|
await navigateToAsset(asset);
|
||||||
|
return true;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
handleError(error, $t('errors.cannot_navigate_next_asset'));
|
handleError(error, $t('errors.cannot_navigate_next_asset'));
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const handlePrevious = async () => {
|
const handleRandom = async (): Promise<AssetResponseDto | null> => {
|
||||||
|
try {
|
||||||
|
let asset: AssetResponseDto | undefined;
|
||||||
|
if (onRandom) {
|
||||||
|
asset = await onRandom();
|
||||||
|
} else {
|
||||||
|
if (assets.length > 0) {
|
||||||
|
const randomIndex = Math.floor(Math.random() * assets.length);
|
||||||
|
asset = assets[randomIndex];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!asset) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
await navigateToAsset(asset);
|
||||||
|
return asset;
|
||||||
|
} catch (error) {
|
||||||
|
handleError(error, $t('errors.cannot_navigate_next_asset'));
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const handlePrevious = async (): Promise<boolean> => {
|
||||||
try {
|
try {
|
||||||
let asset: AssetResponseDto | undefined;
|
let asset: AssetResponseDto | undefined;
|
||||||
if (onPrevious) {
|
if (onPrevious) {
|
||||||
asset = await onPrevious();
|
asset = await onPrevious();
|
||||||
} else {
|
} else {
|
||||||
currentViewAssetIndex = Math.max(currentViewAssetIndex - 1, 0);
|
currentViewAssetIndex = currentViewAssetIndex - 1;
|
||||||
asset = assets[currentViewAssetIndex];
|
asset = currentViewAssetIndex >= 0 ? assets[currentViewAssetIndex] : undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!asset) {
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
await navigateToAsset(asset);
|
await navigateToAsset(asset);
|
||||||
|
return true;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
handleError(error, $t('errors.cannot_navigate_previous_asset'));
|
handleError(error, $t('errors.cannot_navigate_previous_asset'));
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -372,6 +410,7 @@
|
|||||||
onAction={handleAction}
|
onAction={handleAction}
|
||||||
onPrevious={handlePrevious}
|
onPrevious={handlePrevious}
|
||||||
onNext={handleNext}
|
onNext={handleNext}
|
||||||
|
onRandom={handleRandom}
|
||||||
onClose={() => {
|
onClose={() => {
|
||||||
assetViewingStore.showAssetViewer(false);
|
assetViewingStore.showAssetViewer(false);
|
||||||
handlePromiseError(navigate({ targetRoute: 'current', assetId: null }));
|
handlePromiseError(navigate({ targetRoute: 'current', assetId: null }));
|
||||||
|
@ -42,6 +42,34 @@
|
|||||||
assetViewingStore.showAssetViewer(false);
|
assetViewingStore.showAssetViewer(false);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const onNext = () => {
|
||||||
|
const index = getAssetIndex($viewingAsset.id) + 1;
|
||||||
|
if (index >= assets.length) {
|
||||||
|
return Promise.resolve(false);
|
||||||
|
}
|
||||||
|
setAsset(assets[index]);
|
||||||
|
return Promise.resolve(true);
|
||||||
|
};
|
||||||
|
|
||||||
|
const onPrevious = () => {
|
||||||
|
const index = getAssetIndex($viewingAsset.id) - 1;
|
||||||
|
if (index < 0) {
|
||||||
|
return Promise.resolve(false);
|
||||||
|
}
|
||||||
|
setAsset(assets[index]);
|
||||||
|
return Promise.resolve(true);
|
||||||
|
};
|
||||||
|
|
||||||
|
const onRandom = () => {
|
||||||
|
if (assets.length <= 0) {
|
||||||
|
return Promise.resolve(null);
|
||||||
|
}
|
||||||
|
const index = Math.floor(Math.random() * assets.length);
|
||||||
|
const asset = assets[index];
|
||||||
|
setAsset(asset);
|
||||||
|
return Promise.resolve(asset);
|
||||||
|
};
|
||||||
|
|
||||||
const onSelectAsset = (asset: AssetResponseDto) => {
|
const onSelectAsset = (asset: AssetResponseDto) => {
|
||||||
if (selectedAssetIds.has(asset.id)) {
|
if (selectedAssetIds.has(asset.id)) {
|
||||||
selectedAssetIds.delete(asset.id);
|
selectedAssetIds.delete(asset.id);
|
||||||
@ -153,14 +181,9 @@
|
|||||||
<AssetViewer
|
<AssetViewer
|
||||||
asset={$viewingAsset}
|
asset={$viewingAsset}
|
||||||
showNavigation={assets.length > 1}
|
showNavigation={assets.length > 1}
|
||||||
onNext={() => {
|
{onNext}
|
||||||
const index = getAssetIndex($viewingAsset.id) + 1;
|
{onPrevious}
|
||||||
setAsset(assets[index % assets.length]);
|
{onRandom}
|
||||||
}}
|
|
||||||
onPrevious={() => {
|
|
||||||
const index = getAssetIndex($viewingAsset.id) - 1 + assets.length;
|
|
||||||
setAsset(assets[index % assets.length]);
|
|
||||||
}}
|
|
||||||
onClose={() => {
|
onClose={() => {
|
||||||
assetViewingStore.showAssetViewer(false);
|
assetViewingStore.showAssetViewer(false);
|
||||||
handlePromiseError(navigate({ targetRoute: 'current', assetId: null }));
|
handlePromiseError(navigate({ targetRoute: 'current', assetId: null }));
|
||||||
|
@ -15,9 +15,10 @@ function createAssetViewingStore() {
|
|||||||
viewState.set(true);
|
viewState.set(true);
|
||||||
};
|
};
|
||||||
|
|
||||||
const setAssetId = async (id: string) => {
|
const setAssetId = async (id: string): Promise<AssetResponseDto> => {
|
||||||
const asset = await getAssetInfo({ id, key: getKey() });
|
const asset = await getAssetInfo({ id, key: getKey() });
|
||||||
setAsset(asset);
|
setAsset(asset);
|
||||||
|
return asset;
|
||||||
};
|
};
|
||||||
|
|
||||||
const showAssetViewer = (show: boolean) => {
|
const showAssetViewer = (show: boolean) => {
|
||||||
|
@ -107,14 +107,28 @@
|
|||||||
if (viewingAssetCursor < viewingAssets.length - 1) {
|
if (viewingAssetCursor < viewingAssets.length - 1) {
|
||||||
await setAssetId(viewingAssets[++viewingAssetCursor]);
|
await setAssetId(viewingAssets[++viewingAssetCursor]);
|
||||||
await navigate({ targetRoute: 'current', assetId: $viewingAsset.id });
|
await navigate({ targetRoute: 'current', assetId: $viewingAsset.id });
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
async function navigatePrevious() {
|
async function navigatePrevious() {
|
||||||
if (viewingAssetCursor > 0) {
|
if (viewingAssetCursor > 0) {
|
||||||
await setAssetId(viewingAssets[--viewingAssetCursor]);
|
await setAssetId(viewingAssets[--viewingAssetCursor]);
|
||||||
await navigate({ targetRoute: 'current', assetId: $viewingAsset.id });
|
await navigate({ targetRoute: 'current', assetId: $viewingAsset.id });
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
async function navigateRandom() {
|
||||||
|
if (viewingAssets.length <= 0) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
const index = Math.floor(Math.random() * viewingAssets.length);
|
||||||
|
const asset = await setAssetId(viewingAssets[index]);
|
||||||
|
await navigate({ targetRoute: 'current', assetId: $viewingAsset.id });
|
||||||
|
return asset;
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
@ -132,6 +146,7 @@
|
|||||||
showNavigation={viewingAssets.length > 1}
|
showNavigation={viewingAssets.length > 1}
|
||||||
onNext={navigateNext}
|
onNext={navigateNext}
|
||||||
onPrevious={navigatePrevious}
|
onPrevious={navigatePrevious}
|
||||||
|
onRandom={navigateRandom}
|
||||||
onClose={() => {
|
onClose={() => {
|
||||||
assetViewingStore.showAssetViewer(false);
|
assetViewingStore.showAssetViewer(false);
|
||||||
handlePromiseError(navigate({ targetRoute: 'current', assetId: null }));
|
handlePromiseError(navigate({ targetRoute: 'current', assetId: null }));
|
||||||
|
Loading…
x
Reference in New Issue
Block a user