render player earlier, allowing preload

This commit is contained in:
Samuel Newman
2024-08-02 21:58:32 +02:00
parent 17f5d0980a
commit dd0e44e665
5 changed files with 15 additions and 49 deletions
@@ -1,11 +1,7 @@
import React, {useCallback, useEffect, useRef, useState} from 'react'
import React, {useEffect, useRef, useState} from 'react'
import {View} from 'react-native'
import {msg} from '@lingui/macro'
import {useLingui} from '@lingui/react'
import {atoms as a, useTheme} from '#/alf'
import {Button, ButtonIcon} from '#/components/Button'
import {Play_Filled_Corner2_Rounded as PlayIcon} from '#/components/icons/Play'
import {useActiveVideoView} from './ActiveVideoContext'
import {VideoEmbedInner} from './VideoEmbedInner'
@@ -17,10 +13,6 @@ export function VideoEmbed({source}: {source: string}) {
source,
})
const [onScreen, setOnScreen] = useState(false)
const [hasBeenOnScreen, setHasBeenOnScreen] = useState(false)
const {_} = useLingui()
const onPress = useCallback(() => setActive(), [setActive])
useEffect(() => {
if (!ref.current) return
@@ -29,9 +21,6 @@ export function VideoEmbed({source}: {source: string}) {
const entry = entries[0]
if (!entry) return
setOnScreen(entry.isIntersecting)
if (entry.isIntersecting) {
setHasBeenOnScreen(true)
}
sendPosition(
entry.boundingClientRect.y + entry.boundingClientRect.height / 2,
)
@@ -42,11 +31,6 @@ export function VideoEmbed({source}: {source: string}) {
return () => observer.disconnect()
}, [sendPosition])
const onGoFarOffScreen = useCallback(() => {
setOnScreen(false)
setHasBeenOnScreen(false)
}, [])
return (
<View
style={[
@@ -60,27 +44,14 @@ export function VideoEmbed({source}: {source: string}) {
ref={ref}
style={{display: 'flex', flex: 1}}
onClick={evt => evt.stopPropagation()}>
{hasBeenOnScreen || active ? (
<VideoEmbedInner
source={source}
active={active}
setActive={setActive}
sendPosition={sendPosition}
onScreen={onScreen}
isAnyViewActive={currentActiveView !== null}
onGoFarOffScreen={onGoFarOffScreen}
/>
) : (
<Button
style={[a.flex_1, t.atoms.bg_contrast_25, a.rounded_sm]}
onPress={onPress}
label={_(msg`Play video`)}
variant="ghost"
color="secondary"
size="large">
<ButtonIcon icon={PlayIcon} />
</Button>
)}
<VideoEmbedInner
source={source}
active={active}
setActive={setActive}
sendPosition={sendPosition}
onScreen={onScreen}
isAnyViewActive={currentActiveView !== null}
/>
</div>
</View>
)
@@ -20,7 +20,6 @@ export function VideoEmbedInner({}: {
sendPosition: (position: number) => void
onScreen: boolean
isAnyViewActive?: boolean
onGoFarOffScreen: () => void
}) {
const player = useVideoPlayer()
const aref = useAnimatedRef<Animated.View>()
@@ -9,7 +9,6 @@ export function VideoEmbedInner({
active,
sendPosition,
isAnyViewActive,
onGoFarOffScreen,
...props
}: {
source: string
@@ -17,10 +16,10 @@ export function VideoEmbedInner({
setActive: () => void
sendPosition: (position: number) => void
onScreen: boolean
onGoFarOffScreen: () => void
isAnyViewActive?: boolean
}) {
const ref = useRef<HTMLDivElement>(null)
const [nearScreen, setNearScreen] = useState(false)
// Send position when scrolling. This is done with an IntersectionObserver
// observing a div of 100vh height
@@ -33,16 +32,13 @@ export function VideoEmbedInner({
const position =
entry.boundingClientRect.y + entry.boundingClientRect.height / 2
sendPosition(position)
if (!entry.isIntersecting) {
// unmounts the video player
onGoFarOffScreen()
}
setNearScreen(entry.isIntersecting)
},
{threshold: Array.from({length: 101}, (_, i) => i / 100)},
)
observer.observe(ref.current)
return () => observer.disconnect()
}, [sendPosition, onGoFarOffScreen])
}, [sendPosition])
// In case scrolling hasn't started yet, send up the position
useEffect(() => {
@@ -55,7 +51,7 @@ export function VideoEmbedInner({
return (
<View style={[a.flex_1, a.flex_row]}>
<VideoPlayer active={active} {...props} />
{nearScreen && <VideoPlayer active={active} {...props} />}
<div
ref={ref}
style={{
@@ -3,7 +3,7 @@ import type Hls from 'hls.js'
export function Controls({}: {
videoRef: React.RefObject<HTMLVideoElement>
hlsRef: React.RefObject<Hls>
hlsRef: React.RefObject<Hls | undefined>
active: boolean
setActive: () => void
focused: boolean
@@ -40,7 +40,7 @@ export function Controls({
hasSubtitleTrack,
}: {
videoRef: React.RefObject<HTMLVideoElement>
hlsRef: React.RefObject<Hls>
hlsRef: React.RefObject<Hls | undefined>
active: boolean
setActive: () => void
focused: boolean