fix: hide cursor during fullscreen playback

This commit is contained in:
kuekhaoyang
2026-07-08 22:12:34 +08:00
parent f2667d42de
commit dedf496761
4 changed files with 82 additions and 1 deletions
+9
View File
@@ -13,6 +13,7 @@ import { Icons } from '@/components/ui/Icon';
import type { M3UChannel } from '@/lib/utils/m3u-parser';
import type { IPTVSource } from '@/lib/store/iptv-store';
import { settingsStore, DEFAULT_SEEK_STEP_SECONDS } from '@/lib/store/settings-store';
import { shouldHidePlayerCursor } from '@/lib/player/cursor-visibility';
const HLS_LIVE_CONFIG: Partial<Hls['config']> = {
enableWorker: true,
@@ -495,6 +496,13 @@ export function IPTVPlayer({ channel, onClose, channels, onChannelChange, channe
return Math.max(0, Math.min(100, (currentTime / duration) * 100));
}, [currentTime, duration, seekWindow]);
const shouldHideCursor = shouldHidePlayerCursor({
isFullscreen,
isPlaying,
showControls,
hasInteractiveOverlay: showSidebar || showVolumeSlider || Boolean(error),
});
const toggleFullscreen = async () => {
if (!containerRef.current) return;
if (document.fullscreenElement) {
@@ -781,6 +789,7 @@ export function IPTVPlayer({ channel, onClose, channels, onChannelChange, channe
<div
ref={containerRef}
className="fixed inset-0 z-[9999] bg-black flex"
style={{ cursor: shouldHideCursor ? 'none' : undefined }}
onMouseMove={resetControlsTimeout}
onClick={(e) => {
if ((e.target as HTMLElement).closest('[data-controls]') || (e.target as HTMLElement).closest('[data-sidebar]')) return;
+14 -1
View File
@@ -16,6 +16,7 @@ import { useIsIOS, useIsMobile } from '@/lib/hooks/mobile/useDeviceDetection';
import { useDoubleTap } from '@/lib/hooks/mobile/useDoubleTap';
import { settingsStore, DEFAULT_SEEK_STEP_SECONDS } from '@/lib/store/settings-store';
import { premiumModeSettingsStore } from '@/lib/store/premium-mode-settings';
import { shouldHidePlayerCursor } from '@/lib/player/cursor-visibility';
import './web-fullscreen.css';
type WebFullscreenSize = 'full' | 'large' | 'focused';
@@ -312,6 +313,18 @@ export function DesktopVideoPlayer({
};
}, [data.fullscreenMode, shouldForceLandscape, viewportMetrics, webFullscreenSize]);
const shouldHideCursor = shouldHidePlayerCursor({
isFullscreen: data.isFullscreen,
isPlaying: data.isPlaying,
showControls: data.showControls,
hasInteractiveOverlay: data.showSpeedMenu || data.showMoreMenu || data.showVolumeBar,
});
const containerStyle = React.useMemo<React.CSSProperties>(() => ({
...(webFullscreenStyle ?? {}),
cursor: shouldHideCursor ? 'none' : undefined,
}), [webFullscreenStyle, shouldHideCursor]);
const stageClassName = data.fullscreenMode === 'window'
? 'kvideo-stage kvideo-web-fullscreen-stage'
: 'kvideo-stage absolute inset-0';
@@ -344,7 +357,7 @@ export function DesktopVideoPlayer({
ref={containerRef}
className={`kvideo-container relative aspect-video bg-black group ${data.fullscreenMode === 'window' ? 'is-web-fullscreen' : ''
} ${shouldForceLandscape ? 'force-landscape' : ''} ${isTopAlignedWebFullscreen ? 'top-align-stage' : ''} overflow-hidden rounded-none sm:rounded-[var(--radius-2xl)]`}
style={webFullscreenStyle}
style={containerStyle}
onMouseMove={() => { handleMouseMove(); }}
onMouseLeave={() => isPlaying && setShowControls(false)}
>