UNPKG

@tencentcloud/call-uikit-vue

Version:

An Open-source Voice & Video Calling UI Component Based on Tencent Cloud Service.

261 lines (257 loc) 10.8 kB
import { NAME, StoreName, CallStatus, StatusChange, CallMediaType, ROOM_ID_TYPE } from '../const/index'; import { handleNoDevicePermissionError } from '../utils/common-utils'; import { IUserInfo } from '../interface/ICallService'; import { ITUIStore } from '../interface/ITUIStore'; import { CallTips, t } from '../locales/index'; import TuiStore from '../TUIStore/tuiStore'; // @ts-ignore const TUIStore: ITUIStore = TuiStore.getInstance(); // 设置默认的 UserInfo 信息 export function setDefaultUserInfo(userId: string, domId?: string): IUserInfo { const userInfo: IUserInfo = { userId, nick: '', avatar: '', remark: '', displayUserInfo: '', isAudioAvailable: false, isVideoAvailable: false, isEnter: false, domId: domId || userId, }; return domId ? userInfo : { ...userInfo, isEnter: false }; // localUserInfo 没有 isEnter, remoteUserInfoList 有 isEnter } // 获取个人用户信息 export async function getMyProfile(myselfUserId: string, tim: any): Promise<IUserInfo> { let localUserInfo: IUserInfo = setDefaultUserInfo(myselfUserId, NAME.LOCAL_VIDEO); try { if (!tim) return localUserInfo; const res = await tim.getMyProfile(); const currentLocalUserInfo = TUIStore?.getData(StoreName.CALL, NAME.LOCAL_USER_INFO); // localUserInfo may have been updated if (res?.code === 0) { localUserInfo = { ...localUserInfo, ...currentLocalUserInfo, userId: res?.data?.userID, nick: res?.data?.nick, avatar: res?.data?.avatar, displayUserInfo: res?.data?.nick || res?.data?.userID, }; } return localUserInfo; } catch (error) { console.error(`${NAME.PREFIX}getMyProfile failed, error: ${error}.`); return localUserInfo; } } // 获取远端用户列表信息 export async function getRemoteUserProfile(userIdList: Array<string>, tim: any): Promise<any> { let remoteUserInfoList: IUserInfo[] = userIdList.map((userId: string) => setDefaultUserInfo(userId)); try { if (!tim) return remoteUserInfoList; const res = await tim.getFriendProfile({ userIDList: userIdList }); if (res.code === 0) { const { friendList = [], failureUserIDList = [] } = res.data; let unFriendList: IUserInfo[] = failureUserIDList.map((obj: any) => obj.userID); if (failureUserIDList.length > 0) { const res = await tim.getUserProfile({ userIDList: failureUserIDList.map((obj: any) => obj.userID) }); if (res?.code === 0) { unFriendList = res?.data || []; } } const currentRemoteUserInfoList = TUIStore?.getData(StoreName.CALL, NAME.REMOTE_USER_INFO_LIST); // remoteUserInfoList may have been updated const tempFriendIdList: string[] = friendList.map((obj: any) => obj.userID); const tempUnFriendIdList: string[] = unFriendList.map((obj: any) => obj.userID); remoteUserInfoList = userIdList.map((userId: string) => { const defaultUserInfo: IUserInfo = setDefaultUserInfo(userId); const friendListIndex: number = tempFriendIdList.indexOf(userId); const unFriendListIndex: number = tempUnFriendIdList.indexOf(userId); let remark = ''; let nick = ''; let displayUserInfo = '' ; let avatar = ''; if (friendListIndex !== -1) { remark = friendList[friendListIndex]?.remark || ''; nick = friendList[friendListIndex]?.profile?.nick || ''; displayUserInfo = remark || nick || defaultUserInfo.userId || ''; avatar = friendList[friendListIndex]?.profile?.avatar || ''; } if (unFriendListIndex !== -1) { nick = unFriendList[unFriendListIndex]?.nick || ''; displayUserInfo = nick || defaultUserInfo.userId || ''; avatar = unFriendList[unFriendListIndex]?.avatar || ''; } const userInfo = currentRemoteUserInfoList.find(subObj => subObj.userId === userId) || {}; return { ...defaultUserInfo, ...userInfo, remark, nick, displayUserInfo, avatar }; }); } return remoteUserInfoList; } catch (error) { console.error(`${NAME.PREFIX}getRemoteUserProfile failed, error: ${error}.`); return remoteUserInfoList; } } // 生成弹框提示文案 export function generateText(key: string, prefix?: string, suffix?: string): string { const isGroup = TUIStore.getData(StoreName.CALL, NAME.IS_GROUP); let callTips = `${t(key)}`; if (isGroup) { callTips = prefix ? `${prefix} ${callTips}` : callTips; callTips = suffix ? `${callTips} ${suffix}` : callTips; } return callTips; } // 生成 statusChange 抛出的字符串 export function generateStatusChangeText(): string { const callStatus = TUIStore.getData(StoreName.CALL, NAME.CALL_STATUS); if (callStatus === CallStatus.IDLE) { return StatusChange.IDLE; } const isGroup = TUIStore.getData(StoreName.CALL, NAME.IS_GROUP); if (callStatus === CallStatus.CALLING) { return isGroup ? StatusChange.DIALING_GROUP : StatusChange.DIALING_C2C; } const callMediaType = TUIStore.getData(StoreName.CALL, NAME.CALL_MEDIA_TYPE); if (isGroup) { return callMediaType === CallMediaType.AUDIO ? StatusChange.CALLING_GROUP_AUDIO : StatusChange.CALLING_GROUP_VIDEO; } return callMediaType === CallMediaType.AUDIO ? StatusChange.CALLING_C2C_AUDIO : StatusChange.CALLING_C2C_VIDEO; } // 获取群组[offset, count + offset]区间成员 export async function getGroupMemberList(groupID: string, tim: any, count, offset) { let groupMemberList = []; try { const res = await tim.getGroupMemberList({ groupID, count, offset }); if (res.code === 0) { return res.data.memberList || groupMemberList; } } catch(error) { console.error(`${NAME.PREFIX}getGroupMember failed, error: ${error}.`); return groupMemberList; } } // 获取 IM 群信息 export async function getGroupProfile(groupID: string, tim: any): Promise<any> { let groupProfile = {}; try { const res = await tim.getGroupProfile({ groupID }); return res.data.group || groupProfile; } catch(error) { console.warn(`${NAME.PREFIX}getGroupProfile failed, error: ${error}.`); return groupProfile; } } /** * update roomId and roomIdType * @param {number} roomId number roomId * @param {string} strRoomId string roomId */ export function updateRoomIdAndRoomIdType(roomId, strRoomId) { if (roomId === 0 && strRoomId) { // use strRoomID TUIStore.update(StoreName.CALL, NAME.ROOM_ID, strRoomId); TUIStore.update(StoreName.CALL, NAME.ROOM_ID_TYPE, ROOM_ID_TYPE.STRING_ROOM_ID); } else { TUIStore.update(StoreName.CALL, NAME.ROOM_ID, roomId); TUIStore.update(StoreName.CALL, NAME.ROOM_ID_TYPE, ROOM_ID_TYPE.NUMBER_ROOM_ID); } } /** * web and miniProgram call engine throw event data structure are different * @param {any} event call engine throw out data * @returns {any} data */ export function analyzeEventData(event: any): any { return event || {}; } /** * delete user from remoteUserInfoList * @param {string[]} userIdList to be deleted userIdList * @param {ITUIStore} TUIStore TUIStore instance */ export function deleteRemoteUser(userIdList: string[]): void { if (userIdList.length === 0) return; let remoteUserInfoList = TUIStore.getData(StoreName.CALL, NAME.REMOTE_USER_INFO_LIST); userIdList.forEach((userId) => { remoteUserInfoList = remoteUserInfoList.filter((obj: IUserInfo) => obj.userId !== userId); }); TUIStore.update(StoreName.CALL, NAME.REMOTE_USER_INFO_LIST, remoteUserInfoList); TUIStore.update(StoreName.CALL, NAME.REMOTE_USER_INFO_EXCLUDE_VOLUMN_LIST, remoteUserInfoList); } export function updateDeviceList(tuiCallEngine) { tuiCallEngine?.getDeviceList('speaker').then((result)=>{ const deviceList = TUIStore.getData(StoreName.CALL, NAME.DEVICE_LIST); const currentSpeaker = result?.[0] || {}; TUIStore.update( StoreName.CALL, NAME.DEVICE_LIST, { ...deviceList, speakerList: result, currentSpeaker }, ); }).catch(error =>{ console.error(`${NAME.PREFIX}updateSpeakerList failed, error: ${JSON.stringify(error)}.`); }); const callMediaType = TUIStore.getData(StoreName.CALL, NAME.CALL_MEDIA_TYPE); if (callMediaType === CallMediaType.VIDEO) { tuiCallEngine?.getDeviceList('camera').then((result) => { const deviceList = TUIStore.getData(StoreName.CALL, NAME.DEVICE_LIST); const currentCamera = result?.[0] || {}; TUIStore.update( StoreName.CALL, NAME.DEVICE_LIST, { ...deviceList, cameraList: result, currentCamera }, ); }).catch(error => { console.error(`${NAME.PREFIX}updateCameraList failed, error: ${error}.`); }); } tuiCallEngine?.getDeviceList('microphones').then((result) => { const deviceList = TUIStore.getData(StoreName.CALL, NAME.DEVICE_LIST); const currentMicrophone = result?.[0] || {}; TUIStore.update( StoreName.CALL, NAME.DEVICE_LIST, { ...deviceList, microphoneList: result, currentMicrophone }, ); }).catch(error => { console.error(`${NAME.PREFIX}updateMicrophoneList failed, error: ${error}.`); }); } /** * update the no device permission toast * @param {any} error error * @param {CallMediaType} type call midia type * @param {any} tuiCallEngine TUICallEngine instance */ export function noDevicePermissionToast(error, type: CallMediaType, tuiCallEngine: any) { let toastInfoKey = ''; if (handleNoDevicePermissionError(error)) { if (type === CallMediaType.AUDIO) { toastInfoKey = CallTips.NO_MICROPHONE_DEVICE_PERMISSION; } if (type === CallMediaType.VIDEO) { toastInfoKey = CallTips.NO_CAMERA_DEVICE_PERMISSION; } const permission = tuiCallEngine?.getDevicePermission(); if (!permission?.audio) { TUIStore.update(StoreName.CALL, NAME.SHOW_PERMISSION_TIP, true); } toastInfoKey && TUIStore.update(StoreName.CALL, NAME.TOAST_INFO, { content: toastInfoKey, type: NAME.ERROR }); console.error(`${NAME.PREFIX}call failed, error: ${error.message}.`); } } /** * set localUserInfo audio/video available * @param {boolean} isAvailable is available * @param {string} type callMediaType 'audio' | 'video' * @param {ITUIStore} TUIStore TUIStore instance */ export function setLocalUserInfoAudioVideoAvailable(isAvailable: boolean, type: string) { let localUserInfo = TUIStore.getData(StoreName.CALL, NAME.LOCAL_USER_INFO); if (type === NAME.AUDIO) { localUserInfo = { ...localUserInfo, isAudioAvailable: isAvailable }; } if (type === NAME.VIDEO) { localUserInfo = { ...localUserInfo, isVideoAvailable: isAvailable }; } TUIStore.update(StoreName.CALL, NAME.LOCAL_USER_INFO, localUserInfo); TUIStore.update(StoreName.CALL, NAME.LOCAL_USER_INFO_EXCLUDE_VOLUMN, localUserInfo); }