2024-03-18 18:50:29 +08:00

1192 lines
65 KiB
JavaScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"use strict";
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var __metadata = (this && this.__metadata) || function (k, v) {
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
};
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
var __rest = (this && this.__rest) || function (s, e) {
var t = {};
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
t[p] = s[p];
if (s != null && typeof Object.getOwnPropertySymbols === "function")
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
t[p[i]] = s[p[i]];
}
return t;
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.TUIStore = exports.TUIGlobal = void 0;
const tui_core_1 = require("../../min-npm/@tencentcloud/tui-core/index");
//const tui_core_1 = require("@tencentcloud/tui-core");
const index_1 = require("../const/index");
// @ts-ignore
const tuicall_engine_wx_1 = require("../../min-npm/tuicall-engine-wx/index");
//const tuicall_engine_wx_1 = require("tuicall-engine-wx");
const index_2 = require("../locales/index");
const miniProgram_1 = require("./miniProgram");
const bellContext_1 = require("./bellContext");
const index_3 = require("../utils/validate/index");
const common_utils_1 = require("../utils/common-utils");
const utils_1 = require("./utils");
const timer_1 = __importDefault(require("../utils/timer"));
const tuiGlobal_1 = __importDefault(require("../TUIGlobal/tuiGlobal"));
const tuiStore_1 = __importDefault(require("../TUIStore/tuiStore"));
const TUIGlobal = tuiGlobal_1.default.getInstance();
exports.TUIGlobal = TUIGlobal;
const TUIStore = tuiStore_1.default.getInstance();
exports.TUIStore = TUIStore;
const version = '2.1.1';
class TUICallService {
constructor() {
this._tim = null;
this._TUICore = null;
this._timerId = -1;
this._startTimeStamp = (0, common_utils_1.performanceNow)();
this._bellContext = null;
this._defaultOfflinePushInfo = {
title: '',
description: (0, index_2.t)('you have a new call'),
};
// =========================【监听 TUIStore 中的状态】=========================
this._handleCallStatusChange = (value) => __awaiter(this, void 0, void 0, function* () {
var _a, _b;
try {
const bellParams = {
callRole: TUIStore.getData(index_1.StoreName.CALL, index_1.NAME.CALL_ROLE),
callStatus: TUIStore.getData(index_1.StoreName.CALL, index_1.NAME.CALL_STATUS),
};
this._bellContext.setBellProperties(bellParams);
if (value === index_1.CallStatus.CALLING) {
yield ((_a = this === null || this === void 0 ? void 0 : this._bellContext) === null || _a === void 0 ? void 0 : _a.play());
}
else {
// 状态变更通知
if (value === index_1.CallStatus.CONNECTED) {
const isGroup = TUIStore.getData(index_1.StoreName.CALL, index_1.NAME.IS_GROUP);
const callMediaType = TUIStore.getData(index_1.StoreName.CALL, index_1.NAME.CALL_MEDIA_TYPE);
const remoteUserInfoList = TUIStore.getData(index_1.StoreName.CALL, index_1.NAME.REMOTE_USER_INFO_LIST);
const oldStatus = isGroup ? index_1.StatusChange.DIALING_GROUP : index_1.StatusChange.DIALING_C2C;
TUIStore.update(index_1.StoreName.CALL, index_1.NAME.CALL_TIPS, '');
this.statusChanged && this.statusChanged({ oldStatus, newStatus: (0, utils_1.generateStatusChangeText)(TUIStore) });
if (!isGroup && callMediaType === index_1.CallMediaType.VIDEO) {
this.switchScreen(remoteUserInfoList[0].domId);
}
}
yield ((_b = this === null || this === void 0 ? void 0 : this._bellContext) === null || _b === void 0 ? void 0 : _b.stop());
}
}
catch (error) {
console.warn(`${index_1.NAME.PREFIX}handleCallStatusChange, ${error}.`);
}
});
console.log(`${index_1.NAME.PREFIX}version: ${version}`);
this._watchTUIStore();
this._bellContext = new bellContext_1.BellContext();
// 下面TUICore注册事件注册组件服务注册界面拓展
tui_core_1.TUICore.registerEvent(tui_core_1.TUIConstants.TUILogin.EVENT.LOGIN_STATE_CHANGED, tui_core_1.TUIConstants.TUILogin.EVENT_SUB_KEY.USER_LOGIN_SUCCESS, this);
tui_core_1.TUICore.registerService(tui_core_1.TUIConstants.TUICalling.SERVICE.NAME, this);
tui_core_1.TUICore.registerExtension(tui_core_1.TUIConstants.TUIChat.EXTENSION.INPUT_MORE.EXT_ID, this);
}
static getInstance() {
if (!TUICallService.instance) {
TUICallService.instance = new TUICallService();
}
return TUICallService.instance;
}
init(params) {
return __awaiter(this, void 0, void 0, function* () {
try {
if (this._tuiCallEngine)
return;
// @ts-ignore
let { userID, tim, userSig, sdkAppID, SDKAppID, isFromChat } = params;
if (this._TUICore) {
sdkAppID = this._TUICore.SDKAppID;
tim = this._TUICore.tim;
}
this._tim = tim;
console.log(`${index_1.NAME.PREFIX}init sdkAppId: ${sdkAppID || SDKAppID}, userId: ${userID}`);
this._tuiCallEngine = tuicall_engine_wx_1.TUICallEngine.createInstance({
tim,
// @ts-ignore
sdkAppID: sdkAppID || SDKAppID,
callkitVersion: version,
chat: isFromChat || false,
});
this._addListenTuiCallEngineEvent();
TUIStore.update(index_1.StoreName.CALL, index_1.NAME.LOCAL_USER_INFO, { userId: userID });
TUIStore.update(index_1.StoreName.CALL, index_1.NAME.LOCAL_USER_INFO_EXCLUDE_VOLUMN, { userId: userID });
yield this._tuiCallEngine.login({ userID, userSig, assetsPath: '' }); // web && mini
}
catch (error) {
console.error(`${index_1.NAME.PREFIX}init failed, error: ${error}.`);
throw error;
}
});
}
// component destroy
destroyed() {
return __awaiter(this, void 0, void 0, function* () {
try {
const currentCallStatus = TUIStore.getData(index_1.StoreName.CALL, index_1.NAME.CALL_STATUS);
if (currentCallStatus !== index_1.CallStatus.IDLE) {
throw new Error(`please destroyed when status is idle, current status: ${currentCallStatus}`);
}
if (this._tuiCallEngine) {
this._removeListenTuiCallEngineEvent();
yield this._tuiCallEngine.destroyInstance();
this._tuiCallEngine = null;
}
}
catch (error) {
console.error(`${index_1.NAME.PREFIX}destroyed failed, error: ${error}.`);
throw error;
}
});
}
// ===============================【通话操作】===============================
call(callParams) {
return __awaiter(this, void 0, void 0, function* () {
try {
const { type, userID, offlinePushInfo } = callParams;
if (TUIStore.getData(index_1.StoreName.CALL, index_1.NAME.CALL_STATUS) !== index_1.CallStatus.IDLE)
return;
yield this._updateCallStoreBeforeCall(type, [{ userId: userID }]);
this._executeExternalBeforeCalling(); // 执行外部传入的 beforeCall 方法
callParams.offlinePushInfo = Object.assign(Object.assign({}, this._defaultOfflinePushInfo), offlinePushInfo);
const response = yield this._tuiCallEngine.call(callParams);
yield this._updateCallStoreAfterCall([userID], response);
}
catch (error) {
this._handleCallError(error, 'call');
}
});
}
;
groupCall(groupCallParams) {
return __awaiter(this, void 0, void 0, function* () {
try {
const { userIDList, type, groupID, offlinePushInfo } = groupCallParams;
if (TUIStore.getData(index_1.StoreName.CALL, index_1.NAME.CALL_STATUS) !== index_1.CallStatus.IDLE)
return;
const remoteUserInfoList = userIDList.map(userId => ({ userId }));
yield this._updateCallStoreBeforeCall(type, remoteUserInfoList, groupID);
this._executeExternalBeforeCalling();
groupCallParams.offlinePushInfo = Object.assign(Object.assign({}, this._defaultOfflinePushInfo), offlinePushInfo);
const response = yield this._tuiCallEngine.groupCall(groupCallParams);
yield this._updateCallStoreAfterCall(userIDList, response);
}
catch (error) {
this._handleCallError(error, 'groupCall');
}
});
}
inviteUser(params) {
return __awaiter(this, void 0, void 0, function* () {
try {
const { userIDList } = params;
let inviteUserInfoList = yield (0, utils_1.getRemoteUserProfile)(userIDList, this.getTim(), TUIStore);
const remoteUserInfoList = TUIStore.getData(index_1.StoreName.CALL, index_1.NAME.REMOTE_USER_INFO_LIST);
TUIStore.update(index_1.StoreName.CALL, index_1.NAME.REMOTE_USER_INFO_LIST, [...remoteUserInfoList, ...inviteUserInfoList]);
TUIStore.update(index_1.StoreName.CALL, index_1.NAME.REMOTE_USER_INFO_EXCLUDE_VOLUMN_LIST, [...remoteUserInfoList, ...inviteUserInfoList]);
this._tuiCallEngine && (yield this._tuiCallEngine.inviteUser(params));
}
catch (error) {
console.error(`${index_1.NAME.PREFIX}inviteUser failed, error: ${error}.`);
this._resetCallStore();
throw error;
}
});
}
joinInGroupCall(params) {
return __awaiter(this, void 0, void 0, function* () {
try {
const updateStoreParams = {
[index_1.NAME.CALL_ROLE]: index_1.CallRole.CALLEE,
[index_1.NAME.IS_GROUP]: true,
[index_1.NAME.CALL_STATUS]: index_1.CallStatus.CONNECTED,
[index_1.NAME.CALL_MEDIA_TYPE]: params.type,
[index_1.NAME.GROUP_ID]: params.groupID,
[index_1.NAME.ROOM_ID]: params.roomID,
};
TUIStore.updateStore(updateStoreParams, index_1.StoreName.CALL);
const response = yield this._tuiCallEngine.joinInGroupCall(params);
(params.type === index_1.CallMediaType.VIDEO) && (yield this.openCamera(index_1.NAME.LOCAL_VIDEO));
TUIStore.update(index_1.StoreName.CALL, index_1.NAME.IS_CLICKABLE, true);
this._startTimer();
TUIStore.update(index_1.StoreName.CALL, index_1.NAME.PUSHER, response);
this.setSoundMode(params.type === index_1.CallMediaType.AUDIO ? index_1.AudioPlayBackDevice.EAR : index_1.AudioPlayBackDevice.SPEAKER);
const localUserInfo = TUIStore.getData(index_1.StoreName.CALL, index_1.NAME.LOCAL_USER_INFO);
TUIStore.update(index_1.StoreName.CALL, index_1.NAME.LOCAL_USER_INFO, Object.assign(Object.assign({}, localUserInfo), { isEnter: true }));
TUIStore.update(index_1.StoreName.CALL, index_1.NAME.LOCAL_USER_INFO_EXCLUDE_VOLUMN, Object.assign(Object.assign({}, localUserInfo), { isEnter: true }));
this._setLocalUserInfoAudioVideoAvailable(true, index_1.NAME.AUDIO);
}
catch (error) {
console.error(`${index_1.NAME.PREFIX}joinInGroupCall failed, error: ${error}.`);
this._resetCallStore();
throw error;
}
});
}
// ===============================【其它对外接口】===============================
getTUICallEngineInstance() {
return (this === null || this === void 0 ? void 0 : this._tuiCallEngine) || null;
}
setLogLevel(level) {
var _a;
(_a = this === null || this === void 0 ? void 0 : this._tuiCallEngine) === null || _a === void 0 ? void 0 : _a.setLogLevel(level);
}
setLanguage(language) {
if (language && Object.values(index_1.LanguageType).includes(language)) {
TUIStore.update(index_1.StoreName.CALL, index_1.NAME.LANGUAGE, language);
}
}
enableFloatWindow(enable) {
TUIStore.update(index_1.StoreName.CALL, index_1.NAME.ENABLE_FLOAT_WINDOW, enable);
}
setSelfInfo(params) {
return __awaiter(this, void 0, void 0, function* () {
const { nickName, avatar } = params;
try {
yield this._tuiCallEngine.setSelfInfo(nickName, avatar);
}
catch (error) {
console.error(`${index_1.NAME.PREFIX}setSelfInfo failed, error: ${error}.`);
}
});
}
// 修改默认铃声:只支持本地铃声文件,不支持在线铃声文件;修改铃声修改的是被叫的铃声
setCallingBell(filePath) {
return __awaiter(this, void 0, void 0, function* () {
let isCheckFileExist = true;
if (!isCheckFileExist) {
console.warn(`${index_1.NAME.PREFIX}setCallingBell failed, filePath: ${filePath}.`);
return;
}
const bellParams = { calleeBellFilePath: filePath };
this._bellContext.setBellProperties(bellParams);
});
}
enableMuteMode(enable) {
return __awaiter(this, void 0, void 0, function* () {
try {
const bellParams = { isMuteBell: enable };
this._bellContext.setBellProperties(bellParams);
yield this._bellContext.setBellMute(enable);
}
catch (error) {
console.warn(`${index_1.NAME.PREFIX}enableMuteMode failed, error: ${error}.`);
}
});
}
// =============================【内部按钮操作方法】=============================
accept() {
var _a;
return __awaiter(this, void 0, void 0, function* () {
try {
const response = yield this._tuiCallEngine.accept();
if (response) {
// 小程序接通时会进行授权弹框, 状态需要放在 accept 后, 否则先接通后再拉起权限设置
TUIStore.update(index_1.StoreName.CALL, index_1.NAME.CALL_STATUS, index_1.CallStatus.CONNECTED);
this._callTUIService({ message: (_a = response === null || response === void 0 ? void 0 : response.data) === null || _a === void 0 ? void 0 : _a.message });
TUIStore.update(index_1.StoreName.CALL, index_1.NAME.IS_CLICKABLE, true);
this._startTimer();
const callMediaType = TUIStore.getData(index_1.StoreName.CALL, index_1.NAME.CALL_MEDIA_TYPE);
(callMediaType === index_1.CallMediaType.VIDEO) && (yield this.openCamera(index_1.NAME.LOCAL_VIDEO));
response.pusher && TUIStore.update(index_1.StoreName.CALL, index_1.NAME.PUSHER, response.pusher);
this.setSoundMode(callMediaType === index_1.CallMediaType.AUDIO ? index_1.AudioPlayBackDevice.EAR : index_1.AudioPlayBackDevice.SPEAKER);
const localUserInfo = TUIStore.getData(index_1.StoreName.CALL, index_1.NAME.LOCAL_USER_INFO);
TUIStore.update(index_1.StoreName.CALL, index_1.NAME.LOCAL_USER_INFO, Object.assign(Object.assign({}, localUserInfo), { isEnter: true }));
TUIStore.update(index_1.StoreName.CALL, index_1.NAME.LOCAL_USER_INFO_EXCLUDE_VOLUMN, Object.assign(Object.assign({}, localUserInfo), { isEnter: true }));
this._setLocalUserInfoAudioVideoAvailable(true, index_1.NAME.AUDIO); // web && mini default open audio
}
}
catch (error) {
if ((0, common_utils_1.handleRepeatedCallError)(error))
return;
this._noDevicePermissionToast(error, index_1.CallMediaType.AUDIO);
this._resetCallStore();
}
});
}
hangup() {
return __awaiter(this, void 0, void 0, function* () {
try {
const response = yield this._tuiCallEngine.hangup();
response === null || response === void 0 ? void 0 : response.forEach((item) => {
var _a;
if ((item === null || item === void 0 ? void 0 : item.code) === 0) {
this._callTUIService({ message: (_a = item === null || item === void 0 ? void 0 : item.data) === null || _a === void 0 ? void 0 : _a.message });
}
});
}
catch (error) {
console.debug(error);
}
this._resetCallStore();
});
}
reject() {
var _a;
return __awaiter(this, void 0, void 0, function* () {
try {
const response = yield this._tuiCallEngine.reject();
if ((response === null || response === void 0 ? void 0 : response.code) === 0) {
this._callTUIService({ message: (_a = response === null || response === void 0 ? void 0 : response.data) === null || _a === void 0 ? void 0 : _a.message });
}
}
catch (error) {
console.debug(error);
}
this._resetCallStore();
});
}
openCamera(videoViewDomID) {
return __awaiter(this, void 0, void 0, function* () {
try {
yield this._tuiCallEngine.openCamera();
this._setLocalUserInfoAudioVideoAvailable(true, index_1.NAME.VIDEO);
}
catch (error) {
this._noDevicePermissionToast(error, index_1.CallMediaType.VIDEO);
console.error(`${index_1.NAME.PREFIX}openCamera error: ${error}.`);
}
});
}
closeCamera() {
return __awaiter(this, void 0, void 0, function* () {
try {
yield this._tuiCallEngine.closeCamera();
this._setLocalUserInfoAudioVideoAvailable(false, index_1.NAME.VIDEO);
}
catch (error) {
console.error(`${index_1.NAME.PREFIX}closeCamera error: ${error}.`);
}
});
}
openMicrophone() {
return __awaiter(this, void 0, void 0, function* () {
try {
yield this._tuiCallEngine.openMicrophone();
this._setLocalUserInfoAudioVideoAvailable(true, index_1.NAME.AUDIO);
}
catch (error) {
console.error(`${index_1.NAME.PREFIX}openMicrophone failed, error: ${error}.`);
}
});
}
closeMicrophone() {
return __awaiter(this, void 0, void 0, function* () {
try {
yield this._tuiCallEngine.closeMicrophone();
this._setLocalUserInfoAudioVideoAvailable(false, index_1.NAME.AUDIO);
}
catch (error) {
console.error(`${index_1.NAME.PREFIX}closeMicrophone failed, error: ${error}.`);
}
});
}
switchScreen(userId) {
if (!userId)
return;
TUIStore.update(index_1.StoreName.CALL, index_1.NAME.BIG_SCREEN_USER_ID, userId);
}
// support video to audio; not support audio to video
switchCallMediaType() {
var _a;
return __awaiter(this, void 0, void 0, function* () {
try {
const callMediaType = TUIStore.getData(index_1.StoreName.CALL, index_1.NAME.CALL_MEDIA_TYPE);
if (callMediaType === index_1.CallMediaType.AUDIO) {
console.warn(`${index_1.NAME.PREFIX}switchCallMediaType failed, ${callMediaType} not support.`);
return;
}
const response = yield this._tuiCallEngine.switchCallMediaType(index_1.CallMediaType.AUDIO);
if ((response === null || response === void 0 ? void 0 : response.code) === 0) {
this._callTUIService({ message: (_a = response === null || response === void 0 ? void 0 : response.data) === null || _a === void 0 ? void 0 : _a.message });
}
TUIStore.update(index_1.StoreName.CALL, index_1.NAME.CALL_MEDIA_TYPE, index_1.CallMediaType.AUDIO);
const isGroup = TUIStore.getData(index_1.StoreName.CALL, index_1.NAME.IS_GROUP);
const oldStatus = isGroup ? index_1.StatusChange.CALLING_GROUP_VIDEO : index_1.StatusChange.CALLING_C2C_VIDEO;
const newStatus = (0, utils_1.generateStatusChangeText)(TUIStore);
this.statusChanged && this.statusChanged({ oldStatus, newStatus });
this.setSoundMode(index_1.AudioPlayBackDevice.EAR);
}
catch (error) {
console.error(`${index_1.NAME.PREFIX}switchCallMediaType failed, error: ${error}.`);
}
});
}
switchCamera() {
return __awaiter(this, void 0, void 0, function* () {
const currentPosition = TUIStore.getData(index_1.StoreName.CALL, index_1.NAME.CAMERA_POSITION);
const targetPosition = currentPosition === index_1.CameraPosition.BACK ? index_1.CameraPosition.FRONT : index_1.CameraPosition.BACK;
try {
yield this._tuiCallEngine.switchCamera(targetPosition);
TUIStore.update(index_1.StoreName.CALL, index_1.NAME.CAMERA_POSITION, targetPosition);
}
catch (error) {
console.error(`${index_1.NAME.PREFIX}_switchCamera failed, error: ${error}.`);
}
});
}
setSoundMode(type) {
var _a;
try {
let isEarPhone = TUIStore.getData(index_1.StoreName.CALL, index_1.NAME.IS_EAR_PHONE);
const soundMode = type || (isEarPhone ? index_1.AudioPlayBackDevice.SPEAKER : index_1.AudioPlayBackDevice.EAR); // UI 层切换时传参数
(_a = this._tuiCallEngine) === null || _a === void 0 ? void 0 : _a.selectAudioPlaybackDevice(soundMode);
if (type) {
isEarPhone = type === index_1.AudioPlayBackDevice.EAR;
}
else {
isEarPhone = !isEarPhone;
}
TUIStore.update(index_1.StoreName.CALL, index_1.NAME.IS_EAR_PHONE, isEarPhone);
}
catch (error) {
console.error(`${index_1.NAME.PREFIX}setSoundMode failed, error: ${error}.`);
}
}
// 切前后置 miniProgram, 切扬声器
getTim() {
var _a, _b;
if (this._tim)
return this._tim;
if (!this._tuiCallEngine) {
console.warn(`${index_1.NAME.PREFIX}getTim warning: _tuiCallEngine Instance is not available.`);
return null;
}
return ((_a = this._tuiCallEngine) === null || _a === void 0 ? void 0 : _a.tim) || ((_b = this._tuiCallEngine) === null || _b === void 0 ? void 0 : _b.getTim()); // mini support getTim interface
}
// ==========================【TUICallEngine 事件处理】==========================
_addListenTuiCallEngineEvent() {
if (!this._tuiCallEngine) {
console.warn(`${index_1.NAME.PREFIX}add engine event listener failed, engine is empty.`);
return;
}
this._tuiCallEngine.on(tuicall_engine_wx_1.EVENT.ERROR, this._handleError, this);
this._tuiCallEngine.on(tuicall_engine_wx_1.EVENT.INVITED, this._handleNewInvitationReceived, this); // 收到邀请事件
this._tuiCallEngine.on(tuicall_engine_wx_1.EVENT.USER_ACCEPT, this._handleUserAccept, this); // 主叫收到被叫接通事件
this._tuiCallEngine.on(tuicall_engine_wx_1.EVENT.USER_ENTER, this._handleUserEnter, this); // 有用户进房事件
this._tuiCallEngine.on(tuicall_engine_wx_1.EVENT.USER_LEAVE, this._handleUserLeave, this); // 有用户离开通话事件
this._tuiCallEngine.on(tuicall_engine_wx_1.EVENT.REJECT, this._handleInviteeReject, this); // 主叫收到被叫的拒绝通话事件
this._tuiCallEngine.on(tuicall_engine_wx_1.EVENT.NO_RESP, this._handleNoResponse, this); // 主叫收到被叫的无应答事件
this._tuiCallEngine.on(tuicall_engine_wx_1.EVENT.LINE_BUSY, this._handleLineBusy, this); // 主叫收到被叫的忙线事件
this._tuiCallEngine.on(tuicall_engine_wx_1.EVENT.CALLING_CANCEL, this._handleCallingCancel, this); // 主被叫在通话未建立时, 收到的取消事件
this._tuiCallEngine.on(tuicall_engine_wx_1.EVENT.SDK_READY, this._handleSDKReady, this); // SDK Ready 回调
this._tuiCallEngine.on(tuicall_engine_wx_1.EVENT.KICKED_OUT, this._handleKickedOut, this); // 未开启多端登录时, 多端登录收到的被踢事件
this._tuiCallEngine.on(tuicall_engine_wx_1.EVENT.MESSAGE_SENT_BY_ME, this._messageSentByMe, this);
this._tuiCallEngine.on(tuicall_engine_wx_1.EVENT.CALL_END, this._handleCallingEnd, this); // 主被叫在通话结束时, 收到的通话结束事件
// @ts-ignore
this._tuiCallEngine.on(tuicall_engine_wx_1.EVENT.CALL_MODE, this._handleCallTypeChange, this);
// @ts-ignore
this._tuiCallEngine.on(tuicall_engine_wx_1.EVENT.USER_UPDATE, this._handleUserUpdate, this); // mini: user data update
}
_removeListenTuiCallEngineEvent() {
this._tuiCallEngine.off(tuicall_engine_wx_1.EVENT.ERROR, this._handleError);
this._tuiCallEngine.off(tuicall_engine_wx_1.EVENT.INVITED, this._handleNewInvitationReceived);
this._tuiCallEngine.off(tuicall_engine_wx_1.EVENT.USER_ACCEPT, this._handleUserAccept);
this._tuiCallEngine.off(tuicall_engine_wx_1.EVENT.USER_ENTER, this._handleUserEnter);
this._tuiCallEngine.off(tuicall_engine_wx_1.EVENT.USER_LEAVE, this._handleUserLeave);
this._tuiCallEngine.off(tuicall_engine_wx_1.EVENT.REJECT, this._handleInviteeReject);
this._tuiCallEngine.off(tuicall_engine_wx_1.EVENT.NO_RESP, this._handleNoResponse);
this._tuiCallEngine.off(tuicall_engine_wx_1.EVENT.LINE_BUSY, this._handleLineBusy);
this._tuiCallEngine.off(tuicall_engine_wx_1.EVENT.CALLING_CANCEL, this._handleCallingCancel);
this._tuiCallEngine.off(tuicall_engine_wx_1.EVENT.SDK_READY, this._handleSDKReady);
this._tuiCallEngine.off(tuicall_engine_wx_1.EVENT.KICKED_OUT, this._handleKickedOut);
this._tuiCallEngine.off(tuicall_engine_wx_1.EVENT.MESSAGE_SENT_BY_ME, this._messageSentByMe);
this._tuiCallEngine.off(tuicall_engine_wx_1.EVENT.CALL_END, this._handleCallingEnd);
// @ts-ignore
this._tuiCallEngine.off(tuicall_engine_wx_1.EVENT.CALL_MODE, this._handleCallTypeChange); // 切换通话事件 miniProgram CALL_MODE
// @ts-ignore
this._tuiCallEngine.off(tuicall_engine_wx_1.EVENT.USER_UPDATE, this._handleUserUpdate); // mini: user data update
}
_handleError(event) {
const { code, message } = event || {};
const index = Object.values(index_1.ErrorCode).indexOf(code);
let callTips = '';
if (index !== -1) {
const key = Object.keys(index_1.ErrorCode)[index];
callTips = (0, index_2.t)(index_1.ErrorMessage[key]);
callTips && TUIStore.update(index_1.StoreName.CALL, index_1.NAME.TOAST_INFO, { text: callTips, type: index_1.NAME.ERROR });
}
this._executeExternalAfterCalling();
console.error(`${index_1.NAME.PREFIX}_handleError, errorCode: ${code}; errorMessage: ${callTips || message}.`);
}
_handleNewInvitationReceived(event) {
return __awaiter(this, void 0, void 0, function* () {
console.log(`${index_1.NAME.PREFIX}onCallReceived event data: ${JSON.stringify(event)}.`);
const { sponsor = '', isFromGroup, callMediaType, inviteData = {}, calleeIdList = [], groupID = '' } = this._analyzeEventData(event);
const currentUserInfo = TUIStore.getData(index_1.StoreName.CALL, index_1.NAME.LOCAL_USER_INFO);
const remoteUserIdList = [sponsor, ...calleeIdList.filter((userId) => userId !== currentUserInfo.userId)];
const type = callMediaType || inviteData.callType;
const callTipsKey = type === index_1.CallMediaType.AUDIO ? index_2.CallTips.CALLEE_CALLING_AUDIO_MSG : index_2.CallTips.CALLEE_CALLING_VIDEO_MSG;
let updateStoreParams = {
[index_1.NAME.CALL_ROLE]: index_1.CallRole.CALLEE,
[index_1.NAME.IS_GROUP]: isFromGroup,
[index_1.NAME.CALL_STATUS]: index_1.CallStatus.CALLING,
[index_1.NAME.CALL_MEDIA_TYPE]: type,
[index_1.NAME.CALL_TIPS]: (0, index_2.t)(callTipsKey),
[index_1.NAME.CALLER_USER_INFO]: { userId: sponsor },
[index_1.NAME.GROUP_ID]: groupID,
};
(0, miniProgram_1.initAndCheckRunEnv)();
const pusher = { enableCamera: type === index_1.CallMediaType.VIDEO, enableMic: true }; // mini 默认打开麦克风
updateStoreParams = Object.assign(Object.assign({}, updateStoreParams), { [index_1.NAME.PUSHER]: pusher });
TUIStore.updateStore(updateStoreParams, index_1.StoreName.CALL);
this._executeExternalBeforeCalling();
this.statusChanged && this.statusChanged({ oldStatus: index_1.StatusChange.IDLE, newStatus: index_1.StatusChange.BE_INVITED });
const remoteUserInfoList = yield (0, utils_1.getRemoteUserProfile)(remoteUserIdList, this.getTim(), TUIStore);
const [userInfo] = remoteUserInfoList.filter((userInfo) => userInfo.userId === sponsor);
remoteUserInfoList.length > 0 && TUIStore.updateStore({
[index_1.NAME.REMOTE_USER_INFO_LIST]: remoteUserInfoList,
[index_1.NAME.REMOTE_USER_INFO_EXCLUDE_VOLUMN_LIST]: remoteUserInfoList,
[index_1.NAME.CALLER_USER_INFO]: {
userId: sponsor,
nick: (userInfo === null || userInfo === void 0 ? void 0 : userInfo.nick) || '',
avatar: (userInfo === null || userInfo === void 0 ? void 0 : userInfo.avatar) || '',
displayUserInfo: (userInfo === null || userInfo === void 0 ? void 0 : userInfo.remark) || (userInfo === null || userInfo === void 0 ? void 0 : userInfo.nick) || sponsor,
},
}, index_1.StoreName.CALL);
});
}
_handleUserAccept(event) {
this._callerChangeToConnected();
TUIStore.update(index_1.StoreName.CALL, index_1.NAME.TOAST_INFO, (0, index_2.t)('answered'));
console.log(`${index_1.NAME.PREFIX}accept event data: ${JSON.stringify(event)}.`);
}
_handleUserEnter(event) {
return __awaiter(this, void 0, void 0, function* () {
this._callerChangeToConnected();
const { userID: userId, data } = this._analyzeEventData(event);
(data === null || data === void 0 ? void 0 : data.playerList) && TUIStore.update(index_1.StoreName.CALL, index_1.NAME.PLAYER, data.playerList);
let remoteUserInfoList = TUIStore.getData(index_1.StoreName.CALL, index_1.NAME.REMOTE_USER_INFO_LIST);
const isInRemoteUserList = remoteUserInfoList.find(item => (item === null || item === void 0 ? void 0 : item.userId) === userId);
if (!isInRemoteUserList) {
remoteUserInfoList.push({ userId });
if (remoteUserInfoList.length > 0) {
TUIStore.update(index_1.StoreName.CALL, index_1.NAME.REMOTE_USER_INFO_LIST, remoteUserInfoList);
TUIStore.update(index_1.StoreName.CALL, index_1.NAME.REMOTE_USER_INFO_EXCLUDE_VOLUMN_LIST, remoteUserInfoList);
}
const [userInfo] = yield (0, utils_1.getRemoteUserProfile)([userId], this.getTim(), TUIStore);
remoteUserInfoList = TUIStore.getData(index_1.StoreName.CALL, index_1.NAME.REMOTE_USER_INFO_LIST);
remoteUserInfoList.forEach((obj) => {
if ((obj === null || obj === void 0 ? void 0 : obj.userId) === userId) {
obj = Object.assign(obj, userInfo);
}
});
}
remoteUserInfoList = remoteUserInfoList.map((obj) => {
if (obj.userId === userId)
obj.isEnter = true;
return obj;
});
if (remoteUserInfoList.length > 0) {
TUIStore.update(index_1.StoreName.CALL, index_1.NAME.REMOTE_USER_INFO_LIST, remoteUserInfoList);
TUIStore.update(index_1.StoreName.CALL, index_1.NAME.REMOTE_USER_INFO_EXCLUDE_VOLUMN_LIST, remoteUserInfoList);
}
console.log(`${index_1.NAME.PREFIX}userEnter event data: ${JSON.stringify(event)}.`);
});
}
_callerChangeToConnected() {
const callRole = TUIStore.getData(index_1.StoreName.CALL, index_1.NAME.CALL_ROLE);
const callStatus = TUIStore.getData(index_1.StoreName.CALL, index_1.NAME.CALL_STATUS);
if (callStatus === index_1.CallStatus.CALLING && callRole === index_1.CallRole.CALLER) {
TUIStore.update(index_1.StoreName.CALL, index_1.NAME.CALL_STATUS, index_1.CallStatus.CONNECTED);
this._startTimer();
}
}
_handleUserLeave(event) {
console.log(`${index_1.NAME.PREFIX}userLeave event data: ${JSON.stringify(event)}.`);
const { data, userID: userId } = this._analyzeEventData(event);
(data === null || data === void 0 ? void 0 : data.playerList) && TUIStore.update(index_1.StoreName.CALL, index_1.NAME.PLAYER, data.playerList);
if (TUIStore.getData(index_1.StoreName.CALL, index_1.NAME.IS_GROUP)) {
const remoteUserInfoList = TUIStore.getData(index_1.StoreName.CALL, index_1.NAME.REMOTE_USER_INFO_LIST);
const prefix = (remoteUserInfoList.find(obj => obj.userId === userId) || {}).displayUserInfo || userId;
const text = (0, utils_1.generateText)(TUIStore, index_2.CallTips.END_CALL, prefix);
TUIStore.update(index_1.StoreName.CALL, index_1.NAME.TOAST_INFO, { text });
}
userId && this._deleteRemoteUser([userId]);
}
_unNormalEventsManager(event, eventName) {
console.log(`${index_1.NAME.PREFIX}${eventName} event data: ${JSON.stringify(event)}.`);
const isGroup = TUIStore.getData(index_1.StoreName.CALL, index_1.NAME.IS_GROUP);
const remoteUserInfoList = TUIStore.getData(index_1.StoreName.CALL, index_1.NAME.REMOTE_USER_INFO_LIST);
switch (eventName) {
case tuicall_engine_wx_1.EVENT.REJECT:
case tuicall_engine_wx_1.EVENT.LINE_BUSY: {
const { userID: userId } = this._analyzeEventData(event);
let callTipsKey = eventName === tuicall_engine_wx_1.EVENT.REJECT ? index_2.CallTips.OTHER_SIDE_REJECT_CALL : index_2.CallTips.OTHER_SIDE_LINE_BUSY;
let text = (0, utils_1.generateText)(TUIStore, callTipsKey);
if (isGroup) {
const prefix = (remoteUserInfoList.find(obj => obj.userId === userId) || {}).displayUserInfo || userId;
callTipsKey = eventName === tuicall_engine_wx_1.EVENT.REJECT ? index_2.CallTips.REJECT_CALL : index_2.CallTips.IN_BUSY;
text = (0, utils_1.generateText)(TUIStore, callTipsKey, prefix);
}
TUIStore.update(index_1.StoreName.CALL, index_1.NAME.TOAST_INFO, { text });
userId && this._deleteRemoteUser([userId]);
break;
}
case tuicall_engine_wx_1.EVENT.NO_RESP: {
const { userIDList = [] } = this._analyzeEventData(event);
const callTipsKey = isGroup ? index_2.CallTips.TIMEOUT : index_2.CallTips.CALL_TIMEOUT;
const userInfoList = userIDList.map(userId => {
const userInfo = remoteUserInfoList.find(obj => obj.userId === userId) || {};
return userInfo.displayUserInfo || userId;
});
const text = isGroup ? (0, utils_1.generateText)(TUIStore, callTipsKey, userInfoList.join()) : (0, utils_1.generateText)(TUIStore, callTipsKey);
TUIStore.update(index_1.StoreName.CALL, index_1.NAME.TOAST_INFO, { text });
userIDList.length > 0 && this._deleteRemoteUser(userIDList);
break;
}
case tuicall_engine_wx_1.EVENT.CALLING_CANCEL: {
// TUIStore.update(StoreName.CALL, NAME.TOAST_INFO, { text: generateText(TUIStore, CallTips.CANCEL) });
this._resetCallStore();
break;
}
}
}
_handleInviteeReject(event) {
this._unNormalEventsManager(event, tuicall_engine_wx_1.EVENT.REJECT);
}
_handleNoResponse(event) {
this._unNormalEventsManager(event, tuicall_engine_wx_1.EVENT.NO_RESP);
}
_handleLineBusy(event) {
this._unNormalEventsManager(event, tuicall_engine_wx_1.EVENT.LINE_BUSY);
}
_handleCallingCancel(event) {
this._executeExternalAfterCalling();
this._unNormalEventsManager(event, tuicall_engine_wx_1.EVENT.CALLING_CANCEL);
}
_handleCallingEnd(event) {
console.log(`${index_1.NAME.PREFIX}callEnd event data: ${JSON.stringify(event)}.`);
this._executeExternalAfterCalling();
this._resetCallStore();
}
// SDK_READY 后才能调用 tim 接口, 否则登录后立刻获取导致调用接口失败. v2.27.4+、v3 接口 login 后会抛出 SDK_READY
_handleSDKReady(event) {
return __awaiter(this, void 0, void 0, function* () {
let localUserInfo = TUIStore.getData(index_1.StoreName.CALL, index_1.NAME.LOCAL_USER_INFO);
localUserInfo = yield (0, utils_1.getMyProfile)(localUserInfo.userId, this.getTim(), TUIStore);
this._defaultOfflinePushInfo.title = localUserInfo === null || localUserInfo === void 0 ? void 0 : localUserInfo.displayUserInfo;
TUIStore.update(index_1.StoreName.CALL, index_1.NAME.LOCAL_USER_INFO, localUserInfo);
TUIStore.update(index_1.StoreName.CALL, index_1.NAME.LOCAL_USER_INFO_EXCLUDE_VOLUMN, localUserInfo);
});
}
_handleKickedOut(event) {
console.log(`${index_1.NAME.PREFIX}kickOut event data: ${JSON.stringify(event)}.`);
this.kickedOut && this.kickedOut(event);
TUIStore.update(index_1.StoreName.CALL, index_1.NAME.CALL_TIPS, (0, utils_1.generateText)(TUIStore, index_2.CallTips.KICK_OUT));
this._resetCallStore();
}
_handleCallTypeChange(event) {
const { newCallType, type } = this._analyzeEventData(event);
TUIStore.update(index_1.StoreName.CALL, index_1.NAME.CALL_MEDIA_TYPE, newCallType || type);
this.setSoundMode(index_1.AudioPlayBackDevice.EAR);
}
_messageSentByMe(event) {
const message = event === null || event === void 0 ? void 0 : event.data;
this.onMessageSentByMe && this.onMessageSentByMe(message);
}
// ==========================【 miniProgram 私有事件】==========================
_handleUserUpdate(event) {
const data = this._analyzeEventData(event);
(data === null || data === void 0 ? void 0 : data.pusher) && TUIStore.update(index_1.StoreName.CALL, index_1.NAME.PUSHER, data.pusher);
(data === null || data === void 0 ? void 0 : data.playerList) && TUIStore.update(index_1.StoreName.CALL, index_1.NAME.PLAYER, data.playerList);
}
// 处理 “呼叫” 抛出的异常
_handleCallError(error, methodName) {
if ((0, common_utils_1.handleRepeatedCallError)(error))
return;
(0, miniProgram_1.handlePackageError)(error); // 无套餐提示, 小程序 engine 不抛出 onError
this._noDevicePermissionToast(error, index_1.CallMediaType.AUDIO);
console.error(`${index_1.NAME.PREFIX}${methodName} failed, error: ${error}.`);
this._resetCallStore();
throw error;
}
setCallback(params) {
const { beforeCalling, afterCalling, onMinimized, onMessageSentByMe, kickedOut, statusChanged } = params;
beforeCalling && (this.beforeCalling = beforeCalling);
afterCalling && (this.afterCalling = afterCalling);
onMinimized && (this.onMinimized = onMinimized);
onMessageSentByMe && (this.onMessageSentByMe = onMessageSentByMe);
kickedOut && (this.kickedOut = kickedOut);
statusChanged && (this.statusChanged = statusChanged);
}
toggleMinimize() {
const isMinimized = TUIStore.getData(index_1.StoreName.CALL, index_1.NAME.IS_MINIMIZED);
TUIStore.update(index_1.StoreName.CALL, index_1.NAME.IS_MINIMIZED, !isMinimized);
console.log(`${index_1.NAME.PREFIX}toggleMinimize: ${isMinimized} -> ${!isMinimized}.`);
this.onMinimized && this.onMinimized(isMinimized, !isMinimized);
}
_executeExternalBeforeCalling() {
this.beforeCalling && this.beforeCalling();
}
_executeExternalAfterCalling() {
this.afterCalling && this.afterCalling();
}
// ========================【TUICallKit 组件属性设置方法】========================
setVideoDisplayMode(displayMode) {
TUIStore.update(index_1.StoreName.CALL, index_1.NAME.DISPLAY_MODE, displayMode);
}
setVideoResolution(resolution) {
return __awaiter(this, void 0, void 0, function* () {
try {
if (!resolution)
return;
TUIStore.update(index_1.StoreName.CALL, index_1.NAME.VIDEO_RESOLUTION, resolution);
yield this._tuiCallEngine.setVideoQuality(resolution);
}
catch (error) {
console.warn(`${index_1.NAME.PREFIX}setVideoResolution failed, error: ${error}.`);
}
});
}
// =========================【 miniProgram 私有公共方法】=========================
// 处理用户异常退出的情况,处理了右滑退出,以及返回退出的情况。
_handleExceptionExit() {
return __awaiter(this, void 0, void 0, function* () {
const callStatus = TUIStore.getData(index_1.StoreName.CALL, index_1.NAME.CALL_STATUS);
const callRole = TUIStore.getData(index_1.StoreName.CALL, index_1.NAME.CALL_ROLE);
// 在呼叫状态下, 被叫调用 reject主叫调用 hangup
if (callStatus === index_1.CallStatus.CALLING) {
callRole === index_1.CallRole.CALLER && (yield this.hangup());
callRole === index_1.CallRole.CALLEE && (yield this.reject());
}
// 在通话状态下, 统一调用 hangup 接口
callStatus === index_1.CallStatus.CONNECTED && (yield this.hangup());
});
}
_setLocalUserInfoAudioVideoAvailable(isAvailable, type) {
let localUserInfo = TUIStore.getData(index_1.StoreName.CALL, index_1.NAME.LOCAL_USER_INFO);
if (type === index_1.NAME.AUDIO) {
localUserInfo = Object.assign(Object.assign({}, localUserInfo), { isAudioAvailable: isAvailable });
}
if (type === index_1.NAME.VIDEO) {
localUserInfo = Object.assign(Object.assign({}, localUserInfo), { isVideoAvailable: isAvailable });
}
TUIStore.update(index_1.StoreName.CALL, index_1.NAME.LOCAL_USER_INFO, localUserInfo);
TUIStore.update(index_1.StoreName.CALL, index_1.NAME.LOCAL_USER_INFO_EXCLUDE_VOLUMN, localUserInfo);
}
_updateCallStoreBeforeCall(type, remoteUserInfoList, groupID) {
return __awaiter(this, void 0, void 0, function* () {
const callTips = groupID || TUIStore.getData(index_1.StoreName.CALL, index_1.NAME.IS_MINIMIZED) ? index_2.CallTips.CALLER_GROUP_CALLING_MSG : index_2.CallTips.CALLER_CALLING_MSG;
let updateStoreParams = {
[index_1.NAME.CALL_MEDIA_TYPE]: type,
[index_1.NAME.CALL_ROLE]: index_1.CallRole.CALLER,
[index_1.NAME.REMOTE_USER_INFO_LIST]: remoteUserInfoList,
[index_1.NAME.REMOTE_USER_INFO_EXCLUDE_VOLUMN_LIST]: remoteUserInfoList,
[index_1.NAME.IS_GROUP]: !!groupID,
[index_1.NAME.CALL_TIPS]: (0, index_2.t)(callTips),
[index_1.NAME.GROUP_ID]: groupID
};
const pusher = { enableCamera: type === index_1.CallMediaType.VIDEO, enableMic: true }; // mini 默认打开麦克风
updateStoreParams = Object.assign(Object.assign({}, updateStoreParams), { [index_1.NAME.PUSHER]: pusher });
TUIStore.updateStore(updateStoreParams, index_1.StoreName.CALL);
const callStatus = yield (0, miniProgram_1.beforeCall)(type, this); // 如果没有权限, 此时为 false. 因此需要在 call 后设置为 calling. 和 web 存在差异
console.log(`${index_1.NAME.PREFIX}mini beforeCall return callStatus: ${callStatus}.`);
TUIStore.update(index_1.StoreName.CALL, index_1.NAME.CALL_STATUS, callStatus);
const remoteUserInfoLists = yield (0, utils_1.getRemoteUserProfile)(remoteUserInfoList.map(obj => obj.userId), this.getTim(), TUIStore);
if (remoteUserInfoLists.length > 0) {
TUIStore.update(index_1.StoreName.CALL, index_1.NAME.REMOTE_USER_INFO_LIST, remoteUserInfoLists);
TUIStore.update(index_1.StoreName.CALL, index_1.NAME.REMOTE_USER_INFO_EXCLUDE_VOLUMN_LIST, remoteUserInfoLists);
}
});
}
_updateCallStoreAfterCall(userIdList, response) {
var _a;
return __awaiter(this, void 0, void 0, function* () {
if (response) {
TUIStore.update(index_1.StoreName.CALL, index_1.NAME.IS_CLICKABLE, true);
TUIStore.update(index_1.StoreName.CALL, index_1.NAME.ROOM_ID, response.roomID);
this._callTUIService({ message: (_a = response === null || response === void 0 ? void 0 : response.data) === null || _a === void 0 ? void 0 : _a.message });
response.pusher && TUIStore.update(index_1.StoreName.CALL, index_1.NAME.PUSHER, response.pusher);
const callMediaType = TUIStore.getData(index_1.StoreName.CALL, index_1.NAME.CALL_MEDIA_TYPE);
(callMediaType === index_1.CallMediaType.VIDEO) && (yield this.openCamera(index_1.NAME.LOCAL_VIDEO));
this.setSoundMode(callMediaType === index_1.CallMediaType.AUDIO ? index_1.AudioPlayBackDevice.EAR : index_1.AudioPlayBackDevice.SPEAKER);
TUIStore.update(index_1.StoreName.CALL, index_1.NAME.CALL_STATUS, index_1.CallStatus.CALLING); // 小程序未授权时, 此时状态为 idle; web 直接设置为 calling
const localUserInfo = TUIStore.getData(index_1.StoreName.CALL, index_1.NAME.LOCAL_USER_INFO);
TUIStore.update(index_1.StoreName.CALL, index_1.NAME.LOCAL_USER_INFO, Object.assign(Object.assign({}, localUserInfo), { isEnter: true }));
TUIStore.update(index_1.StoreName.CALL, index_1.NAME.LOCAL_USER_INFO_EXCLUDE_VOLUMN, Object.assign(Object.assign({}, localUserInfo), { isEnter: true }));
this._setLocalUserInfoAudioVideoAvailable(true, index_1.NAME.AUDIO); // web && mini, default open audio
}
else {
this._resetCallStore();
}
});
}
_resetCurrentDevice() {
// 挂断后,重置当前摄像头,麦克风和扬声器为默认设备
const { cameraList, microphoneList, speakerList } = TUIStore.getData(index_1.StoreName.CALL, index_1.NAME.DEVICE_LIST);
TUIStore.update(index_1.StoreName.CALL, index_1.NAME.DEVICE_LIST, { microphoneList, cameraList, speakerList,
currentCamera: (cameraList === null || cameraList === void 0 ? void 0 : cameraList[0]) || {},
currentMicrophone: (microphoneList === null || microphoneList === void 0 ? void 0 : microphoneList[0]) || {},
currentSpeaker: (speakerList === null || speakerList === void 0 ? void 0 : speakerList[0]) || {}
});
}
_resetCallStore() {
const oldStatusStr = (0, utils_1.generateStatusChangeText)(TUIStore);
this._stopTimer();
// localUserInfo, language 在通话结束后不需要清除
// callStatus 清除需要通知; isMinimized 也需要通知basic-vue3 中切小窗关闭后, 再呼叫还是小窗, 因此需要通知到组件侧)
// isGroup 也不清除(engine 先抛 cancel 事件, 再抛 reject 事件)
// displayMode、videoResolution 也不能清除, 组件不卸载, 这些属性也需保留, 否则采用默认值.
// enableFloatWindow 不清除:开启/关闭悬浮窗功能。
let notResetOrNotifyKeys = Object.keys(index_1.CALL_DATA_KEY).filter((key) => {
switch (index_1.CALL_DATA_KEY[key]) {
case index_1.NAME.CALL_STATUS:
case index_1.NAME.LANGUAGE:
case index_1.NAME.IS_GROUP:
case index_1.NAME.DISPLAY_MODE:
case index_1.NAME.VIDEO_RESOLUTION:
case index_1.NAME.ENABLE_FLOAT_WINDOW:
case index_1.NAME.LOCAL_USER_INFO:
case index_1.NAME.LOCAL_USER_INFO_EXCLUDE_VOLUMN: {
return false;
}
default: {
return true;
}
}
});
notResetOrNotifyKeys = notResetOrNotifyKeys.map(key => index_1.CALL_DATA_KEY[key]);
TUIStore.reset(index_1.StoreName.CALL, notResetOrNotifyKeys);
const callStatus = TUIStore.getData(index_1.StoreName.CALL, index_1.NAME.CALL_STATUS);
callStatus !== index_1.CallStatus.IDLE && TUIStore.reset(index_1.StoreName.CALL, [index_1.NAME.CALL_STATUS], true); // callStatus reset need notify
TUIStore.reset(index_1.StoreName.CALL, [index_1.NAME.IS_MINIMIZED], true); // isMinimized reset need notify
TUIStore.reset(index_1.StoreName.CALL, [index_1.NAME.IS_EAR_PHONE], true); // isEarPhone reset need notify
TUIStore.update(index_1.StoreName.CALL, index_1.NAME.LOCAL_USER_INFO, Object.assign(Object.assign({}, TUIStore.getData(index_1.StoreName.CALL, index_1.NAME.LOCAL_USER_INFO)), { isVideoAvailable: false, isAudioAvailable: false }));
TUIStore.update(index_1.StoreName.CALL, index_1.NAME.LOCAL_USER_INFO_EXCLUDE_VOLUMN, Object.assign(Object.assign({}, TUIStore.getData(index_1.StoreName.CALL, index_1.NAME.LOCAL_USER_INFO_EXCLUDE_VOLUMN)), { isVideoAvailable: false, isAudioAvailable: false }));
TUIStore.update(index_1.StoreName.CALL, index_1.NAME.REMOTE_USER_INFO_LIST, []);
TUIStore.update(index_1.StoreName.CALL, index_1.NAME.REMOTE_USER_INFO_EXCLUDE_VOLUMN_LIST, []);
this._resetCurrentDevice();
const newStatusStr = (0, utils_1.generateStatusChangeText)(TUIStore);
if (oldStatusStr !== newStatusStr) {
this.statusChanged && this.statusChanged({ oldStatus: oldStatusStr, newStatus: newStatusStr });
}
}
_noDevicePermissionToast(error, type) {
if ((0, common_utils_1.handleNoDevicePermissionError)(error)) {
let text = '';
if (type === index_1.CallMediaType.AUDIO) {
text = (0, utils_1.generateText)(TUIStore, index_2.CallTips.NO_MICROPHONE_DEVICE_PERMISSION);
}
if (type === index_1.CallMediaType.VIDEO) {
text = (0, utils_1.generateText)(TUIStore, index_2.CallTips.NO_CAMERA_DEVICE_PERMISSION);
}
text && TUIStore.update(index_1.StoreName.CALL, index_1.NAME.TOAST_INFO, { text, type: index_1.NAME.ERROR });
console.error(`${index_1.NAME.PREFIX}call failed, error: ${error.message}.`);
}
}
// 通话时长更新
_startTimer() {
if (this._timerId === -1) {
this._startTimeStamp = (0, common_utils_1.performanceNow)();
this._timerId = timer_1.default.run(index_1.NAME.TIMEOUT, this._updateCallDuration.bind(this), { delay: 1000 });
}
}
_updateCallDuration() {
const callDurationNum = Math.round(((0, common_utils_1.performanceNow)() - this._startTimeStamp) / 1000); // miniProgram stop timer when background
const callDurationStr = (0, common_utils_1.formatTime)(callDurationNum);
TUIStore.update(index_1.StoreName.CALL, index_1.NAME.CALL_DURATION, callDurationStr);
}
_stopTimer() {
if (this._timerId !== -1) {
timer_1.default.clearTask(this._timerId);
this._timerId = -1;
}
}
_deleteRemoteUser(userIdList) {
if (userIdList.length === 0)
return;
let remoteUserInfoList = TUIStore.getData(index_1.StoreName.CALL, index_1.NAME.REMOTE_USER_INFO_LIST);
userIdList.forEach((userId) => {
remoteUserInfoList = remoteUserInfoList.filter((obj) => obj.userId !== userId);
});
TUIStore.update(index_1.StoreName.CALL, index_1.NAME.REMOTE_USER_INFO_LIST, remoteUserInfoList);
TUIStore.update(index_1.StoreName.CALL, index_1.NAME.REMOTE_USER_INFO_EXCLUDE_VOLUMN_LIST, remoteUserInfoList);
}
_analyzeEventData(event) {
return (event === null || event === void 0 ? void 0 : event.data) || {}; // mini INVITED
}
// =========================【调用 chat api】=========================
// 获取群成员
getGroupMemberList(count, offset) {
return __awaiter(this, void 0, void 0, function* () {
const groupID = TUIStore.getData(index_1.StoreName.CALL, index_1.NAME.GROUP_ID);
let groupMemberList = yield (0, utils_1.getGroupMemberList)(groupID, this.getTim(), count, offset);
return groupMemberList;
});
}
// 获取群信息
getGroupProfile() {
return __awaiter(this, void 0, void 0, function* () {
const groupID = TUIStore.getData(index_1.StoreName.CALL, index_1.NAME.GROUP_ID);
return yield (0, utils_1.getGroupProfile)(groupID, this.getTim());
});
}
_watchTUIStore() {
TUIStore === null || TUIStore === void 0 ? void 0 : TUIStore.watch(index_1.StoreName.CALL, {
[index_1.NAME.CALL_STATUS]: this._handleCallStatusChange,
});
}
_unwatchTUIStore() {
TUIStore === null || TUIStore === void 0 ? void 0 : TUIStore.unwatch(index_1.StoreName.CALL, {
[index_1.NAME.CALL_STATUS]: this._handleCallStatusChange,
});
}
// =========================【web 融合 chat 提供的方法】=========================
bindTUICore(TUICore) {
this._TUICore = TUICore;
}
// 下面方法用于接入 TUICore
_callTUIService(params) {
const { message } = params || {};
tui_core_1.TUICore.callService({
serviceName: tui_core_1.TUIConstants.TUIChat.SERVICE.NAME,
method: tui_core_1.TUIConstants.TUIChat.SERVICE.METHOD.UPDATE_MESSAGE_LIST,
params: { message },
});
}
onNotifyEvent(eventName, subKey) {
return __awaiter(this, void 0, void 0, function* () {
try {
if (eventName === tui_core_1.TUIConstants.TUILogin.EVENT.LOGIN_STATE_CHANGED) {
if (subKey === tui_core_1.TUIConstants.TUILogin.EVENT_SUB_KEY.USER_LOGIN_SUCCESS) {
// TUICallkit 收到登录成功时执行自己的业务逻辑处理
// @ts-ignore
const { chat, userID, userSig, SDKAppID } = tui_core_1.TUILogin.getContext();
yield this.init({ tim: chat, userID, userSig, sdkAppID: SDKAppID, isFromChat: true });
}
else if (subKey === tui_core_1.TUIConstants.TUILogin.EVENT_SUB_KEY.USER_LOGOUT_SUCCESS) {
yield this.destroyed();
}
}
}
catch (error) {
console.error(`${index_1.NAME.PREFIX}TUICore onNotifyEvent failed, error: ${error}.`);
}
});
}
onCall(method, params) {
return __awaiter(this, void 0, void 0, function* () {
if (method === tui_core_1.TUIConstants.TUICalling.SERVICE.METHOD.START_CALL) {
yield this._handleTUICoreOnClick(params, params.type);
}
});
}
_handleTUICoreOnClick(options, type) {
return __awaiter(this, void 0, void 0, function* () {
try {
const { groupID, userIDList = [] } = options, rest = __rest(options, ["groupID", "userIDList"]);
if (groupID) {
yield this.groupCall(Object.assign({ groupID, userIDList, type }, rest));
}
else if (userIDList.length === 1) {
yield this.call(Object.assign({ userID: userIDList[0], type }, rest));
}
}
catch (error) {
console.debug(error);
}
});
}
onGetExtension(extensionID, params) {
if (extensionID === tui_core_1.TUIConstants.TUIChat.EXTENSION.INPUT_MORE.EXT_ID) {
const list = [];
const audioCallExtension = {
weight: 1000,
text: '语音通话',
icon: index_1.AudioCallIcon,
data: {
name: 'voiceCall',
},
listener: {
onClicked: (options) => __awaiter(this, void 0, void 0, function* () { return yield this._handleTUICoreOnClick(options, options.type || index_1.CallMediaType.AUDIO); }), // 点击时发起通话
},
};
const videoCallExtension = {
weight: 900,
text: '视频通话',
icon: index_1.VideoCallIcon,
data: {
name: 'videoCall',
},
listener: {
onClicked: (options) => __awaiter(this, void 0, void 0, function* () { return yield this._handleTUICoreOnClick(options, options.type || index_1.CallMediaType.VIDEO); }), // 点击时发起通话
},
};
if (!(params === null || params === void 0 ? void 0 : params.filterVoice)) {
list.push(audioCallExtension);
}
if (!(params === null || params === void 0 ? void 0 : params.filterVideo)) {
list.push(videoCallExtension);
}
return list;
}
}
}
__decorate([
(0, index_3.avoidRepeatedCall)(),
(0, index_3.paramValidate)(index_3.VALIDATE_PARAMS.init),
__metadata("design:type", Function),
__metadata("design:paramtypes", [Object]),
__metadata("design:returntype", Promise)
], TUICallService.prototype, "init", null);
__decorate([
(0, index_3.avoidRepeatedCall)(),
(0, index_3.paramValidate)(index_3.VALIDATE_PARAMS.call),
__metadata("design:type", Function),
__metadata("design:paramtypes", [Object]),
__metadata("design:returntype", Promise)
], TUICallService.prototype, "call", null);
__decorate([
(0, index_3.avoidRepeatedCall)(),
(0, index_3.paramValidate)(index_3.VALIDATE_PARAMS.groupCall),
__metadata("design:type", Function),
__metadata("design:paramtypes", [Object]),
__metadata("design:returntype", Promise)
], TUICallService.prototype, "groupCall", null);
__decorate([
(0, index_3.avoidRepeatedCall)(),
(0, index_3.paramValidate)(index_3.VALIDATE_PARAMS.inviteUser),
__metadata("design:type", Function),
__metadata("design:paramtypes", [Object]),
__metadata("design:returntype", Promise)
], TUICallService.prototype, "inviteUser", null);
__decorate([
(0, index_3.avoidRepeatedCall)(),
(0, index_3.paramValidate)(index_3.VALIDATE_PARAMS.joinInGroupCall),
__metadata("design:type", Function),
__metadata("design:paramtypes", [Object]),
__metadata("design:returntype", Promise)
], TUICallService.prototype, "joinInGroupCall", null);
__decorate([
(0, index_3.paramValidate)(index_3.VALIDATE_PARAMS.setLanguage),
__metadata("design:type", Function),
__metadata("design:paramtypes", [String]),
__metadata("design:returntype", void 0)
], TUICallService.prototype, "setLanguage", null);
__decorate([
(0, index_3.paramValidate)(index_3.VALIDATE_PARAMS.enableFloatWindow),
__metadata("design:type", Function),
__metadata("design:paramtypes", [Boolean]),
__metadata("design:returntype", void 0)
], TUICallService.prototype, "enableFloatWindow", null);
__decorate([
(0, index_3.paramValidate)(index_3.VALIDATE_PARAMS.setSelfInfo),
__metadata("design:type", Function),
__metadata("design:paramtypes", [Object]),
__metadata("design:returntype", Promise)
], TUICallService.prototype, "setSelfInfo", null);
__decorate([
(0, index_3.paramValidate)(index_3.VALIDATE_PARAMS.setCallingBell),
__metadata("design:type", Function),
__metadata("design:paramtypes", [String]),
__metadata("design:returntype", Promise)
], TUICallService.prototype, "setCallingBell", null);
__decorate([
(0, index_3.paramValidate)(index_3.VALIDATE_PARAMS.enableMuteMode),
__metadata("design:type", Function),
__metadata("design:paramtypes", [Boolean]),
__metadata("design:returntype", Promise)
], TUICallService.prototype, "enableMuteMode", null);
__decorate([
(0, index_3.avoidRepeatedCall)(),
__metadata("design:type", Function),
__metadata("design:paramtypes", []),
__metadata("design:returntype", Promise)
], TUICallService.prototype, "accept", null);
__decorate([
(0, index_3.avoidRepeatedCall)(),
__metadata("design:type", Function),
__metadata("design:paramtypes", []),
__metadata("design:returntype", Promise)
], TUICallService.prototype, "hangup", null);
__decorate([
(0, index_3.avoidRepeatedCall)(),
__metadata("design:type", Function),
__metadata("design:paramtypes", []),
__metadata("design:returntype", Promise)
], TUICallService.prototype, "reject", null);
__decorate([
(0, index_3.avoidRepeatedCall)(),
__metadata("design:type", Function),
__metadata("design:paramtypes", [String]),
__metadata("design:returntype", Promise)
], TUICallService.prototype, "openCamera", null);
__decorate([
(0, index_3.avoidRepeatedCall)(),
__metadata("design:type", Function),
__metadata("design:paramtypes", []),
__metadata("design:returntype", Promise)
], TUICallService.prototype, "closeCamera", null);
__decorate([
(0, index_3.avoidRepeatedCall)(),
__metadata("design:type", Function),
__metadata("design:paramtypes", []),
__metadata("design:returntype", Promise)
], TUICallService.prototype, "openMicrophone", null);
__decorate([
(0, index_3.avoidRepeatedCall)(),
__metadata("design:type", Function),
__metadata("design:paramtypes", []),
__metadata("design:returntype", Promise)
], TUICallService.prototype, "closeMicrophone", null);
__decorate([
(0, index_3.avoidRepeatedCall)(),
__metadata("design:type", Function),
__metadata("design:paramtypes", [String]),
__metadata("design:returntype", void 0)
], TUICallService.prototype, "switchScreen", null);
__decorate([
(0, index_3.avoidRepeatedCall)(),
__metadata("design:type", Function),
__metadata("design:paramtypes", []),
__metadata("design:returntype", Promise)
], TUICallService.prototype, "switchCallMediaType", null);
__decorate([
(0, index_3.avoidRepeatedCall)(),
__metadata("design:type", Function),
__metadata("design:paramtypes", []),
__metadata("design:returntype", Promise)
], TUICallService.prototype, "switchCamera", null);
__decorate([
(0, index_3.avoidRepeatedCall)(),
__metadata("design:type", Function),
__metadata("design:paramtypes", [String]),
__metadata("design:returntype", void 0)
], TUICallService.prototype, "setSoundMode", null);
__decorate([
(0, index_3.paramValidate)(index_3.VALIDATE_PARAMS.setVideoDisplayMode),
__metadata("design:type", Function),
__metadata("design:paramtypes", [String]),
__metadata("design:returntype", void 0)
], TUICallService.prototype, "setVideoDisplayMode", null);
__decorate([
(0, index_3.paramValidate)(index_3.VALIDATE_PARAMS.setVideoResolution),
__metadata("design:type", Function),
__metadata("design:paramtypes", [String]),
__metadata("design:returntype", Promise)
], TUICallService.prototype, "setVideoResolution", null);
exports.default = TUICallService;