From 438d59b94211e0397b07c4d26d3b7dfd2c3ea09d Mon Sep 17 00:00:00 2001 From: Rob Rogers Date: Sun, 19 Apr 2026 22:02:41 -0400 Subject: [PATCH 1/2] Fix freeze caused by progress bar firing onDone during asset transitions --- .../components/elements/progress-bar.svelte | 4 ++- .../lib/components/home-page/home-page.svelte | 34 +++++++++---------- 2 files changed, 20 insertions(+), 18 deletions(-) diff --git a/immichFrame.Web/src/lib/components/elements/progress-bar.svelte b/immichFrame.Web/src/lib/components/elements/progress-bar.svelte index 3cb7d832..162e264c 100644 --- a/immichFrame.Web/src/lib/components/elements/progress-bar.svelte +++ b/immichFrame.Web/src/lib/components/elements/progress-bar.svelte @@ -28,7 +28,9 @@ const onChange = async (progressDuration: number) => { progress = setDuration(progressDuration); - await play(); + if (status === ProgressBarStatus.Playing) { + await play(); + } }; let progress = setDuration(duration); diff --git a/immichFrame.Web/src/lib/components/home-page/home-page.svelte b/immichFrame.Web/src/lib/components/home-page/home-page.svelte index fa183550..7c51f6de 100644 --- a/immichFrame.Web/src/lib/components/home-page/home-page.svelte +++ b/immichFrame.Web/src/lib/components/home-page/home-page.svelte @@ -149,24 +149,24 @@ } } - let isHandlingAssetTransition = false; + let transitionLock: Promise = Promise.resolve(); + const handleDone = async (previous: boolean = false, instant: boolean = false) => { - if (isHandlingAssetTransition) { - return; - } - isHandlingAssetTransition = true; - try { - userPaused = false; - progressBar.restart(false); - $instantTransition = instant; - if (previous) await getPreviousAssets(); - else await getNextAssets(); - await tick(); - await assetComponent?.play?.(); - progressBar.play(); - } finally { - isHandlingAssetTransition = false; - } + transitionLock = transitionLock + .then(async () => { + userPaused = false; + progressBar.restart(false); + $instantTransition = instant; + if (previous) await getPreviousAssets(); + else await getNextAssets(); + await tick(); + await assetComponent?.play?.(); + progressBar.play(); + }) + .catch((err) => { + console.error('handleDone transition failed:', err); + }); + await transitionLock; }; async function getNextAssets() { From 02a8aad481d2794ffeb7c2462abfc26c2520fbaf Mon Sep 17 00:00:00 2001 From: Rob Rogers Date: Mon, 20 Apr 2026 20:29:00 -0400 Subject: [PATCH 2/2] add onDestroy to asset.svelte, roll back non-working fixes. --- .../src/lib/components/elements/asset.svelte | 22 ++++++++++++++++--- .../components/elements/progress-bar.svelte | 4 +--- 2 files changed, 20 insertions(+), 6 deletions(-) diff --git a/immichFrame.Web/src/lib/components/elements/asset.svelte b/immichFrame.Web/src/lib/components/elements/asset.svelte index 14ee6465..92679fd2 100644 --- a/immichFrame.Web/src/lib/components/elements/asset.svelte +++ b/immichFrame.Web/src/lib/components/elements/asset.svelte @@ -9,6 +9,7 @@ import { thumbHashToDataURL } from 'thumbhash'; import AssetInfo from '$lib/components/elements/asset-info.svelte'; import ImageOverlay from '$lib/components/elements/imageoverlay/image-overlay.svelte'; + import { onDestroy } from 'svelte'; interface Props { asset: [url: string, asset: AssetResponseDto, albums: AlbumResponseDto[]]; @@ -184,6 +185,18 @@ } } }; + + let isDestroyed = false; + + onDestroy(() => { + isDestroyed = true; + if (videoElement) { + videoElement.pause(); + videoElement.src = ''; + videoElement.removeAttribute('src'); + videoElement.load(); + } + }); {#if showInfo} @@ -246,9 +259,12 @@ } } }} - onerror={() => console.error('Video failed to load:', asset[0])} - onwaiting={onVideoWaiting} - onplaying={onVideoPlaying} + onwaiting={() => { + if (!isDestroyed) onVideoWaiting(); + }} + onplaying={() => { + if (!isDestroyed) onVideoPlaying(); + }} > {:else} { progress = setDuration(progressDuration); - if (status === ProgressBarStatus.Playing) { - await play(); - } + await play(); }; let progress = setDuration(duration);