mirror of
https://github.com/immich-app/immich.git
synced 2025-12-30 22:51:47 -08:00
Co-authored-by: Daniel Dietzler <36593685+danieldietzler@users.noreply.github.com>
This commit is contained in:
@@ -451,6 +451,7 @@
|
||||
<div class="absolute w-full flex">
|
||||
<SlideshowBar
|
||||
{isFullScreen}
|
||||
assetType={previewStackedAsset?.type ?? asset.type}
|
||||
onSetToFullScreen={() => assetViewerHtmlElement?.requestFullscreen?.()}
|
||||
onPrevious={() => navigateAsset('previous')}
|
||||
onNext={() => navigateAsset('next')}
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
<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 { ProgressBarStatus } from '$lib/constants';
|
||||
import SlideshowSettingsModal from '$lib/modals/SlideshowSettingsModal.svelte';
|
||||
import { SlideshowNavigation, slideshowStore } from '$lib/stores/slideshow.store';
|
||||
import { AssetTypeEnum } from '@immich/sdk';
|
||||
import { IconButton, modalManager } from '@immich/ui';
|
||||
import { mdiChevronLeft, mdiChevronRight, mdiClose, mdiCog, mdiFullscreen, mdiPause, mdiPlay } from '@mdi/js';
|
||||
import { onDestroy, onMount } from 'svelte';
|
||||
@@ -13,6 +14,7 @@
|
||||
|
||||
interface Props {
|
||||
isFullScreen: boolean;
|
||||
assetType: AssetTypeEnum;
|
||||
onNext?: () => void;
|
||||
onPrevious?: () => void;
|
||||
onClose?: () => void;
|
||||
@@ -21,6 +23,7 @@
|
||||
|
||||
let {
|
||||
isFullScreen,
|
||||
assetType,
|
||||
onNext = () => {},
|
||||
onPrevious = () => {},
|
||||
onClose = () => {},
|
||||
@@ -35,6 +38,7 @@
|
||||
let showControls = $state(true);
|
||||
let timer: NodeJS.Timeout;
|
||||
let isOverControls = $state(false);
|
||||
const isVideoSlide = $derived(assetType === AssetTypeEnum.Video);
|
||||
|
||||
let unsubscribeRestart: () => void;
|
||||
let unsubscribeStop: () => void;
|
||||
@@ -132,27 +136,34 @@
|
||||
{ onswipedown: showControlBar },
|
||||
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>
|
||||
|
||||
<svelte:document
|
||||
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,
|
||||
},
|
||||
]}
|
||||
/>
|
||||
<svelte:document onmousemove={showControlBar} use:shortcuts={shortcutBindings} />
|
||||
|
||||
{/* @ts-expect-error https://github.com/Rezi/svelte-gestures/issues/38#issuecomment-3315953573 */ null}
|
||||
<svelte:body {@attach swipe} {onswipe} {onswipedown} />
|
||||
@@ -174,14 +185,16 @@
|
||||
aria-label={$t('exit_slideshow')}
|
||||
/>
|
||||
|
||||
<IconButton
|
||||
variant="ghost"
|
||||
shape="round"
|
||||
color="secondary"
|
||||
icon={progressBarStatus === ProgressBarStatus.Paused ? mdiPlay : mdiPause}
|
||||
onclick={() => (progressBarStatus === ProgressBarStatus.Paused ? progressBar?.play() : progressBar?.pause())}
|
||||
aria-label={progressBarStatus === ProgressBarStatus.Paused ? $t('play') : $t('pause')}
|
||||
/>
|
||||
{#if !isVideoSlide}
|
||||
<IconButton
|
||||
variant="ghost"
|
||||
shape="round"
|
||||
color="secondary"
|
||||
icon={progressBarStatus === ProgressBarStatus.Paused ? mdiPlay : mdiPause}
|
||||
onclick={() => (progressBarStatus === ProgressBarStatus.Paused ? progressBar?.play() : progressBar?.pause())}
|
||||
aria-label={progressBarStatus === ProgressBarStatus.Paused ? $t('play') : $t('pause')}
|
||||
/>
|
||||
{/if}
|
||||
<IconButton
|
||||
variant="ghost"
|
||||
shape="round"
|
||||
@@ -219,11 +232,13 @@
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
<ProgressBar
|
||||
autoplay={$slideshowAutoplay}
|
||||
hidden={!$showProgressBar}
|
||||
duration={$slideshowDelay}
|
||||
bind:this={progressBar}
|
||||
bind:status={progressBarStatus}
|
||||
onDone={handleDone}
|
||||
/>
|
||||
{#if !isVideoSlide}
|
||||
<ProgressBar
|
||||
autoplay={$slideshowAutoplay}
|
||||
hidden={!$showProgressBar}
|
||||
duration={$slideshowDelay}
|
||||
bind:this={progressBar}
|
||||
bind:status={progressBarStatus}
|
||||
onDone={handleDone}
|
||||
/>
|
||||
{/if}
|
||||
|
||||
Reference in New Issue
Block a user