From 7bbc1d9f68a87d39b7a21f6b53d30b3742457171 Mon Sep 17 00:00:00 2001 From: Yaros Date: Mon, 3 Mar 2025 16:54:26 +0100 Subject: [PATCH] feat(web): Video memories on web (#16500) * Video memories on web * switched mixed up strings --- i18n/en.json | 2 + .../memory-page/memory-viewer.svelte | 73 ++++++++++++++++--- 2 files changed, 65 insertions(+), 10 deletions(-) diff --git a/i18n/en.json b/i18n/en.json index 4f84d140e0e..c4cf1e80a1a 100644 --- a/i18n/en.json +++ b/i18n/en.json @@ -890,6 +890,7 @@ "month": "Month", "more": "More", "moved_to_trash": "Moved to trash", + "mute_memories": "Mute Memories", "my_albums": "My albums", "name": "Name", "name_or_nickname": "Name or nickname", @@ -1304,6 +1305,7 @@ "unnamed_album": "Unnamed Album", "unnamed_album_delete_confirmation": "Are you sure you want to delete this album?", "unnamed_share": "Unnamed Share", + "unmute_memories": "Unmute Memories", "unsaved_change": "Unsaved change", "unselect_all": "Unselect all", "unselect_all_duplicates": "Unselect all duplicates", diff --git a/web/src/lib/components/memory-page/memory-viewer.svelte b/web/src/lib/components/memory-page/memory-viewer.svelte index c1ec31470fd..0e4c1725afd 100644 --- a/web/src/lib/components/memory-page/memory-viewer.svelte +++ b/web/src/lib/components/memory-page/memory-viewer.svelte @@ -28,13 +28,14 @@ import { assetViewingStore } from '$lib/stores/asset-viewing.store'; import { type Viewport } from '$lib/stores/assets.store'; import { loadMemories, memoryStore } from '$lib/stores/memory.store'; - import { locale } from '$lib/stores/preferences.store'; + import { locale, videoViewerMuted } from '$lib/stores/preferences.store'; import { preferences } from '$lib/stores/user.store'; - import { getAssetThumbnailUrl, handlePromiseError, memoryLaneTitle } from '$lib/utils'; + import { getAssetPlaybackUrl, getAssetThumbnailUrl, handlePromiseError, memoryLaneTitle } from '$lib/utils'; import { cancelMultiselect } from '$lib/utils/asset-utils'; import { fromLocalDateTime } from '$lib/utils/timeline-util'; import { AssetMediaSize, + AssetTypeEnum, deleteMemory, removeMemoryAssets, updateMemory, @@ -57,6 +58,8 @@ mdiPlay, mdiPlus, mdiSelectAll, + mdiVolumeOff, + mdiVolumeHigh, } from '@mdi/js'; import type { NavigationTarget } from '@sveltejs/kit'; import { DateTime } from 'luxon'; @@ -91,9 +94,10 @@ const { isViewing } = assetViewingStore; const viewport: Viewport = $state({ width: 0, height: 0 }); const assetInteraction = new AssetInteraction(); - const progressBarController = tweened(0, { + let progressBarController = tweened(0, { duration: (from: number, to: number) => (to ? 5000 * (to - from) : 0), }); + let videoPlayer: HTMLVideoElement | undefined = $state(); const memories = storeDerived(memoryStore, (memories) => { memories = memories ?? []; const memoryAssets: MemoryAsset[] = []; @@ -139,8 +143,24 @@ return; } + // Adjust the progress bar duration to the video length + setProgressDuration(asset); + await goto(asHref(asset)); }; + const setProgressDuration = (asset: AssetResponseDto) => { + if (asset.type === AssetTypeEnum.Video) { + const timeParts = asset.duration.split(':').map(Number); + const durationInMilliseconds = (timeParts[0] * 3600 + timeParts[1] * 60 + timeParts[2]) * 1000; + progressBarController = tweened(0, { + duration: (from: number, to: number) => (to ? durationInMilliseconds * (to - from) : 0), + }); + } else { + progressBarController = tweened(0, { + duration: (from: number, to: number) => (to ? 5000 * (to - from) : 0), + }); + } + }; const handleNextAsset = () => handleNavigate(current?.next?.asset); const handlePreviousAsset = () => handleNavigate(current?.previous?.asset); const handleNextMemory = () => handleNavigate(current?.nextMemory?.assets[0]); @@ -151,18 +171,21 @@ switch (action) { case 'play': { paused = false; + await videoPlayer?.play(); await progressBarController.set(1); break; } case 'pause': { paused = true; + videoPlayer?.pause(); await progressBarController.set($progressBarController); break; } case 'reset': { paused = false; + videoPlayer?.pause(); resetPromise = progressBarController.set(0); break; } @@ -203,6 +226,9 @@ } current = loadFromParams($memories, $page); + + // Adjust the progress bar duration to the video length + setProgressDuration(current.asset); }; const handleDeleteMemoryAsset = async (current?: MemoryAsset) => { @@ -290,6 +316,12 @@ $effect(() => { handlePromiseError(handleAction(galleryInView ? 'pause' : 'play')); }); + + $effect(() => { + if (videoPlayer) { + videoPlayer.muted = $videoViewerMuted; + } + }); + ($videoViewerMuted = !$videoViewerMuted)} + /> @@ -436,13 +473,29 @@ >
{#key current.asset.id} - {current.asset.exifInfo?.description} +
+ {#if current.asset.type == AssetTypeEnum.Video} + + {:else} + {current.asset.exifInfo?.description} + {/if} +
{/key}