···11import React from 'react'
22import {useVideoPlayer, VideoPlayer} from 'expo-video'
3344-import {isNative} from '#/platform/detection'
44+import {isAndroid, isNative} from '#/platform/detection'
5566const Context = React.createContext<{
77 activeSource: string
···2626 })
27272828 const setActiveSourceOuter = (src: string | null, viewId: string | null) => {
2929- setActiveSource(src ? src : '')
2929+ // HACK
3030+ // expo-video doesn't like it when you try and move a `player` to another `VideoView`. Instead, we need to actually
3131+ // unregister that player to let the new screen register it. This is only a problem on Android, so we only need to
3232+ // apply it there.
3333+ if (src === activeSource && isAndroid) {
3434+ setActiveSource('')
3535+ setTimeout(() => {
3636+ setActiveSource(src ? src : '')
3737+ }, 100)
3838+ } else {
3939+ setActiveSource(src ? src : '')
4040+ }
3041 setActiveViewId(viewId ? viewId : '')
3142 }
3243
···8899import {HITSLOP_30} from '#/lib/constants'
1010import {clamp} from '#/lib/numbers'
1111+import {isAndroid} from 'platform/detection'
1112import {useActiveVideoNative} from 'view/com/util/post-embeds/ActiveVideoNativeContext'
1213import {atoms as a, useTheme} from '#/alf'
1314import {Mute_Stroke2_Corner0_Rounded as MuteIcon} from '#/components/icons/Mute'
···6162 PlatformInfo.setAudioActive(true)
6263 player.muted = false
6364 setIsFullscreen(true)
6565+ if (isAndroid) {
6666+ player.play()
6767+ }
6468 }}
6569 onFullscreenExit={() => {
6670 PlatformInfo.setAudioCategory(AudioCategory.Ambient)
+24-1
src/view/shell/index.tsx
···1111import {useSafeAreaInsets} from 'react-native-safe-area-context'
1212import * as NavigationBar from 'expo-navigation-bar'
1313import {StatusBar} from 'expo-status-bar'
1414-import {useNavigationState} from '@react-navigation/native'
1414+import {useNavigation, useNavigationState} from '@react-navigation/native'
15151616import {useSession} from '#/state/session'
1717import {
···2020 useSetDrawerOpen,
2121} from '#/state/shell'
2222import {useCloseAnyActiveElement} from '#/state/util'
2323+import {useDedupe} from 'lib/hooks/useDedupe'
2324import {useNotificationsHandler} from 'lib/hooks/useNotificationHandler'
2425import {usePalette} from 'lib/hooks/usePalette'
2526import {useNotificationsRegistration} from 'lib/notifications/notifications'
···3334import {MutedWordsDialog} from '#/components/dialogs/MutedWords'
3435import {SigninDialog} from '#/components/dialogs/Signin'
3536import {Outlet as PortalOutlet} from '#/components/Portal'
3737+import {updateActiveViewAsync} from '../../../modules/expo-bluesky-swiss-army/src/VisibilityView'
3638import {RoutesContainer, TabsNavigator} from '../../Navigation'
3739import {Composer} from './Composer'
3840import {DrawerContent} from './Drawer'
···7577 listener.remove()
7678 }
7779 }, [closeAnyActiveElement])
8080+8181+ // HACK
8282+ // expo-video doesn't like it when you try and move a `player` to another `VideoView`. Instead, we need to actually
8383+ // unregister that player to let the new screen register it. This is only a problem on Android, so we only need to
8484+ // apply it there.
8585+ // The `state` event should only fire whenever we push or pop to a screen, and should not fire consecutively quickly.
8686+ // To be certain though, we will also dedupe these calls.
8787+ const navigation = useNavigation()
8888+ const dedupe = useDedupe(1000)
8989+ React.useEffect(() => {
9090+ if (!isAndroid) return
9191+ const onFocusOrBlur = () => {
9292+ setTimeout(() => {
9393+ dedupe(updateActiveViewAsync)
9494+ }, 500)
9595+ }
9696+ navigation.addListener('state', onFocusOrBlur)
9797+ return () => {
9898+ navigation.removeListener('state', onFocusOrBlur)
9999+ }
100100+ }, [dedupe, navigation])
7810179102 return (
80103 <>