From dee28f378a815e6518a010a293733b26ae7bed9c Mon Sep 17 00:00:00 2001 From: Hailey Date: Wed, 4 Sep 2024 08:06:45 -0700 Subject: [PATCH] [Video] Only allow one `VideoView` to be active at a time, regardless of source (#5131) --- .../post-embeds/ActiveVideoNativeContext.tsx | 19 ++++++++++++++++--- src/view/com/util/post-embeds/VideoEmbed.tsx | 17 ++++++++++------- 2 files changed, 26 insertions(+), 10 deletions(-) diff --git a/src/view/com/util/post-embeds/ActiveVideoNativeContext.tsx b/src/view/com/util/post-embeds/ActiveVideoNativeContext.tsx index 77616d78..bdc7967c 100644 --- a/src/view/com/util/post-embeds/ActiveVideoNativeContext.tsx +++ b/src/view/com/util/post-embeds/ActiveVideoNativeContext.tsx @@ -4,8 +4,9 @@ import {useVideoPlayer, VideoPlayer} from 'expo-video' import {isNative} from '#/platform/detection' const Context = React.createContext<{ - activeSource: string | null - setActiveSource: (src: string) => void + activeSource: string + activeViewId: string | undefined + setActiveSource: (src: string, viewId: string) => void player: VideoPlayer } | null>(null) @@ -15,6 +16,7 @@ export function Provider({children}: {children: React.ReactNode}) { } const [activeSource, setActiveSource] = React.useState('') + const [activeViewId, setActiveViewId] = React.useState() const player = useVideoPlayer(activeSource, p => { p.muted = true @@ -22,8 +24,19 @@ export function Provider({children}: {children: React.ReactNode}) { p.play() }) + const setActiveSourceOuter = (src: string, viewId: string) => { + setActiveSource(src) + setActiveViewId(viewId) + } + return ( - + {children} ) diff --git a/src/view/com/util/post-embeds/VideoEmbed.tsx b/src/view/com/util/post-embeds/VideoEmbed.tsx index 03838b66..988ba573 100644 --- a/src/view/com/util/post-embeds/VideoEmbed.tsx +++ b/src/view/com/util/post-embeds/VideoEmbed.tsx @@ -1,4 +1,4 @@ -import React, {useCallback, useState} from 'react' +import React, {useCallback, useId, useState} from 'react' import {View} from 'react-native' import {Image} from 'expo-image' import {AppBskyEmbedVideo} from '@atproto/api' @@ -17,11 +17,14 @@ import {useActiveVideoNative} from './ActiveVideoNativeContext' import * as VideoFallback from './VideoEmbedInner/VideoFallback' 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 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 renderError = useCallback( @@ -34,7 +37,7 @@ export function VideoEmbed({embed}: {embed: AppBskyEmbedVideo.View}) { const onChangeStatus = (isVisible: boolean) => { if (isVisible) { - setActiveSource(embed.playlist) + setActiveSource(embed.playlist, viewId) if (!player.playing) { player.play() } @@ -88,7 +91,7 @@ export function VideoEmbed({embed}: {embed: AppBskyEmbedVideo.View}) {