Video Player: Fix isSeeking change (#5977)
This commit is contained in:
parent
ad4e496446
commit
850daef3b0
@ -13,6 +13,7 @@ import { IS_TOUCH_ENV } from '../../util/browser/windowEnvironment';
|
||||
import buildClassName from '../../util/buildClassName';
|
||||
import { captureEvents } from '../../util/captureEvents';
|
||||
import { formatMediaDuration } from '../../util/dates/dateFormat';
|
||||
import getPointerPosition from '../../util/events/getPointerPosition';
|
||||
import { clamp, round } from '../../util/math';
|
||||
|
||||
import { useThrottledSignal } from '../../hooks/useAsyncResolvers';
|
||||
@ -151,7 +152,7 @@ const SeekLine: FC<OwnProps> = ({
|
||||
let offset = 0;
|
||||
|
||||
const getPreviewProps = (e: MouseEvent | TouchEvent) => {
|
||||
const pageX = e instanceof MouseEvent ? e.pageX : e.touches[0].pageX;
|
||||
const pageX = getPointerPosition(e).x;
|
||||
const t = clamp(duration * ((pageX - seekerSize.left) / seekerSize.width), 0, duration);
|
||||
if (isPreviewDisabled) return [t, 0];
|
||||
if (!seekerSize.width) seekerSize = seeker.getBoundingClientRect();
|
||||
|
||||
@ -1,13 +1,14 @@
|
||||
import type { FC } from '../../lib/teact/teact';
|
||||
import type React from '../../lib/teact/teact';
|
||||
import {
|
||||
memo, useEffect, useRef, useState,
|
||||
memo, useEffect, useRef, useSignal, useState,
|
||||
} from '../../lib/teact/teact';
|
||||
import { getActions } from '../../global';
|
||||
|
||||
import type { ApiDimensions } from '../../api/types';
|
||||
|
||||
import { IS_IOS, IS_TOUCH_ENV, IS_YA_BROWSER } from '../../util/browser/windowEnvironment';
|
||||
import getPointerPosition from '../../util/events/getPointerPosition';
|
||||
import { clamp } from '../../util/math';
|
||||
import safePlay from '../../util/safePlay';
|
||||
import stopEvent from '../../util/stopEvent';
|
||||
@ -112,17 +113,47 @@ const VideoPlayer: FC<OwnProps> = ({
|
||||
] = usePictureInPicture(videoRef, handleEnterFullscreen, handleLeaveFullscreen);
|
||||
|
||||
const [, toggleControls, lockControls] = useControlsSignal();
|
||||
const [getIsSeeking, setIsSeeking] = useSignal(false);
|
||||
const lastMousePosition = useRef({ x: 0, y: 0 });
|
||||
|
||||
useEffect(() => {
|
||||
const updateMousePosition = (e: MouseEvent | TouchEvent) => {
|
||||
lastMousePosition.current = getPointerPosition(e);
|
||||
};
|
||||
|
||||
window.addEventListener('mousemove', updateMousePosition);
|
||||
window.addEventListener('touchmove', updateMousePosition);
|
||||
|
||||
return () => {
|
||||
window.removeEventListener('mousemove', updateMousePosition);
|
||||
window.removeEventListener('touchmove', updateMousePosition);
|
||||
};
|
||||
}, []);
|
||||
|
||||
const checkMousePositionAndToggleControls = useLastCallback((clientX: number, clientY: number) => {
|
||||
const bounds = videoRef.current?.getBoundingClientRect();
|
||||
if (!bounds) return;
|
||||
if (clientX <= bounds.left || clientX >= bounds.right
|
||||
|| clientY <= bounds.top || clientY >= bounds.bottom) {
|
||||
if (!getIsSeeking()) {
|
||||
toggleControls(false);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
const handleVideoMove = useLastCallback(() => {
|
||||
toggleControls(true);
|
||||
});
|
||||
|
||||
const handleVideoLeave = useLastCallback((e) => {
|
||||
const bounds = videoRef.current?.getBoundingClientRect();
|
||||
if (!bounds) return;
|
||||
if (e.clientX <= bounds.left || e.clientX >= bounds.right
|
||||
|| e.clientY <= bounds.top || e.clientY >= bounds.bottom) {
|
||||
toggleControls(false);
|
||||
checkMousePositionAndToggleControls(e.clientX, e.clientY);
|
||||
});
|
||||
|
||||
const handleSeekingChange = useLastCallback((isSeeking: boolean) => {
|
||||
setIsSeeking(isSeeking);
|
||||
if (!isSeeking) {
|
||||
const { x, y } = lastMousePosition.current;
|
||||
checkMousePositionAndToggleControls(x, y);
|
||||
}
|
||||
});
|
||||
|
||||
@ -374,6 +405,7 @@ const VideoPlayer: FC<OwnProps> = ({
|
||||
onVolumeClick={handleVolumeMuted}
|
||||
onVolumeChange={handleVolumeChange}
|
||||
onPlaybackRateChange={handlePlaybackRateChange}
|
||||
onSeekingChange={handleSeekingChange}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
|
||||
@ -58,6 +58,7 @@ type OwnProps = {
|
||||
onPlaybackRateChange: (playbackRate: number) => void;
|
||||
onPlayPause: (e: React.MouseEvent<HTMLButtonElement, MouseEvent>) => void;
|
||||
onSeek: (position: number) => void;
|
||||
onSeekingChange: (isSeeking: boolean) => void;
|
||||
};
|
||||
|
||||
const stopEvent = (e: React.MouseEvent<HTMLElement>) => {
|
||||
@ -98,6 +99,7 @@ const VideoPlayerControls: FC<OwnProps> = ({
|
||||
onPictureInPictureChange,
|
||||
onPlayPause,
|
||||
onSeek,
|
||||
onSeekingChange,
|
||||
}) => {
|
||||
const [isPlaybackMenuOpen, openPlaybackMenu, closePlaybackMenu] = useFlag();
|
||||
const [getCurrentTime] = useCurrentTimeSignal();
|
||||
@ -146,10 +148,12 @@ const VideoPlayerControls: FC<OwnProps> = ({
|
||||
const handleSeek = useLastCallback((position: number) => {
|
||||
setIsSeeking(false);
|
||||
onSeek(position);
|
||||
onSeekingChange(false);
|
||||
});
|
||||
|
||||
const handleSeekStart = useLastCallback(() => {
|
||||
setIsSeeking(true);
|
||||
onSeekingChange(true);
|
||||
});
|
||||
|
||||
const volumeIcon: IconName = useMemo(() => {
|
||||
|
||||
@ -1,11 +1,11 @@
|
||||
import type { FC } from '../../lib/teact/teact';
|
||||
import type React from '../../lib/teact/teact';
|
||||
import {
|
||||
memo, useCallback, useEffect, useMemo, useRef, useState,
|
||||
} from '../../lib/teact/teact';
|
||||
|
||||
import buildClassName from '../../util/buildClassName';
|
||||
import buildStyle from '../../util/buildStyle';
|
||||
import getPointerPosition from '../../util/events/getPointerPosition';
|
||||
|
||||
import useOldLang from '../../hooks/useOldLang';
|
||||
|
||||
@ -59,7 +59,7 @@ const Draggable: FC<OwnProps> = ({
|
||||
const handleMouseDown = (e: React.MouseEvent | React.TouchEvent) => {
|
||||
e.stopPropagation();
|
||||
e.preventDefault();
|
||||
const { x, y } = getClientCoordinate(e);
|
||||
const { x, y } = getPointerPosition(e);
|
||||
|
||||
setState({
|
||||
...state,
|
||||
@ -71,7 +71,7 @@ const Draggable: FC<OwnProps> = ({
|
||||
};
|
||||
|
||||
const handleMouseMove = useCallback((e: MouseEvent | TouchEvent) => {
|
||||
const { x, y } = getClientCoordinate(e);
|
||||
const { x, y } = getPointerPosition(e);
|
||||
|
||||
const translation = {
|
||||
x: x - state.origin.x,
|
||||
@ -172,18 +172,3 @@ const Draggable: FC<OwnProps> = ({
|
||||
};
|
||||
|
||||
export default memo(Draggable);
|
||||
|
||||
function getClientCoordinate(e: MouseEvent | TouchEvent | React.MouseEvent | React.TouchEvent) {
|
||||
let x;
|
||||
let y;
|
||||
|
||||
if ('touches' in e) {
|
||||
x = e.touches[0].clientX;
|
||||
y = e.touches[0].clientY;
|
||||
} else {
|
||||
x = e.clientX;
|
||||
y = e.clientY;
|
||||
}
|
||||
|
||||
return { x, y };
|
||||
}
|
||||
|
||||
@ -9,6 +9,7 @@ import type { Point, Size } from '../types';
|
||||
import { RESIZE_HANDLE_SELECTOR } from '../config';
|
||||
import buildStyle from '../util/buildStyle';
|
||||
import { captureEvents } from '../util/captureEvents';
|
||||
import getPointerPosition from '../util/events/getPointerPosition';
|
||||
import useFlag from './useFlag';
|
||||
import useLastCallback from './useLastCallback';
|
||||
|
||||
@ -124,11 +125,11 @@ export default function useDraggable(
|
||||
if (targetElement.closest('.no-drag') || !element) {
|
||||
return;
|
||||
}
|
||||
const { pageX, pageY } = ('touches' in event) ? event.touches[0] : event;
|
||||
const { x, y } = getPointerPosition(event);
|
||||
|
||||
const { left, top } = element.getBoundingClientRect();
|
||||
setElementPositionOnStartTransform({ x: left, y: top });
|
||||
setTransformStartPoint({ x: pageX, y: pageY });
|
||||
setTransformStartPoint({ x, y });
|
||||
|
||||
startDragging();
|
||||
});
|
||||
@ -159,14 +160,14 @@ export default function useDraggable(
|
||||
if (resizeHandle === undefined) return;
|
||||
setHitResizeHandle(resizeHandle);
|
||||
|
||||
const { pageX, pageY } = ('touches' in event) ? event.touches[0] : event;
|
||||
const { x, y } = getPointerPosition(event);
|
||||
|
||||
const {
|
||||
left, right, top, bottom,
|
||||
} = element.getBoundingClientRect();
|
||||
setElementPositionOnStartTransform({ x: left, y: top });
|
||||
setElementSizeOnStartTransform({ width: right - left, height: bottom - top });
|
||||
setTransformStartPoint({ x: pageX, y: pageY });
|
||||
setTransformStartPoint({ x, y });
|
||||
|
||||
startResizing();
|
||||
});
|
||||
@ -269,10 +270,10 @@ export default function useDraggable(
|
||||
|
||||
const handleDrag = useLastCallback((event: MouseEvent | TouchEvent) => {
|
||||
if (!isDragging || !element) return;
|
||||
const { pageX, pageY } = ('touches' in event) ? event.touches[0] : event;
|
||||
const { x, y } = getPointerPosition(event);
|
||||
|
||||
const offsetX = pageX - transformStartPoint.x;
|
||||
const offsetY = pageY - transformStartPoint.y;
|
||||
const offsetX = x - transformStartPoint.x;
|
||||
const offsetY = y - transformStartPoint.y;
|
||||
|
||||
const newX = elementPositionOnStartTransform.x + offsetX;
|
||||
const newY = elementPositionOnStartTransform.y + offsetY;
|
||||
@ -282,11 +283,11 @@ export default function useDraggable(
|
||||
|
||||
const handleResize = useLastCallback((event: MouseEvent | TouchEvent) => {
|
||||
if (!isResizing || !element || hitResizeHandle === undefined) return;
|
||||
const { pageX, pageY } = ('touches' in event) ? event.touches[0] : event;
|
||||
const { x, y } = getPointerPosition(event);
|
||||
const sizeOnStartTransform = getElementSizeOnStartTransform();
|
||||
|
||||
const pageVisibleX = Math.min(Math.max(0, pageX), getVisibleArea().width);
|
||||
const pageVisibleY = Math.min(Math.max(0, pageY), getVisibleArea().height);
|
||||
const pageVisibleX = Math.min(Math.max(0, x), getVisibleArea().width);
|
||||
const pageVisibleY = Math.min(Math.max(0, y), getVisibleArea().height);
|
||||
|
||||
const offsetX = pageVisibleX - transformStartPoint.x;
|
||||
const offsetY = pageVisibleY - transformStartPoint.y;
|
||||
|
||||
13
src/util/events/getPointerPosition.ts
Normal file
13
src/util/events/getPointerPosition.ts
Normal file
@ -0,0 +1,13 @@
|
||||
export default function getPointerPosition(e: MouseEvent | TouchEvent | React.MouseEvent | React.TouchEvent) {
|
||||
if ('touches' in e) {
|
||||
return {
|
||||
x: e.touches[0].clientX,
|
||||
y: e.touches[0].clientY,
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
x: e.clientX,
|
||||
y: e.clientY,
|
||||
};
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user