Media Viewer: Fix seeking on mobile (#1736)
This commit is contained in:
parent
5c8c9d2672
commit
cb37404b8c
@ -178,8 +178,9 @@ const MediaViewerSlides: FC<OwnProps> = ({
|
|||||||
|
|
||||||
return captureEvents(containerRef.current, {
|
return captureEvents(containerRef.current, {
|
||||||
isNotPassive: true,
|
isNotPassive: true,
|
||||||
excludedClosestSelector: '.VideoPlayerControls, .MediaViewerFooter',
|
excludedClosestSelector: '.MediaViewerFooter',
|
||||||
onCapture: () => {
|
onCapture: (e) => {
|
||||||
|
if (checkIfControlTarget(e)) return;
|
||||||
lastGestureTime = Date.now();
|
lastGestureTime = Date.now();
|
||||||
if (arePropsShallowEqual(transformRef.current, { x: 0, y: 0, scale: 1 })) {
|
if (arePropsShallowEqual(transformRef.current, { x: 0, y: 0, scale: 1 })) {
|
||||||
if (!activeSlideRef.current) return;
|
if (!activeSlideRef.current) return;
|
||||||
@ -193,6 +194,7 @@ const MediaViewerSlides: FC<OwnProps> = ({
|
|||||||
dragOffsetX,
|
dragOffsetX,
|
||||||
dragOffsetY,
|
dragOffsetY,
|
||||||
}) => {
|
}) => {
|
||||||
|
if (checkIfControlTarget(event)) return;
|
||||||
// Avoid conflicts with swipe-to-back gestures
|
// Avoid conflicts with swipe-to-back gestures
|
||||||
if (IS_IOS) {
|
if (IS_IOS) {
|
||||||
const { pageX } = (captureEvent as RealTouchEvent).touches[0];
|
const { pageX } = (captureEvent as RealTouchEvent).touches[0];
|
||||||
@ -553,3 +555,20 @@ export default memo(MediaViewerSlides);
|
|||||||
function getAnimationStyle(x = 0, y = 0, scale = 1) {
|
function getAnimationStyle(x = 0, y = 0, scale = 1) {
|
||||||
return `transform: translate3d(${x.toFixed(3)}px, ${y.toFixed(3)}px, 0px) scale(${scale.toFixed(3)});`;
|
return `transform: translate3d(${x.toFixed(3)}px, ${y.toFixed(3)}px, 0px) scale(${scale.toFixed(3)});`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function checkIfInsideSelector(element: HTMLElement, selector: string) {
|
||||||
|
if (!element) return false;
|
||||||
|
if (element.matches(selector)) return true;
|
||||||
|
return Boolean(element.closest(selector));
|
||||||
|
}
|
||||||
|
|
||||||
|
function checkIfControlTarget(e: TouchEvent | MouseEvent) {
|
||||||
|
const target = e.target as HTMLElement;
|
||||||
|
if (checkIfInsideSelector(target, '.VideoPlayerControls')) {
|
||||||
|
if (checkIfInsideSelector(target, '.play, .fullscreen')) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
e.preventDefault();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@ -18,7 +18,7 @@
|
|||||||
|
|
||||||
@media (max-width: 600px) {
|
@media (max-width: 600px) {
|
||||||
position: fixed;
|
position: fixed;
|
||||||
padding: 1.25rem 0.5rem 0.75rem;
|
padding: 2.25rem 0.5rem 0.75rem;
|
||||||
background: none;
|
background: none;
|
||||||
z-index: var(--z-media-viewer);
|
z-index: var(--z-media-viewer);
|
||||||
}
|
}
|
||||||
@ -110,6 +110,10 @@
|
|||||||
touch-action: none;
|
touch-action: none;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
|
|
||||||
|
@media (max-width: 600px) {
|
||||||
|
top: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
&-track {
|
&-track {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 50%;
|
top: 50%;
|
||||||
|
|||||||
@ -52,12 +52,13 @@ const VideoPlayerControls: FC<IProps> = ({
|
|||||||
}) => {
|
}) => {
|
||||||
// eslint-disable-next-line no-null/no-null
|
// eslint-disable-next-line no-null/no-null
|
||||||
const seekerRef = useRef<HTMLDivElement>(null);
|
const seekerRef = useRef<HTMLDivElement>(null);
|
||||||
const isSeeking = useRef<boolean>(false);
|
const isSeekingRef = useRef<boolean>(false);
|
||||||
|
const isSeeking = isSeekingRef.current;
|
||||||
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
let timeout: number | undefined;
|
let timeout: number | undefined;
|
||||||
if (!isVisible || !isPlayed) {
|
if (!isVisible || !isPlayed || isSeeking) {
|
||||||
if (timeout) window.clearTimeout(timeout);
|
if (timeout) window.clearTimeout(timeout);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -67,7 +68,7 @@ const VideoPlayerControls: FC<IProps> = ({
|
|||||||
return () => {
|
return () => {
|
||||||
if (timeout) window.clearTimeout(timeout);
|
if (timeout) window.clearTimeout(timeout);
|
||||||
};
|
};
|
||||||
}, [isPlayed, isVisible, setVisibility]);
|
}, [isPlayed, isVisible, isSeeking, setVisibility]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (isVisible) {
|
if (isVisible) {
|
||||||
@ -83,7 +84,7 @@ const VideoPlayerControls: FC<IProps> = ({
|
|||||||
const lang = useLang();
|
const lang = useLang();
|
||||||
|
|
||||||
const handleSeek = useCallback((e: MouseEvent | TouchEvent) => {
|
const handleSeek = useCallback((e: MouseEvent | TouchEvent) => {
|
||||||
if (isSeeking.current && seekerRef.current) {
|
if (isSeekingRef.current && seekerRef.current) {
|
||||||
const {
|
const {
|
||||||
width,
|
width,
|
||||||
left,
|
left,
|
||||||
@ -94,12 +95,12 @@ const VideoPlayerControls: FC<IProps> = ({
|
|||||||
}, [duration, onSeek]);
|
}, [duration, onSeek]);
|
||||||
|
|
||||||
const handleStartSeek = useCallback((e: MouseEvent | TouchEvent) => {
|
const handleStartSeek = useCallback((e: MouseEvent | TouchEvent) => {
|
||||||
isSeeking.current = true;
|
isSeekingRef.current = true;
|
||||||
handleSeek(e);
|
handleSeek(e);
|
||||||
}, [handleSeek]);
|
}, [handleSeek]);
|
||||||
|
|
||||||
const handleStopSeek = useCallback(() => {
|
const handleStopSeek = useCallback(() => {
|
||||||
isSeeking.current = false;
|
isSeekingRef.current = false;
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user