diff --git a/app/styles/video-player.css b/app/styles/video-player.css index 9b31bba..7bfef3a 100644 --- a/app/styles/video-player.css +++ b/app/styles/video-player.css @@ -165,8 +165,8 @@ /* Spinner with Glass Background */ .spinner-glass { - width: 56px; - height: 56px; + width: clamp(40px, 8vw, 56px); + height: clamp(40px, 8vw, 56px); border: 4px solid rgba(255, 255, 255, 0.15); border-top-color: var(--accent-color); border-radius: var(--radius-full); diff --git a/components/player/DesktopVideoPlayer.tsx b/components/player/DesktopVideoPlayer.tsx index 367284d..1ed1b24 100644 --- a/components/player/DesktopVideoPlayer.tsx +++ b/components/player/DesktopVideoPlayer.tsx @@ -1,5 +1,6 @@ 'use client'; +import React from 'react'; import { useDesktopPlayerState } from './hooks/useDesktopPlayerState'; import { useDesktopPlayerLogic } from './hooks/useDesktopPlayerLogic'; import { useHlsPlayer } from './hooks/useHlsPlayer'; @@ -53,6 +54,11 @@ export function DesktopVideoPlayer({ setIsLoading, } = state; + // Reset loading state and show spinner when source changes + React.useEffect(() => { + setIsLoading(true); + }, [src, setIsLoading]); + const logic = useDesktopPlayerLogic({ src, initialTime, @@ -120,12 +126,17 @@ export function DesktopVideoPlayer({ onMoreMenuMouseEnter={() => { if (refs.moreMenuTimeoutRef.current) { clearTimeout(refs.moreMenuTimeoutRef.current); + refs.moreMenuTimeoutRef.current = null; } }} onMoreMenuMouseLeave={() => { + if (refs.moreMenuTimeoutRef.current) { + clearTimeout(refs.moreMenuTimeoutRef.current); + } refs.moreMenuTimeoutRef.current = setTimeout(() => { state.setShowMoreMenu(false); - }, 300); + refs.moreMenuTimeoutRef.current = null; + }, 800); // Increased timeout for better stability }} onCopyLink={logic.handleCopyLink} // Speed Menu Props diff --git a/components/player/desktop/DesktopOverlay.tsx b/components/player/desktop/DesktopOverlay.tsx index b127f99..0083eeb 100644 --- a/components/player/desktop/DesktopOverlay.tsx +++ b/components/player/desktop/DesktopOverlay.tsx @@ -123,7 +123,7 @@ export function DesktopOverlay({ {/* Previous Button (Method: Skip Backward) */}
@@ -132,16 +132,16 @@ export function DesktopOverlay({ e.stopPropagation(); onSkipBackward(); }} - className="group flex items-center justify-center w-16 h-16 rounded-full bg-black/40 hover:bg-black/60 backdrop-blur-sm transition-all duration-300 hover:scale-110 active:scale-95" + className="group flex items-center justify-center w-12 h-12 md:w-16 md:h-16 rounded-full bg-black/40 hover:bg-black/60 backdrop-blur-sm transition-all duration-300 hover:scale-110 active:scale-95" aria-label="Skip Backward 10s" > - +
{/* Next Button (Method: Skip Forward) */}
@@ -150,10 +150,10 @@ export function DesktopOverlay({ e.stopPropagation(); onSkipForward(); }} - className="group flex items-center justify-center w-16 h-16 rounded-full bg-black/40 hover:bg-black/60 backdrop-blur-sm transition-all duration-300 hover:scale-110 active:scale-95" + className="group flex items-center justify-center w-12 h-12 md:w-16 md:h-16 rounded-full bg-black/40 hover:bg-black/60 backdrop-blur-sm transition-all duration-300 hover:scale-110 active:scale-95" aria-label="Skip Forward 10s" > - +
@@ -162,10 +162,10 @@ export function DesktopOverlay({
)} diff --git a/components/player/hooks/desktop/useControlsVisibility.ts b/components/player/hooks/desktop/useControlsVisibility.ts index d97cddf..d54a130 100644 --- a/components/player/hooks/desktop/useControlsVisibility.ts +++ b/components/player/hooks/desktop/useControlsVisibility.ts @@ -4,8 +4,10 @@ interface UseControlsVisibilityProps { isPlaying: boolean; showControls: boolean; showSpeedMenu: boolean; + showMoreMenu: boolean; setShowControls: (show: boolean) => void; setShowSpeedMenu: (show: boolean) => void; + setShowMoreMenu: (show: boolean) => void; controlsTimeoutRef: React.MutableRefObject; speedMenuTimeoutRef: React.MutableRefObject; mouseMoveThrottleRef: React.MutableRefObject; @@ -15,25 +17,46 @@ export function useControlsVisibility({ isPlaying, showControls, showSpeedMenu, + showMoreMenu, setShowControls, setShowSpeedMenu, + setShowMoreMenu, controlsTimeoutRef, speedMenuTimeoutRef, mouseMoveThrottleRef }: UseControlsVisibilityProps) { - useEffect(() => { - if (!isPlaying) return; + // Shared hide controls logic + const hideControls = useCallback(() => { + if (controlsTimeoutRef.current) { + clearTimeout(controlsTimeoutRef.current); + } + controlsTimeoutRef.current = setTimeout(() => { + if (isPlaying && !showSpeedMenu && !showMoreMenu) { + setShowControls(false); + } + }, 3000); + }, [isPlaying, showSpeedMenu, showMoreMenu, setShowControls, controlsTimeoutRef]); - const hideControls = () => { + // Force controls to show when paused + useEffect(() => { + if (!isPlaying) { + setShowControls(true); if (controlsTimeoutRef.current) { clearTimeout(controlsTimeoutRef.current); } - controlsTimeoutRef.current = setTimeout(() => { - if (isPlaying && !showSpeedMenu) { - setShowControls(false); - } - }, 3000); - }; + } else { + // When resuming play, start the timer to hide controls + hideControls(); + } + }, [isPlaying, setShowControls, hideControls, controlsTimeoutRef]); + + useEffect(() => { + if (!isPlaying || showSpeedMenu || showMoreMenu) { + if (controlsTimeoutRef.current) { + clearTimeout(controlsTimeoutRef.current); + } + return; + } hideControls(); diff --git a/components/player/hooks/desktop/usePlaybackControls.ts b/components/player/hooks/desktop/usePlaybackControls.ts index 9ecd9cf..8697c3d 100644 --- a/components/player/hooks/desktop/usePlaybackControls.ts +++ b/components/player/hooks/desktop/usePlaybackControls.ts @@ -40,7 +40,15 @@ export function usePlaybackControls({ if (isPlaying) { videoRef.current.pause(); } else { - videoRef.current.play(); + const playPromise = videoRef.current.play(); + if (playPromise !== undefined) { + playPromise.catch(error => { + // Ignore AbortError: The play() request was interrupted by a call to pause(). + if (error.name !== 'AbortError') { + console.error('Playback failed:', error); + } + }); + } } }, [isPlaying, videoRef]); diff --git a/components/player/hooks/useDesktopPlayerLogic.ts b/components/player/hooks/useDesktopPlayerLogic.ts index b91ee40..0987b12 100644 --- a/components/player/hooks/useDesktopPlayerLogic.ts +++ b/components/player/hooks/useDesktopPlayerLogic.ts @@ -58,7 +58,8 @@ export function useDesktopPlayerLogic({ setIsSkipForwardAnimatingOut, setIsSkipBackwardAnimatingOut, setShowVolumeBar, setToastMessage, setShowToast, isCastAvailable, setIsCastAvailable, - isCasting, setIsCasting + isCasting, setIsCasting, + showMoreMenu, setShowMoreMenu } = state; const playbackControls = usePlaybackControls({ @@ -94,8 +95,8 @@ export function useDesktopPlayerLogic({ }); const controlsVisibility = useControlsVisibility({ - isPlaying, showControls, showSpeedMenu, - setShowControls, setShowSpeedMenu, + isPlaying, showControls, showSpeedMenu, showMoreMenu, + setShowControls, setShowSpeedMenu, setShowMoreMenu, controlsTimeoutRef, speedMenuTimeoutRef, mouseMoveThrottleRef }); diff --git a/package-lock.json b/package-lock.json index 9c742a6..926346e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "kvideo", - "version": "3.5.0", + "version": "3.6.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "kvideo", - "version": "3.5.0", + "version": "3.6.0", "dependencies": { "@dnd-kit/core": "^6.3.1", "@dnd-kit/sortable": "^10.0.0", diff --git a/package.json b/package.json index 77783b6..28d0d2e 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "kvideo", - "version": "3.5.0", + "version": "3.6.0", "private": true, "scripts": { "dev": "next dev",