diff options
author | Hailey <me@haileyok.com> | 2024-08-07 14:45:06 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-08-07 14:45:06 -0700 |
commit | 1b02f81cb85333462e3a9a42accc05d09aca4f2c (patch) | |
tree | 766e80438c1f109a1a7d751e9f04b7f6242f9766 /src/view/com/util/post-embeds/VideoEmbedInner.tsx | |
parent | fff2c079c2554861764974aaeeb56f79a25ba82a (diff) | |
download | voidsky-1b02f81cb85333462e3a9a42accc05d09aca4f2c.tar.zst |
[Video] Visibility detection view (#4741)
Co-authored-by: Samuel Newman <10959775+mozzius@users.noreply.github.com>
Diffstat (limited to 'src/view/com/util/post-embeds/VideoEmbedInner.tsx')
-rw-r--r-- | src/view/com/util/post-embeds/VideoEmbedInner.tsx | 143 |
1 files changed, 0 insertions, 143 deletions
diff --git a/src/view/com/util/post-embeds/VideoEmbedInner.tsx b/src/view/com/util/post-embeds/VideoEmbedInner.tsx deleted file mode 100644 index 9b1fd54fb..000000000 --- a/src/view/com/util/post-embeds/VideoEmbedInner.tsx +++ /dev/null @@ -1,143 +0,0 @@ -import React, {useCallback, useEffect, useRef, useState} from 'react' -import {Pressable, StyleSheet, useWindowDimensions, View} from 'react-native' -import Animated, { - measure, - runOnJS, - useAnimatedRef, - useFrameCallback, - useSharedValue, -} from 'react-native-reanimated' -import {VideoPlayer, VideoView} from 'expo-video' - -import {atoms as a} from '#/alf' -import {Text} from '#/components/Typography' -import {useVideoPlayer} from './VideoPlayerContext' - -export function VideoEmbedInner({}: { - source: string - active: boolean - setActive: () => void - onScreen: boolean -}) { - const player = useVideoPlayer() - const aref = useAnimatedRef<Animated.View>() - const {height: windowHeight} = useWindowDimensions() - const hasLeftView = useSharedValue(false) - const ref = useRef<VideoView>(null) - - const onEnterView = useCallback(() => { - if (player.status === 'readyToPlay') { - player.play() - } - }, [player]) - - const onLeaveView = useCallback(() => { - player.pause() - }, [player]) - - const enterFullscreen = useCallback(() => { - if (ref.current) { - ref.current.enterFullscreen() - } - }, []) - - useFrameCallback(() => { - const measurement = measure(aref) - - if (measurement) { - if (hasLeftView.value) { - // Check if the video is in view - if ( - measurement.pageY >= 0 && - measurement.pageY + measurement.height <= windowHeight - ) { - runOnJS(onEnterView)() - hasLeftView.value = false - } - } else { - // Check if the video is out of view - if ( - measurement.pageY + measurement.height < 0 || - measurement.pageY > windowHeight - ) { - runOnJS(onLeaveView)() - hasLeftView.value = true - } - } - } - }) - - return ( - <Animated.View - style={[a.flex_1, a.relative]} - ref={aref} - collapsable={false}> - <VideoView - ref={ref} - player={player} - style={a.flex_1} - nativeControls={true} - /> - <VideoControls player={player} enterFullscreen={enterFullscreen} /> - </Animated.View> - ) -} - -function VideoControls({ - player, - enterFullscreen, -}: { - player: VideoPlayer - enterFullscreen: () => void -}) { - const [currentTime, setCurrentTime] = useState(Math.floor(player.currentTime)) - - useEffect(() => { - const interval = setInterval(() => { - setCurrentTime(Math.floor(player.duration - player.currentTime)) - // how often should we update the time? - // 1000 gets out of sync with the video time - }, 250) - - return () => { - clearInterval(interval) - } - }, [player]) - - const minutes = Math.floor(currentTime / 60) - const seconds = String(currentTime % 60).padStart(2, '0') - - return ( - <View style={[a.absolute, a.inset_0]}> - <View style={styles.timeContainer} pointerEvents="none"> - <Text style={styles.timeElapsed}> - {minutes}:{seconds} - </Text> - </View> - <Pressable - onPress={enterFullscreen} - style={a.flex_1} - accessibilityLabel="Video" - accessibilityHint="Tap to enter full screen" - accessibilityRole="button" - /> - </View> - ) -} - -const styles = StyleSheet.create({ - timeContainer: { - backgroundColor: 'rgba(0, 0, 0, 0.75)', - borderRadius: 6, - paddingHorizontal: 6, - paddingVertical: 3, - position: 'absolute', - left: 5, - bottom: 5, - }, - timeElapsed: { - color: 'white', - fontSize: 12, - fontWeight: 'bold', - }, -}) |