New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

@tencentcloud/call-uikit-vue2

Package Overview
Dependencies
Maintainers
8
Versions
67
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@tencentcloud/call-uikit-vue2 - npm Package Compare versions

Comparing version 2.3.4 to 2.3.5

src/adapter-vue.ts

6

package.json
{
"name": "@tencentcloud/call-uikit-vue2",
"version": "2.3.4",
"main": "./tuicall-uikit-vue2.umd.js",
"module": "./tuicall-uikit-vue2.es.js",
"version": "2.3.5",
"main": "./tuicall-uikit-vue.umd.js",
"module": "./tuicall-uikit-vue.es.js",
"types": "./types/src/index.d.ts",

@@ -7,0 +7,0 @@ "description": "An Open-source Voice & Video Calling UI Component Based on Tencent Cloud Service.",

@@ -1,9 +0,5 @@

import { TUIGlobal, TUIStore, StoreName, TUICallKitServer, NAME, StatusChange as STATUS, CallRole, CallMediaType, VideoResolution, VideoDisplayMode, t } from './TUICallService/index';
// @if process.env.BUILD_TARGET!='MINI'
// @ts-ignore
import TUICallKit from './Components/TUICallKit-vue2/TUICallKit.vue';
import { TUICallType } from "tuicall-engine-webrtc"; // ≤v2.2.1 抛出的字段
// 原 web callKit 融合 chat 方法. ref: https://tapd.woa.com/20396022/prong/stories/view/1020396022885708891
// @ts-ignore
import TUICallKit from './Components/TUICallKit.vue';
const plugin = (TUICore) => {

@@ -14,3 +10,2 @@ TUICore.component("TUICallKit", { server: TUICallKitServer });

};
// @ts-ignore
const install = (app) => {

@@ -22,3 +17,9 @@ app.component("TUICallKit", TUICallKit);

TUICallKit.install = install;
const Version = '2.3.4'; // basic-demo 原来上报使用
const TUICallType = { // Web TUICallKit ≤v2.2.1 抛出的字段
AUDIO_CALL: 1,
VIDEO_CALL: 2,
}
// @endif
const Version = '2.3.5'; // basic-demo 原来上报使用
// 输出产物

@@ -30,5 +31,8 @@ export {

TUICallKitServer,
// @if process.env.BUILD_TARGET!='MINI'
// uni-app 打包小程序无法引入 vue 组件, 只能在使用侧单独引入 vue 文件
TUICallKit,
plugin,
install,
// @endif
NAME,

@@ -35,0 +39,0 @@ STATUS,

import { ITUICallService, ICallParams, IGroupCallParams, IUserInfo, ICallbackParam, ISelfInfoParams } from '../interface/ICallService';
import { StoreName, TUIStore, TUIGlobal } from '../index';
import { CallStatus, CallMediaType, NAME, CALL_DATA_KEY, LanguageType, CallRole, LOG_LEVEL, VideoDisplayMode, VideoResolution, StatusChange, DEVICE_STATUS } from '../const';
// @ts-ignore
import { StoreName, TUIStore } from '../index';
import { CallStatus, CallMediaType, NAME, CALL_DATA_KEY, LanguageType, CallRole, LOG_LEVEL, VideoDisplayMode, VideoResolution, StatusChange, AudioCallIcon, VideoCallIcon, ErrorCode, ErrorMessage, AudioPlayBackDevice } from '../const';
import { TUICallEngine, TUICallEvent } from 'tuicall-engine-webrtc';
import { CallTips } from '../locales';
import { beforeCall, BellContext } from './miniProgram';
import { BellContext } from './web';
import { checkLocalMP3FileExists } from '../utils';
import { avoidRepeatedCall } from '../utils/validate';

@@ -12,5 +12,5 @@ import { handleRepeatedCallError, handleNoDevicePermissionError, setDefaultUserInfo, formatTime, formatTimeInverse } from '../utils/common-utils';

import { t } from '../locales';
const version = '2.3.4';
let INVITER_BELL_FILEPATH = '../static/phone_dialing.mp3';
let INVITEE_BELL_FILEPATH = '../static/phone_ringing.mp3';
const version = '2.3.5';
import DEFAULT_CALLER_BELL_FILEPATH from '../assets/phone_dialing.mp3';
import DEFAULT_CALLEE_BELL_FILEPATH from '../assets/phone_ringing.mp3';

@@ -24,2 +24,3 @@ export default class TUICallService implements ITUICallService {

private _callingBell: any = null;
private _bellFilePath: string | undefined;
constructor() {

@@ -35,4 +36,7 @@ console.log(`${NAME.PREFIX}version: ${version}`);

}
@avoidRepeatedCall()
public async init(params: any = {}) {
try {
if (this._tuiCallEngine) return;
this._watchTUIStore();
let { sdkAppID, tim, userID, userSig, SDKAppID } = params;

@@ -44,12 +48,11 @@ if (this._TUICore) {

this._tim = tim;
console.warn(`${NAME.PREFIX}init params: ${JSON.stringify(params)}`);
if (!this._tuiCallEngine) {
this._tuiCallEngine = TUICallEngine.createInstance({
tim,
SDKAppID: sdkAppID || SDKAppID, // 兼容传入 SDKAppID 的问题,
});
}
console.log(`${NAME.PREFIX}init sdkAppId: ${sdkAppID || SDKAppID}, userId: ${userID}`);
this._tuiCallEngine = TUICallEngine.createInstance({
tim,
SDKAppID: sdkAppID || SDKAppID, // 兼容传入 SDKAppID 的问题
});
this._addListenTuiCallEngineEvent();
TUIStore.update(StoreName.CALL, NAME.LOCAL_USER_INFO, { userId: userID });
await this._tuiCallEngine.login({ userID, userSig, assetsPath: '' })
await this._tuiCallEngine.login({ userID, userSig, assetsPath: '' }); // web && mini
this._callingBell = new BellContext();
} catch (error) {

@@ -65,3 +68,3 @@ console.error(`${NAME.PREFIX}init failed, error: ${JSON.stringify(error)}.`);

if (currentCallStatus !== CallStatus.IDLE) {
throw new Error(`please destroyed when status is idle, now status: ${currentCallStatus}`);
throw new Error(`please destroyed when status is idle, current status: ${currentCallStatus}`);
}

@@ -80,4 +83,4 @@ if (this._tuiCallEngine) {

}
// ==============================【通话操作】==============================
@avoidRepeatedCall() // ref: https://tapd.woa.com/TerWebG/prong/stories/view/1020396022885692351
// ===============================【通话操作】===============================
@avoidRepeatedCall()
public async call(callParams: ICallParams) {

@@ -87,12 +90,6 @@ try {

if (TUIStore.getData(StoreName.CALL, NAME.CALL_STATUS) !== CallStatus.IDLE) return;
this._updateCallStoreBeforeCall(type, [{ userId: userID }]);
await this._updateCallStoreBeforeCall(type, [{ userId: userID }]);
this._executeExternalBeforeCalling(); // 执行外部传入的 beforeCall 方法
const response = await this._tuiCallEngine.call(callParams);
// web callEngine 返回的是邀请信令的返回值. groupCall 同理
if (response?.code === 0) {
(type === CallMediaType.VIDEO) && await this.openCamera(NAME.LOCAL_VIDEO);
await this._updateCallStoreAfterCall([userID]);
} else {
this._resetCallStore();
}
await this._updateCallStoreAfterCall([userID], response);
} catch (error: any) {

@@ -112,11 +109,6 @@ if (handleRepeatedCallError(error)) return;

const remoteUserInfoList = userIDList.map(userId => ({ userId }))
this._updateCallStoreBeforeCall(type, remoteUserInfoList, groupID);
await this._updateCallStoreBeforeCall(type, remoteUserInfoList, groupID);
this._executeExternalBeforeCalling();
const response = await this._tuiCallEngine.groupCall(groupCallParams);
if (response?.code === 0) {
(type === CallMediaType.VIDEO) && await this.openCamera(NAME.LOCAL_VIDEO);
await this._updateCallStoreAfterCall(userIDList);
} else {
this._resetCallStore();
}
await this._updateCallStoreAfterCall(userIDList, response);
} catch (error: any) {

@@ -154,3 +146,3 @@ if (handleRepeatedCallError(error)) return;

}
// ==============================【其它对外接口】==============================
// ===============================【其它对外接口】===============================
public setLogLevel(level: LOG_LEVEL) {

@@ -160,3 +152,5 @@ this?._tuiCallEngine?.setLogLevel(level);

public setLanguage(language: LanguageType) {
TUIStore.update(StoreName.CALL, NAME.LANGUAGE, language);
if (language && Object.values(LanguageType).includes(language)) {
TUIStore.update(StoreName.CALL, NAME.LANGUAGE, language);
}
}

@@ -180,3 +174,3 @@ public async setSelfInfo(params: ISelfInfoParams) {

}
// ==============================【内部按钮操作方法】==============================
// =============================【内部按钮操作方法】=============================
@avoidRepeatedCall()

@@ -188,14 +182,11 @@ public async accept() {

if (response) {
const callMediaType = TUIStore.getData(StoreName.CALL, NAME.CALL_MEDIA_TYPE);
// 只有pc下才有摄像头的开关状态记录,h5和小程序默认都是打开
const isCameraOpen = TUIGlobal.isPC
? TUIStore.getData(StoreName.CALL, NAME.CAMERA_STATUS) === DEVICE_STATUS.OPEN
: true;
(callMediaType === CallMediaType.VIDEO) && isCameraOpen && await this.openCamera(NAME.LOCAL_VIDEO);
TUIStore.update(StoreName.CALL, NAME.IS_CLICKABLE, true);
this._setLocalUserInfoAudioVideoAvailable(true, NAME.AUDIO); // 呼叫默认是打开 audio 的
this._startTimer();
const callMediaType = TUIStore.getData(StoreName.CALL, NAME.CALL_MEDIA_TYPE);
(callMediaType === CallMediaType.VIDEO) && await this.openCamera(NAME.LOCAL_VIDEO);
await this._tuiCallEngine.setVideoQuality(TUIStore.getData(StoreName.CALL, NAME.VIDEO_RESOLUTION));
const localUserInfo = TUIStore.getData(StoreName.CALL, NAME.LOCAL_USER_INFO);
TUIStore.update(StoreName.CALL, NAME.LOCAL_USER_INFO, { ...localUserInfo, isEnter: true });
this._setLocalUserInfoAudioVideoAvailable(true, NAME.AUDIO); // web && mini default open audio
}
await this._tuiCallEngine.setVideoQuality(TUIStore.getData(StoreName.CALL, NAME.VIDEO_RESOLUTION));
} catch (error) {

@@ -210,4 +201,6 @@ if (handleRepeatedCallError(error)) return;

try {
await this._tuiCallEngine.hangup();
} catch (error) {} // catch 不需要处理
const response = await this._tuiCallEngine.hangup();
} catch (error) {
console.debug(error);
}
this._resetCallStore()

@@ -218,4 +211,6 @@ }

try {
await this._tuiCallEngine.reject();
} catch (error) {}
const response = await this._tuiCallEngine.reject();
} catch (error) {
console.debug(error);
}
this._resetCallStore()

@@ -239,3 +234,3 @@ }

} catch (error: any) {
console.error(`${NAME.PREFIX}openCamera error: ${JSON.stringify(error)}.`);
console.error(`${NAME.PREFIX}closeCamera error: ${JSON.stringify(error)}.`);
}

@@ -270,6 +265,6 @@ }

}
await this._tuiCallEngine.switchCallMediaType(CallMediaType.AUDIO);
const response = await this._tuiCallEngine.switchCallMediaType(CallMediaType.AUDIO);
TUIStore.update(StoreName.CALL, NAME.CALL_MEDIA_TYPE, CallMediaType.AUDIO);
const isGroup = TUIStore.getData(StoreName.CALL, NAME.IS_GROUP);
const oldStatus = isGroup ? StatusChange.CALLING_GROUP_VIDEO : StatusChange.CALLING_C2C_VIDEO;
const oldStatus = isGroup ? StatusChange.CALLING_GROUP_VIDEO : StatusChange.CALLING_C2C_VIDEO;
this.statusChanged && this.statusChanged({ oldStatus, newStatus: this._generateStatusChangeText() });

@@ -287,5 +282,18 @@ } catch (error: any) {

}
return this._tuiCallEngine.tim;
return this._tuiCallEngine?.tim || this._tuiCallEngine?.getTim(); // mini support getTim interface
}
// ==============================【TUICallEngine 事件处理】==============================
// 修改默认铃声:只支持本地铃声文件,不支持在线铃声文件;修改铃声修改的是被叫的铃声
public async setCallingBell(filePath?: string) {
// @ts-ignore
let result = await checkLocalMP3FileExists(filePath);
if (result) {
this._bellFilePath = filePath;
} else {
this._bellFilePath = DEFAULT_CALLEE_BELL_FILEPATH;
console.warn(`${NAME.PREFIX}setCallingBell: ${filePath} The media ringtone file does not exist or has an incorrect format.`);
}
this._callingBell.setBellSrc(this._bellFilePath);
}
// ==========================【TUICallEngine 事件处理】==========================
private _addListenTuiCallEngineEvent() {

@@ -301,3 +309,2 @@ if (!this._tuiCallEngine) {

this._tuiCallEngine.on(TUICallEvent.USER_LEAVE, this._handleUserLeave, this); // 有用户离开通话事件
// this._tuiCallEngine.on(TUICallEvent.USER_UPDATE, this.handleUserUpdate, this);
this._tuiCallEngine.on(TUICallEvent.REJECT, this._handleInviteeReject, this); // 主叫收到被叫的拒绝通话事件

@@ -307,13 +314,12 @@ this._tuiCallEngine.on(TUICallEvent.NO_RESP, this._handleNoResponse, this); // 主叫收到被叫的无应答事件

this._tuiCallEngine.on(TUICallEvent.CALLING_CANCEL, this._handleCallingCancel, this); // 主被叫在通话未建立时, 收到的取消事件
this._tuiCallEngine.on(TUICallEvent.CALL_END, this._handleCallingEnd, this); // 主被叫在通话结束时, 收到的通话结束事件
this._tuiCallEngine.on(TUICallEvent.SDK_READY, this._handleSDKReady, this); // SDK Ready 回调
this._tuiCallEngine.on(TUICallEvent.KICKED_OUT, this._handleKickedOut, this); // 未开启多端登录时, 多端登录收到的被踢事件
this._tuiCallEngine.on(TUICallEvent.CALL_TYPE_CHANGED, this._handleCallTypeChange, this); // 切换通话事件 miniProgram CALL_MODE
this._tuiCallEngine.on(TUICallEvent.MESSAGE_SENT_BY_ME, this._messageSentByMe, this);
this._tuiCallEngine.on(TUICallEvent.CALLING_END, this._handleCallingEnd, this); // 主被叫在通话结束时, 收到的通话结束事件
this._tuiCallEngine.on(TUICallEvent.CALL_TYPE_CHANGED, this._handleCallTypeChange, this);
this._tuiCallEngine.on(TUICallEvent.USER_VIDEO_AVAILABLE, this._handleUserVideoAvailable, this);
this._tuiCallEngine.on(TUICallEvent.USER_AUDIO_AVAILABLE, this._handleUserAudioAvailable, this);
this._tuiCallEngine.on(TUICallEvent.MESSAGE_SENT_BY_ME, this._messageSentByMe, this); // miniProgram 才有
this._tuiCallEngine.on(TUICallEvent.USER_VOICE_VOLUME, this._handleUserVoiceVolume, this); // web
this._tuiCallEngine.on(TUICallEvent.USER_VOICE_VOLUME, this._handleUserVoiceVolume, this);
}
private _removeListenTuiCallEngineEvent() {
// this._tuiCallEngine.off('*');
this._tuiCallEngine.off(TUICallEvent.ERROR, this._handleError);

@@ -324,3 +330,2 @@ this._tuiCallEngine.off(TUICallEvent.INVITED, this._handleNewInvitationReceived);

this._tuiCallEngine.off(TUICallEvent.USER_LEAVE, this._handleUserLeave);
// this._tuiCallEngine.off(TUICallEvent.USER_UPDATE, this.handleUserUpdate); // TODO: 小程序抛出该事件意义
this._tuiCallEngine.off(TUICallEvent.REJECT, this._handleInviteeReject);

@@ -330,25 +335,33 @@ this._tuiCallEngine.off(TUICallEvent.NO_RESP, this._handleNoResponse);

this._tuiCallEngine.off(TUICallEvent.CALLING_CANCEL, this._handleCallingCancel);
this._tuiCallEngine.off(TUICallEvent.CALL_END, this._handleCallingEnd);
this._tuiCallEngine.off(TUICallEvent.SDK_READY, this._handleSDKReady);
this._tuiCallEngine.off(TUICallEvent.KICKED_OUT, this._handleKickedOut);
this._tuiCallEngine.off(TUICallEvent.MESSAGE_SENT_BY_ME, this._messageSentByMe);
this._tuiCallEngine.off(TUICallEvent.CALLING_END, this._handleCallingEnd);
this._tuiCallEngine.off(TUICallEvent.CALL_TYPE_CHANGED, this._handleCallTypeChange); // TODO: web 是 CALL_TYPE_CHANGED 事件, miniProgram 为 CALL_MODE
this._tuiCallEngine.off(TUICallEvent.USER_VIDEO_AVAILABLE, this._handleUserVideoAvailable);
this._tuiCallEngine.off(TUICallEvent.USER_AUDIO_AVAILABLE, this._handleUserAudioAvailable);
this._tuiCallEngine.off(TUICallEvent.MESSAGE_SENT_BY_ME, this._messageSentByMe);
this._tuiCallEngine.off(TUICallEvent.USER_VOICE_VOLUME, this._handleUserVoiceVolume); // web
}
private _handleError(event: any): void {
console.error(`${NAME.PREFIX}_handleError, error: ${JSON.stringify(event)}.`);
const { code, message } = event || {};
const index = Object.values(ErrorCode).indexOf(code);
let callTips = '';
if (index !== -1) {
const key = Object.keys(ErrorCode)[index];
callTips = t(ErrorMessage[key]);
callTips && TUIStore.update(StoreName.CALL, NAME.TOAST_INFO, { text: callTips, type: NAME.ERROR });
}
console.error(`${NAME.PREFIX}_handleError, errorCode: ${code}; errorMessage: ${callTips || message}.`);
}
private async _handleNewInvitationReceived(event: any) {
console.warn(`${NAME.PREFIX}onCallReceived event data: ${JSON.stringify(event)}.`);
const { sponsor = '', isFromGroup, callMediaType, inviteData = {}, userIDList = [] } = event || event.data || {};
console.log(`${NAME.PREFIX}onCallReceived event data: ${JSON.stringify(event)}.`);
const { sponsor = '', isFromGroup, callMediaType, inviteData = {}, calleeIdList = [] } = this._analyzeEventData(event);
const currentUserInfo: IUserInfo = TUIStore.getData(StoreName.CALL, NAME.LOCAL_USER_INFO);
const remoteUserIdList: string[] = [sponsor, ...userIDList.filter((userId: string) => userId !== currentUserInfo.userId)];
const remoteUserIdList: string[] = [sponsor, ...calleeIdList.filter((userId: string) => userId !== currentUserInfo.userId)];
const type = callMediaType || inviteData.callType;
const callTipsKey = type === CallMediaType.AUDIO ? CallTips.CALLEE_CALLING_AUDIO_MSG : CallTips.CALLEE_CALLING_VIDEO_MSG;
const updateStoreParams = {
let updateStoreParams = {
[NAME.CALL_ROLE]: CallRole.CALLEE,
[NAME.IS_GROUP]: isFromGroup,
[NAME.CALL_STATUS]: CallStatus.CALLING,
[NAME.CALL_ROLE]: CallRole.CALLEE,
[NAME.CALL_MEDIA_TYPE]: type,

@@ -374,7 +387,7 @@ [NAME.CALL_TIPS]: t(callTipsKey),

this._callerChangeToConnected();
console.warn(`${NAME.PREFIX}accept event data: ${JSON.stringify(event)}.`);
console.log(`${NAME.PREFIX}accept event data: ${JSON.stringify(event)}.`);
}
private _handleUserEnter(event: any): void {
this._callerChangeToConnected();
const { userID: userId } = event;
const { userID: userId, data } = this._analyzeEventData(event);
let remoteUserInfoList = TUIStore.getData(StoreName.CALL, NAME.REMOTE_USER_INFO_LIST);

@@ -386,3 +399,3 @@ remoteUserInfoList = remoteUserInfoList.map((obj: IUserInfo) => {

remoteUserInfoList.length > 0 && TUIStore.update(StoreName.CALL, NAME.REMOTE_USER_INFO_LIST, remoteUserInfoList);
console.warn(`${NAME.PREFIX}userEnter event data: ${JSON.stringify(event)}.`);
console.log(`${NAME.PREFIX}userEnter event data: ${JSON.stringify(event)}.`);
}

@@ -398,11 +411,12 @@ private _callerChangeToConnected() {

private _handleUserLeave(event: any): void {
console.warn(`${NAME.PREFIX}userLeave event data: ${JSON.stringify(event)}.`);
console.log(`${NAME.PREFIX}userLeave event data: ${JSON.stringify(event)}.`);
const { data, userID: userId } = this._analyzeEventData(event);
if (TUIStore.getData(StoreName.CALL, NAME.IS_GROUP)) {
const text = this._generateText(CallTips.END_CALL, event.userID);
const text = this._generateText(CallTips.END_CALL, userId);
TUIStore.update(StoreName.CALL, NAME.TOAST_INFO, { text });
}
event.userID && this._deleteRemoteUser([event.userID]);
userId && this._deleteRemoteUser([userId]);
}
private _unNormalEventsManager(event: any, eventName: TUICallEvent): void {
console.warn(`${NAME.PREFIX}${eventName} event data: ${JSON.stringify(event)}.`);
console.log(`${NAME.PREFIX}${eventName} event data: ${JSON.stringify(event)}.`);
const isGroup = TUIStore.getData(StoreName.CALL, NAME.IS_GROUP);

@@ -412,3 +426,3 @@ switch(eventName) {

case TUICallEvent.LINE_BUSY: {
const { userID: userId } = event;
const { userID: userId } = this._analyzeEventData(event);
let callTipsKey = eventName === TUICallEvent.REJECT ? CallTips.OTHER_SIDE_REJECT_CALL : CallTips.OTHER_SIDE_LINE_BUSY;

@@ -425,3 +439,3 @@ let text = this._generateText(callTipsKey);

case TUICallEvent.NO_RESP: {
const { userIDList = [] } = event;
const { userIDList = [] } = this._analyzeEventData(event);
const callTipsKey = isGroup ? CallTips.TIMEOUT : CallTips.CALL_TIMEOUT;

@@ -454,3 +468,3 @@ const text = isGroup ? this._generateText(callTipsKey, userIDList.join()) : this._generateText(callTipsKey);

private _handleCallingEnd(event: any): void {
console.warn(`${NAME.PREFIX}callEnd event data: ${JSON.stringify(event)}.`);
console.log(`${NAME.PREFIX}callEnd event data: ${JSON.stringify(event)}.`);
this._executeExternalAfterCalling();

@@ -466,3 +480,3 @@ this._resetCallStore()

private _handleKickedOut(event: any): void {
console.warn(`${NAME.PREFIX}kickOut event data: ${JSON.stringify(event)}.`);
console.log(`${NAME.PREFIX}kickOut event data: ${JSON.stringify(event)}.`);
this.kickedOut && this.kickedOut(event);

@@ -473,7 +487,12 @@ TUIStore.update(StoreName.CALL, NAME.CALL_TIPS, this._generateText(CallTips.KICK_OUT));

private _handleCallTypeChange(event: any): void {
const { newCallType } = event;
TUIStore.update(StoreName.CALL, NAME.CALL_MEDIA_TYPE, newCallType);
const { newCallType , type } = this._analyzeEventData(event);
TUIStore.update(StoreName.CALL, NAME.CALL_MEDIA_TYPE, newCallType || type);
}
private _messageSentByMe(event: any): void {
const message = event?.data;
this.onMessageSentByMe && this.onMessageSentByMe(message);
}
// =============================【 WEB 私有事件】==============================
private async _handleUserVideoAvailable(event: any): Promise<any> {
const { userID: userId, isVideoAvailable } = event;
const { userID: userId, isVideoAvailable } = this._analyzeEventData(event);
console.log(`${NAME.PREFIX}_handleUserVideoAvailable event data: ${JSON.stringify(event)}.`);

@@ -484,13 +503,9 @@ isVideoAvailable && await this._startRemoteView(userId);

private _handleUserAudioAvailable(event: any): void {
const { userID: userId, isAudioAvailable } = event;
const { userID: userId, isAudioAvailable } = this._analyzeEventData(event);
console.log(`${NAME.PREFIX}_handleUserAudioAvailable event data: ${JSON.stringify(event)}.`);
this._setRemoteUserInfoAudioVideoAvailable(isAudioAvailable, NAME.AUDIO, userId);
}
private _messageSentByMe(event: any): void {
const message = event?.data;
this.onMessageSentByMe && this.onMessageSentByMe(message);
}
private _handleUserVoiceVolume(event: any): void {
try {
const { volumeMap: volumeList } = event;
const { volumeMap: volumeList } = this._analyzeEventData(event);
if ((volumeList || []).length === 0) return; // 减少不必要的更新

@@ -518,5 +533,8 @@ let localUserInfo: IUserInfo = TUIStore.getData(StoreName.CALL, NAME.LOCAL_USER_INFO);

TUIStore.updateStore(updateStoreParams, StoreName.CALL);
} catch (error) {}
} catch (error) {
console.debug(error);
}
}
// =======================【原 Web CallKit 提供的方法】=======================
// ==========================【 miniProgram 私有事件】==========================
// ========================【原 Web CallKit 提供的方法】========================
public beforeCalling: ((...args: any[]) => void) | undefined; // 原来

@@ -544,8 +562,8 @@ public afterCalling: ((...args: any[]) => void) | undefined;

private _executeExternalBeforeCalling(): void {
this.beforeCalling && this.beforeCalling(); // ref: https://tapd.woa.com/TerWebG/prong/stories/view/1020396022885604991
this.beforeCalling && this.beforeCalling();
}
private _executeExternalAfterCalling(): void {
this.afterCalling && this.afterCalling(); // ref: https://tapd.woa.com/TerWebG/prong/stories/view/1020396022885604991
this.afterCalling && this.afterCalling();
}
// =========================【TUICallKit 组件属性设置方法】========================
// ========================【TUICallKit 组件属性设置方法】========================
public setVideoDisplayMode(displayMode: VideoDisplayMode) {

@@ -563,4 +581,3 @@ TUIStore.update(StoreName.CALL, NAME.DISPLAY_MODE, displayMode);

}
// ==============================【私有公共方法】==============================
// web, miniProgram not
// =============================【 WEB 私有公共方法】=============================
private async _startRemoteView(userId: string) {

@@ -582,6 +599,21 @@ if (!userId) {

}
private _setRemoteUserInfoAudioVideoAvailable(isAvailable: boolean, type: string, userId: string) {
let remoteUserInfoList = TUIStore.getData(StoreName.CALL, NAME.REMOTE_USER_INFO_LIST);
remoteUserInfoList = remoteUserInfoList.map((obj: IUserInfo) => {
if (obj.userId === userId) {
if (type === NAME.AUDIO) {
return { ...obj, isAudioAvailable: isAvailable };
}
if (type === NAME.VIDEO) {
return { ...obj, isVideoAvailable: isAvailable };
}
}
return obj;
});
remoteUserInfoList.length > 0 && TUIStore.update(StoreName.CALL, NAME.REMOTE_USER_INFO_LIST, remoteUserInfoList);
}
private async _getMyProfile(myselfUserId: string): Promise<IUserInfo> {
const localUserInfo: IUserInfo = setDefaultUserInfo(myselfUserId, NAME.LOCAL_VIDEO);
try {
const tim = this._tuiCallEngine.tim;
const tim = this.getTim();
if (!tim) return localUserInfo;

@@ -606,3 +638,3 @@ const res = await tim.getMyProfile();

try {
const tim = this._tuiCallEngine.tim;
const tim = this.getTim();
if (!tim) return remoteUserInfoList;

@@ -636,19 +668,4 @@ const res = await tim.getUserProfile({ userIDList: userIdList });

}
private _setRemoteUserInfoAudioVideoAvailable(isAvailable: boolean, type: string, userId: string) {
let remoteUserInfoList = TUIStore.getData(StoreName.CALL, NAME.REMOTE_USER_INFO_LIST);
remoteUserInfoList = remoteUserInfoList.map((obj: IUserInfo) => {
if (obj.userId === userId) {
if (type === NAME.AUDIO) {
return { ...obj, isAudioAvailable: isAvailable };
}
if (type === NAME.VIDEO) {
return { ...obj, isVideoAvailable: isAvailable };
}
}
return obj;
});
remoteUserInfoList.length > 0 && TUIStore.update(StoreName.CALL, NAME.REMOTE_USER_INFO_LIST, remoteUserInfoList);
}
private _updateCallStoreBeforeCall(type: number, remoteUserInfoList: IUserInfo[], groupID?: string): void {
const updateStoreParams = {
private async _updateCallStoreBeforeCall(type: number, remoteUserInfoList: IUserInfo[], groupID?: string): void {
let updateStoreParams: any = {
[NAME.CALL_MEDIA_TYPE]: type,

@@ -666,14 +683,27 @@ [NAME.CALL_ROLE]: CallRole.CALLER,

}
private async _updateCallStoreAfterCall(userIdList: string[]) {
TUIStore.update(StoreName.CALL, NAME.IS_CLICKABLE, true);
this._setLocalUserInfoAudioVideoAvailable(true, NAME.AUDIO); // 呼叫默认是打开 audio 的
const remoteUserInfoList = await this._getRemoteUserProfile(userIdList);
remoteUserInfoList.length > 0 && TUIStore.update(StoreName.CALL, NAME.REMOTE_USER_INFO_LIST, remoteUserInfoList);
try {
await this._tuiCallEngine.setVideoQuality(TUIStore.getData(StoreName.CALL, NAME.VIDEO_RESOLUTION));
} catch (error) {
console.warn(`${NAME.PREFIX}setVideoQuality failed, error: ${JSON.stringify(error)}.`);
private async _updateCallStoreAfterCall(userIdList: string[], response: any) {
if (response) {
TUIStore.update(StoreName.CALL, NAME.IS_CLICKABLE, true);
if (response.code === 0) {
const callMediaType = TUIStore.getData(StoreName.CALL, NAME.CALL_MEDIA_TYPE);
(callMediaType === CallMediaType.VIDEO) && await this.openCamera(NAME.LOCAL_VIDEO);
try {
await this._tuiCallEngine.setVideoQuality(TUIStore.getData(StoreName.CALL, NAME.VIDEO_RESOLUTION));
} catch (error) {
console.warn(`${NAME.PREFIX}setVideoQuality failed, error: ${JSON.stringify(error)}.`);
}
} else {
this._resetCallStore();
return;
}
const localUserInfo = TUIStore.getData(StoreName.CALL, NAME.LOCAL_USER_INFO);
TUIStore.update(StoreName.CALL, NAME.LOCAL_USER_INFO, { ...localUserInfo, isEnter: true });
this._setLocalUserInfoAudioVideoAvailable(true, NAME.AUDIO); // web && mini, default open audio
const remoteUserInfoList = await this._getRemoteUserProfile(userIdList);
remoteUserInfoList.length > 0 && TUIStore.update(StoreName.CALL, NAME.REMOTE_USER_INFO_LIST, remoteUserInfoList);
} else {
this._resetCallStore();
}
}
// ref: https://tapd.woa.com/TerWebG/prong/stories/view/1020396022885485083
// 生成弹框提示文案
private _generateText(key: string, prefix?: string, suffix?: string): string {

@@ -706,4 +736,6 @@ let callTips = `${t(key)}`;

this._stopTimer();
// localUserInfo, language 在通话结束后不需要清除, callStatus 清除需要通知, isGroup 也不清除(engine 先抛 cancel 事件, 再抛 reject 事件)
// displayMode、videoResolution 也不能清除, 组件不卸载, 这些属性也需保留, 否则采用默认值. ref: https://tapd.woa.com/10155901/bugtrace/bugs/view?bug_id=1010155901114183539
// localUserInfo, language 在通话结束后不需要清除
// callStatus 清除需要通知; isMinimized 也需要通知(basic-vue3 中切小窗关闭后, 再呼叫还是小窗, 因此需要通知到组件侧)
// isGroup 也不清除(engine 先抛 cancel 事件, 再抛 reject 事件)
// displayMode、videoResolution 也不能清除, 组件不卸载, 这些属性也需保留, 否则采用默认值.
let notResetOrNotifyKeys = Object.keys(CALL_DATA_KEY).filter(key => {

@@ -726,9 +758,10 @@ switch (CALL_DATA_KEY[key]) {

TUIStore.reset(StoreName.CALL, notResetOrNotifyKeys);
TUIStore.reset(StoreName.CALL, [NAME.CALL_STATUS], true); // callStatus reset need notify
const callStatus = TUIStore.getData(StoreName.CALL, NAME.CALL_STATUS);
callStatus !== CallStatus.IDLE && TUIStore.reset(StoreName.CALL, [NAME.CALL_STATUS], true); // callStatus reset need notify
TUIStore.reset(StoreName.CALL, [NAME.IS_MINIMIZED], true); // isMinimized reset need notify
TUIStore.update(StoreName.CALL, NAME.LOCAL_USER_INFO, {
...TUIStore.getData(StoreName.CALL, NAME.LOCAL_USER_INFO),
isVideoAvailable: false,
isAudioAvailable: false,
isVideoAvailable: false,
});
TUIStore.reset(StoreName.CALL, [NAME.CAMERA_STATUS], true);
const newStatusStr = this._generateStatusChangeText();

@@ -778,2 +811,5 @@ if (oldStatusStr !== newStatusStr) {

}
private _analyzeEventData(event: any): any {
return event || {}; // web INVITED
}
// =========================【监听 TUIStore 中的状态】=========================

@@ -783,7 +819,10 @@ private _handleCallStatusChange = async (value: CallStatus) => {

const callRole = TUIStore.getData(StoreName.CALL, NAME.CALL_ROLE);
const musicFilePath = callRole === CallRole.CALLER ? INVITER_BELL_FILEPATH : INVITEE_BELL_FILEPATH;
this?._callingBell?.setBellSrc(musicFilePath);
this?._callingBell?.play();
const bellFilePath = callRole === CallRole.CALLEE ? this._bellFilePath : DEFAULT_CALLER_BELL_FILEPATH;
await this?.setCallingBell(bellFilePath);
if (TUIStore.getData(StoreName.CALL, NAME.CALL_STATUS) === CallStatus.CALLING) {
// 连续两个异步请求,会导致 play 和 stop 的调用顺序混乱,因此再多加一次状态判断
await this?._callingBell?.play();
}
} else {
this?._callingBell?.stop();
await this?._callingBell?.stop();
// 状态变更通知

@@ -798,3 +837,3 @@ if (value === CallStatus.CONNECTED) {

private _watchTUIStore() {
TUIStore.watch(StoreName.CALL, {
TUIStore?.watch(StoreName.CALL, {
[NAME.CALL_STATUS]: this._handleCallStatusChange,

@@ -804,3 +843,3 @@ });

private _unwatchTUIStore() {
TUIStore.unwatch(StoreName.CALL, {
TUIStore?.unwatch(StoreName.CALL, {
[NAME.CALL_STATUS]: this._handleCallStatusChange,

@@ -812,3 +851,3 @@ });

this._TUICore = TUICore;
}
}
}
import { CallMediaType, CallStatus, NAME } from '../const';
const wx: any = {};
export function initialUI() {
// 收起键盘
wx.hideKeyboard();
// 隐藏 tabBar
// if (shouldHideTabBar) {
// wx.hideTabBar();
// }
wx.hideKeyboard({
complete: res => {},
});
};
// 检测运行时环境, 当是微信开发者工具时, 提示用户需要手机调试

@@ -17,3 +13,3 @@ export function checkRunPlatform() {

if (systemInfo.platform === 'devtools') {
// 当前运行在微信开发者工具里
// 当前运行在微信开发者工具里
wx.showModal({

@@ -27,7 +23,9 @@ icon: 'none',

};
export function initAndCheckRunEnv() {
initialUI(); // miniProgram 收起键盘, 隐藏 tabBar
checkRunPlatform() // miniProgram 检测运行时环境
}
export async function beforeCall(type: CallMediaType, that: any) {
try {
initialUI(); // miniProgram 收起键盘, 隐藏 tabBar
checkRunPlatform() // miniProgram 检测运行时环境
initAndCheckRunEnv();
// 检查设备权限

@@ -41,2 +39,3 @@ const deviceMap = {

} catch (error) {
console.debug(error);
return CallStatus.IDLE;

@@ -61,2 +60,3 @@ }

} catch (e) {
console.debug(e);
console.warn(`${NAME.PREFIX}setCallingBell: 媒体铃声路径错误`, filePath);

@@ -93,5 +93,5 @@ }

}
destroyInstance() {
destroy() {
this.context.destroy();
}
}

@@ -1,12 +0,4 @@

export * from './callMediaType';
export * from './callStatus';
export * from './errorCode';
export * from './errorMsg';
export * from './storeName';
export * from './callRole';
export * from './language';
export * from './logLevel';
export * from './videoDisplayMode';
export * from './videoResolution';
export * from './statusChange';
export * from './call';
export * from './error';
export * from './log';

@@ -33,3 +25,5 @@ // import { keys } from 'ts-transformer-keys';

VIDEO_RESOLUTION: 'videoResolution',
CAMERA_STATUS: 'cameraStatus',
PUSHER: 'pusher',
PLAYER: 'player',
IS_EAR_PHONE: 'isEarPhone',
};

@@ -53,8 +47,8 @@

FUNCTION: 'function',
ALL: 'all',
MYSELF: 'myself',
...CALL_DATA_KEY,
};
export enum DEVICE_STATUS {
OPEN = 'open',
CLOSE = 'close',
};
export const AudioCallIcon = 'https://web.sdk.qcloud.com/component/TUIKit/assets/call.png';
export const VideoCallIcon = 'https://web.sdk.qcloud.com/component/TUIKit/assets/call-video-reverse.svg';

@@ -7,3 +7,3 @@ import { ITUIGlobal } from './interface/ITUIGlobal';

import TUICallService from './CallService';
import { NAME, CallRole, CallMediaType, CallStatus, StatusChange, VideoResolution, VideoDisplayMode } from './const';
import { NAME, CallRole, CallMediaType, CallStatus, StatusChange, VideoResolution, VideoDisplayMode, AudioPlayBackDevice } from './const';
import { t } from './locales';

@@ -16,10 +16,2 @@

// 输出 service 方法参数和 model 声明文件
// export * from './type';
// export * from './interface/model';
// TODO: 发布时, 下面的进行删除, 调式使用
(window as any).$TUIStore = tuiStore;
(window as any).$TUIGlobal = tuiGlobal;
// 输出产物

@@ -38,3 +30,4 @@ export {

VideoDisplayMode,
AudioPlayBackDevice,
t,
};

@@ -45,6 +45,6 @@ /**

avatar?: string;
isAudioAvailable?: boolean;
isVideoAvailable?: boolean;
isAudioAvailable?: boolean; // 用来设置: 麦克风是否打开
isVideoAvailable?: boolean; // 用来设置: 摄像头是否打开
volume?: number;
isEnter?: boolean;
isEnter?: boolean; // 远端用户, 用来控制预览远端是否显示 loading 效果; 本地用户, 用来控制 "呼叫"、"接通" 接通后显示的 loading 效果
domId?: string; // 播放流 dom 节点, localUserInfo 的 domId = 'localVideo'; remoteUserInfo 的 domId 就是 userId

@@ -51,0 +51,0 @@ }

@@ -1,2 +0,2 @@

import { CallStatus, CallRole, CallMediaType, VideoDisplayMode, VideoResolution, DEVICE_STATUS } from '../const';
import { CallStatus, CallRole, CallMediaType, VideoDisplayMode, VideoResolution } from '../const';
import { IUserInfo } from './index';

@@ -12,5 +12,7 @@

callMediaType: CallMediaType; // 通话类型
localUserInfo: IUserInfo; // 自己的信息, 默认: {}
localUserInfo: IUserInfo; // 自己的信息, 默认: { userId: '' }
remoteUserInfoList: Array<IUserInfo>; // 远端用户信息列表, 默认: []
callerUserInfo: IUserInfo; // 添加原因: https://tapd.woa.com/TerWebG/prong/stories/view/1020396022885976377
// 被叫在未接通时,展示主叫的 userId、头像。但是如果主叫进入通话后再挂断,此时被叫无法知道主叫的信息了。
// 因为目前 store 中仅提供了 remoteUserInfoList 数据,主叫离开后,被叫就没有主叫的信息了。因此考虑在 store 中增加 callerUserInfo 字段。
callerUserInfo: IUserInfo;
isGroup: boolean; // 是否是群组通话, 默认: false

@@ -26,4 +28,6 @@ callDuration: string; // 通话时长, 默认: '00:00:00'

videoResolution: VideoResolution; // 设置视频分辨率, 默认: VideoResolution.RESOLUTION_480P
// 摄像头开关状态
cameraStatus: DEVICE_STATUS;
// 小程序相关属性
pusher: any;
player: any[];
isEarPhone: boolean; // 是否是听筒, 默认: false
}

@@ -22,2 +22,4 @@ import { StoreName } from '../const';

* @param {IOptions} options UI 组件注册的监听信息
* @param {Object} params 扩展参数
* @param {String} params.notifyRangeWhenWatch 注册时监听时的通知范围
* @example

@@ -32,3 +34,3 @@ * // UI 层监听会话列表更新通知

*/
watch(storeName: StoreName, options: IOptions): void;
watch(storeName: StoreName, options: IOptions, params?: any): void;

@@ -35,0 +37,0 @@ /**

@@ -61,4 +61,6 @@ export const en = {

'environment-detection-failed': 'Failed to check the environment',
'call-failed': 'call method failed',
'switchToAudioCall-call-failed': 'switch to audio call method failed',
'switchToVideoCall-call-failed': 'switch to video call method failed',
'microphone-unavailable': 'No mic found',
'camera-unavailable': 'No camera found',
'ban-device': 'Device access denied',

@@ -65,0 +67,0 @@ 'not-supported-webrtc': 'Your current environment does not support WebRTC',

@@ -1,3 +0,1 @@

import { CallTips } from './index';
export const zh = {

@@ -67,4 +65,6 @@ 'hangup': '挂断',

'environment-detection-failed': '环境检测失败',
'call-failed': '调用失败',
'switchToAudioCall-call-failed': '切语音调用失败',
'switchToVideoCall-call-failed': '切视频调用失败',
'microphone-unavailable': '没有可用的麦克风设备',
'camera-unavailable': '没有可用的摄像头设备',
'ban-device': '用户禁止使用设备',

@@ -77,3 +77,3 @@ 'not-supported-webrtc': '当前环境不支持 WebRTC',

'accept-device-error': '接通失败,通话设备获取失败',
'call-error': '发起通话失败'
'call-error': '发起通话失败',
}

@@ -1,3 +0,4 @@

import { CallStatus, CallRole, CallMediaType, NAME, VideoDisplayMode, VideoResolution, DEVICE_STATUS } from '../const';
import { CallStatus, CallRole, CallMediaType, NAME, VideoDisplayMode, VideoResolution } from '../const';
import { ICallStore } from '../interface/ICallStore';
import { getLanguage } from '../utils/common-utils';

@@ -16,10 +17,12 @@ export default class CallStore {

toastInfo: { text: '' }, // 远端用户挂断、拒绝、超时、忙线等的 toast 提示信息
isMinimized: false,
language: 'zh-cn', // en, zh-cn
isClickable: false, // 是否可点击, ref: https://tapd.woa.com/TerWebG/prong/stories/view/1020396022885692719
isMinimized: false, // 用来记录 web 是否是小窗模式
language: getLanguage(), // en, zh-cn
isClickable: false, // 是否可点击, 用于按钮增加 loading 效果,不可点击
// TUICallKit 组件上的属性
displayMode: VideoDisplayMode.COVER, // 设置预览远端的画面显示模式
videoResolution: VideoResolution.RESOLUTION_480P,
// 摄像头开关状态
cameraStatus: DEVICE_STATUS.CLOSE,
// 小程序相关属性
pusher: {},
player: [],
isEarPhone: false, // 是否是听筒, 默认: false
};

@@ -26,0 +29,0 @@ public store: ICallStore = Object.assign({}, this.defaultStore);;

@@ -33,4 +33,6 @@ import { ITUIStore, IOptions, Task } from '../interface/ITUIStore';

* @param {IOptions} options 监听信息
* @param {Object} params 扩展参数
* @param {String} params.notifyRangeWhenWatch 注册时监听时的通知范围, 'all' - 通知所有注册该 key 的监听; 'myself' - 通知本次注册该 key 的监听; 默认不通知
*/
watch(storeName: StoreName, options: IOptions) {
watch(storeName: StoreName, options: IOptions, params?: any) {
if (!this.task[storeName]) {

@@ -46,4 +48,12 @@ this.task[storeName] = {};

watcher[key].set(callback, 1);
// 注册监听后立即通知一次默认数据,避免UI层初始化调用 getData
this.notify(storeName, key);
const { notifyRangeWhenWatch } = params || {};
// 注册监听后, 通知所有注册该 key 的监听,使用 'all' 时要特别注意是否对其他地方的监听产生影响
if (notifyRangeWhenWatch === NAME.ALL) {
this.notify(storeName, key);
}
// 注册监听后, 仅通知自己本次监听该 key 的数据
if (notifyRangeWhenWatch === NAME.MYSELF) {
const data = this.getData(storeName, key);
callback.call(this, data);
}
});

@@ -91,3 +101,2 @@ }

const currentData = this.storeMap[storeName]['store'][key];
const te = this.getData(StoreName.CALL, key);
if (currentData === data) return;

@@ -94,0 +103,0 @@ }

@@ -83,2 +83,3 @@ import { IUserInfo } from '../interface';

} catch (error) {
console.debug(error);
return false;

@@ -197,1 +198,15 @@ }

};
/*
* 获取浏览器语言
* @export
* @return {zh-cn | en}
*/
export const getLanguage = () => {
// @ts-ignore
let lang = navigator?.language || navigator?.userLanguage || '';
lang = lang.substr(0, 2);
return lang === 'zh' ? 'zh-cn' : 'en';
};
export function noop(e: any) {}

@@ -40,3 +40,3 @@ // eslint-disable-next-line

const USER_AGENT = IN_BROWSER && window && window.navigator && window.navigator.userAgent || '';
const USER_AGENT = IN_BROWSER && window && window.navigator && window.navigator.userAgent || ''
const IS_ANDROID = /Android/i.test(USER_AGENT);

@@ -43,0 +43,0 @@ const IS_WIN_PHONE = /(?:Windows Phone)/.test(USER_AGENT);

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is too big to display

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc