Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(web): improvements to slideshow #8032

Merged
merged 9 commits into from
Mar 21, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
7 changes: 7 additions & 0 deletions web/src/lib/components/asset-viewer/asset-viewer.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,9 @@
let isShowActivity = false;
let isLiked: ActivityResponseDto | null = null;
let numberOfComments: number;
let fullscreenElement: Element;

$: isFullScreen = fullscreenElement !== null;

$: {
if (asset.stackCount && asset.stack) {
Expand Down Expand Up @@ -512,6 +515,8 @@
]}
/>

<svelte:document bind:fullscreenElement />

<section
id="immich-asset-viewer"
class="fixed left-0 top-0 z-[1001] grid h-screen w-screen grid-cols-4 grid-rows-[64px_1fr] overflow-hidden bg-black"
Expand Down Expand Up @@ -562,6 +567,8 @@
{#if $slideshowState != SlideshowState.None}
<div class="z-[1000] absolute w-full flex">
<SlideshowBar
{isFullScreen}
onSetToFullScreen={() => assetViewerHtmlElement.requestFullscreen()}
onPrevious={() => navigateAsset('previous')}
onNext={() => navigateAsset('next')}
onClose={() => ($slideshowState = SlideshowState.StopSlideshow)}
Expand Down
67 changes: 54 additions & 13 deletions web/src/lib/components/asset-viewer/slideshow-bar.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -3,23 +3,46 @@
import ProgressBar, { ProgressBarStatus } from '$lib/components/shared-components/progress-bar/progress-bar.svelte';
import SlideshowSettings from '$lib/components/slideshow-settings.svelte';
import { SlideshowNavigation, slideshowStore } from '$lib/stores/slideshow.store';
import { mdiChevronLeft, mdiChevronRight, mdiClose, mdiCog, mdiPause, mdiPlay } from '@mdi/js';
import { mdiChevronLeft, mdiChevronRight, mdiClose, mdiCog, mdiFullscreen, mdiPause, mdiPlay } from '@mdi/js';
import { onDestroy, onMount } from 'svelte';
import { fly } from 'svelte/transition';

export let isFullScreen: boolean;
export let onNext = () => {};
export let onPrevious = () => {};
export let onClose = () => {};
export let onSetToFullScreen = () => {};

const { restartProgress, stopProgress, slideshowDelay, showProgressBar, slideshowNavigation } = slideshowStore;

let progressBarStatus: ProgressBarStatus;
let progressBar: ProgressBar;
let showSettings = false;
let showControls = true;
let timer: NodeJS.Timeout;
let isOverControls = false;

let unsubscribeRestart: () => void;
let unsubscribeStop: () => void;

const resetTimer = () => {
clearTimeout(timer);
document.body.style.cursor = '';
showControls = true;
startTimer();
};

const startTimer = () => {
timer = setTimeout(() => {
if (!isOverControls) {
showControls = false;
document.body.style.cursor = 'none';
}
}, 10_000);
};

onMount(() => {
startTimer();
unsubscribeRestart = restartProgress.subscribe((value) => {
if (value) {
progressBar.restart(value);
Expand Down Expand Up @@ -52,19 +75,37 @@
};
</script>

<div class="m-4 flex gap-2">
<CircleIconButton buttonSize="50" icon={mdiClose} on:click={onClose} title="Exit Slideshow" />
<CircleIconButton
buttonSize="50"
icon={progressBarStatus === ProgressBarStatus.Paused ? mdiPlay : mdiPause}
on:click={() => (progressBarStatus === ProgressBarStatus.Paused ? progressBar.play() : progressBar.pause())}
title={progressBarStatus === ProgressBarStatus.Paused ? 'Play' : 'Pause'}
/>
<CircleIconButton buttonSize="50" icon={mdiChevronLeft} on:click={onPrevious} title="Previous" />
<CircleIconButton buttonSize="50" icon={mdiChevronRight} on:click={onNext} title="Next" />
<CircleIconButton buttonSize="50" icon={mdiCog} on:click={() => (showSettings = !showSettings)} title="Next" />
</div>
<svelte:window on:mousemove={resetTimer} />

{#if showControls}
<!-- svelte-ignore a11y-no-static-element-interactions -->
<div
class="m-4 flex gap-2"
on:mouseenter={() => (isOverControls = true)}
on:mouseleave={() => (isOverControls = false)}
transition:fly={{ duration: 150 }}
>
<CircleIconButton buttonSize="50" icon={mdiClose} on:click={onClose} title="Exit Slideshow" />

<CircleIconButton
buttonSize="50"
icon={progressBarStatus === ProgressBarStatus.Paused ? mdiPlay : mdiPause}
on:click={() => (progressBarStatus === ProgressBarStatus.Paused ? progressBar.play() : progressBar.pause())}
title={progressBarStatus === ProgressBarStatus.Paused ? 'Play' : 'Pause'}
/>
<CircleIconButton buttonSize="50" icon={mdiChevronLeft} on:click={onPrevious} title="Previous" />
<CircleIconButton buttonSize="50" icon={mdiChevronRight} on:click={onNext} title="Next" />
<CircleIconButton buttonSize="50" icon={mdiCog} on:click={() => (showSettings = !showSettings)} title="Next" />
{#if !isFullScreen}
<CircleIconButton
buttonSize="50"
icon={mdiFullscreen}
on:click={onSetToFullScreen}
title="Set Slideshow to fullscreen"
/>
{/if}
</div>
{/if}
{#if showSettings}
<SlideshowSettings onClose={() => (showSettings = false)} />
{/if}
Expand Down
3 changes: 3 additions & 0 deletions web/src/lib/components/asset-viewer/video-viewer.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,9 @@

export let assetId: string;

let element: HTMLVideoElement | undefined = undefined;
let isVideoLoading = true;

const dispatch = createEventDispatcher<{ onVideoEnded: void; onVideoStarted: void }>();

const handleCanPlay = async (event: Event) => {
Expand All @@ -29,6 +31,7 @@

<div transition:fade={{ duration: 150 }} class="flex h-full select-none place-content-center place-items-center">
<video
bind:this={element}
autoplay
playsinline
controls
Expand Down