Reactions

Reactions are a great way to communicate between users when you have limited speakers or even if the users are in mute mode.

You can send an emoji to the call with the code below:

const reaction = {
  type: "reaction",
  emoji_code: ":like:",
  custom: {},
};
const call = useCall();
call?.sendReaction(reaction);

Reaction Mapper

Stream Video React Native SDK provides the default reaction mapper to display proper emojis. It basically handles a couple of default emojis, but you can customize those emoji maps by building your own mapper and passing it to supportedReactions prop of CallContent.

Once you pass the reaction map here, it is automatically handled in the ParticipantReaction component.

import {
  StreamReactionType,
  Call,
  CallContent,
  StreamCall,
} from "@stream-io/video-react-native-sdk";

const reactions: StreamReactionType[] = [
  {
    type: "reaction",
    emoji_code: ":rolling_on_the_floor_laughing:",
    custom: {},
    icon: "🤣",
  },
  {
    type: "reaction",
    emoji_code: ":like:",
    custom: {},
    icon: "👍",
  },
  {
    type: "reaction",
    emoji_code: ":rocket:",
    custom: {},
    icon: "🚀",
  },
  {
    type: "reaction",
    emoji_code: ":dislike:",
    custom: {},
    icon: "👎",
  },
  {
    type: "reaction",
    emoji_code: ":fireworks:",
    custom: {},
    icon: "🎉",
  },
  {
    type: "reaction",
    emoji_code: ":raised-hands:",
    custom: {},
    icon: "🙌",
  },
  {
    type: "raised-hand",
    emoji_code: ":raised-hand:",
    custom: {},
    icon: "✋",
  },
];

const VideoCallUI = () => {
  let call: Call;
  // your logic to create a new call or get an existing call

  return (
    <StreamCall call={call}>
      <CallContent supportedReactions={reactions} />
    </StreamCall>
  );
};

You can also use it in the ReactionsControls in order to list the supported reactions in the call controls and use them to send it.

import {
  StreamReactionType,
  Call,
  CallContent,
  StreamCall,
  ReactionsButton,
} from "@stream-io/video-react-native-sdk";
import { View, StyleSheet } from "react-native";

const reactions: StreamReactionType[] = [
  {
    type: "reaction",
    emoji_code: ":rolling_on_the_floor_laughing:",
    custom: {},
    icon: "🤣",
  },
  {
    type: "reaction",
    emoji_code: ":like:",
    custom: {},
    icon: "👍",
  },
  {
    type: "reaction",
    emoji_code: ":rocket:",
    custom: {},
    icon: "🚀",
  },
  {
    type: "reaction",
    emoji_code: ":dislike:",
    custom: {},
    icon: "👎",
  },
  {
    type: "reaction",
    emoji_code: ":fireworks:",
    custom: {},
    icon: "🎉",
  },
  {
    type: "reaction",
    emoji_code: ":raised-hands:",
    custom: {},
    icon: "🙌",
  },
  {
    type: "raised-hand",
    emoji_code: ":raised-hand:",
    custom: {},
    icon: "✋",
  },
];

const CustomCallControls = () => {
  return (
    <View style={styles.buttonGroup}>
      <ReactionsButton supportedReactions={supportedReactions} />
      {/* Other Call Controls */}
    </View>
  );
};

const VideoCallUI = () => {
  let call: Call;
  // your logic to create a new call or get an existing call

  return (
    <StreamCall call={call}>
      <CallContent CallControls={CustomCallControls} />
    </StreamCall>
  );
};

const styles = StyleSheet.create({
  buttonGroup: {
    flexDirection: "row",
    justifyContent: "space-evenly",
    paddingVertical: 10,
  },
});

Custom Participant Reaction

Preview of the Custom Participant reaction

You can customize the participant reaction by implementing your own reaction component and passing it to the CallContent component.

import { ParticipantReactionProps } from "@stream-io/video-react-native-sdk";
import { StyleSheet, Text, View } from "react-native";

const CustomParticipantReaction = ({
  participant,
  supportedReactions,
}: ParticipantReactionProps) => {
  const { reaction } = participant;

  const currentReaction =
    reaction &&
    supportedReactions.find(
      (supportedReaction) =>
        supportedReaction.emoji_code === reaction.emoji_code,
    );

  return (
    <View style={styles.background}>
      <Text style={styles.reaction}>{currentReaction?.icon}</Text>
    </View>
  );
};

const styles = StyleSheet.create({
  background: {
    alignItems: "center",
    justifyContent: "center",
    zIndex: Z_INDEX.IN_FRONT,
  },
  reaction: {
    fontSize: 50,
  },
});

Final Steps

Now this can be passed to the ParticipantReaction prop of the CallContent component, as follows:

import {
  Call,
  CallContent,
  StreamCall,
} from "@stream-io/video-react-native-sdk";

const VideoCallUI = () => {
  let call: Call;
  // your logic to create a new call or get an existing call

  const reactions: StreamReactionType[] = [
    {
      type: "reaction",
      emoji_code: ":rolling_on_the_floor_laughing:",
      custom: {},
      icon: "🤣",
    },
    {
      type: "reaction",
      emoji_code: ":like:",
      custom: {},
      icon: "👍",
    },
    {
      type: "reaction",
      emoji_code: ":rocket:",
      custom: {},
      icon: "🚀",
    },
    {
      type: "reaction",
      emoji_code: ":dislike:",
      custom: {},
      icon: "👎",
    },
    {
      type: "reaction",
      emoji_code: ":fireworks:",
      custom: {},
      icon: "🎉",
    },
    {
      type: "reaction",
      emoji_code: ":raised-hands:",
      custom: {},
      icon: "🙌",
    },
    {
      type: "raised-hand",
      emoji_code: ":raised-hand:",
      custom: {},
      icon: "✋",
    },
  ];

  return (
    <StreamCall call={call}>
      <CallContent
        supportedReactions={reactions}
        ParticipantReaction={CustomParticipantReaction}
      />
    </StreamCall>
  );
};

To get the participant data, you can use the following hooks from the useCallStateHooks:

  • useParticipants hook that provides all the necessary details of all the participants.
  • useRemoteParticipants hook that provides all the details of the participants other than the local participant.
  • useConnectedUser or useLocalParticipant provides the details of the local or connected participant.
© Getstream.io, Inc. All Rights Reserved.