Skip to content

Commit dee28f3

Browse files
authored
[Video] Only allow one VideoView to be active at a time, regardless of source (#5131)
1 parent 21e48bb commit dee28f3

File tree

2 files changed

+25
-9
lines changed

2 files changed

+25
-9
lines changed

src/view/com/util/post-embeds/ActiveVideoNativeContext.tsx

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,9 @@ import {useVideoPlayer, VideoPlayer} from 'expo-video'
44
import {isNative} from '#/platform/detection'
55

66
const Context = React.createContext<{
7-
activeSource: string | null
8-
setActiveSource: (src: string) => void
7+
activeSource: string
8+
activeViewId: string | undefined
9+
setActiveSource: (src: string, viewId: string) => void
910
player: VideoPlayer
1011
} | null>(null)
1112

@@ -15,15 +16,27 @@ export function Provider({children}: {children: React.ReactNode}) {
1516
}
1617

1718
const [activeSource, setActiveSource] = React.useState('')
19+
const [activeViewId, setActiveViewId] = React.useState<string>()
1820

1921
const player = useVideoPlayer(activeSource, p => {
2022
p.muted = true
2123
p.loop = true
2224
p.play()
2325
})
2426

27+
const setActiveSourceOuter = (src: string, viewId: string) => {
28+
setActiveSource(src)
29+
setActiveViewId(viewId)
30+
}
31+
2532
return (
26-
<Context.Provider value={{activeSource, setActiveSource, player}}>
33+
<Context.Provider
34+
value={{
35+
activeSource,
36+
setActiveSource: setActiveSourceOuter,
37+
activeViewId,
38+
player,
39+
}}>
2740
{children}
2841
</Context.Provider>
2942
)

src/view/com/util/post-embeds/VideoEmbed.tsx

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import React, {useCallback, useState} from 'react'
1+
import React, {useCallback, useId, useState} from 'react'
22
import {View} from 'react-native'
33
import {Image} from 'expo-image'
44
import {AppBskyEmbedVideo} from '@atproto/api'
@@ -17,11 +17,14 @@ import {useActiveVideoNative} from './ActiveVideoNativeContext'
1717
import * as VideoFallback from './VideoEmbedInner/VideoFallback'
1818

1919
export function VideoEmbed({embed}: {embed: AppBskyEmbedVideo.View}) {
20+
const {_} = useLingui()
2021
const t = useTheme()
21-
const {activeSource, setActiveSource, player} = useActiveVideoNative()
22+
const {activeSource, activeViewId, setActiveSource, player} =
23+
useActiveVideoNative()
24+
const viewId = useId()
25+
2226
const [isFullscreen, setIsFullscreen] = React.useState(false)
23-
const isActive = embed.playlist === activeSource
24-
const {_} = useLingui()
27+
const isActive = embed.playlist === activeSource && activeViewId === viewId
2528

2629
const [key, setKey] = useState(0)
2730
const renderError = useCallback(
@@ -34,7 +37,7 @@ export function VideoEmbed({embed}: {embed: AppBskyEmbedVideo.View}) {
3437

3538
const onChangeStatus = (isVisible: boolean) => {
3639
if (isVisible) {
37-
setActiveSource(embed.playlist)
40+
setActiveSource(embed.playlist, viewId)
3841
if (!player.playing) {
3942
player.play()
4043
}
@@ -88,7 +91,7 @@ export function VideoEmbed({embed}: {embed: AppBskyEmbedVideo.View}) {
8891
<Button
8992
style={[a.absolute, a.inset_0]}
9093
onPress={() => {
91-
setActiveSource(embed.playlist)
94+
setActiveSource(embed.playlist, viewId)
9295
}}
9396
label={_(msg`Play video`)}
9497
color="secondary">

0 commit comments

Comments
 (0)