import React, { JSX, useLayoutEffect } from "react"; import { PixelRatio, Text, TouchableOpacity, View } from "react-native"; import { CometChat } from "@cometchat/chat-sdk-react-native"; import { MessageBubbleAlignmentType } from "../../base/Types"; import { CometChatTheme } from "../../../theme/type"; import { DeepPartial } from "../../helper/types"; /** * Props for rendering reactions on a message bubble. */ export interface CometChatReactionsInterface { /** * The message object for which reactions will be displayed. */ messageObject: CometChat.BaseMessage; /** * Custom styles for the reaction bubble. */ style?: DeepPartial; /** * Callback invoked when a reaction is pressed. * * @param reaction - The reaction count object that was pressed. * @param messageObject - The message object associated with the reaction. */ onReactionPress?: ( reaction: CometChat.ReactionCount, messageObject: CometChat.BaseMessage ) => void; /** * Callback invoked when a reaction is long pressed. * * @param reaction - The reaction count object that was long pressed. * @param messageObject - The message object associated with the reaction. */ onReactionLongPress?: ( reaction: CometChat.ReactionCount, messageObject: CometChat.BaseMessage ) => void; /** * Alignment of the reaction bubble. */ alignment?: MessageBubbleAlignmentType; /** * Maximum width for the content inside the reaction bubble. */ maxContentWidth?: number; } const CometChatReactions = (props: CometChatReactionsInterface) => { const { messageObject, style, onReactionPress, onReactionLongPress, alignment, maxContentWidth } = props; const [reactionList, setReactionList] = React.useState<(JSX.Element | null)[]>([]); const reactionRef = React.useRef([]); const reactionView = (reactionObj: CometChat.ReactionCount, index : any) => { let count: number = reactionObj?.getCount(); let Emoji: string = reactionObj?.getReaction(); const reactedByme = reactionObj.getReactedByMe(); return count >= 1 ? ( { onReactionPress && onReactionPress(reactionObj, messageObject!); }} onLongPress={() => { onReactionLongPress && onReactionLongPress(reactionObj, messageObject!); }} style={ reactedByme ? style?.activeEmojiStyle?.containerStyle : style?.emojiStyle?.containerStyle } > {Emoji} {count} ) : null; }; const extraEmojisView = (numberOfExtraEmojis: number) => { let extraEmojis = reactionRef.current.slice(reactionRef.current.length - numberOfExtraEmojis); let reactedByMe = extraEmojis.some((reaction) => reaction.getReactedByMe()); let totalCount = reactionRef.current.reduce((acc, curr) => acc + curr.getCount(), 0); let AllObj = new CometChat.ReactionCount("All", totalCount, false); // { reaction: "All", count: totalCount }; return ( { onReactionPress && onReactionPress(AllObj, messageObject); }} onLongPress={() => { onReactionLongPress && onReactionLongPress(AllObj, messageObject); }} key={new Date().getTime()} style={ reactedByMe ? style?.extraReactionStyle?.activeContainerStyle : style?.extraReactionStyle?.containerStyle } > +{numberOfExtraEmojis} ); }; useLayoutEffect(() => { reactionRef.current = messageObject?.getReactions()!; let countEmoji = maxContentWidth ? 0 : 3; // Scale width estimates by the system font scale so that when the user // increases the device font/display size the layout calculation still // fits reactions correctly and avoids cropping. const fontScale = PixelRatio.getFontScale(); if (maxContentWidth) { let remainingWidth = maxContentWidth; for (let i = 0; i < reactionRef.current.length; i++) { const currentReactionCount = reactionRef.current[i].getCount(); let widthToReduce = 0; if (currentReactionCount < 10) { widthToReduce = 45 * fontScale; } else if (currentReactionCount < 100) { widthToReduce = 55 * fontScale; } else if (currentReactionCount < 1000) { widthToReduce = 65 * fontScale; } if (remainingWidth > 30 * fontScale + widthToReduce) { remainingWidth = remainingWidth - widthToReduce; countEmoji++; continue; } break; } countEmoji = countEmoji ? countEmoji : 1; } const messageReactions = reactionRef.current.slice(0, countEmoji).map(reactionView); if (reactionRef.current.length > 0) { if (reactionRef.current.length > countEmoji) { messageReactions.push(extraEmojisView(reactionRef.current.length - countEmoji)); setReactionList(messageReactions); } else setReactionList(messageReactions); } }, [messageObject, maxContentWidth]); return reactionList.length ? ( {reactionList} ) : null; }; export { CometChatReactions };