import React, {useCallback, useEffect, useRef, useState} from 'react' import {Pressable, View} from 'react-native' import Animated, {FadeIn} from 'react-native-reanimated' import {VideoPlayer, VideoView} from 'expo-video' import {msg} from '@lingui/macro' import {useLingui} from '@lingui/react' import {useIsFocused} from '@react-navigation/native' import {HITSLOP_30} from '#/lib/constants' import {useVideoPlayer} from '#/view/com/util/post-embeds/VideoPlayerContext' import {android, 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 {PlatformInfo} from '../../../../../../modules/expo-bluesky-swiss-army' export function VideoEmbedInnerNative() { const player = useVideoPlayer() const ref = useRef(null) const isScreenFocused = useIsFocused() // pause the video when the screen is not focused useEffect(() => { if (!isScreenFocused) { let wasPlaying = player.playing player.pause() return () => { if (wasPlaying) player.play() } } }, [isScreenFocused, player]) return ( { PlatformInfo.setAudioMixWithOthers(false) player.muted = false }} onExitFullscreen={() => { PlatformInfo.setAudioMixWithOthers(true) player.muted = true }} /> { ref.current?.enterFullscreen() }} /> ) } function Controls({ player, enterFullscreen, }: { player: VideoPlayer enterFullscreen: () => void }) { const {_} = useLingui() const t = useTheme() const [isMuted, setIsMuted] = useState(player.muted) const [duration, setDuration] = useState(() => Math.floor(player.duration)) const [currentTime, setCurrentTime] = useState(() => 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 if (player.duration) setDuration(Math.floor(player.duration)) setCurrentTime(Math.floor(player.currentTime)) // how often should we update the time? // 1000 gets out of sync with the video time }, 250) // eslint-disable-next-line @typescript-eslint/no-shadow const sub = player.addListener('volumeChange', ({isMuted}) => { setIsMuted(isMuted) }) return () => { clearInterval(interval) sub.remove() } }, [player]) const toggleSound = useCallback(() => { const newValue = !player.muted // We want to set this to the _inverse_ of the new value, because we actually want for the audio to be mixed when // the video is muted, and vice versa. PlatformInfo.setAudioMixWithOthers(!newValue) player.muted = newValue }, [player]) return ( {!isNaN(timeRemaining) && ( {minutes}:{seconds} )} {isMuted ? ( ) : ( )} ) }