diff --git a/frontend/src/components/video.tsx b/frontend/src/components/video.tsx index bf68c9d66..3a861b065 100644 --- a/frontend/src/components/video.tsx +++ b/frontend/src/components/video.tsx @@ -327,12 +327,16 @@ export default function Video({ URL, startTime, nextItemId, endTime, points, ano // Prevent playing if current time is at or beyond endTime if (endTimeSeconds > 0 && currentTime >= endTimeSeconds) { return; - }else{ - player.playVideo(); } + // Block resuming if any proctoring anomalies or gesture prompts are active + if (pauseVid || rewindVid || doGesture) { + console.log("🔒 Play blocked: Anomaly or gesture prompt active"); + return; + } + player.playVideo(); setTimeout(() => { playerRef.current?.setPlaybackRate?.(playbackRate); }, 50); } - }, [playing, endTimeSeconds, currentTime, isSkipping, isStopFailed, isStopping, playbackRate]); + }, [playing, endTimeSeconds, currentTime, isSkipping, isStopFailed, isStopping, playbackRate, pauseVid, rewindVid, doGesture]); const handleBackward = () => { const player = playerRef.current; @@ -989,6 +993,10 @@ export default function Video({ URL, startTime, nextItemId, endTime, points, ano if (rawEvent.code === 'Space') { rawEvent.preventDefault(); rawEvent.stopImmediatePropagation(); + if (rawEvent.repeat) { + // Ignore held down spacebar to prevent rapid play/pause bypass + return; + } handlePlayPause(); return; } @@ -1355,6 +1363,10 @@ export default function Video({ URL, startTime, nextItemId, endTime, points, ano className='shadow-2xl' + onClick={(e) => e.stopPropagation()} + + onMouseDown={(e) => e.stopPropagation()} + style={{ position: 'absolute', @@ -2095,6 +2107,8 @@ export function NavigatingOverlay({ return (
e.stopPropagation()} + onMouseDown={(e) => e.stopPropagation()} > @@ -2152,6 +2166,8 @@ export function ConfirmOverlay({ return (
e.stopPropagation()} + onMouseDown={(e) => e.stopPropagation()} >