fix(web): wait for image to load before playing memories. (#19757)

This commit is contained in:
Dag Stuan 2025-08-31 15:50:33 +02:00 committed by GitHub
parent 03dafba522
commit fd2b7a344c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 28 additions and 10 deletions

View File

@ -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);
};
});

View File

@ -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}