import { Text } from "react-native";
import { ReactionData } from "stream-chat-react-native";
const supportedReactions: ReactionData[] = [
{ type: "happy", Icon: () => <Text>😄</Text> },
{ type: "sad", Icon: () => <Text>😦</Text> },
{ type: "love", Icon: () => <Text>❤️</Text> },
{ type: "angry", Icon: () => <Text>😠</Text> },
{ type: "haha", Icon: () => <Text>😆</Text> },
];
<Channel supportedReactions={supportedReactions}>
{/* Underlying MessageList and MessageInput components */}
</Channel>;
Customize Message Reactions
Message reactions are a crucial part of a chat applications. The SDK comes with built-in support for adding reactions to messages.
Supported Reaction types
You can customize the supported types of reactions for your application using the supportedReactions
prop of the Channel
component.
It expects an array of object with keys Icon
and type
. You can use ReactionData
type for additional type safety.
An example of how you can pass the supportedRections
to the Channel
component could be:
Reaction List Position
For the display of the reactions in the message we support both top
and bottom
view which can be customized using the reactionListPosition
prop of the Channel
component.
<Channel reactionListPosition="bottom">
{/* Underlying MessageList and MessageInput components */}
</Channel>
Top Reactions | Bottom Reactions |
Enforce unique reactions
We allow customizing the reaction behaviour for a message, such that a message can only have a single type of reaction as reacted by the user.
To do this, you can enable the enforceUniqueReaction
prop in the Channel
component.
<Channel enforceUniqueReaction>
{/* Underlying MessageList and MessageInput components */}
</Channel>
Customizing message Reaction List components
The message reaction list component on the message when the message has some reactions can be customized using the following components:
ReactionListTop
ReactionListBottom
These components can be customized by passing a custom UI implementation to the Channel
component as follows:
import { Pressable, StyleSheet } from "react-native";
import { Channel, useMessageContext } from "stream-chat-react-native";
const CustomReactionListBottomComponent = () => {
const {
handleReaction,
onPress,
onLongPress,
reactions,
showMessageOverlay,
} = useMessageContext<StreamChatGenerics>();
return (
<View style={styles.container}>
{reactions?.map((reaction) => {
const { type, Icon } = reaction;
return (
<Pressable
onLongPress={(event) => {
if (onLongPress) {
onLongPress({
defaultHandler: () => {
if (handleReaction) {
showMessageOverlay(true);
}
},
emitter: "reactionList",
event,
});
}
}}
onPress={(event) => {
onPress({
defaultHandler: () => {
if (handleReaction) {
handleReaction(reaction.type);
}
},
emitter: "reactionList",
event,
});
}}
key={type}
>
{Icon ? <Icon /> : null}
</Pressable>
);
})}
</View>
);
};
const ChannelScreen = () => {
return (
<Channel
reactionListPosition="bottom"
ReactionListBottom={CustomReactionListBottomComponent}
>
{/* Underlying MessageList and MessageInput components */}
</Channel>
);
};
const styles = StyleSheet.create({
container: {
borderRadius: 4,
flexDirection: "row",
marginVertical: 2,
},
});
Customizing Reaction Picker component
The UI for the Reaction Picker can be customized by passing a custom MessageReactionPicker
component in the Channel component
.
import { FlatList, Pressable, StyleSheet } from "react-native";
import { Channel, useMessageContext } from "stream-chat-react-native";
const CustomMessageReactionPicker = () => {
const { supportedReactions } = useMessagesContext<StreamChatGenerics>();
const { dismissOverlay, handleReaction } =
useMessageContext<StreamChatGenerics>();
const renderItem = ({ item }: { item: ReactionData }) => {
return (
<Pressable
key={item.type}
onPress={() => {
if (handleReaction) {
handleReaction(item.type);
}
dismissOverlay();
}}
>
{item.Icon ? <item.Icon /> : null}
</Pressable>
);
};
return (
<FlatList
columnWrapperStyle={styles.container1}
data={supportedReactions}
keyExtractor={(item) => item.type}
numColumns={6}
renderItem={renderItem}
/>
);
};
const ChannelScreen = () => {
return (
<Channel
reactionListPosition="bottom"
MessageReactionPicker={CustomMessageReactionPicker}
>
{/* Underlying MessageList and MessageInput components */}
</Channel>
);
};
const styles = StyleSheet.create({
container: {
justifyContent: "space-evenly",
marginVertical: 8,
},
});
Customizing Message Reactions by user list component
We display the list of the reactions reacted by users in the channel in the MessageUserReactions
component and each of the item in the list using the MessageUserReactionsItem
and the avatar using the MessageUserReactionsAvatar
component.
import { useMemo } from "react";
import { Image, FlatList, StyleSheet, Text, View } from "react-native";
import { ReactionSortBase } from "stream-chat";
import {
Channel,
Reaction,
useFetchReactions,
useMessageContext,
} from "stream-chat-react-native";
const CustomMessageUserReactions = () => {
const { message } = useMessageContext<StreamChatGenerics>();
const reactionSort: ReactionSortBase = {
created_at: -1,
};
const { reactions: fetchedReactions } = useFetchReactions({
message,
sort: reactionSort,
});
const reactions = useMemo(
() =>
fetchedReactions.map((reaction) => ({
id: reaction.user?.id,
image: reaction.user?.image,
name: reaction.user?.name,
type: reaction.type,
})) as Reaction[],
[fetchedReactions],
);
const renderItem = ({ item }: { item: Reaction }) => {
const Icon = supportedReactions?.find(
(supportedReaction) => supportedReaction.type === item.type,
)?.Icon;
return (
<View style={styles.container}>
<MessageUserReactionsAvatar reaction={item} />
<Text style={styles.text}>{item.name}</Text>
<View style={styles.icon}>{Icon && <Icon />}</View>
</View>
);
};
return (
<FlatList
data={reactions}
keyExtractor={(item) => item.id}
renderItem={renderItem}
/>
);
};
const styles = StyleSheet.create({
container: {
flexDirection: "row",
flexWrap: "wrap",
marginHorizontal: 16,
alignItems: "center",
marginVertical: 8,
},
icon: {
position: "absolute",
right: 0,
},
text: {
marginHorizontal: 16,
},
});
Similarly, you can customize the MessageUserReactionsItem
and MessageUserReactionsAvatar
component.