Skip to content

Commit

Permalink
feat(web): Video memories on web (#16500)
Browse files Browse the repository at this point in the history
* Video memories on web

* switched mixed up strings
  • Loading branch information
YarosMallorca authored Mar 3, 2025
1 parent 8b24c31 commit 7bbc1d9
Show file tree
Hide file tree
Showing 2 changed files with 65 additions and 10 deletions.
2 changes: 2 additions & 0 deletions i18n/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down Expand Up @@ -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",
Expand Down
73 changes: 63 additions & 10 deletions web/src/lib/components/memory-page/memory-viewer.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -57,6 +58,8 @@
mdiPlay,
mdiPlus,
mdiSelectAll,
mdiVolumeOff,
mdiVolumeHigh,
} from '@mdi/js';
import type { NavigationTarget } from '@sveltejs/kit';
import { DateTime } from 'luxon';
Expand Down Expand Up @@ -91,9 +94,10 @@
const { isViewing } = assetViewingStore;
const viewport: Viewport = $state({ width: 0, height: 0 });
const assetInteraction = new AssetInteraction();
const progressBarController = tweened<number>(0, {
let progressBarController = tweened<number>(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[] = [];
Expand Down Expand Up @@ -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<number>(0, {
duration: (from: number, to: number) => (to ? durationInMilliseconds * (to - from) : 0),
});
} else {
progressBarController = tweened<number>(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]);
Expand All @@ -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;
}
Expand Down Expand Up @@ -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) => {
Expand Down Expand Up @@ -290,6 +316,12 @@
$effect(() => {
handlePromiseError(handleAction(galleryInView ? 'pause' : 'play'));
});
$effect(() => {
if (videoPlayer) {
videoPlayer.muted = $videoViewerMuted;
}
});
</script>

<svelte:window
Expand Down Expand Up @@ -373,6 +405,11 @@
{(current.assetIndex + 1).toLocaleString($locale)}/{current.memory.assets.length.toLocaleString($locale)}
</p>
</div>
<CircleIconButton
title={$videoViewerMuted ? $t('unmute_memories') : $t('mute_memories')}
icon={$videoViewerMuted ? mdiVolumeOff : mdiVolumeHigh}
onclick={() => ($videoViewerMuted = !$videoViewerMuted)}
/>
</div>
</ControlAppBar>

Expand Down Expand Up @@ -436,13 +473,29 @@
>
<div class="relative h-full w-full rounded-2xl bg-black">
{#key current.asset.id}
<img
transition:fade
class="h-full w-full rounded-2xl object-contain transition-all"
src={getAssetThumbnailUrl({ id: current.asset.id, size: AssetMediaSize.Preview })}
alt={current.asset.exifInfo?.description}
draggable="false"
/>
<div transition:fade class="h-full w-full">
{#if current.asset.type == AssetTypeEnum.Video}
<video
bind:this={videoPlayer}
autoplay
playsinline
class="h-full w-full rounded-2xl object-contain transition-all"
src={getAssetPlaybackUrl({ id: current.asset.id })}
poster={getAssetThumbnailUrl({ id: current.asset.id, size: AssetMediaSize.Preview })}
draggable="false"
muted={$videoViewerMuted}
transition:fade
></video>
{:else}
<img
class="h-full w-full rounded-2xl object-contain transition-all"
src={getAssetThumbnailUrl({ id: current.asset.id, size: AssetMediaSize.Preview })}
alt={current.asset.exifInfo?.description}
draggable="false"
transition:fade
/>
{/if}
</div>
{/key}

<div
Expand Down

0 comments on commit 7bbc1d9

Please sign in to comment.