animate controls + fade out time after a while (#4913)

Co-authored-by: Samuel Newman <10959775+mozzius@users.noreply.github.com>
zio/stable
Samuel Newman 2024-08-09 23:32:28 +01:00 committed by GitHub
parent 5bfe5aa503
commit 0a9782ac19
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
1 changed files with 40 additions and 28 deletions

View File

@ -1,6 +1,6 @@
import React, {useCallback, useEffect, useRef, useState} from 'react' import React, {useCallback, useEffect, useRef, useState} from 'react'
import {Pressable, View} from 'react-native' import {Pressable, View} from 'react-native'
import Animated, {FadeIn} from 'react-native-reanimated' import Animated, {FadeInDown, FadeOutDown} from 'react-native-reanimated'
import {VideoPlayer, VideoView} from 'expo-video' import {VideoPlayer, VideoView} from 'expo-video'
import {msg} from '@lingui/macro' import {msg} from '@lingui/macro'
import {useLingui} from '@lingui/react' import {useLingui} from '@lingui/react'
@ -39,7 +39,7 @@ export function VideoEmbedInnerNative() {
<VideoView <VideoView
ref={ref} ref={ref}
player={player} player={player}
style={a.flex_1} style={[a.flex_1, a.rounded_sm]}
nativeControls={true} nativeControls={true}
onEnterFullscreen={() => { onEnterFullscreen={() => {
PlatformInfo.setAudioCategory(AudioCategory.Playback) PlatformInfo.setAudioCategory(AudioCategory.Playback)
@ -86,6 +86,7 @@ function Controls({
// duration gets reset to 0 on loop // duration gets reset to 0 on loop
if (player.duration) setDuration(Math.floor(player.duration)) if (player.duration) setDuration(Math.floor(player.duration))
setCurrentTime(Math.floor(player.currentTime)) setCurrentTime(Math.floor(player.currentTime))
// how often should we update the time? // how often should we update the time?
// 1000 gets out of sync with the video time // 1000 gets out of sync with the video time
}, 250) }, 250)
@ -113,11 +114,18 @@ function Controls({
player.muted = muted player.muted = muted
}, [player]) }, [player])
// show countdown when:
// 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 showTime = !isNaN(timeRemaining) && duration > 0 && currentTime <= 5
return ( return (
<View style={[a.absolute, a.inset_0]}> <View style={[a.absolute, a.inset_0]}>
{!isNaN(timeRemaining) && ( {showTime && (
<Animated.View <Animated.View
entering={FadeIn.duration(100)} entering={FadeInDown.duration(300)}
exiting={FadeOutDown.duration(500)}
style={[ style={[
{ {
backgroundColor: 'rgba(0, 0, 0, 0.75)', backgroundColor: 'rgba(0, 0, 0, 0.75)',
@ -148,31 +156,35 @@ function Controls({
accessibilityHint={_(msg`Tap to enter full screen`)} accessibilityHint={_(msg`Tap to enter full screen`)}
accessibilityRole="button" accessibilityRole="button"
/> />
<Pressable {duration > 0 && (
onPress={toggleMuted} <Animated.View
style={{ entering={FadeInDown.duration(300)}
backgroundColor: 'rgba(0, 0, 0, 0.75)', style={{
borderRadius: 6, backgroundColor: 'rgba(0, 0, 0, 0.75)',
paddingHorizontal: 6, borderRadius: 6,
paddingVertical: 3, paddingHorizontal: 6,
position: 'absolute', paddingVertical: 3,
bottom: 5, position: 'absolute',
right: 5, bottom: 5,
minHeight: 20, right: 5,
justifyContent: 'center', minHeight: 20,
}} justifyContent: 'center',
accessibilityLabel={isMuted ? _(msg`Muted`) : _(msg`Unmuted`)} }}>
accessibilityHint={_(msg`Tap to toggle sound`)} <Pressable
accessibilityRole="button" onPress={toggleMuted}
hitSlop={HITSLOP_30}> style={a.flex_1}
<Animated.View entering={FadeIn.duration(100)}> accessibilityLabel={isMuted ? _(msg`Muted`) : _(msg`Unmuted`)}
{isMuted ? ( accessibilityHint={_(msg`Tap to toggle sound`)}
<MuteIcon width={14} fill={t.palette.white} /> accessibilityRole="button"
) : ( hitSlop={HITSLOP_30}>
<UnmuteIcon width={14} fill={t.palette.white} /> {isMuted ? (
)} <MuteIcon width={14} fill={t.palette.white} />
) : (
<UnmuteIcon width={14} fill={t.palette.white} />
)}
</Pressable>
</Animated.View> </Animated.View>
</Pressable> )}
</View> </View>
) )
} }