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