split into inner component again
This commit is contained in:
@@ -27,7 +27,7 @@ export function VideoEmbed({source}: {source: string}) {
|
|||||||
a.my_xs,
|
a.my_xs,
|
||||||
]}>
|
]}>
|
||||||
{active ? (
|
{active ? (
|
||||||
<VideoEmbedInner source={source} />
|
<VideoEmbedInner source={source} active={active} />
|
||||||
) : (
|
) : (
|
||||||
<Button
|
<Button
|
||||||
style={[a.flex_1, t.atoms.bg_contrast_25]}
|
style={[a.flex_1, t.atoms.bg_contrast_25]}
|
||||||
|
|||||||
@@ -1,47 +1,35 @@
|
|||||||
import React, {useCallback, useEffect, useRef, useState} from 'react'
|
import React, {useCallback, useEffect, useRef, useState} from 'react'
|
||||||
import {View} from 'react-native'
|
import {View} from 'react-native'
|
||||||
import Hls from 'hls.js'
|
import {msg} from '@lingui/macro'
|
||||||
|
import {useLingui} from '@lingui/react'
|
||||||
|
|
||||||
import {atoms as a, useTheme} from '#/alf'
|
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 {useActiveVideoView} from './ActiveVideoContext'
|
||||||
|
import {VideoEmbedInner} from './VideoEmbedInner'
|
||||||
|
|
||||||
export function VideoEmbed({source}: {source: string}) {
|
export function VideoEmbed({source}: {source: string}) {
|
||||||
const [hls] = useState(() => new Hls())
|
const t = useTheme()
|
||||||
const hasLoaded = useRef(false)
|
const ref = useRef<HTMLDivElement>(null)
|
||||||
const ref = useRef<HTMLVideoElement>(null)
|
|
||||||
const {active, setActive} = useActiveVideoView({
|
const {active, setActive} = useActiveVideoView({
|
||||||
source,
|
source,
|
||||||
measure: useCallback(() => {
|
measure: () => {
|
||||||
if (ref.current) {
|
if (ref.current) {
|
||||||
return ref.current.getBoundingClientRect()
|
return ref.current.getBoundingClientRect()
|
||||||
}
|
}
|
||||||
}, []),
|
},
|
||||||
})
|
})
|
||||||
const t = useTheme()
|
const [hasBeenActive, setHasBeenActive] = useState(false)
|
||||||
|
const {_} = useLingui()
|
||||||
|
|
||||||
|
const onPress = useCallback(() => setActive(), [setActive])
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (ref.current && active && !hasLoaded.current) {
|
if (active) {
|
||||||
hasLoaded.current = true
|
setHasBeenActive(true)
|
||||||
if (ref.current.canPlayType('application/vnd.apple.mpegurl')) {
|
|
||||||
ref.current.src = source
|
|
||||||
} else if (Hls.isSupported()) {
|
|
||||||
hls.loadSource(source)
|
|
||||||
} else {
|
|
||||||
// TODO: fallback
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}, [source, active, hls])
|
}, [active])
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (ref.current) {
|
|
||||||
if (
|
|
||||||
!ref.current.canPlayType('application/vnd.apple.mpegurl') &&
|
|
||||||
Hls.isSupported()
|
|
||||||
) {
|
|
||||||
hls.attachMedia(ref.current)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}, [source, active, hls])
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<View
|
<View
|
||||||
@@ -50,23 +38,24 @@ export function VideoEmbed({source}: {source: string}) {
|
|||||||
a.rounded_sm,
|
a.rounded_sm,
|
||||||
{aspectRatio: 16 / 9},
|
{aspectRatio: 16 / 9},
|
||||||
a.overflow_hidden,
|
a.overflow_hidden,
|
||||||
active ? t.atoms.bg_contrast_25 : t.atoms.bg_contrast_200,
|
t.atoms.bg_contrast_25,
|
||||||
a.my_xs,
|
a.my_xs,
|
||||||
]}>
|
]}>
|
||||||
<video
|
<div ref={ref} style={{display: 'flex', flex: 1}}>
|
||||||
ref={ref}
|
{hasBeenActive ? (
|
||||||
style={a.flex_1}
|
<VideoEmbedInner source={source} active={active} />
|
||||||
playsInline
|
) : (
|
||||||
preload="none"
|
<Button
|
||||||
loop
|
style={[a.flex_1, t.atoms.bg_contrast_25]}
|
||||||
muted
|
onPress={onPress}
|
||||||
autoPlay={active}
|
label={_(msg`Play video`)}
|
||||||
onClick={() => {
|
variant="ghost"
|
||||||
if (!active) {
|
color="secondary"
|
||||||
setActive()
|
size="large">
|
||||||
}
|
<ButtonIcon icon={PlayIcon} />
|
||||||
}}
|
</Button>
|
||||||
/>
|
)}
|
||||||
|
</div>
|
||||||
</View>
|
</View>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ import {atoms as a} from '#/alf'
|
|||||||
import {Text} from '#/components/Typography'
|
import {Text} from '#/components/Typography'
|
||||||
import {useVideoPlayer} from './VideoPlayerContext'
|
import {useVideoPlayer} from './VideoPlayerContext'
|
||||||
|
|
||||||
export const VideoEmbedInner = ({}: {source: string}) => {
|
export function VideoEmbedInner({}: {source: string; active: boolean}) {
|
||||||
const player = useVideoPlayer()
|
const player = useVideoPlayer()
|
||||||
const aref = useAnimatedRef<Animated.View>()
|
const aref = useAnimatedRef<Animated.View>()
|
||||||
const {height: windowHeight} = useWindowDimensions()
|
const {height: windowHeight} = useWindowDimensions()
|
||||||
|
|||||||
@@ -0,0 +1,63 @@
|
|||||||
|
import React, {useEffect, useRef, useState} from 'react'
|
||||||
|
import {View} from 'react-native'
|
||||||
|
import Hls from 'hls.js'
|
||||||
|
|
||||||
|
import {atoms as a, useTheme} from '#/alf'
|
||||||
|
|
||||||
|
export function VideoEmbedInner({
|
||||||
|
source,
|
||||||
|
active,
|
||||||
|
}: {
|
||||||
|
source: string
|
||||||
|
active: boolean
|
||||||
|
}) {
|
||||||
|
const [hls] = useState(() => new Hls())
|
||||||
|
const ref = useRef<HTMLVideoElement>(null)
|
||||||
|
const t = useTheme()
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (ref.current) {
|
||||||
|
if (ref.current.canPlayType('application/vnd.apple.mpegurl')) {
|
||||||
|
ref.current.src = source
|
||||||
|
} else if (Hls.isSupported()) {
|
||||||
|
hls.loadSource(source)
|
||||||
|
} else {
|
||||||
|
// TODO: fallback
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, [source, hls])
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (ref.current) {
|
||||||
|
if (
|
||||||
|
!ref.current.canPlayType('application/vnd.apple.mpegurl') &&
|
||||||
|
Hls.isSupported()
|
||||||
|
) {
|
||||||
|
hls.attachMedia(ref.current)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, [source, hls])
|
||||||
|
|
||||||
|
return (
|
||||||
|
<View
|
||||||
|
style={[
|
||||||
|
a.w_full,
|
||||||
|
a.rounded_sm,
|
||||||
|
{aspectRatio: 16 / 9},
|
||||||
|
a.overflow_hidden,
|
||||||
|
t.atoms.bg_contrast_25,
|
||||||
|
a.my_xs,
|
||||||
|
]}>
|
||||||
|
<video
|
||||||
|
src={source}
|
||||||
|
ref={ref}
|
||||||
|
style={a.flex_1}
|
||||||
|
playsInline
|
||||||
|
preload="none"
|
||||||
|
loop
|
||||||
|
muted
|
||||||
|
autoPlay={active}
|
||||||
|
/>
|
||||||
|
</View>
|
||||||
|
)
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user