2023-01-09 21:51:24 +01:00
|
|
|
import {
|
|
|
|
makePercentage,
|
|
|
|
makePercentageString,
|
|
|
|
useProgressBar,
|
|
|
|
} from "@/hooks/useProgressBar";
|
2023-01-10 19:53:55 +01:00
|
|
|
import { useCallback, useEffect, useRef } from "react";
|
2023-01-08 17:51:38 +01:00
|
|
|
import { useVideoPlayerState } from "../VideoContext";
|
|
|
|
|
|
|
|
export function ProgressControl() {
|
|
|
|
const { videoState } = useVideoPlayerState();
|
|
|
|
const ref = useRef<HTMLDivElement>(null);
|
2023-01-10 19:53:55 +01:00
|
|
|
const dragRef = useRef<boolean>(false);
|
2023-01-08 17:51:38 +01:00
|
|
|
|
2023-01-09 21:51:24 +01:00
|
|
|
const commitTime = useCallback(
|
|
|
|
(percentage) => {
|
|
|
|
videoState.setTime(percentage * videoState.duration);
|
|
|
|
},
|
|
|
|
[videoState]
|
|
|
|
);
|
|
|
|
const { dragging, dragPercentage, dragMouseDown } = useProgressBar(
|
|
|
|
ref,
|
|
|
|
commitTime
|
|
|
|
);
|
2023-01-17 21:12:39 +01:00
|
|
|
|
|
|
|
// TODO make dragging update timer
|
2023-01-10 19:53:55 +01:00
|
|
|
useEffect(() => {
|
|
|
|
if (dragRef.current === dragging) return;
|
|
|
|
dragRef.current = dragging;
|
|
|
|
videoState.setSeeking(dragging);
|
|
|
|
}, [dragRef, dragging, videoState]);
|
2023-01-08 22:29:38 +01:00
|
|
|
|
2023-01-09 21:51:24 +01:00
|
|
|
let watchProgress = makePercentageString(
|
|
|
|
makePercentage((videoState.time / videoState.duration) * 100)
|
|
|
|
);
|
|
|
|
if (dragging)
|
|
|
|
watchProgress = makePercentageString(makePercentage(dragPercentage));
|
2023-01-08 22:29:38 +01:00
|
|
|
|
2023-01-09 21:51:24 +01:00
|
|
|
const bufferProgress = makePercentageString(
|
|
|
|
makePercentage((videoState.buffered / videoState.duration) * 100)
|
|
|
|
);
|
2023-01-08 17:51:38 +01:00
|
|
|
|
|
|
|
return (
|
2023-01-24 18:12:37 +01:00
|
|
|
<div className="group pointer-events-auto w-full cursor-pointer rounded-full px-2">
|
2023-01-08 17:51:38 +01:00
|
|
|
<div
|
2023-01-09 21:51:24 +01:00
|
|
|
ref={ref}
|
|
|
|
className="-my-3 flex h-8 items-center"
|
|
|
|
onMouseDown={dragMouseDown}
|
2023-01-23 22:38:05 +01:00
|
|
|
onTouchStart={dragMouseDown}
|
2023-01-09 21:51:24 +01:00
|
|
|
>
|
|
|
|
<div
|
|
|
|
className={`relative h-1 flex-1 rounded-full bg-gray-500 bg-opacity-50 transition-[height] duration-100 group-hover:h-2 ${
|
|
|
|
dragging ? "!h-2" : ""
|
|
|
|
}`}
|
|
|
|
>
|
|
|
|
<div
|
2023-01-10 00:27:04 +01:00
|
|
|
className="absolute inset-y-0 left-0 flex items-center justify-end rounded-full bg-gray-300 bg-opacity-20"
|
2023-01-09 21:51:24 +01:00
|
|
|
style={{
|
|
|
|
width: bufferProgress,
|
|
|
|
}}
|
|
|
|
/>
|
|
|
|
<div
|
2023-01-10 00:27:04 +01:00
|
|
|
className="absolute inset-y-0 left-0 flex items-center justify-end rounded-full bg-bink-600"
|
2023-01-09 21:51:24 +01:00
|
|
|
style={{
|
|
|
|
width: watchProgress,
|
|
|
|
}}
|
|
|
|
>
|
|
|
|
<div
|
|
|
|
className={`absolute h-1 w-1 translate-x-1/2 rounded-full bg-white opacity-0 transition-[transform,opacity] group-hover:scale-[400%] group-hover:opacity-100 ${
|
|
|
|
dragging ? "!scale-[400%] !opacity-100" : ""
|
|
|
|
}`}
|
|
|
|
/>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
2023-01-08 17:51:38 +01:00
|
|
|
</div>
|
|
|
|
);
|
|
|
|
}
|