diff --git a/components/player/MobileVideoPlayer.tsx b/components/player/MobileVideoPlayer.tsx index 9865608..7237850 100644 --- a/components/player/MobileVideoPlayer.tsx +++ b/components/player/MobileVideoPlayer.tsx @@ -39,10 +39,14 @@ export function MobileVideoPlayer({ const [skipAmount, setSkipAmount] = useState(0); const [skipSide, setSkipSide] = useState<'left' | 'right' | null>(null); const [showSkipIndicator, setShowSkipIndicator] = useState(false); + const [wasPlayingBeforeMenu, setWasPlayingBeforeMenu] = useState(false); const controlsTimeoutRef = useRef(null); const skipTimeoutRef = useRef(null); const isDraggingProgressRef = useRef(false); + const menuIdleTimeoutRef = useRef(null); + const submenuIdleTimeoutRef = useRef(null); + const isTogglingRef = useRef(false); // Screen orientation management useScreenOrientation(isFullscreen); @@ -145,12 +149,106 @@ export function MobileVideoPlayer({ }; }, [isPlaying]); - const togglePlay = () => { - if (!videoRef.current) return; - if (isPlaying) { - videoRef.current.pause(); - } else { - videoRef.current.play(); + // Auto-close more menu after 2 seconds + useEffect(() => { + if (showMoreMenu) { + // Pause video when menu opens + if (videoRef.current && isPlaying) { + setWasPlayingBeforeMenu(true); + videoRef.current.pause(); + } + + // Clear existing timeout + if (menuIdleTimeoutRef.current) { + clearTimeout(menuIdleTimeoutRef.current); + } + + // Set timeout to auto-close after 2 seconds + menuIdleTimeoutRef.current = setTimeout(() => { + setShowMoreMenu(false); + + // Resume video if it was playing + if (wasPlayingBeforeMenu && videoRef.current) { + videoRef.current.play().catch(err => console.warn('Resume play error:', err)); + setWasPlayingBeforeMenu(false); + } + }, 2000); + } + + return () => { + if (menuIdleTimeoutRef.current) { + clearTimeout(menuIdleTimeoutRef.current); + } + }; + }, [showMoreMenu, isPlaying, wasPlayingBeforeMenu]); + + // Pause video when submenus open (no auto-close) + useEffect(() => { + if (showVolumeMenu || showSpeedMenu) { + // Pause video when submenu opens + if (videoRef.current && isPlaying) { + setWasPlayingBeforeMenu(true); + videoRef.current.pause(); + } + } + }, [showVolumeMenu, showSpeedMenu, isPlaying]); + + // Close all menus when clicking outside + useEffect(() => { + const handleClickOutside = (e: MouseEvent | TouchEvent) => { + const target = e.target as HTMLElement; + + // Check if click is outside menu areas + const isMenuClick = target.closest('.menu-container') || + target.closest('[aria-label="更多"]'); + + if (!isMenuClick && (showMoreMenu || showVolumeMenu || showSpeedMenu)) { + setShowMoreMenu(false); + setShowVolumeMenu(false); + setShowSpeedMenu(false); + + // Resume video if it was playing + if (wasPlayingBeforeMenu && videoRef.current) { + videoRef.current.play().catch(err => console.warn('Resume play error:', err)); + setWasPlayingBeforeMenu(false); + } + } + }; + + if (showMoreMenu || showVolumeMenu || showSpeedMenu) { + document.addEventListener('mousedown', handleClickOutside); + document.addEventListener('touchstart', handleClickOutside); + } + + return () => { + document.removeEventListener('mousedown', handleClickOutside); + document.removeEventListener('touchstart', handleClickOutside); + }; + }, [showMoreMenu, showVolumeMenu, showSpeedMenu, wasPlayingBeforeMenu]); + + const togglePlay = async () => { + if (!videoRef.current || isTogglingRef.current) return; + + isTogglingRef.current = true; + + try { + if (isPlaying) { + videoRef.current.pause(); + } else { + // Close all menus when resuming playback + setShowMoreMenu(false); + setShowVolumeMenu(false); + setShowSpeedMenu(false); + + await videoRef.current.play(); + } + } catch (error) { + console.warn('Play/pause error:', error); + } finally { + // Small delay to prevent rapid toggling + setTimeout(() => { + isTogglingRef.current = false; + }, 100); } }; @@ -378,17 +476,11 @@ export function MobileVideoPlayer({ {/* Controls Bar */}
- {/* Left: Play + Skip + Time */} + {/* Left: Play + Time */}
- - {/* Time Display */} @@ -414,7 +506,7 @@ export function MobileVideoPlayer({ {/* More Menu Dropdown */} {showMoreMenu && ( -
+
{/* Volume Option */} ))}