Video Player: Fix controls visible (#6901)

This commit is contained in:
Alexander Zinchuk 2026-05-05 13:46:31 +02:00
parent 236aec2bcc
commit 57bcad5215
2 changed files with 37 additions and 5 deletions

View File

@ -22,7 +22,7 @@ import usePictureInPicture from '../../hooks/usePictureInPicture';
import useShowTransitionDeprecated from '../../hooks/useShowTransitionDeprecated';
import useVideoCleanup from '../../hooks/useVideoCleanup';
import useFullscreen from '../../hooks/window/useFullscreen';
import useControlsSignal from './hooks/useControlsSignal';
import useControlsSignal, { registerPlayerElement } from './hooks/useControlsSignal';
import useVideoWaitingSignal from './hooks/useVideoWaitingSignal';
import Button from '../ui/Button';
@ -113,7 +113,7 @@ const VideoPlayer: FC<OwnProps> = ({
const [, toggleControls, lockControls] = useControlsSignal();
const [getIsSeeking, setIsSeeking] = useSignal(false);
const lastMousePositionRef = useRef({ x: 0, y: 0 });
const lastMousePositionRef = useRef<{ x: number; y: number }>();
useEffect(() => {
const updateMousePosition = (e: MouseEvent | TouchEvent) => {
@ -129,6 +129,11 @@ const VideoPlayer: FC<OwnProps> = ({
};
}, []);
useEffect(() => {
registerPlayerElement(videoRef.current, () => lastMousePositionRef.current);
return () => registerPlayerElement(undefined);
}, []);
const checkMousePositionAndToggleControls = useLastCallback((clientX: number, clientY: number) => {
const bounds = videoRef.current?.getBoundingClientRect();
if (!bounds) return;
@ -150,7 +155,7 @@ const VideoPlayer: FC<OwnProps> = ({
const handleSeekingChange = useLastCallback((isSeeking: boolean) => {
setIsSeeking(isSeeking);
if (!isSeeking) {
if (!isSeeking && lastMousePositionRef.current) {
const { x, y } = lastMousePositionRef.current;
checkMousePositionAndToggleControls(x, y);
}
@ -250,7 +255,7 @@ const VideoPlayer: FC<OwnProps> = ({
if (isLooped) return;
setCurrentTime(0);
setIsPlaying(false);
toggleControls(true);
toggleControls(true, true);
});
const handleFullscreenChange = useLastCallback(() => {

View File

@ -1,10 +1,37 @@
import { IS_TOUCH_ENV } from '../../../util/browser/windowEnvironment';
import { createSignal } from '../../../util/signals';
import useDerivedSignal from '../../../hooks/useDerivedSignal';
const [getControlsVisible, setControlsVisible] = createSignal(false);
const [getControlsVisible, setControlsVisibleSignal] = createSignal(false);
const [getIsLocked, setIsLocked] = createSignal(false);
let playerElement: HTMLElement | undefined;
let getMousePosition: (() => { x: number; y: number } | undefined) | undefined;
function isMouseInsidePlayer() {
if (IS_TOUCH_ENV) return true;
if (!playerElement || !getMousePosition) return false;
const pos = getMousePosition();
if (!pos) return true;
const bounds = playerElement.getBoundingClientRect();
return pos.x >= bounds.left && pos.x <= bounds.right
&& pos.y >= bounds.top && pos.y <= bounds.bottom;
}
const setControlsVisible = (value: boolean, noPositionCheck?: boolean) => {
if (value && (!noPositionCheck && !isMouseInsidePlayer())) return;
setControlsVisibleSignal(value);
};
export function registerPlayerElement(
el: HTMLElement | undefined,
mousePositionGetter?: () => { x: number; y: number } | undefined,
) {
playerElement = el;
getMousePosition = mousePositionGetter;
}
export default function useControlsSignal() {
const getVisible = useDerivedSignal(
() => getControlsVisible() && !getIsLocked(),