diff --git a/src/lib/components/VideoPlayer/ProgressBar.svelte b/src/lib/components/VideoPlayer/ProgressBar.svelte index f856f8e..3bbfbe5 100644 --- a/src/lib/components/VideoPlayer/ProgressBar.svelte +++ b/src/lib/components/VideoPlayer/ProgressBar.svelte @@ -5,17 +5,26 @@ import type { NavigateEvent } from '../../selectable'; import { formatMinutesToTime, formatSecondsToTime } from '../../utils'; - export let totalTime: number; - export let progressTime: number; + export let duration: number; + export let currentTime: number; export let bufferedTime: number; export let step = 0.1; export let paused = false; - export let seeking = false; + let displayTime = currentTime; + + const updateDisplayTime = (time: number) => { + if (!seeking) { + displayTime = time; + } + }; + $: updateDisplayTime(currentTime); + const dispatch = createEventDispatcher<{ jumpTo: number; - playPause: void; + play: void; + pause: void; }>(); let pausedBeforeSeeking = paused; @@ -23,25 +32,28 @@ seeking = true; pausedBeforeSeeking = paused; - paused = true; + dispatch('pause'); } function handleStopSeeking() { if (!seeking) return; - paused = pausedBeforeSeeking; - seeking = false; + dispatch('jumpTo', displayTime); - dispatch('jumpTo', progressTime); + if (!pausedBeforeSeeking) { + dispatch('play'); + } else { + dispatch('pause'); + } + seeking = false; } - let pauseTime = 0; + let pauseTime: number | undefined = undefined; const handlePause = (paused: boolean) => { - if (paused) { - pauseTime = progressTime; - } else if (pauseTime > 0) { + if (pauseTime !== undefined) { dispatch('jumpTo', pauseTime); - pauseTime = 0; + displayTime = pauseTime; + pauseTime = undefined; } }; $: handlePause(paused); @@ -49,16 +61,16 @@ function handleNavigateEvent({ detail }: CustomEvent) { if (detail.direction === 'left') { if (paused) { - pauseTime = pauseTime - 10; + pauseTime = Math.max(0, (pauseTime ?? currentTime) - 10); } else { - dispatch('jumpTo', progressTime - 10); + dispatch('jumpTo', displayTime - 10); detail.preventNavigation(); } } else if (detail.direction === 'right') { if (paused) { - pauseTime = pauseTime + 30; + pauseTime = Math.min(duration, (pauseTime ?? currentTime) + 30); } else { - dispatch('jumpTo', progressTime + 30); + dispatch('jumpTo', displayTime + 30); detail.preventNavigation(); } } @@ -71,15 +83,15 @@ let:hasFocus focusOnMount on:navigate={handleNavigateEvent} - on:select={() => dispatch('playPause')} + on:select={() => dispatch(paused ? 'play' : 'pause')} >
@@ -87,8 +99,8 @@
0 ? pauseTime : progressTime) / totalTime) * 100 - }% - 0.5rem + ${(pauseTime > 0 ? pauseTime : progressTime) / totalTime}rem);`} + (1 - (pauseTime ?? displayTime) / duration) * 100 + }% - 0.5rem + ${(pauseTime ?? displayTime) / duration}rem);`} />
0 ? pauseTime : progressTime) / totalTime) * 100}% - ${ - (pauseTime > 0 ? pauseTime : progressTime) / totalTime + style={`left: calc(${((pauseTime ?? displayTime) / duration) * 100}% - ${ + (pauseTime ?? displayTime) / duration }rem); box-shadow: 0 0 0.25rem 2px #00000033; `} @@ -109,9 +121,9 @@ type="range" class="w-full absolute cursor-pointer h-4 inset-y-0 opacity-0" min={0} - max={totalTime} + max={duration} {step} - bind:value={progressTime} + bind:value={displayTime} on:mousedown={handleStartSeeking} on:mouseup={handleStopSeeking} on:touchstart={handleStartSeeking} @@ -119,7 +131,7 @@ />
- {formatSecondsToTime(pauseTime || progressTime)} - -{formatSecondsToTime(totalTime - (pauseTime || progressTime))} + {formatSecondsToTime(pauseTime || displayTime)} + -{formatSecondsToTime(duration - (pauseTime || displayTime))}
diff --git a/src/lib/components/VideoPlayer/TmdbVideoPlayerModal.svelte b/src/lib/components/VideoPlayer/TmdbVideoPlayerModal.svelte index b5ff382..705d528 100644 --- a/src/lib/components/VideoPlayer/TmdbVideoPlayerModal.svelte +++ b/src/lib/components/VideoPlayer/TmdbVideoPlayerModal.svelte @@ -1,23 +1,24 @@ @@ -110,14 +116,14 @@ } handleShowInterface(); }} + on:click={() => (paused ? video?.play() : video?.pause())} > {/if} - { - if (detail.direction === 'up') { - detail.stopPropagation(); - detail.preventNavigation(); - handleHideInterface(); - } - }} - class="flex justify-between px-2 py-4 items-end" +
+
@{source}
+
-
- {subtitle} + Ends at {new Date( + clockTime + ((duration ?? 0) - (currentTime ?? 0)) * 1000 + ).toLocaleTimeString('en-US', { hour: '2-digit', minute: '2-digit' })} +
+
+ +
e.stopPropagation()}> + { + if (detail.direction === 'up') { + detail.stopPropagation(); + detail.preventNavigation(); + handleHideInterface(); + } + }} + class="flex justify-between px-2 py-4 items-end" + > +
+
+ {subtitle} +
+

{title}

-

{title}

-
-
- { - // video.pause(); - modalStack.create(SelectSubtitlesModal, { - subtitleInfo, - selectSubtitles - }); - }} - > - - - { - // video.pause(); - modalStack.create(SelectAudioModal, { - selectedAudioStreamIndex: playbackInfo?.audioStreamIndex || -1, - audioTracks: playbackInfo?.audioTracks || [], - selectAudioStream - // onClose: () => video.play() - }); - }} - > - - -
- - { - video.currentTime = e.detail; - }} - on:playPause={() => { - if (paused) video.play(); - else video.pause(); - }} - bind:totalTime - bind:progressTime - bind:bufferedTime - bind:paused - /> +
+ { + // video.pause(); + modalStack.create(SelectSubtitlesModal, { + subtitleInfo, + selectSubtitles + }); + }} + > + + + { + // video.pause(); + modalStack.create(SelectAudioModal, { + selectedAudioStreamIndex: playbackInfo?.audioStreamIndex || -1, + audioTracks: playbackInfo?.audioTracks || [], + selectAudioStream + // onClose: () => video.play() + }); + }} + > + + +
+ + { + video.currentTime = e.detail; + video.play(); + }} + on:play={() => video.play()} + on:pause={() => video.pause()} + {duration} + {currentTime} + {bufferedTime} + bind:paused + /> +