mirror of
https://github.com/samsonjs/immich.git
synced 2026-04-27 15:07:45 +00:00
Co-authored-by: Daniel Dietzler <36593685+danieldietzler@users.noreply.github.com>
This commit is contained in:
parent
369a30e227
commit
e87bfa548a
2 changed files with 52 additions and 36 deletions
|
|
@ -451,6 +451,7 @@
|
||||||
<div class="absolute w-full flex">
|
<div class="absolute w-full flex">
|
||||||
<SlideshowBar
|
<SlideshowBar
|
||||||
{isFullScreen}
|
{isFullScreen}
|
||||||
|
assetType={previewStackedAsset?.type ?? asset.type}
|
||||||
onSetToFullScreen={() => assetViewerHtmlElement?.requestFullscreen?.()}
|
onSetToFullScreen={() => assetViewerHtmlElement?.requestFullscreen?.()}
|
||||||
onPrevious={() => navigateAsset('previous')}
|
onPrevious={() => navigateAsset('previous')}
|
||||||
onNext={() => navigateAsset('next')}
|
onNext={() => navigateAsset('next')}
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,10 @@
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { shortcuts } from '$lib/actions/shortcut';
|
import { shortcuts, type ShortcutOptions } from '$lib/actions/shortcut';
|
||||||
import ProgressBar from '$lib/components/shared-components/progress-bar/progress-bar.svelte';
|
import ProgressBar from '$lib/components/shared-components/progress-bar/progress-bar.svelte';
|
||||||
import { ProgressBarStatus } from '$lib/constants';
|
import { ProgressBarStatus } from '$lib/constants';
|
||||||
import SlideshowSettingsModal from '$lib/modals/SlideshowSettingsModal.svelte';
|
import SlideshowSettingsModal from '$lib/modals/SlideshowSettingsModal.svelte';
|
||||||
import { SlideshowNavigation, slideshowStore } from '$lib/stores/slideshow.store';
|
import { SlideshowNavigation, slideshowStore } from '$lib/stores/slideshow.store';
|
||||||
|
import { AssetTypeEnum } from '@immich/sdk';
|
||||||
import { IconButton, modalManager } from '@immich/ui';
|
import { IconButton, modalManager } from '@immich/ui';
|
||||||
import { mdiChevronLeft, mdiChevronRight, mdiClose, mdiCog, mdiFullscreen, mdiPause, mdiPlay } from '@mdi/js';
|
import { mdiChevronLeft, mdiChevronRight, mdiClose, mdiCog, mdiFullscreen, mdiPause, mdiPlay } from '@mdi/js';
|
||||||
import { onDestroy, onMount } from 'svelte';
|
import { onDestroy, onMount } from 'svelte';
|
||||||
|
|
@ -13,6 +14,7 @@
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
isFullScreen: boolean;
|
isFullScreen: boolean;
|
||||||
|
assetType: AssetTypeEnum;
|
||||||
onNext?: () => void;
|
onNext?: () => void;
|
||||||
onPrevious?: () => void;
|
onPrevious?: () => void;
|
||||||
onClose?: () => void;
|
onClose?: () => void;
|
||||||
|
|
@ -21,6 +23,7 @@
|
||||||
|
|
||||||
let {
|
let {
|
||||||
isFullScreen,
|
isFullScreen,
|
||||||
|
assetType,
|
||||||
onNext = () => {},
|
onNext = () => {},
|
||||||
onPrevious = () => {},
|
onPrevious = () => {},
|
||||||
onClose = () => {},
|
onClose = () => {},
|
||||||
|
|
@ -35,6 +38,7 @@
|
||||||
let showControls = $state(true);
|
let showControls = $state(true);
|
||||||
let timer: NodeJS.Timeout;
|
let timer: NodeJS.Timeout;
|
||||||
let isOverControls = $state(false);
|
let isOverControls = $state(false);
|
||||||
|
const isVideoSlide = $derived(assetType === AssetTypeEnum.Video);
|
||||||
|
|
||||||
let unsubscribeRestart: () => void;
|
let unsubscribeRestart: () => void;
|
||||||
let unsubscribeStop: () => void;
|
let unsubscribeStop: () => void;
|
||||||
|
|
@ -132,27 +136,34 @@
|
||||||
{ onswipedown: showControlBar },
|
{ onswipedown: showControlBar },
|
||||||
true,
|
true,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const shortcutBindings = $derived.by((): ShortcutOptions[] => {
|
||||||
|
const bindings: ShortcutOptions[] = [
|
||||||
|
{ shortcut: { key: 'Escape' }, onShortcut: onClose },
|
||||||
|
{ shortcut: { key: 'ArrowLeft' }, onShortcut: onPrevious },
|
||||||
|
{ shortcut: { key: 'ArrowRight' }, onShortcut: onNext },
|
||||||
|
];
|
||||||
|
|
||||||
|
// For videos, allow the native HTML5 element to handle space for play/pause
|
||||||
|
if (!isVideoSlide) {
|
||||||
|
bindings.push({
|
||||||
|
shortcut: { key: ' ' },
|
||||||
|
onShortcut: () => {
|
||||||
|
if (progressBarStatus === ProgressBarStatus.Paused) {
|
||||||
|
progressBar?.play();
|
||||||
|
} else {
|
||||||
|
progressBar?.pause();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
preventDefault: true,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return bindings;
|
||||||
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<svelte:document
|
<svelte:document onmousemove={showControlBar} use:shortcuts={shortcutBindings} />
|
||||||
onmousemove={showControlBar}
|
|
||||||
use:shortcuts={[
|
|
||||||
{ shortcut: { key: 'Escape' }, onShortcut: onClose },
|
|
||||||
{ shortcut: { key: 'ArrowLeft' }, onShortcut: onPrevious },
|
|
||||||
{ shortcut: { key: 'ArrowRight' }, onShortcut: onNext },
|
|
||||||
{
|
|
||||||
shortcut: { key: ' ' },
|
|
||||||
onShortcut: () => {
|
|
||||||
if (progressBarStatus === ProgressBarStatus.Paused) {
|
|
||||||
progressBar?.play();
|
|
||||||
} else {
|
|
||||||
progressBar?.pause();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
preventDefault: true,
|
|
||||||
},
|
|
||||||
]}
|
|
||||||
/>
|
|
||||||
|
|
||||||
{/* @ts-expect-error https://github.com/Rezi/svelte-gestures/issues/38#issuecomment-3315953573 */ null}
|
{/* @ts-expect-error https://github.com/Rezi/svelte-gestures/issues/38#issuecomment-3315953573 */ null}
|
||||||
<svelte:body {@attach swipe} {onswipe} {onswipedown} />
|
<svelte:body {@attach swipe} {onswipe} {onswipedown} />
|
||||||
|
|
@ -174,14 +185,16 @@
|
||||||
aria-label={$t('exit_slideshow')}
|
aria-label={$t('exit_slideshow')}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<IconButton
|
{#if !isVideoSlide}
|
||||||
variant="ghost"
|
<IconButton
|
||||||
shape="round"
|
variant="ghost"
|
||||||
color="secondary"
|
shape="round"
|
||||||
icon={progressBarStatus === ProgressBarStatus.Paused ? mdiPlay : mdiPause}
|
color="secondary"
|
||||||
onclick={() => (progressBarStatus === ProgressBarStatus.Paused ? progressBar?.play() : progressBar?.pause())}
|
icon={progressBarStatus === ProgressBarStatus.Paused ? mdiPlay : mdiPause}
|
||||||
aria-label={progressBarStatus === ProgressBarStatus.Paused ? $t('play') : $t('pause')}
|
onclick={() => (progressBarStatus === ProgressBarStatus.Paused ? progressBar?.play() : progressBar?.pause())}
|
||||||
/>
|
aria-label={progressBarStatus === ProgressBarStatus.Paused ? $t('play') : $t('pause')}
|
||||||
|
/>
|
||||||
|
{/if}
|
||||||
<IconButton
|
<IconButton
|
||||||
variant="ghost"
|
variant="ghost"
|
||||||
shape="round"
|
shape="round"
|
||||||
|
|
@ -219,11 +232,13 @@
|
||||||
</div>
|
</div>
|
||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
<ProgressBar
|
{#if !isVideoSlide}
|
||||||
autoplay={$slideshowAutoplay}
|
<ProgressBar
|
||||||
hidden={!$showProgressBar}
|
autoplay={$slideshowAutoplay}
|
||||||
duration={$slideshowDelay}
|
hidden={!$showProgressBar}
|
||||||
bind:this={progressBar}
|
duration={$slideshowDelay}
|
||||||
bind:status={progressBarStatus}
|
bind:this={progressBar}
|
||||||
onDone={handleDone}
|
bind:status={progressBarStatus}
|
||||||
/>
|
onDone={handleDone}
|
||||||
|
/>
|
||||||
|
{/if}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue