about summary refs log tree commit diff
diff options
context:
space:
mode:
authorSamuel Newman <mozzius@protonmail.com>2024-08-27 22:15:59 +0100
committerGitHub <noreply@github.com>2024-08-27 22:15:59 +0100
commitb69c40da33c584edbaff3f1112aad727a3631a77 (patch)
tree55207e6fc822cc76d284ded8813f18dac164a662
parent9b534b968da2a87e2cfc0c8e62cda127f98edae1 (diff)
downloadvoidsky-b69c40da33c584edbaff3f1112aad727a3631a77.tar.zst
add indicator of time remaining (#5000)
-rw-r--r--src/view/com/util/post-embeds/VideoEmbedInner/TimeIndicator.tsx48
-rw-r--r--src/view/com/util/post-embeds/VideoEmbedInner/VideoEmbedInnerNative.tsx41
-rw-r--r--src/view/com/util/post-embeds/VideoEmbedInner/VideoWebControls.tsx4
3 files changed, 58 insertions, 35 deletions
diff --git a/src/view/com/util/post-embeds/VideoEmbedInner/TimeIndicator.tsx b/src/view/com/util/post-embeds/VideoEmbedInner/TimeIndicator.tsx
new file mode 100644
index 000000000..4d07ee78d
--- /dev/null
+++ b/src/view/com/util/post-embeds/VideoEmbedInner/TimeIndicator.tsx
@@ -0,0 +1,48 @@
+import React from 'react'
+import Animated, {FadeInDown, FadeOutDown} from 'react-native-reanimated'
+
+import {atoms as a, native, useTheme} from '#/alf'
+import {Text} from '#/components/Typography'
+
+/**
+ * Absolutely positioned time indicator showing how many seconds are remaining
+ * Time is in seconds
+ */
+export function TimeIndicator({time}: {time: number}) {
+  const t = useTheme()
+
+  if (isNaN(time)) {
+    return null
+  }
+
+  const minutes = Math.floor(time / 60)
+  const seconds = String(time % 60).padStart(2, '0')
+
+  return (
+    <Animated.View
+      entering={native(FadeInDown.duration(300))}
+      exiting={native(FadeOutDown.duration(500))}
+      style={[
+        {
+          backgroundColor: 'rgba(0, 0, 0, 0.5)',
+          borderRadius: 6,
+          paddingHorizontal: 6,
+          paddingVertical: 3,
+          position: 'absolute',
+          left: 5,
+          bottom: 5,
+          minHeight: 20,
+          justifyContent: 'center',
+        },
+      ]}>
+      <Text
+        style={[
+          {color: t.palette.white, fontSize: 12},
+          a.font_bold,
+          {lineHeight: 1.25},
+        ]}>
+        {minutes}:{seconds}
+      </Text>
+    </Animated.View>
+  )
+}
diff --git a/src/view/com/util/post-embeds/VideoEmbedInner/VideoEmbedInnerNative.tsx b/src/view/com/util/post-embeds/VideoEmbedInner/VideoEmbedInnerNative.tsx
index fa4943876..8cbf32a83 100644
--- a/src/view/com/util/post-embeds/VideoEmbedInner/VideoEmbedInnerNative.tsx
+++ b/src/view/com/util/post-embeds/VideoEmbedInner/VideoEmbedInnerNative.tsx
@@ -1,6 +1,6 @@
 import React, {useCallback, useEffect, useRef, useState} from 'react'
 import {Pressable, View} from 'react-native'
-import Animated, {FadeInDown, FadeOutDown} from 'react-native-reanimated'
+import Animated, {FadeInDown} from 'react-native-reanimated'
 import {VideoPlayer, VideoView} from 'expo-video'
 import {msg} from '@lingui/macro'
 import {useLingui} from '@lingui/react'
@@ -10,14 +10,14 @@ import {HITSLOP_30} from '#/lib/constants'
 import {useAppState} from '#/lib/hooks/useAppState'
 import {logger} from '#/logger'
 import {useVideoPlayer} from '#/view/com/util/post-embeds/VideoPlayerContext'
-import {android, atoms as a, useTheme} from '#/alf'
+import {atoms as a, useTheme} from '#/alf'
 import {Mute_Stroke2_Corner0_Rounded as MuteIcon} from '#/components/icons/Mute'
 import {SpeakerVolumeFull_Stroke2_Corner0_Rounded as UnmuteIcon} from '#/components/icons/Speaker'
-import {Text} from '#/components/Typography'
 import {
   AudioCategory,
   PlatformInfo,
 } from '../../../../../../modules/expo-bluesky-swiss-army'
+import {TimeIndicator} from './TimeIndicator'
 
 export function VideoEmbedInnerNative() {
   const player = useVideoPlayer()
@@ -86,10 +86,6 @@ function Controls({
     Math.floor(player.currentTime),
   )
 
-  const timeRemaining = duration - currentTime
-  const minutes = Math.floor(timeRemaining / 60)
-  const seconds = String(timeRemaining % 60).padStart(2, '0')
-
   useEffect(() => {
     const interval = setInterval(() => {
       // duration gets reset to 0 on loop
@@ -143,37 +139,12 @@ function Controls({
   // 1. timeRemaining is a number - was seeing NaNs
   // 2. duration is greater than 0 - means metadata has loaded
   // 3. we're less than 5 second into the video
+  const timeRemaining = duration - currentTime
   const showTime = !isNaN(timeRemaining) && duration > 0 && currentTime <= 5
 
   return (
     <View style={[a.absolute, a.inset_0]}>
-      {showTime && (
-        <Animated.View
-          entering={FadeInDown.duration(300)}
-          exiting={FadeOutDown.duration(500)}
-          style={[
-            {
-              backgroundColor: 'rgba(0, 0, 0, 0.75)',
-              borderRadius: 6,
-              paddingHorizontal: 6,
-              paddingVertical: 3,
-              position: 'absolute',
-              left: 5,
-              bottom: 5,
-              minHeight: 20,
-              justifyContent: 'center',
-            },
-          ]}>
-          <Text
-            style={[
-              {color: t.palette.white, fontSize: 12},
-              a.font_bold,
-              android({lineHeight: 1.25}),
-            ]}>
-            {minutes}:{seconds}
-          </Text>
-        </Animated.View>
-      )}
+      {showTime && <TimeIndicator time={timeRemaining} />}
       <Pressable
         onPress={onPressFullscreen}
         style={a.flex_1}
@@ -185,7 +156,7 @@ function Controls({
         <Animated.View
           entering={FadeInDown.duration(300)}
           style={{
-            backgroundColor: 'rgba(0, 0, 0, 0.75)',
+            backgroundColor: 'rgba(0, 0, 0, 0.5)',
             borderRadius: 6,
             paddingHorizontal: 6,
             paddingVertical: 3,
diff --git a/src/view/com/util/post-embeds/VideoEmbedInner/VideoWebControls.tsx b/src/view/com/util/post-embeds/VideoEmbedInner/VideoWebControls.tsx
index 09524b91c..7a4c6e914 100644
--- a/src/view/com/util/post-embeds/VideoEmbedInner/VideoWebControls.tsx
+++ b/src/view/com/util/post-embeds/VideoEmbedInner/VideoWebControls.tsx
@@ -36,6 +36,7 @@ import {Play_Filled_Corner0_Rounded as PlayIcon} from '#/components/icons/Play'
 import {SpeakerVolumeFull_Stroke2_Corner0_Rounded as UnmuteIcon} from '#/components/icons/Speaker'
 import {Loader} from '#/components/Loader'
 import {Text} from '#/components/Typography'
+import {TimeIndicator} from './TimeIndicator'
 
 export function Controls({
   videoRef,
@@ -252,6 +253,9 @@ export function Controls({
         style={a.flex_1}
         onPress={onPressEmptySpace}
       />
+      {active && !showControls && !focused && (
+        <TimeIndicator time={Math.floor(duration - currentTime)} />
+      )}
       <View
         style={[
           a.flex_shrink_0,