@@ -6,11 +6,11 @@ import type { ComputedRef, Ref } from 'vue';
66import { getScreenSize , handleStorageURL , isInputLikeElement , isMobileDevice , toFormattedDate , toFormattedDuration } from ' @/service/util' ;
77import { computed , nextTick , onBeforeUnmount , onMounted , ref , useTemplateRef , watch } from ' vue' ;
88import { copyVideoFrame , saveVideoFrame } from ' @/service/video/frameService' ;
9- import { debounce , round , throttle } from ' lodash' ;
109import { useRoute , useRouter } from ' vue-router' ;
1110import { UseCreatePlayback } from ' @/service/mutations' ;
1211import { useVideoPlayback } from ' @/service/queries' ;
1312import { useContentStore } from ' @/stores/ContentStore' ;
13+ import { debounce , round } from ' lodash' ;
1414import { useAuthStore } from ' @/stores/AuthStore' ;
1515import { useAppStore } from ' @/stores/AppStore' ;
1616import { storeToRefs } from ' pinia' ;
@@ -20,13 +20,12 @@ import { onSeek } from '@/service/video/seekBus';
2020import { toast } from ' @/service/toaster/toastService' ;
2121
2222import VideoPopoverSlider from ' @/components/video/VideoPopoverSlider.vue' ;
23- import VideoTooltipSlider from ' @/components/video/VideoTooltipSlider.vue' ;
2423import VideoPopoverItem from ' @/components/video/VideoPopoverItem.vue' ;
2524import VideoPartyPanel from ' @/components/video/VideoPartyPanel.vue' ;
25+ import VideoTimeline from ' @/components/video/VideoTimeline.vue' ;
2626import ButtonCorner from ' @/components/inputs/ButtonCorner.vue' ;
2727import VideoHeatmap from ' @/components/video/VideoHeatmap.vue' ;
2828import VideoPopover from ' @/components/video/VideoPopover.vue' ;
29-
3029import VideoButton from ' @/components/video/VideoButton.vue' ;
3130import VideoSlider from ' @/components/video/VideoSlider.vue' ;
3231import VideoLyrics from ' @/components/video/VideoLyrics.vue' ;
@@ -179,11 +178,11 @@ const keyBinds = computed(() => {
179178});
180179
181180// Elements
182- const container = useTemplateRef (' video-container' );
183- const progressBar = useTemplateRef (' progress-bar' );
184- const popover = useTemplateRef (' popover' );
185- const progressTooltip = useTemplateRef (' progress-tooltip' );
186181const player = useTemplateRef (' player' );
182+ const popover = useTemplateRef (' popover' );
183+ const container = useTemplateRef (' video-container' );
184+ const timeline = useTemplateRef (' video-timeline' );
185+ const progressTooltip = timeline .value ?.progressTooltip ;
187186// const url = ref('');
188187
189188const contextMenuItems = computed (() => {
@@ -730,7 +729,7 @@ function resetControlsTimeout() {
730729 controlsHideTimeout .value = window .setTimeout (() => {
731730 isShowingControls .value = false ;
732731 popover .value ?.handleClose ();
733- progressTooltip . value ?.tooltipToggle (false );
732+ progressTooltip ?.tooltipToggle (false );
734733 }, controlsHideTime );
735734}
736735
@@ -792,25 +791,6 @@ function getPlayerInfo() {
792791 frameHealth .value = ` ${playbackQuality .droppedVideoFrames } / ${playbackQuality .totalVideoFrames } ` ;
793792}
794793
795- const handleProgressTooltip = throttle ((event : MouseEvent ) => {
796- getProgressTooltip (event );
797- requestAnimationFrame (() => {
798- if (! progressTooltip .value ) return ;
799- progressTooltip .value .calculateTooltipPosition (event );
800- });
801- }, 7 );
802-
803- const getProgressTooltip = (event : MouseEvent ) => {
804- if (! player .value || ! timeDuration .value || ! progressBar .value ) return ;
805- const rect = progressBar .value .getBoundingClientRect ();
806- const offsetX = event .clientX - rect .left ;
807- const percent = offsetX / rect .width ;
808-
809- const time = percent < 0 ? 0 : Math .min (timeDuration .value , percent * timeDuration .value );
810-
811- timeSeeking .value = toFormattedDuration (time , true , ' digital' ) ?? ' 00:00' ;
812- };
813-
814794const handleLoadSavedVolume = () => {
815795 const savedVolume = parseFloat (localStorage .getItem (' videoVolume' ) ?? ' ' );
816796 if (isNaN (savedVolume ) || ! player .value ) {
@@ -1023,7 +1003,7 @@ defineExpose({
10231003 preload =" metadata"
10241004 :class =" [
10251005 `relative focus:outline-none object-contain h-full select-none`,
1026- `${!stateVideo?.path ? 'aspect-video' : (isAudio || aspectRatio.isPortrait) && !isFullScreen ? ` max-h-[60vh ]` : ' aspect-video'}`,
1006+ `${!stateVideo?.path ? 'aspect-video' : (isAudio || aspectRatio.isPortrait) && !isFullScreen ? ` max-h-[71vh ]` : ' aspect-video'}`,
10271007 { 'bg-black': !isAudio && !aspectRatio.isAspectVideo },
10281008 `${isShowingControls ? 'cursor-auto' : 'cursor-none'}`,
10291009 ]"
@@ -1135,7 +1115,20 @@ defineExpose({
11351115 style =" z-index : 7 "
11361116 >
11371117 <!-- Heatmap and Timeline -->
1138- <section class =" flex-1 w-full rounded-full flex flex-col-reverse px-2 h-8 relative" >
1118+ <VideoTimeline
1119+ ref="video-timeline"
1120+ :buffer-percentage =" bufferPercentage "
1121+ :time-duration =" timeDuration "
1122+ :time-elapsed-verbose =" timeStrings .timeElapsedVerbose "
1123+ :video-button-offset =" videoButtonOffset "
1124+ v-model =" timeElapsed "
1125+ @seek =" handleSeek "
1126+ @seek-preview =" handleSeekPreview "
1127+ @key-bind =" handleKeyBinds "
1128+ >
1129+ <VideoHeatmap :playback-data =" playbackData " />
1130+ </VideoTimeline >
1131+ <!-- <section class="flex-1 w-full rounded-full flex flex-col-reverse px-2 h-8 relative">
11391132 <VideoTooltipSlider
11401133 ref="progress-tooltip"
11411134 tooltip-position="top"
@@ -1145,39 +1138,53 @@ defineExpose({
11451138 :offset="videoButtonOffset"
11461139 :tooltip-arrow="false"
11471140 />
1148- <input
1149- @mousemove =" handleProgressTooltip"
1150- @pointerdown =" handleSeekPreview"
1151- @pointerup =" handleSeek()"
1152- @mouseenter ="
1153- () => {
1154- if (!progressTooltip) return;
1155- progressTooltip?.tooltipToggle();
1156- }
1157- "
1158- @mouseleave ="
1159- () => {
1160- if (!progressTooltip) return;
1161- progressTooltip?.tooltipToggle(false);
1162- }
1163- "
1164- @keydown.prevent =" (e) => handleKeyBinds(e, true)"
1165- ref =" progress-bar"
1166- placeholder =" 0"
1167- v-model =" timeElapsed"
1168- type =" range"
1169- min =" 0"
1170- max =" 100"
1171- value =" 0"
1172- step =" 0.01"
1173- :class =" [`peer w-full h-2 flex items-center slider timeline pointer-events-auto focus:outline-none`]"
1174- :style =" {
1175- '--buffer': bufferPercentage,
1176- }"
1177- :aria-valuetext =" timeStrings.timeElapsedVerbose"
1178- />
1179- <VideoHeatmap :playback-data =" playbackData " />
1180- </section >
1141+ <div class="relative group h-2 bg-white/10 flex items-center hover:bg-white/20 pointer-events-auto">
1142+ <input
1143+ @mousemove="handleProgressTooltip"
1144+ @pointerdown="handleSeekPreview"
1145+ @pointerup="handleSeek()"
1146+ @mouseenter="
1147+ () => {
1148+ if (!progressTooltip) return;
1149+ progressTooltip?.tooltipToggle();
1150+ }
1151+ "
1152+ @mouseleave="
1153+ () => {
1154+ if (!progressTooltip) return;
1155+ progressTooltip?.tooltipToggle(false);
1156+ }
1157+ "
1158+ @keydown.prevent="(e) => handleKeyBinds(e, true)"
1159+ ref="progress-bar"
1160+ placeholder="0"
1161+ v-model="timeElapsed"
1162+ type="range"
1163+ min="0"
1164+ max="100"
1165+ value="0"
1166+ step="0.01"
1167+ :class="[`peer absolute left-0 top-0 w-full h-2 flex items-center slider timeline pointer-events-auto focus:outline-none -px-0.5`]"
1168+ :style="{
1169+ '-- buffer': bufferPercentage,
1170+ '-- progress-color': 'ffffff00',
1171+ '-- thumb-color': 'ffffff00',
1172+ '-- track-color': 'ffffff00',
1173+ }"
1174+ :aria-valuetext="timeStrings.timeElapsedVerbose"
1175+ />
1176+ <div
1177+ class="h-1 group-hover:h-2 transition-all duration-200 ease-in-out w-full z-[5] rounded-full group-hover:rounded-[1px] overflow-clip pointer-events-none"
1178+ >
1179+ <div class="h-full bg-purple-600 z-[5] max-w-full relative" :style="`-- progress-color: #111827; width: ${timeElapsed}%; `">
1180+ <button
1181+ class="size-1 group-hover:size-2 bg-white rounded-full -right-0.5 group-hover:-right-1 absolute transition-all duration-200 ease-in-out hover:bg-neutral-300"
1182+ ></button>
1183+ </div>
1184+ </div>
1185+ </div>
1186+
1187+ </section> -->
11811188
11821189 <!-- Controls -->
11831190 <section class =" w-full flex items-center gap-2 p-2 pointer-events-auto" >
0 commit comments