Fix Progress bar can't drag

This commit is contained in:
kuekhaoyang
2026-01-13 16:11:25 +08:00
parent b11e762350
commit a93f96c967
7 changed files with 61 additions and 6 deletions
@@ -30,6 +30,7 @@ interface DesktopControlsProps {
onShowCastMenu: () => void;
onProgressClick: (e: React.MouseEvent<HTMLDivElement>) => void;
onProgressMouseDown: (e: React.MouseEvent<HTMLDivElement>) => void;
onProgressTouchStart: (e: React.TouchEvent<HTMLDivElement>) => void;
formatTime: (seconds: number) => string;
}
@@ -41,6 +42,7 @@ export function DesktopControls(props: DesktopControlsProps) {
progressBarRef,
onProgressClick,
onProgressMouseDown,
onProgressTouchStart,
formatTime,
} = props;
@@ -57,6 +59,7 @@ export function DesktopControls(props: DesktopControlsProps) {
duration={duration}
onProgressClick={onProgressClick}
onProgressMouseDown={onProgressMouseDown}
onProgressTouchStart={onProgressTouchStart}
/>
{/* Controls Bar */}
@@ -37,6 +37,7 @@ export function DesktopControlsWrapper({ src, data, actions, logic, refs }: Desk
showCastMenu,
handleProgressClick,
handleProgressMouseDown,
handleProgressTouchStart,
formatTime,
} = logic;
@@ -73,6 +74,7 @@ export function DesktopControlsWrapper({ src, data, actions, logic, refs }: Desk
onShowCastMenu={showCastMenu}
onProgressClick={handleProgressClick}
onProgressMouseDown={handleProgressMouseDown}
onProgressTouchStart={handleProgressTouchStart}
formatTime={formatTime}
/>
);
@@ -7,6 +7,7 @@ interface DesktopProgressBarProps {
duration: number;
onProgressClick: (e: React.MouseEvent<HTMLDivElement>) => void;
onProgressMouseDown: (e: React.MouseEvent<HTMLDivElement>) => void;
onProgressTouchStart: (e: React.TouchEvent<HTMLDivElement>) => void;
}
export function DesktopProgressBar({
@@ -14,7 +15,8 @@ export function DesktopProgressBar({
currentTime,
duration,
onProgressClick,
onProgressMouseDown
onProgressMouseDown,
onProgressTouchStart
}: DesktopProgressBarProps) {
return (
<div className="px-4 pb-1">
@@ -23,6 +25,7 @@ export function DesktopProgressBar({
className="slider-track cursor-pointer"
onClick={onProgressClick}
onMouseDown={onProgressMouseDown}
onTouchStart={onProgressTouchStart}
style={{ pointerEvents: 'auto' }}
>
<div
@@ -33,6 +33,24 @@ export function useProgressControls({
handleProgressClick(e);
}, [isDraggingProgressRef, handleProgressClick]);
const handleProgressTouchStart = useCallback((e: any) => {
// e.preventDefault(); // Do not prevent default immediately to allow scrolling if needed, or check logic
// But for a slider, we usually want to capture the drag.
e.preventDefault();
isDraggingProgressRef.current = true;
// Calculate new time immediately on touch start
if (!videoRef.current || !progressBarRef.current) return;
const rect = progressBarRef.current.getBoundingClientRect();
const touch = e.touches[0];
const pos = Math.max(0, Math.min(1, (touch.clientX - rect.left) / rect.width));
const newTime = pos * duration;
videoRef.current.currentTime = newTime;
lastDragTimeRef.current = newTime;
setCurrentTime(newTime);
}, [videoRef, progressBarRef, duration, setCurrentTime, isDraggingProgressRef]);
useEffect(() => {
const handleProgressMouseMove = (e: MouseEvent) => {
if (!isDraggingProgressRef.current || !progressBarRef.current || !videoRef.current) return;
@@ -53,19 +71,47 @@ export function useProgressControls({
}
};
const handleProgressTouchMove = (e: TouchEvent) => {
if (!isDraggingProgressRef.current || !progressBarRef.current || !videoRef.current) return;
// e.preventDefault(); // Prevent scrolling while dragging progress
const rect = progressBarRef.current.getBoundingClientRect();
const touch = e.touches[0];
const pos = Math.max(0, Math.min(1, (touch.clientX - rect.left) / rect.width));
const newTime = pos * duration;
lastDragTimeRef.current = newTime;
setCurrentTime(newTime);
};
const handleTouchEnd = () => {
if (isDraggingProgressRef.current) {
isDraggingProgressRef.current = false;
if (videoRef.current) {
videoRef.current.currentTime = lastDragTimeRef.current;
}
}
};
document.addEventListener('mousemove', handleProgressMouseMove);
document.addEventListener('mouseup', handleMouseUp);
document.addEventListener('touchmove', handleProgressTouchMove, { passive: false });
document.addEventListener('touchend', handleTouchEnd);
document.addEventListener('touchcancel', handleTouchEnd);
return () => {
document.removeEventListener('mousemove', handleProgressMouseMove);
document.removeEventListener('mouseup', handleMouseUp);
document.removeEventListener('touchmove', handleProgressTouchMove);
document.removeEventListener('touchend', handleTouchEnd);
document.removeEventListener('touchcancel', handleTouchEnd);
};
}, [duration, isDraggingProgressRef, progressBarRef, videoRef, setCurrentTime]);
const progressActions = useMemo(() => ({
handleProgressClick,
handleProgressMouseDown
}), [handleProgressClick, handleProgressMouseDown]);
handleProgressMouseDown,
handleProgressTouchStart
}), [handleProgressClick, handleProgressMouseDown, handleProgressTouchStart]);
return progressActions;
}
@@ -156,6 +156,7 @@ export function useDesktopPlayerLogic({
handleVideoError: playbackControls.handleVideoError,
handleProgressClick: progressControls.handleProgressClick,
handleProgressMouseDown: progressControls.handleProgressMouseDown,
handleProgressTouchStart: progressControls.handleProgressTouchStart,
toggleMute: volumeControls.toggleMute,
showVolumeBarTemporarily: volumeControls.showVolumeBarTemporarily,
handleVolumeChange: volumeControls.handleVolumeChange,
+2 -2
View File
@@ -1,12 +1,12 @@
{
"name": "kvideo",
"version": "3.9.4",
"version": "3.9.5",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "kvideo",
"version": "3.9.4",
"version": "3.9.5",
"dependencies": {
"@dnd-kit/core": "^6.3.1",
"@dnd-kit/sortable": "^10.0.0",
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "kvideo",
"version": "3.9.4",
"version": "3.9.5",
"private": true,
"scripts": {
"dev": "next dev",