From f9d736653ccbb6c85e54382da0c59ec8af08a0eb Mon Sep 17 00:00:00 2001
From: Samuel Newman <mozzius@protonmail.com>
Date: Tue, 3 Sep 2024 11:51:16 +0100
Subject: [Video] Hide mouse when inactive (#5094)

---
 .../VideoEmbedInner/VideoWebControls.tsx           | 44 ++++++++++++++++------
 1 file changed, 33 insertions(+), 11 deletions(-)

(limited to 'src/view/com/util/post-embeds/VideoEmbedInner/VideoWebControls.tsx')

diff --git a/src/view/com/util/post-embeds/VideoEmbedInner/VideoWebControls.tsx b/src/view/com/util/post-embeds/VideoEmbedInner/VideoWebControls.tsx
index 2ff2f6516..d9b99ef3a 100644
--- a/src/view/com/util/post-embeds/VideoEmbedInner/VideoWebControls.tsx
+++ b/src/view/com/util/post-embeds/VideoEmbedInner/VideoWebControls.tsx
@@ -78,8 +78,8 @@ export function Controls({
   const setSubtitlesEnabled = useSetSubtitlesEnabled()
   const {
     state: hovered,
-    onIn: onMouseEnter,
-    onOut: onMouseLeave,
+    onIn: onHover,
+    onOut: onEndHover,
   } = useInteractionState()
   const [isFullscreen, toggleFullscreen] = useFullscreen(fullscreenRef)
   const {state: hasFocus, onIn: onFocus, onOut: onBlur} = useInteractionState()
@@ -220,6 +220,25 @@ export function Controls({
     onSeek(clamp(currentTime + 5, 0, duration))
   }, [onSeek, videoRef])
 
+  const [showCursor, setShowCursor] = useState(true)
+  const cursorTimeoutRef = useRef<ReturnType<typeof setTimeout>>()
+  const onPointerMoveEmptySpace = useCallback(() => {
+    setShowCursor(true)
+    if (cursorTimeoutRef.current) {
+      clearTimeout(cursorTimeoutRef.current)
+    }
+    cursorTimeoutRef.current = setTimeout(() => {
+      setShowCursor(false)
+      onEndHover()
+    }, 2000)
+  }, [onEndHover])
+  const onPointerLeaveEmptySpace = useCallback(() => {
+    setShowCursor(false)
+    if (cursorTimeoutRef.current) {
+      clearTimeout(cursorTimeoutRef.current)
+    }
+  }, [])
+
   const showControls =
     (focused && !playing) || (interactingViaKeypress ? hasFocus : hovered)
 
@@ -236,13 +255,17 @@ export function Controls({
         evt.stopPropagation()
         setInteractingViaKeypress(false)
       }}
-      onMouseEnter={onMouseEnter}
-      onMouseLeave={onMouseLeave}
+      onPointerEnter={onHover}
+      onPointerMove={onHover}
+      onPointerLeave={onEndHover}
       onFocus={onFocus}
       onBlur={onBlur}
       onKeyDown={onKeyDown}>
       <Pressable
         accessibilityRole="button"
+        onPointerEnter={onPointerMoveEmptySpace}
+        onPointerMove={onPointerMoveEmptySpace}
+        onPointerLeave={onPointerLeaveEmptySpace}
         accessibilityHint={_(
           !focused
             ? msg`Unmute video`
@@ -250,10 +273,10 @@ export function Controls({
             ? msg`Pause video`
             : msg`Play video`,
         )}
-        style={a.flex_1}
+        style={[a.flex_1, web({cursor: showCursor ? 'pointer' : 'none'})]}
         onPress={onPressEmptySpace}
       />
-      {active && !showControls && !focused && duration > 0 && (
+      {!showControls && !focused && duration > 0 && (
         <TimeIndicator time={Math.floor(duration - currentTime)} />
       )}
       <View
@@ -407,8 +430,8 @@ function Scrubber({
   const [scrubberActive, setScrubberActive] = useState(false)
   const {
     state: hovered,
-    onIn: onMouseEnter,
-    onOut: onMouseLeave,
+    onIn: onStartHover,
+    onOut: onEndHover,
   } = useInteractionState()
   const {state: focused, onIn: onFocus, onOut: onBlur} = useInteractionState()
   const [seekPosition, setSeekPosition] = useState(0)
@@ -521,9 +544,8 @@ function Scrubber({
     <View
       testID="scrubber"
       style={[{height: 10, width: '100%'}, a.flex_shrink_0, a.px_xs]}
-      // @ts-expect-error web only -sfn
-      onMouseEnter={onMouseEnter}
-      onMouseLeave={onMouseLeave}>
+      onPointerEnter={onStartHover}
+      onPointerLeave={onEndHover}>
       <div
         ref={barRef}
         style={{
-- 
cgit 1.4.1

