mirror of
https://github.com/immich-app/immich.git
synced 2025-09-29 15:31:13 -04:00
fix(web): wait for image to load before playing memories. (#19757)
This commit is contained in:
parent
03dafba522
commit
fd2b7a344c
@ -10,26 +10,28 @@
|
||||
|
||||
interface Props {
|
||||
asset: TimelineAsset;
|
||||
onImageLoad: () => void;
|
||||
}
|
||||
|
||||
const { asset }: Props = $props();
|
||||
const { asset, onImageLoad }: Props = $props();
|
||||
|
||||
let assetFileUrl: string = $state('');
|
||||
let imageLoaded: boolean = $state(false);
|
||||
let loader = $state<HTMLImageElement>();
|
||||
|
||||
const onload = () => {
|
||||
const onLoadCallback = () => {
|
||||
imageLoaded = true;
|
||||
assetFileUrl = imageLoaderUrl;
|
||||
onImageLoad();
|
||||
};
|
||||
|
||||
onMount(() => {
|
||||
if (loader?.complete) {
|
||||
onload();
|
||||
onLoadCallback();
|
||||
}
|
||||
loader?.addEventListener('load', onload);
|
||||
loader?.addEventListener('load', onLoadCallback);
|
||||
return () => {
|
||||
loader?.removeEventListener('load', onload);
|
||||
loader?.removeEventListener('load', onLoadCallback);
|
||||
};
|
||||
});
|
||||
|
||||
|
@ -84,6 +84,7 @@
|
||||
let progressBarController: Tween<number> | undefined = $state(undefined);
|
||||
let videoPlayer: HTMLVideoElement | undefined = $state();
|
||||
const asHref = (asset: { id: string }) => `?${QueryParameter.ID}=${asset.id}`;
|
||||
|
||||
const handleNavigate = async (asset?: { id: string }) => {
|
||||
if ($isViewing) {
|
||||
return asset;
|
||||
@ -95,6 +96,7 @@
|
||||
|
||||
await goto(asHref(asset));
|
||||
};
|
||||
|
||||
const setProgressDuration = (asset: TimelineAsset) => {
|
||||
if (asset.isVideo) {
|
||||
const timeParts = asset.duration!.split(':').map(Number);
|
||||
@ -108,6 +110,7 @@
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
const handleNextAsset = () => handleNavigate(current?.next?.asset);
|
||||
const handlePreviousAsset = () => handleNavigate(current?.previous?.asset);
|
||||
const handleNextMemory = () => handleNavigate(current?.nextMemory?.assets[0]);
|
||||
@ -115,6 +118,7 @@
|
||||
const handleEscape = async () => goto(AppRoute.PHOTOS);
|
||||
const handleSelectAll = () =>
|
||||
assetInteraction.selectAssets(current?.memory.assets.map((a) => toTimelineAsset(a)) || []);
|
||||
|
||||
const handleAction = async (callingContext: string, action: 'reset' | 'pause' | 'play') => {
|
||||
// leaving these log statements here as comments. Very useful to figure out what's going on during dev!
|
||||
// console.log(`handleAction[${callingContext}] called with: ${action}`);
|
||||
@ -154,6 +158,7 @@
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const handleProgress = async (progress: number) => {
|
||||
if (!progressBarController) {
|
||||
return;
|
||||
@ -184,6 +189,7 @@
|
||||
memoryStore.hideAssetsFromMemory(ids);
|
||||
init(page);
|
||||
};
|
||||
|
||||
const handleDeleteMemoryAsset = async () => {
|
||||
if (!current) {
|
||||
return;
|
||||
@ -192,6 +198,7 @@
|
||||
await memoryStore.deleteAssetFromMemory(current.asset.id);
|
||||
init(page);
|
||||
};
|
||||
|
||||
const handleDeleteMemory = async () => {
|
||||
if (!current) {
|
||||
return;
|
||||
@ -201,6 +208,7 @@
|
||||
notificationController.show({ message: $t('removed_memory'), type: NotificationType.Info });
|
||||
init(page);
|
||||
};
|
||||
|
||||
const handleSaveMemory = async () => {
|
||||
if (!current) {
|
||||
return;
|
||||
@ -214,10 +222,12 @@
|
||||
});
|
||||
init(page);
|
||||
};
|
||||
|
||||
const handleGalleryScrollsIntoView = () => {
|
||||
galleryInView = true;
|
||||
handlePromiseError(handleAction('galleryInView', 'pause'));
|
||||
};
|
||||
|
||||
const handleGalleryScrollsOutOfView = () => {
|
||||
galleryInView = false;
|
||||
// only call play after the first page load. When page first loads the gallery will not be visible
|
||||
@ -246,16 +256,22 @@
|
||||
playerInitialized = false;
|
||||
};
|
||||
|
||||
const resetAndPlay = () => {
|
||||
handlePromiseError(handleAction('resetAndPlay', 'reset'));
|
||||
handlePromiseError(handleAction('resetAndPlay', 'play'));
|
||||
};
|
||||
|
||||
const initPlayer = () => {
|
||||
const isVideoAssetButPlayerHasNotLoadedYet = current && current.asset.isVideo && !videoPlayer;
|
||||
const isVideo = current && current.asset.isVideo;
|
||||
const isVideoAssetButPlayerHasNotLoadedYet = isVideo && !videoPlayer;
|
||||
if (playerInitialized || isVideoAssetButPlayerHasNotLoadedYet) {
|
||||
return;
|
||||
}
|
||||
if ($isViewing) {
|
||||
handlePromiseError(handleAction('initPlayer[AssetViewOpen]', 'pause'));
|
||||
} else {
|
||||
handlePromiseError(handleAction('initPlayer[AssetViewClosed]', 'reset'));
|
||||
handlePromiseError(handleAction('initPlayer[AssetViewClosed]', 'play'));
|
||||
} else if (isVideo) {
|
||||
// Image assets will start playing when the image is loaded. Only autostart video assets.
|
||||
resetAndPlay();
|
||||
}
|
||||
playerInitialized = true;
|
||||
};
|
||||
@ -474,7 +490,7 @@
|
||||
videoViewerVolume={$videoViewerVolume}
|
||||
/>
|
||||
{:else}
|
||||
<MemoryPhotoViewer asset={current.asset} />
|
||||
<MemoryPhotoViewer asset={current.asset} onImageLoad={resetAndPlay} />
|
||||
{/if}
|
||||
{/key}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user