import { NavigationContainer, useNavigation } from '@react-navigation/native';
import {
createNativeStackNavigator,
type NativeStackScreenProps,
} from '@react-navigation/native-stack';
import { useVideoPlayer, VideoView } from 'expo-video';
import { useRef } from 'react';
import {
Pressable,
StatusBar,
StyleSheet,
Text,
useColorScheme,
useWindowDimensions,
View,
} from 'react-native';
import 'react-native-gesture-handler';
import { GestureHandlerRootView } from 'react-native-gesture-handler';
import { SafeAreaProvider, SafeAreaView } from 'react-native-safe-area-context';
import {
Channel,
Chat,
MessageComposer,
MessageList,
OverlayProvider,
useChatContext,
useCreateChatClient,
} from 'stream-chat-expo';
import {
channelId,
channelType,
chatApiKey,
chatUserId,
chatUserName,
chatUserToken,
} from './config';
const liveStream = 'https://live.143b.ch/cam/flux/ts:abr.m3u8';
const user = {
id: chatUserId,
name: chatUserName,
};
const Stack = createNativeStackNavigator<any>();
function App() {
const isDarkMode = useColorScheme() === 'dark';
return (
<SafeAreaProvider>
<GestureHandlerRootView style={styles.flex}>
<StatusBar barStyle={isDarkMode ? 'light-content' : 'dark-content'} />
<ChatWrapper>
<NavigationContainer>
<Stack.Navigator screenOptions={{ headerShown: false }}>
<Stack.Screen name="Home" component={HomeScreen} />
<Stack.Screen
name="Video"
component={VideoScreen}
options={{
animation: 'slide_from_bottom',
animationDuration: 280,
gestureEnabled: false,
presentation: 'fullScreenModal',
headerShown: false,
autoHideHomeIndicator: true,
}}
/>
</Stack.Navigator>
</NavigationContainer>
</ChatWrapper>
</GestureHandlerRootView>
</SafeAreaProvider>
);
}
// HomeScreen.tsx
function HomeScreen({ navigation }: NativeStackScreenProps<any>) {
return (
<SafeAreaView style={styles.home}>
<Pressable onPress={() => navigation.navigate('Video')}>
<Text>Open Stream</Text>
</Pressable>
</SafeAreaView>
);
}
// VideoScreen.tsx
function VideoScreen() {
const navigation = useNavigation();
const player = useVideoPlayer(
{ uri: liveStream, contentType: 'hls' },
videoPlayer => {
videoPlayer.play();
},
);
const { width, height } = useWindowDimensions();
return (
<View style={styles.flex}>
<VideoView
style={StyleSheet.absoluteFill}
player={player}
contentFit="cover"
nativeControls={false}
/>
<Pressable style={[{ top: 24 }]} onPress={() => navigation.goBack()}>
<Text>✕</Text>
</Pressable>
<View
style={{
height,
width: width * 0.4,
position: 'absolute',
top: 0,
left: 0,
}}
>
<ChatChannel />
</View>
</View>
);
}
export const ChatWrapper = ({ children }: { children: React.ReactNode }) => {
const chatClient = useCreateChatClient({
apiKey: chatApiKey,
userData: user,
tokenOrProvider: chatUserToken,
});
if (!chatClient) {
return (
<SafeAreaView style={styles.flex}>
<Text>Loading chat ...</Text>
</SafeAreaView>
);
}
return (
<View style={styles.flex}>
<OverlayProvider
value={{
style: {
messageList: {
container: {
backgroundColor: 'rgba(0, 0, 0, 0.5)',
},
},
},
}}
>
<Chat client={chatClient}>{children}</Chat>
</OverlayProvider>
</View>
);
};
const ChatChannel = () => {
const { client } = useChatContext();
const channel = useRef(client.channel(channelType, channelId));
return (
<Channel channel={channel.current}>
<MessageList />
<MessageComposer />
</Channel>
);
};
const styles = StyleSheet.create({
flex: {
flex: 1,
},
home: {
flex: 1,
alignItems: 'center',
justifyContent: 'center',
},
chatOverlay: {
width: '40%',
},
});
export default App;
Issue
As an example use-case - a twitch-style live stream with chat overlayed on top. We have a video fill the screen and place our stream chat over the top (tested with both absolute positioning and
react-native-teleport- see app examples below - issue occurs with both approaches).In both cases, when we tap-hold a message to react - the message disappears and the actions are invisible.
Screen.Recording.2026-07-06.at.3.36.29.pm.mov
(note, portrait/landscape doesn't matter - landscape just better matches the use-case)
Steps to reproduce
Expected behavior
Reactions should work the same as when not in an overlay/portal. This is the case on Android:
Screen_Recording_20260706_154543_ReactNativeSandbox.mp4
Project Related Information
Example using absolute position
Click To Expand
Example using portal
Click To Expand
Offline support
Environment
Click To Expand
package.json:{ "name": "ReactNativeSandbox", "version": "0.0.1", "private": true, "scripts": { "android": "react-native run-android", "ios": "react-native run-ios", "lint": "eslint .", "start": "react-native start", "test": "jest" }, "reanimated": { "staticFeatureFlags": { "FORCE_REACT_RENDER_FOR_SETTLED_ANIMATIONS": false } }, "dependencies": { "@react-native-community/netinfo": "12.0.1", "@react-native/new-app-screen": "0.85.0", "@react-navigation/native": "^7.3.7", "@react-navigation/native-stack": "^7.17.9", "expo": "~56.0.0", "expo-image-manipulator": "~56.0.20", "expo-image-picker": "^57.0.2", "expo-video": "^57.0.0", "react": "19.2.3", "react-native": "0.85.0", "react-native-gesture-handler": "~2.31.1", "react-native-orientation-director": "^3.0.2", "react-native-reanimated": "4.3.1", "react-native-safe-area-context": "~5.7.0", "react-native-screens": "^4.25.2", "react-native-svg": "15.15.4", "react-native-teleport": "^1.1.10", "react-native-worklets": "0.8.3", "stream-chat-expo": "^9.6.0" }, "devDependencies": { "@babel/core": "^7.25.2", "@babel/preset-env": "^7.25.3", "@babel/runtime": "^7.25.0", "@react-native-community/cli": "20.1.0", "@react-native-community/cli-platform-android": "20.1.0", "@react-native-community/cli-platform-ios": "20.1.0", "@react-native/babel-preset": "0.85.0", "@react-native/eslint-config": "0.85.0", "@react-native/metro-config": "0.85.0", "@react-native/typescript-config": "0.85.0", "@types/jest": "^29.5.13", "@types/react": "^19.2.0", "@types/react-test-renderer": "^19.1.0", "babel-preset-expo": "~56.0.0", "eslint": "^8.19.0", "jest": "^29.6.3", "prettier": "2.8.8", "react-test-renderer": "19.2.3", "typescript": "^5.8.3" }, "engines": { "node": ">= 22.11.0" } }react-native infooutput:stream-chat-react-nativeversion you're using that has this issue:e.g. 5.4.3Additional context
Screenshots
Click To Expand