[Video] Only allow one `VideoView` to be active at a time, regardless of source (#5131)
parent
21e48bb2d8
commit
dee28f378a
|
@ -4,8 +4,9 @@ import {useVideoPlayer, VideoPlayer} from 'expo-video'
|
||||||
import {isNative} from '#/platform/detection'
|
import {isNative} from '#/platform/detection'
|
||||||
|
|
||||||
const Context = React.createContext<{
|
const Context = React.createContext<{
|
||||||
activeSource: string | null
|
activeSource: string
|
||||||
setActiveSource: (src: string) => void
|
activeViewId: string | undefined
|
||||||
|
setActiveSource: (src: string, viewId: string) => void
|
||||||
player: VideoPlayer
|
player: VideoPlayer
|
||||||
} | null>(null)
|
} | null>(null)
|
||||||
|
|
||||||
|
@ -15,6 +16,7 @@ export function Provider({children}: {children: React.ReactNode}) {
|
||||||
}
|
}
|
||||||
|
|
||||||
const [activeSource, setActiveSource] = React.useState('')
|
const [activeSource, setActiveSource] = React.useState('')
|
||||||
|
const [activeViewId, setActiveViewId] = React.useState<string>()
|
||||||
|
|
||||||
const player = useVideoPlayer(activeSource, p => {
|
const player = useVideoPlayer(activeSource, p => {
|
||||||
p.muted = true
|
p.muted = true
|
||||||
|
@ -22,8 +24,19 @@ export function Provider({children}: {children: React.ReactNode}) {
|
||||||
p.play()
|
p.play()
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const setActiveSourceOuter = (src: string, viewId: string) => {
|
||||||
|
setActiveSource(src)
|
||||||
|
setActiveViewId(viewId)
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Context.Provider value={{activeSource, setActiveSource, player}}>
|
<Context.Provider
|
||||||
|
value={{
|
||||||
|
activeSource,
|
||||||
|
setActiveSource: setActiveSourceOuter,
|
||||||
|
activeViewId,
|
||||||
|
player,
|
||||||
|
}}>
|
||||||
{children}
|
{children}
|
||||||
</Context.Provider>
|
</Context.Provider>
|
||||||
)
|
)
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import React, {useCallback, useState} from 'react'
|
import React, {useCallback, useId, useState} from 'react'
|
||||||
import {View} from 'react-native'
|
import {View} from 'react-native'
|
||||||
import {Image} from 'expo-image'
|
import {Image} from 'expo-image'
|
||||||
import {AppBskyEmbedVideo} from '@atproto/api'
|
import {AppBskyEmbedVideo} from '@atproto/api'
|
||||||
|
@ -17,11 +17,14 @@ import {useActiveVideoNative} from './ActiveVideoNativeContext'
|
||||||
import * as VideoFallback from './VideoEmbedInner/VideoFallback'
|
import * as VideoFallback from './VideoEmbedInner/VideoFallback'
|
||||||
|
|
||||||
export function VideoEmbed({embed}: {embed: AppBskyEmbedVideo.View}) {
|
export function VideoEmbed({embed}: {embed: AppBskyEmbedVideo.View}) {
|
||||||
const t = useTheme()
|
|
||||||
const {activeSource, setActiveSource, player} = useActiveVideoNative()
|
|
||||||
const [isFullscreen, setIsFullscreen] = React.useState(false)
|
|
||||||
const isActive = embed.playlist === activeSource
|
|
||||||
const {_} = useLingui()
|
const {_} = useLingui()
|
||||||
|
const t = useTheme()
|
||||||
|
const {activeSource, activeViewId, setActiveSource, player} =
|
||||||
|
useActiveVideoNative()
|
||||||
|
const viewId = useId()
|
||||||
|
|
||||||
|
const [isFullscreen, setIsFullscreen] = React.useState(false)
|
||||||
|
const isActive = embed.playlist === activeSource && activeViewId === viewId
|
||||||
|
|
||||||
const [key, setKey] = useState(0)
|
const [key, setKey] = useState(0)
|
||||||
const renderError = useCallback(
|
const renderError = useCallback(
|
||||||
|
@ -34,7 +37,7 @@ export function VideoEmbed({embed}: {embed: AppBskyEmbedVideo.View}) {
|
||||||
|
|
||||||
const onChangeStatus = (isVisible: boolean) => {
|
const onChangeStatus = (isVisible: boolean) => {
|
||||||
if (isVisible) {
|
if (isVisible) {
|
||||||
setActiveSource(embed.playlist)
|
setActiveSource(embed.playlist, viewId)
|
||||||
if (!player.playing) {
|
if (!player.playing) {
|
||||||
player.play()
|
player.play()
|
||||||
}
|
}
|
||||||
|
@ -88,7 +91,7 @@ export function VideoEmbed({embed}: {embed: AppBskyEmbedVideo.View}) {
|
||||||
<Button
|
<Button
|
||||||
style={[a.absolute, a.inset_0]}
|
style={[a.absolute, a.inset_0]}
|
||||||
onPress={() => {
|
onPress={() => {
|
||||||
setActiveSource(embed.playlist)
|
setActiveSource(embed.playlist, viewId)
|
||||||
}}
|
}}
|
||||||
label={_(msg`Play video`)}
|
label={_(msg`Play video`)}
|
||||||
color="secondary">
|
color="secondary">
|
||||||
|
|
Loading…
Reference in New Issue