Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[CLNP-5587] feat: support the reacted user list in supergroup #217

Merged
merged 9 commits into from
Nov 21, 2024
2 changes: 1 addition & 1 deletion docs-validation/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
"@react-native-firebase/messaging": "^14.7.0",
"@react-navigation/native": "^6.1.17",
"@react-navigation/native-stack": "^6.10.0",
"@sendbird/chat": "^4.13.3",
"@sendbird/chat": "^4.16.0",
"date-fns": "^4.1.0",
"react": "18.2.0",
"react-native": "0.74.3",
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@
]
},
"resolutions": {
"@sendbird/chat": "4.13.3",
"@sendbird/chat": "4.16.0",
"@types/react": "^18"
}
}
2 changes: 1 addition & 1 deletion packages/uikit-chat-hooks/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@
"typescript": "5.2.2"
},
"peerDependencies": {
"@sendbird/chat": "^4.13.3",
"@sendbird/chat": "^4.16.0",
"react": ">=16.13.1"
},
"react-native-builder-bob": {
Expand Down
2 changes: 1 addition & 1 deletion packages/uikit-react-native/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@
"@react-native-clipboard/clipboard": ">=1.8.5",
"@react-native-community/netinfo": ">=9.3.0",
"@react-native-firebase/messaging": ">=14.4.0",
"@sendbird/chat": "^4.13.3",
"@sendbird/chat": "^4.16.0",
"@sendbird/react-native-scrollview-enhancer": "*",
"date-fns": ">=2.28.0",
"expo-av": ">=12.0.4",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -189,7 +189,7 @@ const GroupChannelMessageRenderer: GroupChannelProps['Fragment']['renderMessage'
if (
mentionManager.shouldUseMentionedMessageTemplate(message, sbOptions.uikit.groupChannel.channel.enableMention)
) {
return message.mentionedMessageTemplate;
return message.mentionedMessageTemplate ?? '';
} else {
return message.message;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,18 +7,14 @@ import { useForceUpdate, useGroupChannelHandler } from '@sendbird/uikit-tools';
import type { SendbirdBaseChannel, SendbirdBaseMessage, SendbirdReaction } from '@sendbird/uikit-utils';
import { getReactionCount } from '@sendbird/uikit-utils';

import { DEFAULT_LONG_PRESS_DELAY, UNKNOWN_USER_ID } from '../../constants';
import { DEFAULT_LONG_PRESS_DELAY } from '../../constants';
import { useReaction, useSendbirdChat } from '../../hooks/useContext';
import ReactionRoundedButton from './ReactionRoundedButton';

const NUM_COL = 4;
const REACTION_MORE_KEY = 'reaction-more-button';
export type ReactionAddonType = 'default' | 'thread_parent_message';

const getUserReacted = (reaction: SendbirdReaction, userId = UNKNOWN_USER_ID) => {
return reaction.userIds.indexOf(userId) > -1;
};

const createOnPressReaction = (
reaction: SendbirdReaction,
channel: SendbirdBaseChannel,
Expand All @@ -41,7 +37,6 @@ const createReactionButtons = (
emojiLimit: number,
onOpenReactionList: () => void,
onOpenReactionUserList: (focusIndex: number) => void,
currentUserId?: string,
reactionAddonType?: ReactionAddonType,
) => {
const reactions = message.reactions ?? [];
Expand All @@ -51,15 +46,15 @@ const createReactionButtons = (
return (
<Pressable
key={reaction.key}
onPress={createOnPressReaction(reaction, channel, message, getUserReacted(reaction, currentUserId))}
onPress={createOnPressReaction(reaction, channel, message, reaction.hasCurrentUserReacted)}
onLongPress={() => onOpenReactionUserList(index)}
delayLongPress={DEFAULT_LONG_PRESS_DELAY}
>
{({ pressed }) => (
<ReactionRoundedButton
url={getEmoji(reaction.key).url}
count={getReactionCount(reaction)}
reacted={pressed || getUserReacted(reaction, currentUserId)}
reacted={pressed || reaction.hasCurrentUserReacted}
style={
reactionAddonType === 'default'
? [isNotLastOfRow && styles.marginRight, isNotLastOfCol && styles.marginBottom]
Expand Down Expand Up @@ -91,7 +86,7 @@ const MessageReactionAddon = ({
reactionAddonType?: ReactionAddonType;
}) => {
const { colors } = useUIKitTheme();
const { sdk, emojiManager, currentUser } = useSendbirdChat();
const { sdk, emojiManager } = useSendbirdChat();
const { openReactionList, openReactionUserList } = useReaction();
const forceUpdate = useForceUpdate();

Expand All @@ -113,7 +108,6 @@ const MessageReactionAddon = ({
emojiManager.allEmoji.length,
() => openReactionList({ channel, message }),
(focusIndex) => openReactionUserList({ channel, message, focusIndex }),
currentUser?.userId,
reactionAddonType,
);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -123,31 +123,37 @@ const ReactionUserListBottomSheet = ({
};

const renderPage = () => {
const userCountDifference = (focusedReaction?.count || 0) - (focusedReaction?.sampledUserInfoList.length || 0);

return (
<>
{focusedReaction?.userIds.map((userId) => {
{focusedReaction?.sampledUserInfoList.map((reactedUserInfo) => {
if (channel?.isGroupChannel()) {
const user = channel.members.find((x) => x.userId === userId);
return (
<Pressable
key={userId}
key={reactedUserInfo.userId}
onPress={async () => {
if (user) {
await onClose();
onPressUserProfile(user);
}
await onClose();
onPressUserProfile(reactedUserInfo);
}}
style={styles.pageItem}
>
<Avatar size={36} uri={user?.profileUrl} containerStyle={styles.avatar} />
<Avatar size={36} uri={reactedUserInfo?.profileUrl} containerStyle={styles.avatar} />
<Text subtitle2 style={{ flex: 1 }}>
{user?.nickname || STRINGS.LABELS.USER_NO_NAME}
{reactedUserInfo?.nickname || STRINGS.LABELS.USER_NO_NAME}
</Text>
</Pressable>
);
}
return null;
})}
{userCountDifference > 0 && (
<View style={styles.pageItem}>
<Text body3 color={colors.onBackground02}>
{STRINGS.REACTION.MORE_USERS(userCountDifference)}
</Text>
</View>
)}
</>
);
};
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import type React from 'react';

import type { SendbirdMember, SendbirdUser } from '@sendbird/uikit-utils';
import { SendbirdReactedUserInfo } from '@sendbird/uikit-utils';

import type { LocalizationContext } from '../../contexts/LocalizationCtx';
import type { ReactionContext } from '../../contexts/ReactionCtx';
Expand All @@ -13,7 +13,7 @@ export type ReactionBottomSheetProps = {
visible: boolean;
onDismiss: () => void;
onClose: () => Promise<void>;
onPressUserProfile: (user: SendbirdUser | SendbirdMember) => void;
onPressUserProfile: (user: SendbirdReactedUserInfo) => void;
chatCtx: GetFromContext<typeof SendbirdChatContext>;
reactionCtx: GetFromContext<typeof ReactionContext>;
localizationCtx: GetFromContext<typeof LocalizationContext>;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ const ThreadParentMessageRenderer = (props: ThreadParentMessageRendererProps) =>
if (
mentionManager.shouldUseMentionedMessageTemplate(message, sbOptions.uikit.groupChannel.channel.enableMention)
) {
return message.mentionedMessageTemplate;
return message.mentionedMessageTemplate ?? '';
} else {
return message.message;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import {
SendbirdGroupChannel,
SendbirdGroupChannelCreateParams,
SendbirdMember,
SendbirdReactedUserInfo,
SendbirdUser,
useIsFirstMount,
} from '@sendbird/uikit-utils';
Expand Down Expand Up @@ -141,11 +142,11 @@ export type SendbirdUIKitContainerProps = React.PropsWithChildren<{
onCreateChannel: (channel: SendbirdGroupChannel) => void;
onBeforeCreateChannel?: (
channelParams: SendbirdGroupChannelCreateParams,
users: SendbirdUser[] | SendbirdMember[],
users: SendbirdUser[] | SendbirdMember[] | SendbirdReactedUserInfo[],
) => SendbirdGroupChannelCreateParams | Promise<SendbirdGroupChannelCreateParams>;
};
reaction?: {
onPressUserProfile?: (user: SendbirdUser | SendbirdMember) => void;
onPressUserProfile?: (user: SendbirdReactedUserInfo) => void;
};
userMention?: Pick<Partial<MentionConfigInterface>, 'mentionLimit' | 'suggestionLimit' | 'debounceMills'>;
imageCompression?: Partial<ImageCompressionConfigInterface>;
Expand Down
3 changes: 0 additions & 3 deletions packages/uikit-react-native/src/contexts/ReactionCtx.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -46,9 +46,6 @@ export const ReactionProvider = ({ children, onPressUserProfile }: Props) => {

const openReactionUserList: ReactionContextType['openReactionUserList'] = useCallback(
({ channel, message, focusIndex = 0 }) => {
// NOTE: We don't support reaction user list for supergroup channel
if (channel.isGroupChannel() && channel.isSuper) return;

setState({ channel, message });
setReactionUserListFocusIndex(focusIndex);
setReactionUserListVisible(true);
Expand Down
7 changes: 4 additions & 3 deletions packages/uikit-react-native/src/contexts/UserProfileCtx.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import type {
SendbirdGroupChannel,
SendbirdGroupChannelCreateParams,
SendbirdMember,
SendbirdReactedUserInfo,
SendbirdUser,
} from '@sendbird/uikit-utils';
import { Logger, PASS, getDefaultGroupChannelCreateParams, useIIFE } from '@sendbird/uikit-utils';
Expand All @@ -16,15 +17,15 @@ import { SendbirdChatContext } from '../contexts/SendbirdChatCtx';
type OnCreateChannel = (channel: SendbirdGroupChannel) => void;
type OnBeforeCreateChannel = (
channelParams: SendbirdGroupChannelCreateParams,
users: SendbirdUser[] | SendbirdMember[],
users: SendbirdUser[] | SendbirdMember[] | SendbirdReactedUserInfo[],
) => SendbirdGroupChannelCreateParams | Promise<SendbirdGroupChannelCreateParams>;

type ShowOptions = {
hideMessageButton?: boolean;
};

export type UserProfileContextType = {
show(user: SendbirdUser | SendbirdMember, options?: ShowOptions): void;
show(user: SendbirdUser | SendbirdMember | SendbirdReactedUserInfo, options?: ShowOptions): void;
hide(): void;
};

Expand Down Expand Up @@ -58,7 +59,7 @@ export const UserProfileProvider = ({

const { bottom, left, right } = useSafeAreaInsets();

const [user, setUser] = useState<SendbirdUser | SendbirdMember>();
const [user, setUser] = useState<SendbirdUser | SendbirdMember | SendbirdReactedUserInfo>();
const [visible, setVisible] = useState(false);
const [hideMessageButton, setHideMessageButton] = useState(false);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import type {
SendbirdMessage,
SendbirdOpenChannel,
SendbirdParticipant,
SendbirdReactedUserInfo,
SendbirdUser,
SendbirdUserMessage,
} from '@sendbird/uikit-utils';
Expand Down Expand Up @@ -323,6 +324,9 @@ export interface StringSet {
VOICE_MESSAGE: string;
VOICE_MESSAGE_INPUT_CANCEL: string;
};
REACTION: {
MORE_USERS: (userCountDifference: number) => string;
};
FILE_VIEWER: {
TITLE: (message: SendbirdFileMessage) => string;
SUBTITLE: (message: SendbirdFileMessage) => string;
Expand Down Expand Up @@ -377,6 +381,6 @@ export interface StringSet {
PROFILE_CARD: {
BUTTON_MESSAGE: string;
BODY_LABEL: string;
BODY: (user: SendbirdUser | SendbirdMember) => string;
BODY: (user: SendbirdUser | SendbirdMember | SendbirdReactedUserInfo) => string;
};
}
Original file line number Diff line number Diff line change
Expand Up @@ -345,6 +345,9 @@ export const createBaseStringSet = ({ dateLocale, overrides }: StringSetCreateOp
VOICE_MESSAGE_INPUT_CANCEL: 'Cancel',
...overrides?.LABELS,
},
REACTION: {
MORE_USERS: (userCountDifference) => `And ${userCountDifference} others`,
},
FILE_VIEWER: {
TITLE: (message) => message.sender?.nickname || USER_NO_NAME,
SUBTITLE: (message) => getMessageTimeFormat(new Date(message.createdAt), dateLocale),
Expand Down
2 changes: 1 addition & 1 deletion packages/uikit-testing-tools/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@
"access": "public"
},
"devDependencies": {
"@sendbird/chat": "^4.13.3",
"@sendbird/chat": "^4.16.0",
"@sendbird/uikit-utils": "3.7.6",
"@types/jest": "^29.4.0",
"@types/react": "*",
Expand Down
2 changes: 1 addition & 1 deletion packages/uikit-utils/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@
"typescript": "5.2.2"
},
"peerDependencies": {
"@sendbird/chat": "^4.13.3",
"@sendbird/chat": "^4.16.0",
"date-fns": ">=2.28.0",
"react": ">=17.0.2",
"react-native": ">=0.65.0"
Expand Down
2 changes: 1 addition & 1 deletion packages/uikit-utils/src/sendbird/message.ts
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,7 @@ export function shouldRenderReaction(channel: SendbirdBaseChannel, reactionEnabl
}

export function getReactionCount(reaction: SendbirdReaction) {
return reaction.userIds.length;
return reaction.count;
}

export type MessageType =
Expand Down
2 changes: 2 additions & 0 deletions packages/uikit-utils/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ import type {
MessageSearchQuery,
MultipleFilesMessage,
PreviousMessageListQuery,
ReactedUserInfo,
Reaction,
UserMessage,
UserMessageCreateParams,
Expand Down Expand Up @@ -112,6 +113,7 @@ export type SendbirdOpenChannel = OpenChannel;
export type SendbirdFeedChannel = FeedChannel;

export type SendbirdReaction = Reaction;
export type SendbirdReactedUserInfo = ReactedUserInfo;
export type SendbirdEmoji = Emoji;
export type SendbirdEmojiCategory = EmojiCategory;
export type SendbirdEmojiContainer = EmojiContainer;
Expand Down
Loading