import React, { useRef } from 'react'; import { useUserList } from '@sendbird/uikit-chat-hooks'; import type { ActionMenuItem } from '@sendbird/uikit-react-native-foundation'; import { Icon, useActionMenu } from '@sendbird/uikit-react-native-foundation'; import { useGroupChannelHandler } from '@sendbird/uikit-tools'; import type { SendbirdMember } from '@sendbird/uikit-utils'; import { ifOperator, ifThenOr, isDifferentChannel, useFreshCallback } from '@sendbird/uikit-utils'; import StatusComposition from '../components/StatusComposition'; import UserActionBar from '../components/UserActionBar'; import type { GroupChannelMembersFragment } from '../domain/groupChannelUserList/types'; import createUserListModule from '../domain/userList/module/createUserListModule'; import type { UserListModule } from '../domain/userList/types'; import { useLocalization, useSendbirdChat, useUserProfile } from '../hooks/useContext'; const RETURN_EMPTY_STRING = () => ''; const createGroupChannelMembersFragment = ( initModule?: Partial>, ): GroupChannelMembersFragment => { const UserListModule = createUserListModule(initModule); return ({ channel, onPressHeaderLeft, onPressHeaderRight, renderUser, sortComparator, queryCreator = () => channel.createMemberListQuery({ limit: 20 }), }) => { const refreshSchedule = useRef(undefined); const { STRINGS } = useLocalization(); const { sdk, currentUser } = useSendbirdChat(); const { openMenu } = useActionMenu(); const { show } = useUserProfile(); const { users, refresh, loading, next, error, upsertUser, deleteUser } = useUserList(sdk, { queryCreator, sortComparator, }); useGroupChannelHandler(sdk, { onUserLeft(eventChannel, user) { if (isDifferentChannel(eventChannel, channel)) return; deleteUser(user.userId); }, onUserBanned(eventChannel, user) { if (isDifferentChannel(eventChannel, channel)) return; deleteUser(user.userId); }, onOperatorUpdated(eventChannel) { if (isDifferentChannel(eventChannel, channel)) return; if (refreshSchedule.current) clearTimeout(refreshSchedule.current); refreshSchedule.current = setTimeout(() => refresh(), 500); }, onUserMuted(eventChannel, user) { if (isDifferentChannel(eventChannel, channel) || !eventChannel.isGroupChannel()) return; const memberFromChannel = eventChannel.members.find((it) => it.userId === user.userId); if (memberFromChannel) return upsertUser(memberFromChannel); const memberFromList = users.find((it) => it.userId === user.userId); if (memberFromList) { memberFromList.isMuted = true; upsertUser(memberFromList); } }, onUserUnmuted(eventChannel, user) { if (isDifferentChannel(eventChannel, channel) || !eventChannel.isGroupChannel()) return; const memberFromChannel = eventChannel.members.find((it) => it.userId === user.userId); if (memberFromChannel) return upsertUser(memberFromChannel); const memberFromList = users.find((it) => it.userId === user.userId); if (memberFromList) { memberFromList.isMuted = false; upsertUser(memberFromList); } }, }); const _renderUser: NonNullable = useFreshCallback((user, selectedUsers, setSelectedUsers) => { if (renderUser) return renderUser(user, selectedUsers, setSelectedUsers); return ( { const menuItems: ActionMenuItem['menuItems'] = []; menuItems.push({ title: ifOperator(user.role, STRINGS.LABELS.UNREGISTER_OPERATOR, STRINGS.LABELS.REGISTER_AS_OPERATOR), onPress: ifOperator( user.role, () => channel.removeOperators([user.userId]), () => channel.addOperators([user.userId]), ), }); if (!channel.isBroadcast) { menuItems.push({ title: ifThenOr(user.isMuted, STRINGS.LABELS.UNMUTE, STRINGS.LABELS.MUTE), onPress: ifThenOr( user.isMuted, () => channel.unmuteUser(user), () => channel.muteUser(user), ), }); } menuItems.push({ title: STRINGS.LABELS.BAN, style: 'destructive', onPress: () => channel.banUser(user), }); openMenu({ title: user.nickname || STRINGS.LABELS.USER_NO_NAME, menuItems }); })} onPressAvatar={() => show(user)} /> ); }); return ( true} onPressHeaderLeft={onPressHeaderLeft} right={} onPressHeaderRight={async () => onPressHeaderRight()} /> } error={Boolean(error)} ErrorComponent={} > } /> ); }; }; export default createGroupChannelMembersFragment;