diff --git a/components/video-page-content.tsx b/components/video-page-content.tsx index 099a491..37daeda 100644 --- a/components/video-page-content.tsx +++ b/components/video-page-content.tsx @@ -15,6 +15,7 @@ import { SkipForward, Gauge, MessageSquare, + MessageSquareOff, Mic, Send, Clock, @@ -34,6 +35,8 @@ import { ArrowUpRight, Tag, User, + Maximize, + Minimize, } from 'lucide-react'; import { Button } from '@/components/ui/button'; import { Badge } from '@/components/ui/badge'; @@ -199,6 +202,10 @@ export function VideoPageContent({ mode, videoId, projectId: propProjectId }: Vi const progressSaveTimerRef = useRef | null>(null); const lastSavedProgressRef = useRef(0); + // Fullscreen state + const [isFullscreenMode, setIsFullscreenMode] = useState(false); + const [showComments, setShowComments] = useState(true); + // YouTube API loading state const [isApiLoaded, setIsApiLoaded] = useState(false); const [progressFetchKey, setProgressFetchKey] = useState(0); @@ -259,10 +266,17 @@ export function VideoPageContent({ mode, videoId, projectId: propProjectId }: Vi const handleVideoMouseMove = useCallback(() => { setCursorIdle(false); if (cursorIdleTimerRef.current) clearTimeout(cursorIdleTimerRef.current); - cursorIdleTimerRef.current = setTimeout(() => { - setCursorIdle(true); - }, 3000); - }, []); + + // In fullscreen mode: hide header AND controls when cursor idle for 1s while playing + // Non-fullscreen: hide only the play overlay (existing behavior) + const shouldHideControls = isFullscreenMode; + + if (isPlaying || shouldHideControls) { + cursorIdleTimerRef.current = setTimeout(() => { + setCursorIdle(true); + }, 1000); + } + }, [isFullscreenMode, isPlaying]); const handleVideoMouseLeave = useCallback(() => { if (cursorIdleTimerRef.current) clearTimeout(cursorIdleTimerRef.current); @@ -569,6 +583,40 @@ export function VideoPageContent({ mode, videoId, projectId: propProjectId }: Vi }; }, [video?.isAuthenticated, isReady, currentTime, videoDuration, activeVersionId, videoId]); + const toggleFullscreen = useCallback(() => { + if (!document.fullscreenElement) { + document.documentElement.requestFullscreen().then(() => { + setIsFullscreenMode(true); + setShowComments(false); + }).catch((err) => { + console.error('Fullscreen failed:', err); + toast.error('Unable to enter fullscreen mode'); + }); + } else { + document.exitFullscreen().then(() => { + setIsFullscreenMode(false); + setShowComments(true); + }).catch((err) => { + console.error('Exit fullscreen failed:', err); + toast.error('Unable to exit fullscreen mode'); + }); + } + }, []); + + useEffect(() => { + const handleFullscreenChange = () => { + const isCurrentlyFullscreen = !!document.fullscreenElement; + setIsFullscreenMode(isCurrentlyFullscreen); + if (isCurrentlyFullscreen) { + setShowComments(false); + } else { + setShowComments(true); + } + }; + document.addEventListener('fullscreenchange', handleFullscreenChange); + return () => document.removeEventListener('fullscreenchange', handleFullscreenChange); + }, []); + // Save progress when user leaves the page useEffect(() => { if (!video?.isAuthenticated) return; @@ -754,12 +802,16 @@ export function VideoPageContent({ mode, videoId, projectId: propProjectId }: Vi setCurrentTime(newTime); } break; + case 'KeyF': + e.preventDefault(); + toggleFullscreen(); + break; } }; window.addEventListener('keydown', handleKeyDown); return () => window.removeEventListener('keydown', handleKeyDown); - }, [isPlaying, currentTime, duration, isMuted, playbackSpeed]); + }, [isPlaying, currentTime, duration, isMuted, playbackSpeed, toggleFullscreen]); const handlePlayPause = useCallback(() => { if (!playerRef.current) return; @@ -1621,8 +1673,8 @@ export function VideoPageContent({ mode, videoId, projectId: propProjectId }: Vi return (
-
-
+
+
@@ -1637,7 +1689,7 @@ export function VideoPageContent({ mode, videoId, projectId: propProjectId }: Vi
-
+
@@ -1651,7 +1703,7 @@ export function VideoPageContent({ mode, videoId, projectId: propProjectId }: Vi
-
+
@@ -1759,8 +1811,12 @@ export function VideoPageContent({ mode, videoId, projectId: propProjectId }: Vi onMouseLeave={() => isDragging && handleTimelineMouseUp()} >
-
-
+
+
-
+