import * as React from 'react'; import { ChatServiceListener, UIConversationListListener, UIGroupListListener, UIGroupParticipantListListener, UIListenerType, useChatContext, } from '../../chat'; import { useConfigContext } from '../../config'; import { useLifecycle } from '../../hook'; import { useI18nContext } from '../../i18n'; import { ChatConversationType, ChatMultiDeviceEvent } from '../../rename.chat'; import { Services } from '../../services'; import type { AlertRef } from '../../ui/Alert'; import type { SimpleToastRef } from '../../ui/Toast'; import { useGroupInfoActions } from '../hooks/useGroupInfoActions'; import type { ContextNameMenuRef } from '../types'; import type { GroupInfoProps, GroupInfoRef } from './types'; export function useGroupInfo( props: GroupInfoProps, ref?: React.ForwardedRef ) { const { groupId, ownerId, groupName: propsGroupName, groupAvatar: propsGroupAvatar, groupDescription: propsGroupDescription, groupMyRemark: propsGroupMyRemark, doNotDisturb: propsDoNotDisturb, onDoNotDisturb: propsOnDoNotDisturb, onClearChat: propsOnClearChat, onGroupName: propsOnGroupName, onGroupMyRemark: propsOnGroupMyRemark, onGroupDescription: propsOnGroupDescription, onCopyId: propsOnCopyId, onParticipant: propsOnParticipant, onClickedChangeGroupOwner, onGroupDestroy, onGroupQuit, onInitMenu, onGroupKicked, onSendMessage: propsOnSendMessage, onAudioCall: propsOnAudioCall, onVideoCall: propsOnVideoCall, onSearch: propsOnSearch, onClickedNavigationBarButton, } = props; const im = useChatContext(); const { tr } = useI18nContext(); const alertRef = React.useRef({} as any); const toastRef = React.useRef({} as any); const menuRef = React.useRef({} as any); const ownerIdRef = React.useRef(''); const [doNotDisturb, setDoNotDisturb] = React.useState(propsDoNotDisturb); const [groupName, setGroupName] = React.useState(propsGroupName); const [groupAvatar, setGroupAvatar] = React.useState(propsGroupAvatar); const [groupDescription, setGroupDescription] = React.useState( propsGroupDescription ); const [groupMyRemark, setGroupMyRemark] = React.useState(propsGroupMyRemark); const [groupMemberCount, setGroupMemberCount] = React.useState(0); const [isOwner, setIsOwner] = React.useState(false); const { enableAVMeeting } = useConfigContext(); const hasAudioCall = enableAVMeeting ?? false; const init = React.useCallback(() => { im.getGroupInfoFromServer({ groupId, onResult: (value) => { ownerId; const { isOk } = value; if (isOk === true && value.value) { // todo: useReducer ownerIdRef.current = value.value.owner; setGroupDescription(value.value?.description); setGroupName(value.value?.groupName); setGroupAvatar(value.value.groupAvatar); setGroupMemberCount(value.value.memberCount ?? 0); setGroupMyRemark(value.value?.myRemark); setIsOwner(im.userId === value.value.owner); } }, }); im.getConversation({ convId: groupId, convType: ChatConversationType.GroupChat, createIfNotExist: true, fromNative: true, }) .then((result) => { if (result) { setDoNotDisturb(result.doNotDisturb ?? false); } }) .catch(); if (im.userId) { im.getGroupMyRemark({ groupId, memberId: im.userId, onResult: (value) => { if (value.isOk && value.value) { setGroupMyRemark(value.value); } }, }); } }, [groupId, im, ownerId]); useLifecycle( React.useCallback( (state: any) => { if (state === 'load') { init(); } }, [init] ) ); const quitGroup = React.useCallback(() => { im.quitGroup({ groupId }); }, [groupId, im]); const destroyGroup = React.useCallback(() => { im.destroyGroup({ groupId }); }, [groupId, im]); const { onShowGroupInfoActions } = useGroupInfoActions({ menuRef, alertRef, onQuitGroup: quitGroup, onDestroyGroup: destroyGroup, onClickedChangeGroupOwner, onInit: onInitMenu, }); const doNotDisturbCallback = (value: boolean) => { if (propsOnDoNotDisturb) { propsOnDoNotDisturb(value); return; } im.setConversationSilentMode({ convId: groupId, convType: ChatConversationType.GroupChat, doNotDisturb: value, }); }; const onClearConversation = () => { if (propsOnClearChat) { propsOnClearChat(); return; } alertRef.current.alertWithInit({ title: tr('_uikit_info_alert_clear_chat_title'), buttons: [ { text: tr('cancel'), onPress: () => { alertRef.current.close(); }, }, { text: tr('confirm'), isPreferred: true, onPress: () => { alertRef.current.close(() => { im.removeConversationAllMessages({ convId: groupId, convType: 1, }); }); }, }, ], }); }; const onGroupName = () => { if (propsOnGroupName) { propsOnGroupName(groupId, groupName); return; } alertRef.current.alertWithInit({ message: tr('_uikit_info_alert_modify_group_name'), supportInput: true, supportInputStatistics: true, inputMaxCount: 200, buttons: [ { text: tr('cancel'), onPress: () => { alertRef.current.close(); }, }, { text: tr('confirm'), isPreferred: true, onPress: (text?: string) => { alertRef.current.close(() => { if (text) { im.setGroupName({ groupId, groupNewName: text, }); } }); }, }, ], }); }; const onGroupAvatar = (_newGroupAvatar: string) => { if (propsOnGroupName) { propsOnGroupName(groupId, groupAvatar); return; } }; const onGroupDescription = () => { if (propsOnGroupDescription) { propsOnGroupDescription(groupId, groupDescription); return; } alertRef.current.alertWithInit({ message: tr('_uikit_info_alert_modify_group_desc'), supportInput: true, supportInputStatistics: true, inputMaxCount: 200, buttons: [ { text: tr('cancel'), onPress: () => { alertRef.current.close(); }, }, { text: tr('confirm'), isPreferred: true, onPress: (text?: string) => { alertRef.current.close(() => { if (text) { im.setGroupDescription({ groupId, groupDescription: text, }); } }); }, }, ], }); }; const onGroupMyRemark = () => { if (propsOnGroupMyRemark) { propsOnGroupMyRemark(groupId, groupMyRemark); return; } alertRef.current.alertWithInit({ message: tr('_uikit_info_alert_modify_group_remark'), supportInput: true, supportInputStatistics: true, inputMaxCount: 200, // isSaveInput: true, buttons: [ { text: tr('cancel'), onPress: () => { alertRef.current.close(); }, }, { text: tr('confirm'), isPreferred: true, onPress: (text?: string) => { alertRef.current.close(() => { if (text) { if (text.trim().length === 0) { return; } if (im.userId === undefined) { return; } im.setGroupMyRemark({ groupId, memberId: im.userId, groupMyRemark: text, }); } }); }, }, ], }); }; const onCopyId = () => { if (propsOnCopyId) { propsOnCopyId(groupId); return; } Services.cbs.setString(groupId); im.sendFinished({ event: 'copyGroupId', extra: { groupId }, }); }; const onParticipant = () => { if (propsOnParticipant) { propsOnParticipant(groupId); return; } }; const onRequestCloseMenu = () => { menuRef.current?.startHide?.(); }; const onMoreMenu = () => { if (onClickedNavigationBarButton) { onClickedNavigationBarButton(); } else { onShowGroupInfoActions(im.userId ?? '', ownerIdRef.current, groupId); } }; const onSendMessage = () => { if (propsOnSendMessage) { propsOnSendMessage(groupId); } }; const onAudioCall = () => { if (propsOnAudioCall) { propsOnAudioCall(groupId); } }; const onVideoCall = () => { if (propsOnVideoCall) { propsOnVideoCall(groupId); } }; const onSearch = () => { if (propsOnSearch) { propsOnSearch(groupId); } }; React.useEffect(() => { const listener: ChatServiceListener = { onDestroyed: (params: { groupId: string; groupName?: string | undefined; }) => { onGroupDestroy?.(params.groupId); }, onMemberExited: (params: { groupId: string; member: string }) => { if (params.member === im.userId) { onGroupQuit?.(params.groupId); } else { setGroupMemberCount((prev) => prev - 1); } }, onMemberRemoved: (params: { groupId: string; groupName?: string | undefined; }) => { onGroupKicked?.(params.groupId); }, onDetailChanged: (group): void => { if (group.groupId === groupId) { setGroupName((prev) => { if (prev === group.groupName) { return prev; } return group.groupName; }); setGroupDescription((prev) => { if (prev === group.description) { return prev; } return group.description; }); } }, onOwnerChanged: (params: { groupId: string; newOwner: string; oldOwner: string; }) => { if (params.groupId === groupId) { if (im.userId === params.newOwner) { ownerIdRef.current = params.newOwner; setIsOwner(true); } else { setIsOwner(false); } } }, onGroupEvent: ( event?: ChatMultiDeviceEvent, target?: string, _usernames?: Array ): void => { if (event === ChatMultiDeviceEvent.GROUP_ASSIGN_OWNER) { if (target === groupId) { if (im.userId === target) { ownerIdRef.current = target; setIsOwner(true); } else { setIsOwner(false); } } } }, }; im.addListener(listener); return () => { im.removeListener(listener); }; }, [groupId, im, init, onGroupDestroy, onGroupKicked, onGroupQuit]); React.useEffect(() => { const listener: UIConversationListListener = { onUpdatedEvent: (data) => { if (data.convId === groupId) { setDoNotDisturb(data.doNotDisturb ?? false); } }, type: UIListenerType.Conversation, }; im.addUIListener(listener); return () => { im.removeUIListener(listener); }; }, [groupId, im]); React.useEffect(() => { const uiListener: UIGroupListListener = { onUpdatedEvent: (data) => { if (data.groupId === groupId) { setGroupName((prev) => { if (prev === data.groupName) { return prev; } return data.groupName; }); setGroupDescription((prev) => { if (prev === data.description) { return prev; } return data.description; }); if (data.owner !== ownerIdRef.current) { ownerIdRef.current = data.owner; setIsOwner(im.userId === data.owner); } } }, onDeletedEvent: (data) => { if (data.groupId === groupId) { onGroupQuit?.(data.groupId); } }, type: UIListenerType.Group, }; im.addUIListener(uiListener); return () => { im.removeUIListener(uiListener); }; }, [groupId, im, onGroupQuit]); React.useEffect(() => { const uiListener: UIGroupParticipantListListener = { onUpdatedEvent: (_data) => {}, onDeletedEvent: (_data) => {}, onAddedEvent: (data) => { if (data.memberId === im.userId) { return; } setGroupMemberCount((prev) => prev + 1); }, type: UIListenerType.GroupParticipant, }; im.addUIListener(uiListener); return () => { im.removeUIListener(uiListener); }; }, [groupId, im, onGroupQuit]); React.useImperativeHandle(ref, () => { return { setGroupName: (groupId: string, groupNewName?: string) => { if (groupNewName === undefined || groupName === groupNewName) { return; } im.setGroupName({ groupId, groupNewName: groupNewName, }); }, setGroupDescription: (groupId: string, desc?: string) => { if (desc === undefined || desc === groupDescription) { return; } im.setGroupDescription({ groupId, groupDescription: desc, }); }, setGroupMyRemark: (groupId: string, remark?: string) => { if (remark === undefined || remark === groupMyRemark) { return; } im.setGroupMyRemark({ groupId, memberId: im.userId ?? '', groupMyRemark: remark, }); }, }; }, [groupDescription, groupMyRemark, groupName, im]); return { ...props, doNotDisturb, onDoNotDisturb: doNotDisturbCallback, onClearChat: onClearConversation, groupName, onGroupName, groupAvatar, onGroupAvatar, groupDescription, onGroupDescription, onGroupMyRemark, alertRef, toastRef, onCopyId, onParticipant, onRequestCloseMenu, menuRef, onMore: onMoreMenu, groupMemberCount, isOwner, tr, onAudioCall, onVideoCall, onSendMessage, onSearch, hasAudioCall: hasAudioCall, }; }