make active player indicator subtler, clean up video utils

This commit is contained in:
Samuel Newman
2024-07-26 14:19:05 +01:00
parent d1360376c3
commit c1e19e4fde
2 changed files with 53 additions and 15 deletions
@@ -44,6 +44,7 @@ export function VideoEmbed({source}: {source: string}) {
a.w_full, a.w_full,
{aspectRatio: 16 / 9}, {aspectRatio: 16 / 9},
t.atoms.bg_contrast_25, t.atoms.bg_contrast_25,
a.rounded_sm,
a.my_xs, a.my_xs,
]}> ]}>
<div ref={ref} style={{display: 'flex', flex: 1}}> <div ref={ref} style={{display: 'flex', flex: 1}}>
@@ -2,7 +2,7 @@ import React, {useEffect, useRef, useState} from 'react'
import {View} from 'react-native' import {View} from 'react-native'
import Hls from 'hls.js' import Hls from 'hls.js'
import {atoms as a, useTheme} from '#/alf' import {atoms as a} from '#/alf'
export function VideoEmbedInner({ export function VideoEmbedInner({
active, active,
@@ -78,7 +78,8 @@ export function VideoPlayer({
const [hls] = useState(() => new Hls()) const [hls] = useState(() => new Hls())
const ref = useRef<HTMLVideoElement>(null) const ref = useRef<HTMLVideoElement>(null)
const [focused, setFocused] = useState(false) const [focused, setFocused] = useState(false)
const t = useTheme()
const {play, pause, togglePlayPause} = useVideoUtils(ref)
useEffect(() => { useEffect(() => {
if (ref.current) { if (ref.current) {
@@ -107,12 +108,19 @@ export function VideoPlayer({
}, [source, hls]) }, [source, hls])
useEffect(() => { useEffect(() => {
if (!ref.current) return if (active) {
if (!onScreen || !active) { play()
ref.current.pause()
setFocused(false)
} }
}, [onScreen, active]) return () => {
pause()
}
}, [active, play, pause])
useEffect(() => {
if (!onScreen) {
pause()
}
}, [onScreen, pause])
return ( return (
<View <View
@@ -121,13 +129,15 @@ export function VideoPlayer({
a.rounded_sm, a.rounded_sm,
{aspectRatio: 16 / 9}, {aspectRatio: 16 / 9},
a.overflow_hidden, a.overflow_hidden,
t.atoms.bg_contrast_25,
a.my_xs,
]}> ]}>
<div <div
style={{ style={{
position: 'absolute', position: 'absolute',
inset: 0, top: 5,
right: 5,
borderRadius: '50%',
width: 20,
height: 20,
background: active ? 'red' : 'blue', background: active ? 'red' : 'blue',
opacity: 0.5, opacity: 0.5,
pointerEvents: 'none', pointerEvents: 'none',
@@ -145,11 +155,7 @@ export function VideoPlayer({
onClick={evt => { onClick={evt => {
evt.stopPropagation() evt.stopPropagation()
if (focused) { if (focused) {
if (ref.current?.paused) { togglePlayPause()
ref.current.play()
} else {
ref.current?.pause()
}
} else { } else {
if (!active) { if (!active) {
setActive() setActive()
@@ -161,3 +167,34 @@ export function VideoPlayer({
</View> </View>
) )
} }
function useVideoUtils(ref: React.RefObject<HTMLVideoElement>) {
const play = () => {
if (!ref.current) return
// this is how you check if the video is ready to play
if (ref.current.readyState >= HTMLMediaElement.HAVE_ENOUGH_DATA) {
ref.current.play()
} else {
ref.current.addEventListener('canplay', () => {
ref.current?.play()
})
}
}
const pause = () => {
if (!ref.current) return
ref.current.pause()
}
const togglePlayPause = () => {
if (!ref.current) return
if (ref.current.paused) {
play()
} else {
pause()
}
}
return {play, pause, togglePlayPause}
}