From 0a347d84b2c0edf1f93b797c8ea2f5f636ede58c Mon Sep 17 00:00:00 2001 From: Mees Frensel Date: Mon, 16 Feb 2026 11:54:43 +0100 Subject: [PATCH] add seek & rate buttons --- .../asset-viewer/asset-viewer.svelte | 2 +- .../asset-viewer/video-native-viewer.svelte | 61 ++++++++++++++++--- .../asset-viewer/video-wrapper-viewer.svelte | 6 +- 3 files changed, 56 insertions(+), 13 deletions(-) diff --git a/web/src/lib/components/asset-viewer/asset-viewer.svelte b/web/src/lib/components/asset-viewer/asset-viewer.svelte index 5bb31be7fd..2129c52d99 100644 --- a/web/src/lib/components/asset-viewer/asset-viewer.svelte +++ b/web/src/lib/components/asset-viewer/asset-viewer.svelte @@ -513,7 +513,6 @@ cacheKey={asset.thumbhash} projectionType={asset.exifInfo?.projectionType} loopVideo={$slideshowState !== SlideshowState.PlaySlideshow} - showFullscreen={false} onPreviousAsset={() => navigateAsset('previous')} onNextAsset={() => navigateAsset('next')} onVideoEnded={() => (assetViewerManager.isPlayingMotionPhoto = false)} @@ -537,6 +536,7 @@ cacheKey={asset.thumbhash} projectionType={asset.exifInfo?.projectionType} loopVideo={$slideshowState !== SlideshowState.PlaySlideshow} + extendedControls onPreviousAsset={() => navigateAsset('previous')} onNextAsset={() => navigateAsset('next')} onClose={closeViewer} diff --git a/web/src/lib/components/asset-viewer/video-native-viewer.svelte b/web/src/lib/components/asset-viewer/video-native-viewer.svelte index 287d833e0d..8db6939dc2 100644 --- a/web/src/lib/components/asset-viewer/video-native-viewer.svelte +++ b/web/src/lib/components/asset-viewer/video-native-viewer.svelte @@ -14,6 +14,8 @@ mdiFullscreenExit, mdiPause, mdiPlay, + mdiSkipBackward, + mdiSkipForward, mdiVolumeHigh, mdiVolumeLow, mdiVolumeMedium, @@ -25,6 +27,8 @@ import 'media-chrome/media-mute-button'; import 'media-chrome/media-play-button'; import 'media-chrome/media-playback-rate-button'; + import 'media-chrome/media-seek-backward-button'; + import 'media-chrome/media-seek-forward-button'; import 'media-chrome/media-time-display'; import 'media-chrome/media-time-range'; import 'media-chrome/media-volume-range'; @@ -38,7 +42,7 @@ loopVideo: boolean; cacheKey: string | null; playOriginalVideo: boolean; - showFullscreen?: boolean; + extendedControls?: boolean; onPreviousAsset?: () => void; onNextAsset?: () => void; onVideoEnded?: () => void; @@ -52,7 +56,7 @@ loopVideo, cacheKey, playOriginalVideo, - showFullscreen = true, + extendedControls = false, onPreviousAsset = () => {}, onNextAsset = () => {}, onVideoEnded = () => {}, @@ -67,6 +71,8 @@ ? getAssetMediaUrl({ id: assetId, size: AssetMediaSize.Original, cacheKey }) : getAssetPlaybackUrl({ id: assetId, cacheKey }), ); + let duration = $derived(timeToSeconds(asset.duration)); + let showSeekButtons = $derived(duration > 10); let showVideo = $state(false); onMount(() => { @@ -154,7 +160,8 @@ /> {:else} - + +
- + {#if extendedControls && showSeekButtons} + + + + {/if} + + + + + {#if extendedControls && showSeekButtons} + + + + {/if}
@@ -180,8 +199,21 @@ + {#if extendedControls && showSeekButtons} + + + + + + + {/if} + + {#if extendedControls} + + {/if}
@@ -195,7 +227,7 @@
- {#if showFullscreen} + {#if extendedControls} @@ -244,23 +276,34 @@ /* Small screens */ media-controller { --bottom-play-button-display: none; - --center-play-button-display: inline-flex; + --bottom-seek-buttons-display: none; + --center-buttons-display: inline-flex; + --media-playback-rate-button-display: none; --media-time-range-display: none; } /* Larger screens */ *[breakpointsm] { --bottom-play-button-display: flex; - --center-play-button-display: none; + --center-buttons-display: none; --media-time-range-display: flex; } + *[breakpointmd] { + --bottom-seek-buttons-display: flex; + --media-playback-rate-button-display: inline-flex; + } + *::part(bottom) { --media-play-button-display: var(--bottom-play-button-display); + --media-seek-backward-button-display: var(--bottom-seek-buttons-display); + --media-seek-forward-button-display: var(--bottom-seek-buttons-display); } *::part(center) { - --media-play-button-display: var(--center-play-button-display); + --media-play-button-display: var(--center-buttons-display); + --media-seek-backward-button-display: var(--center-buttons-display); + --media-seek-forward-button-display: var(--center-buttons-display); } *::part(tooltip) { diff --git a/web/src/lib/components/asset-viewer/video-wrapper-viewer.svelte b/web/src/lib/components/asset-viewer/video-wrapper-viewer.svelte index 9698384ad2..a069ab3c4c 100644 --- a/web/src/lib/components/asset-viewer/video-wrapper-viewer.svelte +++ b/web/src/lib/components/asset-viewer/video-wrapper-viewer.svelte @@ -11,7 +11,7 @@ cacheKey: string | null; loopVideo: boolean; playOriginalVideo: boolean; - showFullscreen?: boolean; + extendedControls?: boolean; onClose?: () => void; onPreviousAsset?: () => void; onNextAsset?: () => void; @@ -26,7 +26,7 @@ cacheKey, loopVideo, playOriginalVideo, - showFullscreen = true, + extendedControls = false, onPreviousAsset, onClose, onNextAsset, @@ -46,7 +46,7 @@ {asset} assetId={effectiveAssetId} {playOriginalVideo} - {showFullscreen} + {extendedControls} {onPreviousAsset} {onNextAsset} {onVideoEnded}