Reactions during Live Stream - React Native
To increase interaction between viewers and speakers during a livestream, you can show viewers' reactions to everyone as flying emojis, as seen in livestreams on platforms like Instagram.
This guide explains how to implement this using the VideoSDK PubSub mechanism.
This page uses the following asynchronous methods. Refer to their API reference for the errors each Promise may reject with, and handle these rejections appropriately based on your use case.
Step 1: Creating a button to send reaction
To implement this functionality, start by creating a button that sends reactions to all users. When this button is clicked, publish a message with the emoji name to all participants using the VideoSDK PubSub mechanism. Additionally, use React Native's DeviceEventEmitter to notify the local participant about the reaction.
Use the same usePubSub hook to receive the reactions of other participants, and emit the same event for them. Your own reactions also come back through onMessageReceived, so skip messages whose senderId is your own participant id.
import { useRoom, usePubSub } from "@videosdk.live/react-native-sdk";
import { View, TouchableOpacity, Text, DeviceEventEmitter } from "react-native";
function ILSView() {
const { localParticipant } = useRoom();
const { publish } = usePubSub("REACTION", {
onMessageReceived: ({ message, senderId }) => {
// Your own reactions come back here too, and sendEmoji() already showed them
if (senderId !== localParticipant?.id) {
DeviceEventEmitter.emit("reaction_added", { emoji: message });
}
},
});
function sendEmoji(emoji) {
// Emit event here so the local user can see their own emoji
DeviceEventEmitter.emit("reaction_added", { emoji });
}
return (
<View>
<TouchableOpacity
onPress={async () => {
sendEmoji("confetti");
try {
await publish("confetti");
} catch (error) {
console.log("Error while publishing:", error);
}
}}
>
<Text>Send 🎉 Reaction</Text>
</TouchableOpacity>
<TouchableOpacity
onPress={async () => {
sendEmoji("clap");
try {
await publish("clap");
} catch (error) {
console.log("Error while publishing:", error);
}
}}
>
<Text>Send 👏 Reaction</Text>
</TouchableOpacity>
</View>
);
}
Step 2: Displaying the Reactions to all the users
FlyingEmojiOverlay.js will be utilized to display the reactions on the screen. Listen to the reaction_added event to show the flying emoji, both for your own reactions and for the reactions sent by other participants.
- Listening to local event and adding the
FlyingEmojiOverlaycomponent to theILSView:
import FlyingEmojiOverlay from "./FlyingEmojiOverlay";
function ILSView(){
// ...
return (
<View style={{ flex: 1 }}>
<FlyingEmojiOverlay/>
{/* Other components */}
</View>
);
}
import { View, Animated, StyleSheet, DeviceEventEmitter } from "react-native";
import { useState, useEffect, useCallback } from "react";
const EMOJI_MAP = {
confetti: "🎉",
clap: "👏",
};
const FlyingEmojisOverlay = () => {
const [emojis, setEmojis] = useState([]);
// Handler to display the emoji and start its animations
const handleDisplayFlyingEmoji = useCallback((emoji) => {
const newEmoji = {
id: `${Date.now()}-${Math.random()}`,
emoji: EMOJI_MAP[emoji],
position: new Animated.Value(0),
left: Math.random() * 100,
rotation: -30 + Math.random() * 60,
};
setEmojis((current) => [...current, newEmoji]);
Animated.timing(newEmoji.position, {
toValue: 1,
duration: 3000,
useNativeDriver: true,
}).start(() => {
setEmojis((current) => current.filter((e) => e.id !== newEmoji.id));
});
}, []);
// Listen to the reaction_added event to show your own and other participants' reactions
useEffect(() => {
const subscription = DeviceEventEmitter.addListener(
"reaction_added",
({ emoji }) => {
if (emoji) {
handleDisplayFlyingEmoji(emoji);
}
}
);
return () => subscription.remove();
}, [handleDisplayFlyingEmoji]);
return (
<View style={styles.container}>
{emojis.map((emoji) => (
<Animated.Text
key={emoji.id}
style={[
styles.emoji,
{
transform: [
{ translateY: emoji.position.interpolate({
inputRange: [0, 1],
outputRange: [0, -500]
})
},
{ rotate: `${emoji.rotation}deg` }
],
left: `${emoji.left}%`,
},
]}
>
{emoji.emoji}
</Animated.Text>
))}
</View>
);
};
const styles = StyleSheet.create({
container: {
position: 'absolute',
top: 0,
bottom: 0,
left: 0,
right: 0,
pointerEvents: 'none',
},
emoji: {
position: 'absolute',
bottom: 0,
fontSize: 48,
width: 48,
height: 48,
},
});
export default FlyingEmojisOverlay;
API Reference
The API references for all the methods and events utilized in this guide are provided below.
Got a Question? Ask us on discord

