diff --git a/src/components/mediaViewer/MediaViewerSlides.tsx b/src/components/mediaViewer/MediaViewerSlides.tsx index 533b2ac69..af4d972af 100644 --- a/src/components/mediaViewer/MediaViewerSlides.tsx +++ b/src/components/mediaViewer/MediaViewerSlides.tsx @@ -178,8 +178,9 @@ const MediaViewerSlides: FC = ({ return captureEvents(containerRef.current, { isNotPassive: true, - excludedClosestSelector: '.VideoPlayerControls, .MediaViewerFooter', - onCapture: () => { + excludedClosestSelector: '.MediaViewerFooter', + onCapture: (e) => { + if (checkIfControlTarget(e)) return; lastGestureTime = Date.now(); if (arePropsShallowEqual(transformRef.current, { x: 0, y: 0, scale: 1 })) { if (!activeSlideRef.current) return; @@ -193,6 +194,7 @@ const MediaViewerSlides: FC = ({ dragOffsetX, dragOffsetY, }) => { + if (checkIfControlTarget(event)) return; // Avoid conflicts with swipe-to-back gestures if (IS_IOS) { const { pageX } = (captureEvent as RealTouchEvent).touches[0]; @@ -553,3 +555,20 @@ export default memo(MediaViewerSlides); function getAnimationStyle(x = 0, y = 0, scale = 1) { 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; + } +} diff --git a/src/components/mediaViewer/VideoPlayerControls.scss b/src/components/mediaViewer/VideoPlayerControls.scss index 56f083cc8..ae1f44438 100644 --- a/src/components/mediaViewer/VideoPlayerControls.scss +++ b/src/components/mediaViewer/VideoPlayerControls.scss @@ -18,7 +18,7 @@ @media (max-width: 600px) { position: fixed; - padding: 1.25rem 0.5rem 0.75rem; + padding: 2.25rem 0.5rem 0.75rem; background: none; z-index: var(--z-media-viewer); } @@ -110,6 +110,10 @@ touch-action: none; cursor: pointer; + @media (max-width: 600px) { + top: 1rem; + } + &-track { position: absolute; top: 50%; diff --git a/src/components/mediaViewer/VideoPlayerControls.tsx b/src/components/mediaViewer/VideoPlayerControls.tsx index b521f6a9c..c11d5fc56 100644 --- a/src/components/mediaViewer/VideoPlayerControls.tsx +++ b/src/components/mediaViewer/VideoPlayerControls.tsx @@ -52,12 +52,13 @@ const VideoPlayerControls: FC = ({ }) => { // eslint-disable-next-line no-null/no-null const seekerRef = useRef(null); - const isSeeking = useRef(false); + const isSeekingRef = useRef(false); + const isSeeking = isSeekingRef.current; useEffect(() => { let timeout: number | undefined; - if (!isVisible || !isPlayed) { + if (!isVisible || !isPlayed || isSeeking) { if (timeout) window.clearTimeout(timeout); return; } @@ -67,7 +68,7 @@ const VideoPlayerControls: FC = ({ return () => { if (timeout) window.clearTimeout(timeout); }; - }, [isPlayed, isVisible, setVisibility]); + }, [isPlayed, isVisible, isSeeking, setVisibility]); useEffect(() => { if (isVisible) { @@ -83,7 +84,7 @@ const VideoPlayerControls: FC = ({ const lang = useLang(); const handleSeek = useCallback((e: MouseEvent | TouchEvent) => { - if (isSeeking.current && seekerRef.current) { + if (isSeekingRef.current && seekerRef.current) { const { width, left, @@ -94,12 +95,12 @@ const VideoPlayerControls: FC = ({ }, [duration, onSeek]); const handleStartSeek = useCallback((e: MouseEvent | TouchEvent) => { - isSeeking.current = true; + isSeekingRef.current = true; handleSeek(e); }, [handleSeek]); const handleStopSeek = useCallback(() => { - isSeeking.current = false; + isSeekingRef.current = false; }, []); useEffect(() => {