2227 lines
113 KiB
JavaScript
2227 lines
113 KiB
JavaScript
(function(){"use strict";try{if(typeof document!="undefined"){var e=document.createElement("style");e.appendChild(document.createTextNode("")),document.head.appendChild(e)}}catch(t){console.error("vite-plugin-css-injected-by-js",t)}})();
|
||
import { TUICallEvent as C, TUICallEngine as Re, devicePermissions as Ne } from "@trtc/call-engine-lite-wx";
|
||
import { TUICore as X, TUIConstants as B, TUILogin as $e } from "@tencentcloud/tui-core-lite";
|
||
import Te from "@tencentcloud/lite-chat/basic";
|
||
var s = /* @__PURE__ */ ((n) => (n.CALL = "call", n.CUSTOM = "custom", n))(s || {}), d = /* @__PURE__ */ ((n) => (n[n.UNKNOWN = 0] = "UNKNOWN", n[n.AUDIO = 1] = "AUDIO", n[n.VIDEO = 2] = "VIDEO", n))(d || {}), p = /* @__PURE__ */ ((n) => (n.UNKNOWN = "unknown", n.CALLEE = "callee", n.CALLER = "caller", n))(p || {}), h = /* @__PURE__ */ ((n) => (n.IDLE = "idle", n.CALLING = "calling", n.CONNECTED = "connected", n))(h || {}), me = /* @__PURE__ */ ((n) => (n.CONTAIN = "contain", n.COVER = "cover", n.FILL = "fill", n))(me || {}), Ve = /* @__PURE__ */ ((n) => (n.RESOLUTION_480P = "480p", n.RESOLUTION_720P = "720p", n.RESOLUTION_1080P = "1080p", n))(Ve || {});
|
||
const G = {
|
||
IDLE: "idle",
|
||
BE_INVITED: "be-invited",
|
||
DIALING_C2C: "dialing-c2c",
|
||
DIALING_GROUP: "dialing-group",
|
||
CALLING_C2C_AUDIO: "calling-c2c-audio",
|
||
CALLING_C2C_VIDEO: "calling-c2c-video",
|
||
CALLING_GROUP_AUDIO: "calling-group-audio",
|
||
CALLING_GROUP_VIDEO: "calling-group-video"
|
||
}, et = {
|
||
unknown: 0,
|
||
audio: 1,
|
||
video: 2
|
||
/* VIDEO */
|
||
};
|
||
var M = /* @__PURE__ */ ((n) => (n.EAR = "ear", n.SPEAKER = "speaker", n))(M || {}), V = /* @__PURE__ */ ((n) => (n[n.FRONT = 0] = "FRONT", n[n.BACK = 1] = "BACK", n))(V || {}), x = /* @__PURE__ */ ((n) => (n.Camera = "camera", n.Microphone = "microphone", n.SwitchCamera = "switchCamera", n.InviteUser = "inviteUser", n))(x || {}), ee = /* @__PURE__ */ ((n) => (n.Open = "open", n.Close = "close", n))(ee || {}), Ke = /* @__PURE__ */ ((n) => (n.LocalInLargeView = "local", n.RemoteInLargeView = "remote", n))(Ke || {}), Y = /* @__PURE__ */ ((n) => (n[n.INVITE = 1] = "INVITE", n[n.CANCEL_INVITE = 2] = "CANCEL_INVITE", n[n.ACCEPT_INVITE = 3] = "ACCEPT_INVITE", n[n.REJECT_INVITE = 4] = "REJECT_INVITE", n[n.INVITE_TIMEOUT = 5] = "INVITE_TIMEOUT", n))(Y || {});
|
||
const we = {
|
||
SWITCH_TO_AUDIO_CALL_FAILED: 60001,
|
||
SWITCH_TO_VIDEO_CALL_FAILED: 60002,
|
||
MICROPHONE_UNAVAILABLE: 60003,
|
||
CAMERA_UNAVAILABLE: 60004,
|
||
BAN_DEVICE: 60005,
|
||
NOT_SUPPORTED_WEBRTC: 60006,
|
||
ERROR_BLACKLIST: 20007
|
||
}, pe = {
|
||
SWITCH_TO_AUDIO_CALL_FAILED: "switchToAudioCall-call-failed",
|
||
SWITCH_TO_VIDEO_CALL_FAILED: "switchToVideoCall-call-failed",
|
||
MICROPHONE_UNAVAILABLE: "microphone-unavailable",
|
||
CAMERA_UNAVAILABLE: "camera-unavailable",
|
||
BAN_DEVICE: "ban-device",
|
||
NOT_SUPPORTED_WEBRTC: "not-supported-webrtc",
|
||
ERROR_BLACKLIST: "blacklist-user-tips"
|
||
};
|
||
var be = /* @__PURE__ */ ((n) => (n[n.NORMAL = 0] = "NORMAL", n[n.RELEASE = 1] = "RELEASE", n[n.WARNING = 2] = "WARNING", n[n.ERROR = 3] = "ERROR", n[n.NONE = 4] = "NONE", n))(be || {});
|
||
const re = {
|
||
CALL_STATUS: "callStatus",
|
||
CALL_ROLE: "callRole",
|
||
CALL_MEDIA_TYPE: "callMediaType",
|
||
LOCAL_USER_INFO: "localUserInfo",
|
||
LOCAL_USER_INFO_EXCLUDE_VOLUMN: "localUserInfoExcludeVolume",
|
||
REMOTE_USER_INFO_LIST: "remoteUserInfoList",
|
||
REMOTE_USER_INFO_EXCLUDE_VOLUMN_LIST: "remoteUserInfoExcludeVolumeList",
|
||
CALLER_USER_INFO: "callerUserInfo",
|
||
IS_GROUP: "isGroup",
|
||
CALL_DURATION: "callDuration",
|
||
CALL_TIPS: "callTips",
|
||
TOAST_INFO: "toastInfo",
|
||
IS_MINIMIZED: "isMinimized",
|
||
ENABLE_FLOAT_WINDOW: "enableFloatWindow",
|
||
BIG_SCREEN_USER_ID: "bigScreenUserId",
|
||
LANGUAGE: "language",
|
||
IS_CLICKABLE: "isClickable",
|
||
DISPLAY_MODE: "displayMode",
|
||
VIDEO_RESOLUTION: "videoResolution",
|
||
PUSHER: "pusher",
|
||
PLAYER: "player",
|
||
IS_EAR_PHONE: "isEarPhone",
|
||
IS_MUTE_SPEAKER: "isMuteSpeaker",
|
||
SHOW_PERMISSION_TIP: "SHOW_PERMISSION_TIP",
|
||
NETWORK_STATUS: "NetWorkStatus",
|
||
CALL_ID: "callID",
|
||
GROUP_ID: "groupID",
|
||
ROOM_ID: "roomID",
|
||
ROOM_ID_TYPE: "roomIdType",
|
||
SHOW_SELECT_USER: "showSelectUser",
|
||
IS_SHOW_ENABLE_VIRTUAL_BACKGROUND: "isShowEnableVirtualBackground",
|
||
ENABLE_VIRTUAL_BACKGROUND: "enableVirtualBackground",
|
||
GROUP_CALL_MEMBERS: "groupCallMembers",
|
||
PUSHER_ID: "pusherId",
|
||
IS_FORCE_USE_V2_API: "isForceUseV2API"
|
||
}, tt = {
|
||
INNER_ATTR_KIT_INFO: "inner_attr_kit_info"
|
||
}, it = {
|
||
INITIAL_PUSHER: "initialPusher",
|
||
NEW_PUSHER: "newPusher"
|
||
}, a = {
|
||
PREFIX: "【CallService】",
|
||
AUDIO: "audio",
|
||
VIDEO: "video",
|
||
LOCAL_VIDEO: "localVideo",
|
||
ERROR: "error",
|
||
TIMEOUT: "timeout",
|
||
RAF: "raf",
|
||
INTERVAL: "interval",
|
||
DEFAULT: "default",
|
||
BOOLEAN: "boolean",
|
||
STRING: "string",
|
||
NUMBER: "number",
|
||
OBJECT: "object",
|
||
ARRAY: "array",
|
||
FUNCTION: "function",
|
||
UNDEFINED: "undefined",
|
||
UNKNOWN: "unknown",
|
||
ALL: "all",
|
||
MYSELF: "myself",
|
||
DEVICE_LIST: "deviceList",
|
||
CAMERA_POSITION: "cameraPosition",
|
||
CUSTOM_UI_CONFIG: "customUIConfig",
|
||
TRANSLATE: "translate",
|
||
...it,
|
||
...re,
|
||
...tt
|
||
}, at = "https://web.sdk.qcloud.com/component/TUIKit/assets/call.png", At = "https://web.sdk.qcloud.com/component/TUIKit/assets/call-video-reverse.svg", Fe = 4;
|
||
var de = /* @__PURE__ */ ((n) => (n[n.TUI_CALL_KIT = 14] = "TUI_CALL_KIT", n[n.TIM_CALL_KIT = 15] = "TIM_CALL_KIT", n))(de || {}), _e = /* @__PURE__ */ ((n) => (n[n.NUMBER_ROOM_ID = 1] = "NUMBER_ROOM_ID", n[n.STRING_ROOM_ID = 2] = "STRING_ROOM_ID", n))(_e || {});
|
||
function nt() {
|
||
wx.hideKeyboard && wx.hideKeyboard({
|
||
complete: () => {
|
||
}
|
||
});
|
||
}
|
||
function st() {
|
||
wx.getSystemInfoSync().platform === "devtools" && wx.showModal({
|
||
icon: "none",
|
||
title: "运行环境提醒",
|
||
content: "微信开发者工具不支持原生推拉流组件(即 <live-pusher> 和 <live-player> 标签),请使用真机调试或者扫码预览。",
|
||
showCancel: !1
|
||
});
|
||
}
|
||
function ke() {
|
||
nt(), st();
|
||
}
|
||
async function rt(n, e) {
|
||
try {
|
||
ke();
|
||
const t = {
|
||
microphone: !0,
|
||
camera: n === d.VIDEO
|
||
};
|
||
return await e._tuiCallEngine.deviceCheck(t) ? h.CALLING : h.IDLE;
|
||
} catch (t) {
|
||
return console.debug(t), h.IDLE;
|
||
}
|
||
}
|
||
function ot(n) {
|
||
(n == null ? void 0 : n.code) === -1002 && wx.showModal({
|
||
icon: "none",
|
||
title: "error",
|
||
content: (n == null ? void 0 : n.message) || "",
|
||
showCancel: !1
|
||
});
|
||
}
|
||
function lt() {
|
||
wx.showModal({
|
||
icon: "none",
|
||
title: "权限提示",
|
||
content: "当前小程序 appid 不具备 <live-pusher> 和 <live-player> 的使用权限,您将无法正常使用实时通话能力,请使用企业小程序账号申请权限后再进行开发体验",
|
||
showCancel: !1
|
||
});
|
||
}
|
||
const ct = {
|
||
// 按钮文案
|
||
hangup: "挂断",
|
||
reject: "拒绝",
|
||
accept: "接受",
|
||
camera: "摄像头",
|
||
microphone: "麦克风",
|
||
speaker: "扬声器",
|
||
"open camera": "打开摄像头",
|
||
"close camera": "关闭摄像头",
|
||
"open microphone": "打开麦克风",
|
||
"close microphone": "关闭麦克风",
|
||
"video-to-audio": "转语音通话",
|
||
"virtual-background": "模糊背景",
|
||
// 通话结果
|
||
"other side reject call": "对方已拒绝",
|
||
"reject call": "{{ userList }} 拒绝通话",
|
||
cancel: "取消通话",
|
||
"other side line busy": "对方忙线",
|
||
"in busy": "{{ userList }} 正在忙",
|
||
"call timeout": "呼叫超时",
|
||
"end call": "{{ userList }} 结束通话",
|
||
// 通话提示语
|
||
"caller calling message": "等待对方接受邀请",
|
||
"callee calling video message": "邀请你视频通话",
|
||
"callee calling audio message": "邀请你语音通话",
|
||
"no microphone access": "没有麦克风权限",
|
||
"no camera access": "没有摄像头权限",
|
||
"invite member": "邀请成员",
|
||
"Invited group call": "邀请你加入多人通话",
|
||
"Those involved": "参与通话的有:",
|
||
waiting: "等待接听...",
|
||
me: "(我)",
|
||
// 弹出层文案
|
||
"browser-authorization": "浏览器授权",
|
||
"mac-privacy": "系统偏好设置 -> 安全与隐私 -> 隐私",
|
||
"win-privacy": "设置 -> 隐私和安全性 -> 应用权限",
|
||
"mac-preferences": "打开系统偏好设置",
|
||
"win-preferences": "打开系统设置",
|
||
"Please enter userID": "请输入 userID",
|
||
"View more": "查看更多",
|
||
"people selected": "人已选中",
|
||
"Select all": "全选",
|
||
Cancel: "取消",
|
||
Done: "完成",
|
||
"exist group call": "当前群组中已经存在群组通话",
|
||
// UI3.0 新增
|
||
"camera enabled": "摄像头已开",
|
||
"camera disabled": "摄像头已关",
|
||
"microphone enabled": "麦克风已开",
|
||
"microphone disabled": "麦克风已关",
|
||
"speaker enabled": "扬声器已开",
|
||
"speaker disabled": "扬声器已关",
|
||
"open speaker": "开启扬声器",
|
||
"close speaker": "关闭扬声器",
|
||
"wait to be called": "等待接听",
|
||
answered: "已接通",
|
||
"people in the call": "人参与通话",
|
||
"failed to obtain speakers": "无法获取扬声器",
|
||
"you have a new call": "您有一个新的通话",
|
||
"switch camera": "翻转",
|
||
join: "加入",
|
||
"people on the call": "人正在通话",
|
||
"Supports a maximum of 9 people for simultaneous calls": "最多支持9人同时通话",
|
||
you: "(你)",
|
||
"The network is poor during your current call": "当前通话你的网络不佳",
|
||
"The other user network is poor during the current call": "当前通话对方网络不佳",
|
||
"TUICallKit init is not complete": "TUICallKit 初始化登录未完成,需要在 init 完成后使用此 API",
|
||
// combine chat
|
||
"Video call": "发起视频通话",
|
||
"Voice call": "发起语音通话",
|
||
"Call End": "通话结束",
|
||
"Switch voice call": "切换语音通话",
|
||
"Switch video call": "切换视频通话",
|
||
"Call duration": "通话时长",
|
||
"Call Cancel": "已取消",
|
||
"Other Side Cancel": "对方已取消",
|
||
Decline: "已拒绝",
|
||
"Other Side Decline": "对方已拒绝",
|
||
"No answer": "超时无应答",
|
||
"Other Side No Answer": "对方无应答",
|
||
Answered: "已接听",
|
||
"Other Side Line Busy": "对方忙线中",
|
||
"Line Busy": "忙线无应答",
|
||
// 待废弃文案
|
||
timeout: "{{ userList }} 超时",
|
||
"kick out": "被踢",
|
||
call: "通话",
|
||
"video-call": "视频通话",
|
||
"audio-call": "音频通话",
|
||
search: "搜索",
|
||
"search-result": "搜索结果",
|
||
"Wechat scan right QR code": "微信扫右二维码",
|
||
"Use-phone-and-computer": "用手机与电脑互打体验视频通话",
|
||
"Scan the QR code above": "扫描上方二维码",
|
||
"no-user": "未搜索到用户",
|
||
"member-not-added": "未添加成员",
|
||
"not-login": "未登录",
|
||
"login-status-expire": "登录状态已失效,请刷新网页重试",
|
||
"experience-multi-call": "体验多人通话请下载全功能demo:",
|
||
"not-support-multi-call": "多人通话接口未开放",
|
||
"input-phone-userID": "请输入手机号/用户ID",
|
||
userID: "用户ID",
|
||
"already-enter": "已经进入当前通话",
|
||
"image-resolution": "分辨率",
|
||
"default-image-resolution": "默认分辨率",
|
||
"invited-person": "添加成员",
|
||
"be-rejected": "对方已拒绝,",
|
||
"be-no-response": "对方无应答,",
|
||
"be-line-busy": "对方忙线中,",
|
||
"be-canceled": "对方已取消",
|
||
"voice-call-end": "语音通话结束",
|
||
"video-call-end": "视频通话结束",
|
||
"method-call-failed": "同步操作失败",
|
||
"failed-to-obtain-permission": "权限获取失败",
|
||
"environment-detection-failed": "环境检测失败",
|
||
"switchToAudioCall-call-failed": "切语音调用失败",
|
||
"switchToVideoCall-call-failed": "切视频调用失败",
|
||
"microphone-unavailable": "没有可用的麦克风设备",
|
||
"camera-unavailable": "没有可用的摄像头设备",
|
||
"ban-device": "用户禁止使用设备",
|
||
"not-supported-webrtc": "当前环境不支持 WebRTC",
|
||
"blacklist-user-tips": "发起通话失败,被对方拉入黑名单,禁止发起!",
|
||
"is-already-calling": "TUICallKit 已在通话状态",
|
||
"need-init": "TUICallKit 发起通话前需保证 TUICallKitAPI.init() 方法执行成功",
|
||
"can't call yourself": "不能呼叫自己",
|
||
// eslint-disable-line
|
||
"accept-error": "接通失败",
|
||
"accept-device-error": "接通失败,通话设备获取失败",
|
||
"call-error": "发起通话失败"
|
||
}, ce = typeof wx < "u" && typeof wx.getSystemInfoSync == "function" && !!wx.getSystemInfoSync().fontSizeSetting, Ye = typeof uni < "u" && typeof uni > "u", Ge = ce || Ye, He = typeof uni < "u", xe = function() {
|
||
return (typeof uni < "u" || typeof window < "u") && !Ge;
|
||
}(), It = function() {
|
||
return ce ? wx : He ? uni : window;
|
||
}(), y = xe && window && window.navigator && window.navigator.userAgent || "", Ct = /Android/i.test(y), Et = /(?:Windows Phone)/.test(y), Lt = /(?:SymbianOS)/.test(y), ut = /iPad/i.test(y) || /iPhone/i.test(y) || /iPod/i.test(y), Je = Ct || Et || Lt || ut, fe = xe && !Je, ht = fe && y.includes("Windows NT"), gt = fe && y.includes("Mac");
|
||
let We = class j {
|
||
constructor() {
|
||
this.global = It, this.isPC = !1, this.isH5 = !1, this.isWeChat = !1, this.isApp = !1, this.isUniPlatform = !1, this.isOfficial = !1, this.isWIN = !1, this.isMAC = !1, this.initEnv();
|
||
}
|
||
/**
|
||
* 获取 TUIGlobal 实例
|
||
* @returns {TUIGlobal}
|
||
*/
|
||
static getInstance() {
|
||
return j.instance || (j.instance = new j()), j.instance;
|
||
}
|
||
initEnv() {
|
||
this.isPC = fe, this.isH5 = Je, this.isWeChat = ce, this.isApp = Ye && !ce, this.isUniPlatform = He, this.isWIN = ht, this.isMAC = gt;
|
||
}
|
||
initOfficial(e) {
|
||
this.isOfficial = e === 1400187352 || e === 1400188366;
|
||
}
|
||
};
|
||
const De = function(n) {
|
||
return typeof n === a.UNDEFINED;
|
||
}, Se = function(n) {
|
||
if (typeof n !== a.OBJECT || n === null)
|
||
return !1;
|
||
const e = Object.getPrototypeOf(n);
|
||
if (e === null)
|
||
return !0;
|
||
let t = e;
|
||
for (; Object.getPrototypeOf(t) !== null; )
|
||
t = Object.getPrototypeOf(t);
|
||
return e === t;
|
||
}, ze = function(n) {
|
||
return typeof n === a.STRING;
|
||
}, _t = function(n) {
|
||
return typeof n === a.BOOLEAN;
|
||
}, dt = function(n) {
|
||
return (
|
||
// eslint-disable-next-line
|
||
n !== null && (typeof n === a.NUMBER && !isNaN(n - 0) || typeof n === a.OBJECT && n.constructor === Number)
|
||
);
|
||
};
|
||
function Xe(n) {
|
||
const e = Math.floor(n / 3600), t = Math.floor(n % 3600 / 60), i = Math.floor(n % 60);
|
||
let A = e > 9 ? `${e}` : `0${e}`;
|
||
return A += t > 9 ? `:${t}` : `:0${t}`, A += i > 9 ? `:${i}` : `:0${i}`, A;
|
||
}
|
||
function ft(n) {
|
||
if (typeof n === a.STRING)
|
||
try {
|
||
return !!JSON.parse(n);
|
||
} catch (e) {
|
||
return console.debug(e), !1;
|
||
}
|
||
return !1;
|
||
}
|
||
const Ae = function(n) {
|
||
return !n || !ft(n) ? n : JSON.parse(n);
|
||
};
|
||
function Me(n) {
|
||
var e;
|
||
return ((e = n == null ? void 0 : n.message) == null ? void 0 : e.indexOf("is ongoing, please avoid repeated calls")) !== -1;
|
||
}
|
||
function Dt(n) {
|
||
const { message: e } = n;
|
||
return (e == null ? void 0 : e.indexOf("NotAllowedError: Permission denied")) !== -1;
|
||
}
|
||
function Le() {
|
||
return Date.now();
|
||
}
|
||
const oe = function(n) {
|
||
return typeof n === a.FUNCTION;
|
||
}, St = () => {
|
||
if (We.getInstance().isWeChat)
|
||
return "zh-cn";
|
||
const n = ((navigator == null ? void 0 : navigator.language) || (navigator == null ? void 0 : navigator.userLanguage) || "").substr(0, 2);
|
||
let e = "en";
|
||
switch (n) {
|
||
case "zh":
|
||
e = "zh-cn";
|
||
break;
|
||
case "ja":
|
||
e = "ja_JP";
|
||
break;
|
||
default:
|
||
e = "en";
|
||
}
|
||
return e;
|
||
};
|
||
function Ut(n, e) {
|
||
return n.replace(/{{\s*(\w+)(\s*,\s*[^}]+)?\s*}}/g, (t, i) => {
|
||
const A = i.trim();
|
||
return e[A] !== void 0 ? String(e[A]) : t;
|
||
});
|
||
}
|
||
const N = {
|
||
OTHER_SIDE: "other side",
|
||
CANCEL: "cancel",
|
||
OTHER_SIDE_REJECT_CALL: "other side reject call",
|
||
REJECT_CALL: "reject call",
|
||
OTHER_SIDE_LINE_BUSY: "other side line busy",
|
||
IN_BUSY: "in busy",
|
||
CALL_TIMEOUT: "call timeout",
|
||
END_CALL: "end call",
|
||
TIMEOUT: "timeout",
|
||
KICK_OUT: "kick out",
|
||
CALLER_CALLING_MSG: "caller calling message",
|
||
CALLER_GROUP_CALLING_MSG: "wait to be called",
|
||
CALLEE_CALLING_VIDEO_MSG: "callee calling video message",
|
||
CALLEE_CALLING_AUDIO_MSG: "callee calling audio message",
|
||
NO_MICROPHONE_DEVICE_PERMISSION: "no microphone access",
|
||
NO_CAMERA_DEVICE_PERMISSION: "no camera access",
|
||
EXIST_GROUP_CALL: "exist group call",
|
||
LOCAL_NETWORK_IS_POOR: "The network is poor during your current call",
|
||
REMOTE_NETWORK_IS_POOR: "The other user network is poor during the current call"
|
||
}, k = {
|
||
"zh-cn": ct
|
||
};
|
||
function ie(n) {
|
||
var i, A;
|
||
const e = c.getData(s.CALL, a.LANGUAGE);
|
||
let t = "";
|
||
if (ze(n))
|
||
t = ((i = k == null ? void 0 : k[e]) == null ? void 0 : i[n]) || "";
|
||
else if (Se(n)) {
|
||
const { key: r, options: o } = n;
|
||
t = ((A = k == null ? void 0 : k[e]) == null ? void 0 : A[r]) || "", t = Ut(t, o);
|
||
}
|
||
return t;
|
||
}
|
||
const Bt = "data:audio/mpeg;base64,SUQzAwAAAAAAGFRYWFgAAAAOAAAAVFhYWABpc29taXNvMv/zNGQAAqwAvnihCAADQAF4CUAQAFYAg3Lh8u+XUD5///wx//wQOAhKAgb/////xOoH4g8Hz4Pq8RoAbdTgMsMt9hcb990EP//zNGQQBPDjEgDItAAFWcIoAYoQAN9P/03QQ//umn//91SXL5uXP+pf8WYTvzgJPAQ+p/7f///1//6f///WH///F4BtJhNFkP/zNGQGA/jjNADHiAAEQDJcAYkQAGWrn6vw6ljfPtj/////////9Pv9sL/mL/QezSepgwrimv07//////y3u602OiyhOYb+LP/zNGQIBKTBKADoCACDoCZMAckAAKHKCUIAFsqGZXtSZ/////////Sn/Vy3nVUOJBqSX2UAkQxBddzv//////yq3lcgaTmTQ//zNGQHA9SrJgA8AliD4C5IAApYAKh3FKlMunKHm8H/2//77vkdqB2xfsXaHiDKBGtFKqONF3/////Z9VXClT5ND+syHkjBq//zNGQLBITJIAA8AmQEiDI4AAjSAGa1Vffm3ff/1/0//11tvZpAaIw3dBiIrjJgHQrGVWmdBU1f/////oDqEKrV1OpBUTjQtv/zNGQHAsjDKAAwAl4D0Co8AAmCBHIQNtld6fm0+/VigZzuMnGZlkAMLMJFv/////33UIWeFQkKsaceBsangecHzYXKI//////zNGQUA4QjKAA3CAID8CpEABMCBPfuStx4FQVHYMgKcO6jIJh//////9uIlspQkGQ2YyZscAV83Bv/////ncL6BEiWHyA2K//zNEQbAogfJgAx5hAEwDJcCAsEBtICgF3/////WJaIuuqMCCVGucgkrtwiwBO//////pW4YFRWQhaRRhZZnVwGhf////+ocv/zNEQmApgVJAANjwAFkC5YCApeAolD4kQb+EQJYNKwLWGmc6sqMBwJvf////6tDEOWDgFJk1VywKMGoM2f////+N1JmgJuPv/zNGQuA4AbJAAl5hIDwC48AAIGBEho7wTL5b6kSO7IUAA5uDABYNNjGDBSJEN//////xtQsszVy27IcWBbQkLgzv7YmZYW///zNGQ2AqzFNAgcA1+D8CZIAAhMAP/3/rozCAsBjIqCY/DBWMfQZp1f/////0F6phXSNisgAJjo6icT2vpvM/Vf9v///97eu//z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", ve = "data:audio/mpeg;base64,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//BP/+hwIa///Nf///wqXf/1IwFkb//wi3/1Pf/7FEQGAABjEVkFKKAADSOrIKOcAAKAUWQYooAAUpGswwRwAF//QA7//6iH/7//E1CP66uDpoqjowL/6/GGwzFQx/T3Vp/9XC73/yvuUKYdmmN6evmjf5L5ZKr/8hlL/f/7FGQCgAB5FF2GBKAADYOrUMEIAAGod2YcVoAANI6rg4pQAEZrqH8GxT/UqjT/+aDlf/6dvj/r/4+rR//UH//+wTMuo///86//9QGR//+wCCxv//+MCD//BP//oAIP///7FGQFAABgEdsNFKAAC2I68KOcAAMggWoYVQAAP46tAwQgAMzq//QwCv//4WM/+a0//YWHBbCL/5Hi/IAIkheLBSvsvr6F98kyv/4Zg7A3/0+pcfN//8bL5ar/+8wV/v/7FGQCgACDFF0GFKAADkQLYMCIAAGod2occoAANg7rw4pQAKbXi7oTBez1IPl9X/4G2b//1b7/r6/a/Gy//6HAX//+gDAv///nHf/xoBf//hF////ILP0V//lQuP//qP/7FGQDj/BVHVmBQC2QC6O6wDQHsgGEd2gUI4AAMA7sAopQAE8l+F//2DK3//y4f+Bj5j/+oX//8FpP///x0n//GAf//8Kf///xIcrp/ZHCA4SBM2nH8U7C55TDl+3X6P/7FGQKAADZI1uGFOAAEoRrMMKUAAGQd24cUQAANQ7sQ44gAHOZwyYabiX/9COkKb/T6rj9/09fUt+LGTgn/8YALf/+g43///kFf/zgX///UK////hxPTX/+4Sz//+sR//7FGQEA7BbHdmBoC2QDSEL3gADCQGgAXyUIQAAMw7rwpRwAK/hAeAAAAdAAAAAHQz///6wB/xxxyrjsayv6H/+r/+aBD//+Nm///8QulX+1VhmOIUu/+2UD0jR2CVfp//7FGQIgADVI1uGCOACD+RrYMCIAAGcd2ocE4AAMw7sQ4RQAGP+f8eIEjMMke//iRoP//tvp+v/Unyv4pqf/5n//84CQx///0FRv/+K///C3///6gKLdKr//EJ//9QHx//7FGQED/BSHdkBQBWQC4PKwCgHsgFYR2wUI4AANA7sAopQAD5hv/6Br//+SDvyge2n/+gP//8ISf/w9t//oDv//8K///8ggL6a+nTBTVf043E0UOgZIIdw1v/9FHfE3//7FGQLAADO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";
|
||
class Ot {
|
||
constructor() {
|
||
this._bellContext = null, this._isMuteBell = !1, this._calleeBellFilePath = ve, this._callRole = p.UNKNOWN, this._callStatus = h.IDLE, this._isPlaying = !1, this._handleAudioInterruptionBegin = async () => {
|
||
await this.stop();
|
||
}, this._handleAudioInterruptionEnd = async () => {
|
||
this._callStatus !== h.CALLING ? await this.stop() : this._delayCallback(async () => {
|
||
this._callStatus === h.CALLING && !this._isPlaying && await this.play();
|
||
}, 100);
|
||
}, this._bellContext = wx.createInnerAudioContext({ useWebAudioImplement: !1 }), this._addListenBellContextEvent(), this._bellContext.loop = !0;
|
||
}
|
||
setBellSrc() {
|
||
const e = wx.getFileSystemManager();
|
||
try {
|
||
let t = Bt;
|
||
this._callRole === p.CALLEE && (t = this._calleeBellFilePath || ve), e.readFileSync(t, "utf8", 0), this._bellContext.src = t;
|
||
} catch (t) {
|
||
console.warn(`${a.PREFIX}Failed to setBellSrc, ${t}`);
|
||
}
|
||
}
|
||
setBellProperties(e) {
|
||
this._callRole = e.callRole || this._callRole, this._callStatus = e.callStatus || this._callStatus, this._calleeBellFilePath = e.calleeBellFilePath || this._calleeBellFilePath, this._isMuteBell = De(e.isMuteBell) ? this._isMuteBell : e.isMuteBell;
|
||
}
|
||
async play() {
|
||
try {
|
||
if (this._callStatus !== h.CALLING)
|
||
return;
|
||
if (this._callStatus !== h.CALLING || this._isPlaying) {
|
||
console.warn(`${a.PREFIX}play skipped, callStatus: ${this._callStatus}, isPlaying: ${this._isPlaying}`);
|
||
return;
|
||
}
|
||
if (this._isPlaying = !0, this.setBellSrc(), this._callRole === p.CALLEE && !this._isMuteBell) {
|
||
if (!this._isPlaying || this._callStatus !== h.CALLING)
|
||
return;
|
||
await this._bellContext.play();
|
||
return;
|
||
}
|
||
if (this._callRole === p.CALLER) {
|
||
if (!this._isPlaying || this._callStatus !== h.CALLING)
|
||
return;
|
||
await this._bellContext.play();
|
||
return;
|
||
}
|
||
} catch (e) {
|
||
console.warn(`${a.PREFIX}Failed to play audio file, ${e}`);
|
||
}
|
||
}
|
||
async stop() {
|
||
try {
|
||
this._isPlaying = !1, this._bellContext && (this._bellContext.pause(), await this._delay(100), this._bellContext.stop(), this._bellContext.src = "", await this._delay(100));
|
||
} catch (e) {
|
||
console.warn(`${a.PREFIX}Failed to stop audio file, ${e}`);
|
||
}
|
||
}
|
||
async setBellMute(e) {
|
||
this._callStatus !== h.CALLING && this._callRole !== p.CALLEE || (e ? await this.stop() : await this.play());
|
||
}
|
||
destroy() {
|
||
try {
|
||
this._isMuteBell = !1, this._calleeBellFilePath = "", this._callRole = p.UNKNOWN, this._callStatus = h.IDLE, this._isPlaying = !1, this == null || this._removeListenBellContextEvent(), this._bellContext.destroy(), this._bellContext = null;
|
||
} catch (e) {
|
||
console.warn(`${a.PREFIX}Failed to destroy, ${e}`);
|
||
}
|
||
}
|
||
_delay(e) {
|
||
return new Promise((t) => setTimeout(t, e));
|
||
}
|
||
_delayCallback(e, t) {
|
||
setTimeout(e, t);
|
||
}
|
||
_addListenBellContextEvent() {
|
||
this._bellContext.onPlay(() => {
|
||
var e, t;
|
||
this._isPlaying || ((e = this._bellContext) == null || e.pause(), (t = this._bellContext) == null || t.stop());
|
||
}), wx.onAudioInterruptionBegin(this._handleAudioInterruptionBegin), wx.onAudioInterruptionEnd(this._handleAudioInterruptionEnd);
|
||
}
|
||
_removeListenBellContextEvent() {
|
||
wx.offAudioInterruptionBegin(this._handleAudioInterruptionBegin), wx.offAudioInterruptionEnd(this._handleAudioInterruptionEnd);
|
||
}
|
||
}
|
||
function T() {
|
||
return function(n, e, t) {
|
||
const i = t.value, A = /* @__PURE__ */ new Set();
|
||
return t.value = async function(...r) {
|
||
var o, I;
|
||
if (A.has(this)) {
|
||
console.warn(`${a.PREFIX}previous ${e}() is ongoing, please avoid repeated calls`), (I = (o = this == null ? void 0 : this.getTUICallEngineInstance()) == null ? void 0 : o.reportLog) == null || I.call(o, {
|
||
name: "TUICallKit.avoidRepeatedCall.fail",
|
||
data: { name: e },
|
||
error: `previous ${e}() is ongoing`
|
||
});
|
||
return;
|
||
}
|
||
try {
|
||
A.add(this);
|
||
const l = await i.apply(this, r);
|
||
return A.delete(this), l;
|
||
} catch (l) {
|
||
throw A.delete(this), l;
|
||
}
|
||
}, t.value.clearCallState = function(r) {
|
||
A.delete(r);
|
||
}, t;
|
||
};
|
||
}
|
||
function Ie(n) {
|
||
if (typeof n != "object" || n === null)
|
||
return n;
|
||
let e = Array.isArray(n) ? [] : {};
|
||
for (let t in n)
|
||
n.hasOwnProperty(t) && (e[t] = Ie(n[t]));
|
||
return e;
|
||
}
|
||
class Rt {
|
||
constructor() {
|
||
this.defaultStore = {
|
||
callStatus: h.IDLE,
|
||
callRole: p.UNKNOWN,
|
||
callMediaType: d.UNKNOWN,
|
||
localUserInfo: { userId: "" },
|
||
localUserInfoExcludeVolume: { userId: "" },
|
||
remoteUserInfoList: [],
|
||
remoteUserInfoExcludeVolumeList: [],
|
||
callerUserInfo: { userId: "" },
|
||
isGroup: !1,
|
||
callDuration: "00:00:00",
|
||
// 通话时长
|
||
callTips: "",
|
||
// 通话提示的信息. 例如: '等待谁接听', 'xxx 拒绝通话', 'xxx 挂断通话'
|
||
toastInfo: { text: "" },
|
||
// 远端用户挂断、拒绝、超时、忙线等的 toast 提示信息
|
||
isMinimized: !1,
|
||
// 用来记录当前是否悬浮窗模式
|
||
enableFloatWindow: !1,
|
||
// 开启/关闭悬浮窗功能,设置为false,通话界面左上角的悬浮窗按钮会隐藏
|
||
bigScreenUserId: "",
|
||
// 当前大屏幕显示的 userID 用户
|
||
language: St(),
|
||
// en, zh-cn
|
||
isClickable: !1,
|
||
// 是否可点击, 用于按钮增加 loading 效果,不可点击
|
||
deviceList: { cameraList: [], microphoneList: [], currentCamera: {}, currentMicrophone: {} },
|
||
showPermissionTip: !1,
|
||
netWorkQualityList: [],
|
||
// 显示网络状态差的提示
|
||
isMuteSpeaker: !1,
|
||
callID: "",
|
||
// callEngine 3.1 support
|
||
groupID: "",
|
||
roomID: 0,
|
||
roomIdType: 0,
|
||
cameraPosition: V.FRONT,
|
||
// 前置或后置,值为front, back
|
||
groupCallMembers: [],
|
||
// chat 群会话在的通话中的成员
|
||
// TUICallKit 组件上的属性
|
||
displayMode: me.COVER,
|
||
// 设置预览远端的画面显示模式
|
||
videoResolution: Ve.RESOLUTION_720P,
|
||
showSelectUser: !1,
|
||
// 小程序相关属性
|
||
pusher: {},
|
||
player: [],
|
||
isEarPhone: !1,
|
||
// 是否是听筒, 默认: false
|
||
pusherId: "",
|
||
// 重新渲染 live-Pusher 的标识位
|
||
// 是否开启虚拟背景, 目前仅 web 支持
|
||
isShowEnableVirtualBackground: !1,
|
||
// 是否显示虚拟背景图标, 默认: false
|
||
enableVirtualBackground: !1,
|
||
// 是否开启虚拟背景, 默认: false
|
||
// customUIConfig
|
||
customUIConfig: {
|
||
button: {},
|
||
viewBackground: {},
|
||
layoutMode: Ke.RemoteInLargeView
|
||
},
|
||
// translate function
|
||
translate: ie,
|
||
isForceUseV2API: !1
|
||
}, this.store = Ie(this.defaultStore), this.prevStore = Ie(this.defaultStore);
|
||
}
|
||
update(e, t) {
|
||
switch (e) {
|
||
case a.CALL_TIPS:
|
||
const i = this.getData(e);
|
||
this.prevStore[e] = i;
|
||
default:
|
||
this.store[e] = t;
|
||
}
|
||
}
|
||
getPrevData(e) {
|
||
return e ? this.prevStore[e] : this.prevStore;
|
||
}
|
||
getData(e) {
|
||
return e ? this.store[e] : this.store;
|
||
}
|
||
// reset call store
|
||
reset(e = []) {
|
||
e.length === 0 && (e = Object.keys(this.store));
|
||
const t = e.reduce((i, A) => ({ ...i, [A]: this.defaultStore[A] }), {});
|
||
this.store = {
|
||
...this.defaultStore,
|
||
...this.store,
|
||
...t
|
||
};
|
||
}
|
||
}
|
||
let Ee = class q {
|
||
constructor() {
|
||
this.timerId = -1, this.storeMap = {
|
||
[s.CALL]: new Rt()
|
||
}, this.task = {};
|
||
}
|
||
/**
|
||
* 获取 TUIStore 实例
|
||
* @returns {TUIStore}
|
||
*/
|
||
static getInstance() {
|
||
return q.instance || (q.instance = new q()), q.instance;
|
||
}
|
||
/**
|
||
* UI 组件注册监听回调
|
||
* @param {StoreName} storeName store 名称
|
||
* @param {IOptions} options 监听信息
|
||
* @param {Object} params 扩展参数
|
||
* @param {String} params.notifyRangeWhenWatch 注册时监听时的通知范围, 'all' - 通知所有注册该 key 的监听; 'myself' - 通知本次注册该 key 的监听; 默认不通知
|
||
*/
|
||
watch(e, t, i) {
|
||
this.task[e] || (this.task[e] = {});
|
||
const A = this.task[e];
|
||
Object.keys(t).forEach((r) => {
|
||
const o = t[r];
|
||
A[r] || (A[r] = /* @__PURE__ */ new Map()), A[r].set(o, 1);
|
||
const { notifyRangeWhenWatch: I } = i || {};
|
||
if (I === a.ALL && this.notify(e, r), I === a.MYSELF) {
|
||
const l = this.getData(e, r);
|
||
o.call(this, l);
|
||
}
|
||
});
|
||
}
|
||
/**
|
||
* UI 取消组件监听回调
|
||
* @param {StoreName} storeName store 名称
|
||
* @param {IOptions} options 监听信息,包含需要取消的回掉等
|
||
*/
|
||
unwatch(e, t) {
|
||
if (!this.task[e])
|
||
return;
|
||
const i = this.task[e];
|
||
Object.keys(t).forEach((A) => {
|
||
i[A].delete(t[A]);
|
||
});
|
||
}
|
||
/**
|
||
* 通用 store 数据更新,messageList 的变更需要单独处理
|
||
* @param {StoreName} storeName store 名称
|
||
* @param {string} key 变更的 key
|
||
* @param {unknown} data 变更的数据
|
||
*/
|
||
update(e, t, i) {
|
||
var A;
|
||
(ze(i) || dt(i) || _t(i)) && this.storeMap[e].store[t] === i || ((A = this.storeMap[e]) == null || A.update(t, i), this.notify(e, t));
|
||
}
|
||
/**
|
||
* 获取 Store 的上一个状态值
|
||
* @param {StoreName} storeName store 名称
|
||
* @param {string} key 待获取的 key
|
||
* @returns {Any}
|
||
*/
|
||
getPrevData(e, t) {
|
||
var i;
|
||
return (i = this.storeMap[e]) == null ? void 0 : i.getPrevData(t);
|
||
}
|
||
/**
|
||
* 获取 Store 数据
|
||
* @param {StoreName} storeName store 名称
|
||
* @param {string} key 待获取的 key
|
||
* @returns {Any}
|
||
*/
|
||
getData(e, t) {
|
||
var i;
|
||
return (i = this.storeMap[e]) == null ? void 0 : i.getData(t);
|
||
}
|
||
/**
|
||
* UI 组件注册监听回调
|
||
* @param {StoreName} storeName store 名称
|
||
* @param {string} key 变更的 key
|
||
*/
|
||
notify(e, t) {
|
||
if (!this.task[e])
|
||
return;
|
||
const i = this.task[e];
|
||
if (i[t]) {
|
||
const A = i[t], r = this.getData(e, t);
|
||
for (const [o] of A.entries())
|
||
o.call(this, r);
|
||
}
|
||
}
|
||
reset(e, t = [], i = !1) {
|
||
if (e in this.storeMap) {
|
||
const A = this.storeMap[e];
|
||
t.length === 0 && (t = Object.keys(A == null ? void 0 : A.store)), A.reset(t), i && t.forEach((r) => {
|
||
this.notify(e, r);
|
||
});
|
||
}
|
||
}
|
||
// 批量修改多个 key-value
|
||
updateStore(e, t) {
|
||
const i = t || s.CALL;
|
||
Object.keys(e).forEach((A) => {
|
||
this.update(i, A, e[A]);
|
||
});
|
||
}
|
||
};
|
||
const D = Ee.getInstance();
|
||
function le(n, e) {
|
||
const t = {
|
||
userId: n,
|
||
nick: "",
|
||
avatar: "",
|
||
remark: "",
|
||
displayUserInfo: "",
|
||
isAudioAvailable: !1,
|
||
isVideoAvailable: !1,
|
||
isEnter: !1,
|
||
domId: e || n
|
||
};
|
||
return e ? t : { ...t, isEnter: !1 };
|
||
}
|
||
async function Nt(n, e) {
|
||
var i, A, r, o, I;
|
||
let t = le(n, a.LOCAL_VIDEO);
|
||
try {
|
||
if (!e)
|
||
return t;
|
||
const l = await e.getMyProfile(), u = D == null ? void 0 : D.getData(s.CALL, a.LOCAL_USER_INFO);
|
||
return (l == null ? void 0 : l.code) === 0 && (t = {
|
||
...t,
|
||
...u,
|
||
userId: (i = l == null ? void 0 : l.data) == null ? void 0 : i.userID,
|
||
nick: (A = l == null ? void 0 : l.data) == null ? void 0 : A.nick,
|
||
avatar: (r = l == null ? void 0 : l.data) == null ? void 0 : r.avatar,
|
||
displayUserInfo: ((o = l == null ? void 0 : l.data) == null ? void 0 : o.nick) || ((I = l == null ? void 0 : l.data) == null ? void 0 : I.userID)
|
||
}), t;
|
||
} catch (l) {
|
||
return console.error(`${a.PREFIX}getMyProfile failed, error: ${l}.`), t;
|
||
}
|
||
}
|
||
async function te(n, e) {
|
||
let t = n.map((i) => le(i));
|
||
try {
|
||
if (!e)
|
||
return t;
|
||
if (e != null && e.getFriendProfile) {
|
||
const i = await e.getFriendProfile({ userIDList: n });
|
||
if (i.code === 0) {
|
||
const { friendList: A = [], failureUserIDList: r = [] } = i.data;
|
||
let o = r.map((L) => L.userID);
|
||
if (r.length > 0) {
|
||
const L = await e.getUserProfile({ userIDList: r.map((g) => g.userID) });
|
||
(L == null ? void 0 : L.code) === 0 && (o = (L == null ? void 0 : L.data) || []);
|
||
}
|
||
const I = D == null ? void 0 : D.getData(s.CALL, a.REMOTE_USER_INFO_LIST), l = A.map((L) => L.userID), u = o.map((L) => L.userID);
|
||
t = n.map((L) => {
|
||
var J, W, z, b, Ue, Be, Oe;
|
||
const g = le(L), _ = l.indexOf(L), f = u.indexOf(L);
|
||
let S = "", O = "", v = "", U = "";
|
||
_ !== -1 && (S = ((J = A[_]) == null ? void 0 : J.remark) || "", O = ((z = (W = A[_]) == null ? void 0 : W.profile) == null ? void 0 : z.nick) || "", v = S || O || g.userId || "", U = ((Ue = (b = A[_]) == null ? void 0 : b.profile) == null ? void 0 : Ue.avatar) || ""), f !== -1 && (O = ((Be = o[f]) == null ? void 0 : Be.nick) || "", v = O || g.userId || "", U = ((Oe = o[f]) == null ? void 0 : Oe.avatar) || "");
|
||
const ae = I.find((Ze) => Ze.userId === L) || {};
|
||
return { ...g, ...ae, remark: S, nick: O, displayUserInfo: v, avatar: U };
|
||
});
|
||
}
|
||
return t;
|
||
} else {
|
||
const i = await e.getUserProfile({ userIDList: n }), A = D == null ? void 0 : D.getData(s.CALL, a.REMOTE_USER_INFO_LIST);
|
||
return t = n.map((r) => {
|
||
const o = le(r), I = A.find((u) => u.userId === r) || {}, l = (i.data || []).find((u) => u.userID === r) || {};
|
||
return {
|
||
...o,
|
||
...I,
|
||
nick: (l == null ? void 0 : l.nick) || "",
|
||
displayUserInfo: (l == null ? void 0 : l.nick) || r,
|
||
avatar: (l == null ? void 0 : l.avatar) || ""
|
||
};
|
||
}), t;
|
||
}
|
||
} catch (i) {
|
||
return console.error(`${a.PREFIX}getRemoteUserProfile failed, error: ${i}.`), t;
|
||
}
|
||
}
|
||
function ne() {
|
||
const n = D.getData(s.CALL, a.CALL_STATUS);
|
||
if (n === h.IDLE)
|
||
return G.IDLE;
|
||
const e = D.getData(s.CALL, a.IS_GROUP);
|
||
if (n === h.CALLING)
|
||
return e ? G.DIALING_GROUP : G.DIALING_C2C;
|
||
const t = D.getData(s.CALL, a.CALL_MEDIA_TYPE);
|
||
return e ? t === d.AUDIO ? G.CALLING_GROUP_AUDIO : G.CALLING_GROUP_VIDEO : t === d.AUDIO ? G.CALLING_C2C_AUDIO : G.CALLING_C2C_VIDEO;
|
||
}
|
||
async function Tt(n, e, t, i) {
|
||
let A = [];
|
||
try {
|
||
const r = await e.getGroupMemberList({ groupID: n, count: t, offset: i });
|
||
if (r.code === 0)
|
||
return r.data.memberList || A;
|
||
} catch (r) {
|
||
return console.error(`${a.PREFIX}getGroupMember failed, error: ${r}.`), A;
|
||
}
|
||
}
|
||
async function wt(n, e) {
|
||
let t = {};
|
||
try {
|
||
return (await e.getGroupProfile({ groupID: n })).data.group || t;
|
||
} catch (i) {
|
||
return console.warn(`${a.PREFIX}getGroupProfile failed, error: ${i}.`), t;
|
||
}
|
||
}
|
||
function je(n, e) {
|
||
n === 0 && e ? (D.update(s.CALL, a.ROOM_ID, e), D.update(s.CALL, a.ROOM_ID_TYPE, _e.STRING_ROOM_ID)) : (D.update(s.CALL, a.ROOM_ID, n), D.update(s.CALL, a.ROOM_ID_TYPE, _e.NUMBER_ROOM_ID));
|
||
}
|
||
function F(n) {
|
||
return n || {};
|
||
}
|
||
function ue(n) {
|
||
if (n.length === 0)
|
||
return;
|
||
let e = D.getData(s.CALL, a.REMOTE_USER_INFO_LIST);
|
||
n.forEach((t) => {
|
||
e = e.filter((i) => i.userId !== t);
|
||
}), D.update(s.CALL, a.REMOTE_USER_INFO_LIST, e), D.update(s.CALL, a.REMOTE_USER_INFO_EXCLUDE_VOLUMN_LIST, e);
|
||
}
|
||
function he(n, e, t) {
|
||
let i = "";
|
||
Dt(n) && (e === d.AUDIO && (i = N.NO_MICROPHONE_DEVICE_PERMISSION), e === d.VIDEO && (i = N.NO_CAMERA_DEVICE_PERMISSION), i && D.update(s.CALL, a.TOAST_INFO, { content: i, type: a.ERROR }), console.error(`${a.PREFIX}call failed, error: ${n.message}.`));
|
||
}
|
||
function m(n, e) {
|
||
let t = D.getData(s.CALL, a.LOCAL_USER_INFO);
|
||
e === a.AUDIO && (t = { ...t, isAudioAvailable: n }), e === a.VIDEO && (t = { ...t, isVideoAvailable: n }), D.update(s.CALL, a.LOCAL_USER_INFO, t), D.update(s.CALL, a.LOCAL_USER_INFO_EXCLUDE_VOLUMN, t);
|
||
}
|
||
class Ce {
|
||
static generateTaskID() {
|
||
return this.currentTaskID++;
|
||
}
|
||
/**
|
||
*
|
||
* @param {string} taskName 'interval' 'timeout'
|
||
* @param {function} callback
|
||
* @param {object} options include:
|
||
* @param {number} options.delay millisecond
|
||
* @param {number} options.count 定时器回调执行次数,0 无限次 or n次
|
||
* @param {boolean} options.backgroundTask 在页面静默后是否继续执行定时器
|
||
*/
|
||
static run(e = a.TIMEOUT, t, i) {
|
||
e === a.INTERVAL ? i = { delay: 2e3, count: 0, backgroundTask: !0, ...i } : i = { delay: 2e3, count: 0, backgroundTask: !0, ...i }, Se(t) && (i = { ...i, ...t }), oe(e) && (t = e, e = a.TIMEOUT);
|
||
const A = {
|
||
taskID: this.generateTaskID(),
|
||
loopCount: 0,
|
||
intervalID: null,
|
||
timeoutID: null,
|
||
taskName: e,
|
||
callback: t,
|
||
...i
|
||
};
|
||
return this.taskMap.set(A.taskID, A), e === a.INTERNAL ? this.interval(A) : this.timeout(A), A.taskID;
|
||
}
|
||
/**
|
||
* 定时循环执行回调函数
|
||
* 可以指定循环的时间间隔
|
||
* 可以指定循环次数
|
||
* @param {object} taskItem
|
||
* @param {function} callback
|
||
* @param {*} delay
|
||
* @param {*} count
|
||
* @returns ID
|
||
*/
|
||
static interval(e) {
|
||
const t = () => {
|
||
e.callback(), e.loopCount += 1, this.isBreakLoop(e);
|
||
};
|
||
return e.intervalID = setInterval(t, e.delay);
|
||
}
|
||
/**
|
||
* 延迟执行回调
|
||
* count = 0,循环
|
||
* count = n, 执行n次
|
||
* @param {object} taskItem
|
||
*
|
||
*/
|
||
static timeout(e) {
|
||
const t = () => {
|
||
if (e.callback(), e.loopCount += 1, !this.isBreakLoop(e))
|
||
return e.timeoutID = setTimeout(t, e.delay);
|
||
};
|
||
return e.timeoutID = setTimeout(t, e.delay);
|
||
}
|
||
static hasTask(e) {
|
||
return this.taskMap.has(e);
|
||
}
|
||
static clearTask(e) {
|
||
if (!this.taskMap.has(e))
|
||
return !0;
|
||
const { intervalID: t, timeoutID: i, onVisibilitychange: A } = this.taskMap.get(e);
|
||
return t && clearInterval(t), i && clearTimeout(i), A && document.removeEventListener("visibilitychange", A), this.taskMap.delete(e), !0;
|
||
}
|
||
/**
|
||
* 1. 如果已移除出定时队列,退出当前任务
|
||
* 2. 如果当前任务已满足次数限制,则退出当前任务
|
||
* @param {object} taskItem
|
||
* @returns
|
||
*/
|
||
static isBreakLoop(e) {
|
||
return this.taskMap.has(e.taskID) ? e.count !== 0 && e.loopCount >= e.count ? (this.clearTask(e.taskID), !0) : !1 : !0;
|
||
}
|
||
}
|
||
Ce.taskMap = /* @__PURE__ */ new Map();
|
||
Ce.currentTaskID = 1;
|
||
const pt = function(n) {
|
||
if (n === null || typeof n > "u")
|
||
return !0;
|
||
if (typeof n == "boolean")
|
||
return !1;
|
||
if (typeof n == "number")
|
||
return n === 0;
|
||
if (typeof n == "string" || typeof n == "function" || Array.isArray(n))
|
||
return n.length === 0;
|
||
if (n instanceof Error)
|
||
return n.message === "";
|
||
if (Se(n)) {
|
||
for (const e in n)
|
||
if (Object.prototype.hasOwnProperty.call(n, e))
|
||
return !1;
|
||
return !0;
|
||
}
|
||
return !1;
|
||
}, ge = "_local_user_id";
|
||
class K {
|
||
constructor() {
|
||
this._viewConfig = {
|
||
viewBackground: {
|
||
local: {},
|
||
remote: {}
|
||
}
|
||
}, this._isSetViewBackgroundConfig = { remote: !1, local: !1 }, this._tuiCallEngine = null, this._tuiStore = null;
|
||
}
|
||
static getInstance() {
|
||
return K.instance || (K.instance = new K()), K.instance;
|
||
}
|
||
_updateViewBackground() {
|
||
var i, A, r;
|
||
const e = (i = this._tuiStore) == null ? void 0 : i.getData(s.CALL, a.CUSTOM_UI_CONFIG), { userId: t } = (A = this._tuiStore) == null ? void 0 : A.getData(s.CALL, a.LOCAL_USER_INFO);
|
||
Object.keys(this._viewConfig.viewBackground.remote).includes(t) && delete this._viewConfig.viewBackground.remote[t], (r = this._tuiStore) == null || r.update(
|
||
s.CALL,
|
||
a.CUSTOM_UI_CONFIG,
|
||
{
|
||
...e,
|
||
viewBackground: {
|
||
...this._viewConfig.viewBackground.remote,
|
||
...this._viewConfig.viewBackground.local
|
||
}
|
||
}
|
||
);
|
||
}
|
||
setEngineInstance(e) {
|
||
this._tuiCallEngine = e;
|
||
}
|
||
setTUIStore(e) {
|
||
this._tuiStore = e;
|
||
}
|
||
updateViewBackgroundUserId(e) {
|
||
var t, i;
|
||
if (e === "local") {
|
||
const { userId: A } = (t = this._tuiStore) == null ? void 0 : t.getData(s.CALL, a.LOCAL_USER_INFO);
|
||
if (Object.keys(this._viewConfig.viewBackground.remote).includes(A) && (delete this._viewConfig.viewBackground.remote[A], this._updateViewBackground()), !this._isSetViewBackgroundConfig.local)
|
||
return;
|
||
const r = this._viewConfig.viewBackground.local, o = r[A] || r[ge];
|
||
r[A] = r[ge], this._viewConfig.viewBackground.local = { [A]: o }, this._updateViewBackground();
|
||
} else {
|
||
let A = this._viewConfig.viewBackground.remote;
|
||
this._isSetViewBackgroundConfig.remote && Object.keys(A).includes("*") && (((i = this._tuiStore) == null ? void 0 : i.getData(s.CALL, a.REMOTE_USER_INFO_LIST)).map((I) => I.userId).forEach((I) => {
|
||
Object.keys(A).includes(I) || (A[I] = A["*"]);
|
||
}), this._viewConfig.viewBackground.remote = A, this._updateViewBackground());
|
||
}
|
||
}
|
||
hideFeatureButton(e) {
|
||
var i, A, r, o, I;
|
||
(A = (i = this._tuiCallEngine) == null ? void 0 : i.reportLog) == null || A.call(i, {
|
||
name: "TUICallKit.hideFeatureButton.start",
|
||
data: { buttonName: e }
|
||
});
|
||
const t = (r = this._tuiStore) == null ? void 0 : r.getData(s.CALL, a.CUSTOM_UI_CONFIG);
|
||
(I = this._tuiStore) == null || I.update(
|
||
s.CALL,
|
||
a.CUSTOM_UI_CONFIG,
|
||
{
|
||
...t,
|
||
button: {
|
||
...t.button,
|
||
[e]: { ...((o = t.button) == null ? void 0 : o[e]) || {}, show: !1 }
|
||
}
|
||
}
|
||
);
|
||
}
|
||
setLocalViewBackgroundImage(e) {
|
||
var i, A, r;
|
||
(A = (i = this._tuiCallEngine) == null ? void 0 : i.reportLog) == null || A.call(i, {
|
||
name: "TUICallKit.setLocalViewBackgroundImage.start",
|
||
data: { url: e }
|
||
}), this._isSetViewBackgroundConfig.local = !0;
|
||
let { userId: t } = (r = this._tuiStore) == null ? void 0 : r.getData(s.CALL, a.LOCAL_USER_INFO);
|
||
pt(t) && (t = ge), this._viewConfig.viewBackground.local = { [t]: e }, this._updateViewBackground();
|
||
}
|
||
setRemoteViewBackgroundImage(e, t) {
|
||
var i, A;
|
||
(A = (i = this._tuiCallEngine) == null ? void 0 : i.reportLog) == null || A.call(i, {
|
||
name: "TUICallKit.setRemoteViewBackgroundImage.start",
|
||
data: { userId: e, url: t }
|
||
}), this._isSetViewBackgroundConfig.remote = !0, e === "*" && (this._viewConfig.viewBackground.remote = {}), this._viewConfig.viewBackground.remote[e] = t, this._updateViewBackground();
|
||
}
|
||
setLayoutMode(e) {
|
||
var i, A;
|
||
(A = (i = this._tuiCallEngine) == null ? void 0 : i.reportLog) == null || A.call(i, {
|
||
name: "TUICallKit.setLayoutMode.start",
|
||
data: { layoutMode: e }
|
||
});
|
||
const t = this._tuiStore.getData(s.CALL, a.CUSTOM_UI_CONFIG);
|
||
this._tuiStore.update(
|
||
s.CALL,
|
||
a.CUSTOM_UI_CONFIG,
|
||
{
|
||
...t,
|
||
layoutMode: e
|
||
}
|
||
);
|
||
}
|
||
setCameraDefaultState(e) {
|
||
var i, A;
|
||
(A = (i = this._tuiCallEngine) == null ? void 0 : i.reportLog) == null || A.call(i, {
|
||
name: "TUICallKit.setCameraDefaultState.start",
|
||
data: { isOpen: e }
|
||
});
|
||
const t = Ie(this._tuiStore.getData(s.CALL, a.CUSTOM_UI_CONFIG));
|
||
Object.keys(t.button).includes(x.Camera) || (t.button[x.Camera] = {}), t.button[x.Camera].state = e ? ee.Open : ee.Close, this._tuiStore.update(s.CALL, a.CUSTOM_UI_CONFIG, t);
|
||
}
|
||
}
|
||
const se = Ee.getInstance(), P = {
|
||
audioCall: () => "Voice call",
|
||
videoCall: () => "Video call",
|
||
switchToAudio: () => "Switch audio call",
|
||
switchToVideo: () => "Switch video call",
|
||
hangup: ({ callDuration: n }) => `${ie("Call duration")}:${n}`
|
||
};
|
||
class H {
|
||
constructor(e) {
|
||
var t, i, A;
|
||
this._callService = e.callService, X.registerEvent(B.TUILogin.EVENT.LOGIN_STATE_CHANGED, B.TUILogin.EVENT_SUB_KEY.USER_LOGIN_SUCCESS, this), (t = B.TUIChat) != null && t.EVENT && X.registerEvent((i = B.TUIChat.EVENT) == null ? void 0 : i.CHAT_STATE_CHANGED, (A = B.TUIChat.EVENT_SUB_KEY) == null ? void 0 : A.CHAT_OPENED, this), X.registerService(B.TUICalling.SERVICE.NAME, this), X.registerExtension(B.TUIChat.EXTENSION.INPUT_MORE.EXT_ID, this);
|
||
}
|
||
static getInstance(e) {
|
||
return H.instance || (H.instance = new H(e)), H.instance;
|
||
}
|
||
// ================ 【】 ================
|
||
/**
|
||
* message on screen
|
||
* @param {Any} params Parameters for message up-screening
|
||
*/
|
||
callTUIService(e) {
|
||
const { message: t } = e || {};
|
||
X.callService({
|
||
serviceName: B.TUIChat.SERVICE.NAME,
|
||
method: B.TUIChat.SERVICE.METHOD.UPDATE_MESSAGE_LIST,
|
||
params: { message: t }
|
||
});
|
||
}
|
||
/**
|
||
* tuicore getExtension
|
||
* @param {String} extensionID extension id
|
||
* @param {Any} params tuicore pass parameters
|
||
* @returns {Any[]} return extension
|
||
*/
|
||
onGetExtension(e, t) {
|
||
var i, A;
|
||
if (e === B.TUIChat.EXTENSION.INPUT_MORE.EXT_ID) {
|
||
if ((A = (i = this._callService.getTUICallEngineInstance()) == null ? void 0 : i.reportLog) == null || A.call(i, { name: "TUICallKit.onGetExtension", data: { extensionID: e, params: t } }), De(t))
|
||
return [];
|
||
if ([B.TUIChat.TYPE.ROOM, B.TUIChat.TYPE.CUSTOMER_SERVICE].includes(t.chatType))
|
||
return [];
|
||
let r = [];
|
||
const o = {
|
||
weight: 1e3,
|
||
text: "语音通话",
|
||
icon: at,
|
||
data: {
|
||
name: "voiceCall"
|
||
},
|
||
listener: {
|
||
onClicked: async (l) => await this._handleTUICoreOnClick(l, l.type || d.AUDIO)
|
||
}
|
||
}, I = {
|
||
weight: 900,
|
||
text: "视频通话",
|
||
icon: At,
|
||
data: {
|
||
name: "videoCall"
|
||
},
|
||
listener: {
|
||
onClicked: async (l) => await this._handleTUICoreOnClick(l, l.type || d.VIDEO)
|
||
}
|
||
};
|
||
return t != null && t.chatType ? r = [o, I] : (!(t != null && t.filterVoice) && r.push(o), !(t != null && t.filterVideo) && r.push(I)), r;
|
||
}
|
||
}
|
||
async onCall(e, t) {
|
||
e === B.TUICalling.SERVICE.METHOD.START_CALL && await this._handleTUICoreOnClick(t, t.type);
|
||
}
|
||
/**
|
||
* tuicore notify event manager
|
||
* @param {String} eventName event name
|
||
* @param {String} subKey sub key
|
||
* @param {Any} options tuicore event parameters
|
||
*/
|
||
async onNotifyEvent(e, t, i) {
|
||
var A, r, o, I, l, u, L, g;
|
||
try {
|
||
if (e === B.TUILogin.EVENT.LOGIN_STATE_CHANGED)
|
||
if (t === B.TUILogin.EVENT_SUB_KEY.USER_LOGIN_SUCCESS) {
|
||
const { chat: _, userID: f, userSig: S, SDKAppID: O } = $e.getContext();
|
||
await ((A = this._callService) == null ? void 0 : A.init({ tim: _, userID: f, userSig: S, sdkAppID: O, isFromChat: !0, component: de.TIM_CALL_KIT })), (r = this._callService) == null || r.setIsFromChat(!0), (o = this._callService) == null || o.setLogLevel(be.NORMAL), this._addListenChatEvent();
|
||
} else
|
||
t === B.TUILogin.EVENT_SUB_KEY.USER_LOGOUT_SUCCESS && (this._removeListenChatEvent(), await ((I = this._callService) == null ? void 0 : I.destroyed()));
|
||
if ((l = B.TUIChat) != null && l.EVENT && e === B.TUIChat.EVENT.CHAT_STATE_CHANGED && t === B.TUIChat.EVENT_SUB_KEY.CHAT_OPENED) {
|
||
if ((u = this._callService) == null || u.setCurrentGroupId((i == null ? void 0 : i.groupID) || ""), se.getData(s.CALL, a.CALL_STATUS) !== h.IDLE)
|
||
return;
|
||
const _ = (L = this._callService) == null ? void 0 : L.getCurrentGroupId(), f = _ ? await this.getGroupAttributes((g = this._callService) == null ? void 0 : g.getTim(), _) : {};
|
||
await this.updateStoreBasedOnGroupAttributes(f);
|
||
}
|
||
} catch (_) {
|
||
console.error(`${a.PREFIX}TUICore onNotifyEvent failed, error: ${_}.`);
|
||
}
|
||
}
|
||
// Handling the chat+call scenario, data required for the joinInGroupCall API: update store / clear relevant store data
|
||
async updateStoreBasedOnGroupAttributes(e) {
|
||
var t, i, A, r;
|
||
(A = (i = (t = this._callService) == null ? void 0 : t.getTUICallEngineInstance()) == null ? void 0 : i.reportLog) == null || A.call(i, {
|
||
name: "TUICallKit.getJoinGroupCallInfo.success",
|
||
data: { groupAttributes: e }
|
||
});
|
||
try {
|
||
const {
|
||
call_id: o = "",
|
||
// callEngine v3.1 support
|
||
group_id: I = "",
|
||
room_id: l = 0,
|
||
room_id_type: u = 0,
|
||
call_media_type: L = a.UNKNOWN,
|
||
// @ts-ignore
|
||
user_list: g
|
||
// The default value of the user list returned by the background is null
|
||
} = e[a.INNER_ATTR_KIT_INFO] ? JSON.parse(e[a.INNER_ATTR_KIT_INFO]) : {};
|
||
let _ = (g || []).map((S) => S.userid);
|
||
_.length > 0 && (_ = await te(_, (r = this._callService) == null ? void 0 : r.getTim()));
|
||
const f = {
|
||
[a.CALL_ID]: o,
|
||
[a.GROUP_ID]: I,
|
||
[a.GROUP_CALL_MEMBERS]: _,
|
||
[a.ROOM_ID]: l,
|
||
[a.CALL_MEDIA_TYPE]: et[L],
|
||
[a.ROOM_ID_TYPE]: u
|
||
};
|
||
se.updateStore(f, s.CALL);
|
||
} catch (o) {
|
||
console.warn(`${a.PREFIX}updateStoreBasedOnGroupAttributes fail, error: ${o}`);
|
||
}
|
||
}
|
||
// Get group attribute
|
||
async getGroupAttributes(e, t) {
|
||
if (!t)
|
||
return {};
|
||
try {
|
||
const { data: i } = await e.getGroupAttributes({
|
||
groupID: t,
|
||
keyList: []
|
||
});
|
||
return (i == null ? void 0 : i.groupAttributes) || {};
|
||
} catch (i) {
|
||
return console.warn(`${a.PREFIX}getGroupAttributes fail: ${i}`), {};
|
||
}
|
||
}
|
||
isLineBusy(e) {
|
||
var A;
|
||
const t = Ae(e.payload.data), i = Ae(t == null ? void 0 : t.data);
|
||
return (i == null ? void 0 : i.line_busy) === "line_busy" || (i == null ? void 0 : i.line_busy) === "" || ((A = i == null ? void 0 : i.data) == null ? void 0 : A.message) === "lineBusy";
|
||
}
|
||
async getCallKitMessage(e, t) {
|
||
var _, f, S, O;
|
||
const i = Ae(e.payload.data);
|
||
if ((i == null ? void 0 : i.businessID) !== 1)
|
||
return {};
|
||
let A = "";
|
||
const r = Ae(i == null ? void 0 : i.data), o = r.call_type, I = i.inviteeList, l = (_ = r == null ? void 0 : r.data) == null ? void 0 : _.inviter, u = se.getData(s.CALL, a.LOCAL_USER_INFO).userId, L = l === u, g = (f = r == null ? void 0 : r.data) == null ? void 0 : f.cmd;
|
||
switch (i == null ? void 0 : i.actionType) {
|
||
case Y.INVITE: {
|
||
A = P[g]({ callDuration: Xe(r == null ? void 0 : r.call_end) });
|
||
break;
|
||
}
|
||
case Y.CANCEL_INVITE:
|
||
A = L ? "Call Cancel" : "Other Side Cancel";
|
||
break;
|
||
case Y.ACCEPT_INVITE:
|
||
["switchToAudio", "switchToVideo"].includes(g) ? A = (S = P == null ? void 0 : P[g]) == null ? void 0 : S.call(P) : A = ie("Answered");
|
||
break;
|
||
case Y.REJECT_INVITE:
|
||
this.isLineBusy(e) ? A = L ? "Line Busy" : "Other Side Line Busy" : A = L ? "Other Side Decline" : "Decline";
|
||
break;
|
||
case Y.INVITE_TIMEOUT:
|
||
["switchToAudio", "switchToVideo"].includes(g) ? A = (O = P == null ? void 0 : P[g]) == null ? void 0 : O.call(P) : A = L ? "Other Side No Answer" : "No answer";
|
||
break;
|
||
}
|
||
return { messageCardContent: A, callMediaType: o, inviteeList: I };
|
||
}
|
||
// =========================【chat: event listening】=========================
|
||
_addListenChatEvent() {
|
||
var e, t;
|
||
if (!((e = this._callService) != null && e.getTim())) {
|
||
console.warn(`${a.PREFIX}add tim event listener failed, tim is empty.`);
|
||
return;
|
||
}
|
||
(t = this._callService) == null || t.getTim().on(Te.EVENT.GROUP_ATTRIBUTES_UPDATED, this._handleGroupAttributesUpdated, this);
|
||
}
|
||
_removeListenChatEvent() {
|
||
var e, t;
|
||
if (!((e = this._callService) != null && e.getTim())) {
|
||
console.warn(`${a.PREFIX}remove tim event listener failed, tim is empty.`);
|
||
return;
|
||
}
|
||
(t = this._callService) == null || t.getTim().off(Te.EVENT.GROUP_ATTRIBUTES_UPDATED, this._handleGroupAttributesUpdated, this);
|
||
}
|
||
/**
|
||
* chat start audio/video call via click
|
||
* @param {Any} options Parameters passed in when clicking on an audio/video call from chat
|
||
* @param {CallMediaType} type call media type. 0 - audio; 1 - video.
|
||
*
|
||
* priority: isForceUseV2API > version
|
||
*/
|
||
async _handleTUICoreOnClick(e, t) {
|
||
var i;
|
||
try {
|
||
const { groupID: A, userIDList: r = [], version: o = "", ...I } = e;
|
||
await ((i = this._callService) == null ? void 0 : i.calls({ chatGroupID: A, userIDList: r, type: t, ...I }));
|
||
} catch (A) {
|
||
e != null && e.version || console.warn("Please upgrade to the latest Chat UIKit components."), console.debug(A);
|
||
}
|
||
}
|
||
async _handleGroupAttributesUpdated(e) {
|
||
var r;
|
||
if (se.getData(s.CALL, a.CALL_STATUS) !== h.IDLE)
|
||
return;
|
||
const t = (e == null ? void 0 : e.data) || {}, { groupID: i = "", groupAttributes: A = {} } = t;
|
||
i === ((r = this._callService) == null ? void 0 : r.getCurrentGroupId()) && await this.updateStoreBasedOnGroupAttributes(A);
|
||
}
|
||
}
|
||
const Ft = 0, Gt = 1, Pe = 2;
|
||
function Mt({ retryFunction: n, settings: e, onError: t, onRetrying: i, onRetryFailed: A, context: r }) {
|
||
return function(...o) {
|
||
const I = e.retries || 5;
|
||
let l = 0, u = -1, L = Ft;
|
||
const g = async (_, f) => {
|
||
const S = r || this;
|
||
try {
|
||
const O = await n.apply(S, o);
|
||
l = 0, _(O);
|
||
} catch (O) {
|
||
const v = () => {
|
||
clearTimeout(u), l = 0, L = Pe, f(O);
|
||
}, U = () => {
|
||
L !== Pe && l < I ? (l++, L = Gt, oe(i) && i.call(S, l, v), u = setTimeout(
|
||
() => {
|
||
u = -1, g(_, f);
|
||
},
|
||
De(e.timeout) ? 1e3 : e.timeout
|
||
)) : (v(), oe(A) && A.call(S, O));
|
||
};
|
||
oe(t) ? t.call(S, O, U, f, o) : U();
|
||
}
|
||
};
|
||
return new Promise(g);
|
||
};
|
||
}
|
||
function vt(n) {
|
||
return function(e, t, i) {
|
||
const { retries: A = 5, timeout: r = 2e3, onError: o, onRetrying: I, onRetryFailed: l } = n, u = Mt({
|
||
retryFunction: i.value,
|
||
settings: { retries: A, timeout: r },
|
||
onError: o,
|
||
onRetrying: I,
|
||
onRetryFailed: l,
|
||
context: null
|
||
});
|
||
return i.value = function(...L) {
|
||
return u.apply(this, L);
|
||
}, i;
|
||
};
|
||
}
|
||
var Pt = Object.defineProperty, Qt = Object.getOwnPropertyDescriptor, yt = (n, e, t, i) => {
|
||
for (var A = i > 1 ? void 0 : i ? Qt(e, t) : e, r = n.length - 1, o; r >= 0; r--)
|
||
(o = n[r]) && (A = (i ? o(e, t, A) : o(A)) || A);
|
||
return i && A && Pt(e, t, A), A;
|
||
};
|
||
const E = Ee.getInstance(), mt = K.getInstance(), qe = class Z {
|
||
constructor(e) {
|
||
this._callService = e.callService;
|
||
}
|
||
static getInstance(e) {
|
||
return Z.instance || (Z.instance = new Z(e)), Z.instance;
|
||
}
|
||
addListenTuiCallEngineEvent() {
|
||
var t, i;
|
||
const e = (t = this._callService) == null ? void 0 : t.getTUICallEngineInstance();
|
||
if (!e) {
|
||
console.warn(`${a.PREFIX}add engine event listener failed, engine is empty.`);
|
||
return;
|
||
}
|
||
e.on(C.ERROR, this._handleError, this), e.on(C.ON_CALL_RECEIVED, this._handleNewInvitationReceived, this), (i = C) != null && i.ON_CALL_BEGIN && e.on(C.ON_CALL_BEGIN, this._handleOnCallBegin, this), e.on(C.USER_ENTER, this._handleUserEnter, this), e.on(C.USER_LEAVE, this._handleUserLeave, this), e.on(C.REJECT, this._handleInviteeReject, this), e.on(C.NO_RESP, this._handleNoResponse, this), e.on(C.LINE_BUSY, this._handleLineBusy, this), e.on(C.ON_CALL_NOT_CONNECTED, this._handleCallNotConnected, this), e.on(C.ON_USER_INVITING, this._handleOnUserInviting, this), e.on(C.SDK_READY, this._handleSDKReady, this), e.on(C.KICKED_OUT, this._handleKickedOut, this), e.on(C.MESSAGE_SENT_BY_ME, this._messageSentByMe, this), C.CALL_MESSAGE && e.on(C.CALL_MESSAGE, this._handleCallMessage, this), C.ON_USER_NETWORK_QUALITY_CHANGED && e.on(C.ON_USER_NETWORK_QUALITY_CHANGED, this._handleNetworkQuality, this), e.on(C.USER_VIDEO_AVAILABLE, this._handleUserVideoAvailable, this), e.on(C.USER_AUDIO_AVAILABLE, this._handleUserAudioAvailable, this), e.on(C.ON_CALL_END, this._handleCallingEnd, this), e.on(C.CALL_MODE, this._handleCallTypeChange, this), e.on(C.USER_UPDATE, this._handleUserUpdate, this);
|
||
}
|
||
removeListenTuiCallEngineEvent() {
|
||
var t, i;
|
||
const e = (t = this._callService) == null ? void 0 : t.getTUICallEngineInstance();
|
||
e.off(C.ERROR, this._handleError, this), e.off(C.ON_CALL_RECEIVED, this._handleNewInvitationReceived, this), (i = C) != null && i.ON_CALL_BEGIN && e.off(C.ON_CALL_BEGIN, this._handleOnCallBegin, this), e.off(C.USER_ENTER, this._handleUserEnter, this), e.off(C.USER_LEAVE, this._handleUserLeave, this), e.off(C.REJECT, this._handleInviteeReject, this), e.off(C.NO_RESP, this._handleNoResponse, this), e.off(C.LINE_BUSY, this._handleLineBusy, this), e.off(C.ON_CALL_NOT_CONNECTED, this._handleCallNotConnected, this), e.off(C.ON_USER_INVITING, this._handleOnUserInviting, this), e.off(C.SDK_READY, this._handleSDKReady, this), e.off(C.KICKED_OUT, this._handleKickedOut, this), e.off(C.MESSAGE_SENT_BY_ME, this._messageSentByMe, this), C.ON_USER_NETWORK_QUALITY_CHANGED && e.off(C.ON_USER_NETWORK_QUALITY_CHANGED, this._handleNetworkQuality, this), e.off(C.USER_VIDEO_AVAILABLE, this._handleUserVideoAvailable, this), e.off(C.USER_AUDIO_AVAILABLE, this._handleUserAudioAvailable, this), e.off(C.CALL_END, this._handleCallingEnd, this), e.off(C.CALL_MODE, this._handleCallTypeChange, this), e.off(C.USER_UPDATE, this._handleUserUpdate, this);
|
||
}
|
||
_callerChangeToConnected() {
|
||
var i, A, r;
|
||
const e = E.getData(s.CALL, a.CALL_ROLE);
|
||
E.getData(s.CALL, a.CALL_STATUS) === h.CALLING && e === p.CALLER && ((A = (i = this._callService) == null ? void 0 : i._bellContext) == null || A.stop(), E.update(s.CALL, a.CALL_STATUS, h.CONNECTED), (r = this._callService) == null || r.startTimer());
|
||
}
|
||
_unNormalEventsManager(e, t) {
|
||
var r, o;
|
||
console.log(`${a.PREFIX}${t} event data: ${JSON.stringify(e)}.`);
|
||
const i = E.getData(s.CALL, a.IS_GROUP), A = E.getData(s.CALL, a.REMOTE_USER_INFO_LIST);
|
||
switch (t) {
|
||
case C.REJECT:
|
||
case C.LINE_BUSY: {
|
||
const { userID: I } = F(e);
|
||
let l = t === C.REJECT ? N.OTHER_SIDE_REJECT_CALL : N.OTHER_SIDE_LINE_BUSY, u = "";
|
||
i && (u = (A.find((L) => L.userId === I) || {}).displayUserInfo || I, l = t === C.REJECT ? N.REJECT_CALL : N.IN_BUSY), E.update(s.CALL, a.TOAST_INFO, { content: { key: l, options: { userList: u } } }), I && ue([I]), E.getData(s.CALL, a.REMOTE_USER_INFO_LIST).length === 0 && ((r = this._callService) == null || r._resetCallStore());
|
||
break;
|
||
}
|
||
case C.NO_RESP: {
|
||
const { userIDList: I = [] } = F(e), l = i ? N.TIMEOUT : N.CALL_TIMEOUT, u = I.map((L) => (A.find((_) => _.userId === L) || {}).displayUserInfo || L);
|
||
E.update(s.CALL, a.TOAST_INFO, { content: { key: l, options: { userList: u.join() } } }), I.length > 0 && ue(I);
|
||
break;
|
||
}
|
||
case C.ON_CALL_NOT_CONNECTED: {
|
||
(o = this._callService) == null || o._resetCallStore();
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
_handleError(e) {
|
||
var o;
|
||
const { code: t, message: i } = e || {}, A = Object.values(we).indexOf(t);
|
||
let r = "";
|
||
if (A !== -1) {
|
||
const I = Object.keys(we)[A];
|
||
r = ie(pe[I]), r && E.update(s.CALL, a.TOAST_INFO, { content: pe[I], type: a.ERROR });
|
||
}
|
||
(o = this._callService) == null || o.executeExternalAfterCalling(), console.error(`${a.PREFIX}_handleError, errorCode: ${t}; errorMessage: ${r || i}.`);
|
||
}
|
||
async _handleNewInvitationReceived(e) {
|
||
var ae, J, W, z;
|
||
console.log(`${a.PREFIX}onCallReceived event data: ${JSON.stringify(e)}.`);
|
||
const { callerId: t = "", callMediaType: i, inviteData: A = {}, calleeIdList: r = [], chatGroupID: o = "", roomID: I, strRoomID: l } = F(e), u = E.getData(s.CALL, a.LOCAL_USER_INFO), L = [t, ...r.filter((b) => b !== u.userId)], g = i || A.callType, _ = g === d.AUDIO ? N.CALLEE_CALLING_AUDIO_MSG : N.CALLEE_CALLING_VIDEO_MSG;
|
||
let f = {
|
||
[a.CALL_ROLE]: p.CALLEE,
|
||
[a.IS_GROUP]: !!o || r.length > 1,
|
||
[a.CALL_STATUS]: h.CALLING,
|
||
[a.CALL_MEDIA_TYPE]: g,
|
||
[a.CALL_TIPS]: _,
|
||
[a.CALLER_USER_INFO]: { userId: t },
|
||
[a.GROUP_ID]: o
|
||
};
|
||
ke();
|
||
const S = { enableCamera: g === d.VIDEO, enableMic: !0 };
|
||
f = { ...f, [a.PUSHER]: S }, g === d.VIDEO && this._callService.openCamera(a.LOCAL_VIDEO), this._callService.openMicrophone();
|
||
const O = {
|
||
microphone: !0,
|
||
camera: g === d.VIDEO
|
||
};
|
||
this._callService._preDevicePermission = await this._callService._tuiCallEngine.deviceCheck(O), je(I, l), E.updateStore(f, s.CALL), (ae = this._callService) == null || ae.executeExternalBeforeCalling(), (J = this._callService) != null && J.statusChanged && ((W = this._callService) == null || W.statusChanged({ oldStatus: G.IDLE, newStatus: G.BE_INVITED }));
|
||
const v = await te(L, (z = this._callService) == null ? void 0 : z.getTim()), [U] = v.filter((b) => b.userId === t);
|
||
v.length > 0 && E.updateStore({
|
||
[a.REMOTE_USER_INFO_LIST]: v,
|
||
[a.REMOTE_USER_INFO_EXCLUDE_VOLUMN_LIST]: v,
|
||
[a.CALLER_USER_INFO]: {
|
||
userId: t,
|
||
nick: (U == null ? void 0 : U.nick) || "",
|
||
avatar: (U == null ? void 0 : U.avatar) || "",
|
||
displayUserInfo: (U == null ? void 0 : U.remark) || (U == null ? void 0 : U.nick) || t
|
||
}
|
||
}, s.CALL);
|
||
}
|
||
async _handleOnCallBegin(e) {
|
||
var t, i;
|
||
(i = (t = this._callService) == null ? void 0 : t._bellContext) == null || i.stop(), this._callerChangeToConnected(), E.update(s.CALL, a.CALL_TIPS, { text: "answered", duration: 2e3 }), await this._callService.openMicrophone(), console.log(`${a.PREFIX}accept event data: ${JSON.stringify(e)}.`);
|
||
}
|
||
async _handleUserEnter(e) {
|
||
const { userID: t, data: i } = F(e);
|
||
t && E.getData(s.CALL, a.CALL_ROLE) === p.CALLEE && E.getData(s.CALL, a.CALL_STATUS) === h.CALLING && (this._callService._handleAcceptResponse({}), this._callService._cleanupAvoidRepeatCallState("accept")), this._callerChangeToConnected(), i != null && i.playerList && E.update(s.CALL, a.PLAYER, i.playerList), await this._addUserToRemoteUserInfoList(t);
|
||
let A = E.getData(s.CALL, a.REMOTE_USER_INFO_LIST);
|
||
A = A.map((r) => (r.userId === t && (r.isEnter = !0), r)), A.length > 0 && (E.update(s.CALL, a.REMOTE_USER_INFO_LIST, A), E.update(s.CALL, a.REMOTE_USER_INFO_EXCLUDE_VOLUMN_LIST, A), mt.updateViewBackgroundUserId("remote")), console.log(`${a.PREFIX}userEnter event data: ${JSON.stringify(e)}.`);
|
||
}
|
||
_handleUserLeave(e) {
|
||
console.log(`${a.PREFIX}userLeave event data: ${JSON.stringify(e)}.`);
|
||
const { data: t, userID: i } = F(e);
|
||
if (t != null && t.playerList && E.update(s.CALL, a.PLAYER, t.playerList), E.getData(s.CALL, a.IS_GROUP)) {
|
||
const r = (E.getData(s.CALL, a.REMOTE_USER_INFO_LIST).find((o) => o.userId === i) || {}).displayUserInfo || i;
|
||
E.update(s.CALL, a.TOAST_INFO, { content: { key: N.END_CALL, options: { userList: r } } });
|
||
}
|
||
i && ue([i]);
|
||
}
|
||
_handleInviteeReject(e) {
|
||
this._unNormalEventsManager(e, C.REJECT);
|
||
}
|
||
_handleNoResponse(e) {
|
||
this._unNormalEventsManager(e, C.NO_RESP);
|
||
}
|
||
_handleLineBusy(e) {
|
||
this._unNormalEventsManager(e, C.LINE_BUSY);
|
||
}
|
||
_handleCallNotConnected(e) {
|
||
var t, i, A;
|
||
(i = (t = this == null ? void 0 : this._callService) == null ? void 0 : t._cleanupAvoidRepeatCallState) == null || i.call(t), (A = this._callService) == null || A.executeExternalAfterCalling(), this._unNormalEventsManager(e, C.ON_CALL_NOT_CONNECTED);
|
||
}
|
||
async _handleOnUserInviting(e) {
|
||
const { userID: t } = F(e);
|
||
t && t !== E.getData(s.CALL, a.LOCAL_USER_INFO).userId && await this._addUserToRemoteUserInfoList(t);
|
||
}
|
||
_handleCallingEnd(e) {
|
||
var t, i;
|
||
console.log(`${a.PREFIX}callEnd event data: ${JSON.stringify(e)}.`), (t = this._callService) == null || t.executeExternalAfterCalling(), (i = this._callService) == null || i._resetCallStore();
|
||
}
|
||
// SDK_READY 后才能调用 tim 接口, 否则登录后立刻获取导致调用接口失败. v2.27.4+、v3 接口 login 后会抛出 SDK_READY
|
||
async _handleSDKReady(e) {
|
||
var i;
|
||
let t = E.getData(s.CALL, a.LOCAL_USER_INFO);
|
||
t = await Nt(t.userId, (i = this._callService) == null ? void 0 : i.getTim()), E.update(s.CALL, a.LOCAL_USER_INFO, t), E.update(s.CALL, a.LOCAL_USER_INFO_EXCLUDE_VOLUMN, t);
|
||
}
|
||
_handleKickedOut(e) {
|
||
var t, i, A;
|
||
console.log(`${a.PREFIX}kickOut event data: ${JSON.stringify(e)}.`), (t = this._callService) != null && t.kickedOut && ((i = this._callService) == null || i.kickedOut(e)), E.update(s.CALL, a.CALL_TIPS, N.KICK_OUT), (A = this._callService) == null || A._resetCallStore();
|
||
}
|
||
_messageSentByMe(e) {
|
||
var i, A;
|
||
const t = e == null ? void 0 : e.data;
|
||
(i = this._callService) != null && i.onMessageSentByMe && ((A = this._callService) == null || A.onMessageSentByMe(t));
|
||
}
|
||
_handleCallMessage(e) {
|
||
const t = F(e);
|
||
this._callService._chatCombine.callTUIService({ message: t });
|
||
}
|
||
_handleCallTypeChange(e) {
|
||
var A;
|
||
const { newCallType: t, type: i } = F(e);
|
||
E.update(s.CALL, a.CALL_MEDIA_TYPE, t || i), (A = this._callService) == null || A.setSoundMode(M.EAR);
|
||
}
|
||
_handleNetworkQuality(e) {
|
||
const { networkQualityList: t = [] } = F(e);
|
||
E.update(s.CALL, a.NETWORK_STATUS, t);
|
||
const i = E.getData(s.CALL, a.IS_GROUP), A = E.getData(s.CALL, a.LOCAL_USER_INFO), r = E.getData(s.CALL, a.REMOTE_USER_INFO_LIST);
|
||
if (!i) {
|
||
if (t.find((l) => {
|
||
var u;
|
||
return ((u = r[0]) == null ? void 0 : u.userId) === (l == null ? void 0 : l.userId) && (l == null ? void 0 : l.quality) >= Fe;
|
||
})) {
|
||
E.update(s.CALL, a.CALL_TIPS, N.REMOTE_NETWORK_IS_POOR);
|
||
return;
|
||
}
|
||
if (t.find((l) => (A == null ? void 0 : A.userId) === (l == null ? void 0 : l.userId) && (l == null ? void 0 : l.quality) >= Fe)) {
|
||
E.update(s.CALL, a.CALL_TIPS, N.LOCAL_NETWORK_IS_POOR);
|
||
return;
|
||
}
|
||
}
|
||
}
|
||
async _startRemoteView(e) {
|
||
var t;
|
||
if (!e) {
|
||
console.warn(`${a.PREFIX}_startRemoteView userID is empty`);
|
||
return;
|
||
}
|
||
try {
|
||
const i = E.getData(s.CALL, a.DISPLAY_MODE);
|
||
await ((t = this._callService) == null ? void 0 : t.getTUICallEngineInstance().startRemoteView({ userID: e, videoViewDomID: `${e}_0`, options: { objectFit: i } }));
|
||
} catch (i) {
|
||
return console.error(`${a.PREFIX}_startRemoteView error: ${i}.`), Promise.reject(i);
|
||
}
|
||
}
|
||
_setRemoteUserInfoAudioVideoAvailable(e, t, i) {
|
||
let A = E.getData(s.CALL, a.REMOTE_USER_INFO_LIST);
|
||
A = A.map((r) => {
|
||
if (r.userId === i) {
|
||
if (t === a.AUDIO)
|
||
return { ...r, isAudioAvailable: e };
|
||
if (t === a.VIDEO)
|
||
return { ...r, isVideoAvailable: e };
|
||
}
|
||
return r;
|
||
}), A.length > 0 && (E.update(s.CALL, a.REMOTE_USER_INFO_LIST, A), E.update(s.CALL, a.REMOTE_USER_INFO_EXCLUDE_VOLUMN_LIST, A));
|
||
}
|
||
async _handleUserVideoAvailable(e) {
|
||
const { userID: t, isVideoAvailable: i } = F(e);
|
||
console.log(`${a.PREFIX}_handleUserVideoAvailable event data: ${JSON.stringify(e)}.`), this._setRemoteUserInfoAudioVideoAvailable(i, a.VIDEO, t);
|
||
try {
|
||
i && await this._startRemoteView(t);
|
||
} catch (A) {
|
||
console.error(`${a.PREFIX}_startRemoteView failed, error: ${A}.`);
|
||
}
|
||
}
|
||
_handleUserAudioAvailable(e) {
|
||
const { userID: t, isAudioAvailable: i } = F(e);
|
||
console.log(`${a.PREFIX}_handleUserAudioAvailable event data: ${JSON.stringify(e)}.`), this._setRemoteUserInfoAudioVideoAvailable(i, a.AUDIO, t);
|
||
}
|
||
_handleUserVoiceVolume(e) {
|
||
try {
|
||
const { volumeMap: t } = F(e);
|
||
if ((t || []).length === 0)
|
||
return;
|
||
const i = E.getData(s.CALL, a.LOCAL_USER_INFO);
|
||
let A = E.getData(s.CALL, a.REMOTE_USER_INFO_LIST);
|
||
const [r] = t.filter((l) => l.userId === i.userId), o = t.reduce((l, u) => u.userId !== i.userId ? { ...l, [u.userId]: u.audioVolume } : l, {});
|
||
i.volume = r.audioVolume, A = A.map((l) => ({ ...l, volume: o[l.userId] }));
|
||
const I = {
|
||
[a.LOCAL_USER_INFO]: i,
|
||
[a.REMOTE_USER_INFO_LIST]: A
|
||
};
|
||
E.updateStore(I, s.CALL);
|
||
} catch (t) {
|
||
console.debug(t);
|
||
}
|
||
}
|
||
_handleDeviceUpdate(e) {
|
||
const { cameraList: t, microphoneList: i, speakerList: A, currentCamera: r, currentMicrophone: o, currentSpeaker: I } = e;
|
||
E.update(s.CALL, a.DEVICE_LIST, { cameraList: t, microphoneList: i, speakerList: A, currentCamera: r, currentMicrophone: o, currentSpeaker: I });
|
||
}
|
||
// ==========================【 miniProgram 私有事件】==========================
|
||
_handleUserUpdate(e) {
|
||
const t = F(e);
|
||
t != null && t.pusher && E.update(s.CALL, a.PUSHER, t.pusher), t != null && t.playerList && E.update(s.CALL, a.PLAYER, t.playerList);
|
||
}
|
||
async _addUserToRemoteUserInfoList(e) {
|
||
var A;
|
||
let t = E.getData(s.CALL, a.REMOTE_USER_INFO_LIST);
|
||
if (!t.find((r) => (r == null ? void 0 : r.userId) === e)) {
|
||
t.push({ userId: e }), E.update(s.CALL, a.REMOTE_USER_INFO_LIST, t), E.update(s.CALL, a.REMOTE_USER_INFO_EXCLUDE_VOLUMN_LIST, t);
|
||
const [r] = await te([e], (A = this._callService) == null ? void 0 : A.getTim());
|
||
t = E.getData(s.CALL, a.REMOTE_USER_INFO_LIST), t.forEach((o) => {
|
||
(o == null ? void 0 : o.userId) === e && (o = Object.assign(o, r));
|
||
}), E.update(s.CALL, a.REMOTE_USER_INFO_LIST, t), E.update(s.CALL, a.REMOTE_USER_INFO_EXCLUDE_VOLUMN_LIST, t);
|
||
}
|
||
}
|
||
};
|
||
yt([
|
||
vt({
|
||
retries: 5,
|
||
timeout: 200,
|
||
onRetrying(n) {
|
||
console.warn(`${a.PREFIX}_startRemoteView, retrying [${n}]`);
|
||
}
|
||
})
|
||
], qe.prototype, "_startRemoteView", 1);
|
||
let Vt = qe;
|
||
var Kt = Object.defineProperty, bt = Object.getOwnPropertyDescriptor, w = (n, e, t, i) => {
|
||
for (var A = i > 1 ? void 0 : i ? bt(e, t) : e, r = n.length - 1, o; r >= 0; r--)
|
||
(o = n[r]) && (A = (i ? o(e, t, A) : o(A)) || A);
|
||
return i && A && Kt(e, t, A), A;
|
||
};
|
||
const Qe = We.getInstance(), c = Ee.getInstance(), Q = K.getInstance();
|
||
Q.setTUIStore(c);
|
||
const ye = "4.2.7", R = class $ {
|
||
constructor() {
|
||
this._tim = null, this._TUICore = null, this._timerId = -1, this._startTimeStamp = Le(), this._bellContext = null, this._isFromChat = !1, this._currentGroupId = "", this._offlinePushInfo = null, this._permissionCheckTimer = null, this._chatCombine = null, this._engineEventHandler = null, this._isInitialized = !1, this._handleCallStatusChange = async (e) => {
|
||
var t, i, A, r, o, I;
|
||
try {
|
||
const l = {
|
||
callRole: c.getData(s.CALL, a.CALL_ROLE),
|
||
callStatus: c.getData(s.CALL, a.CALL_STATUS)
|
||
};
|
||
if ((i = (t = this._tuiCallEngine) == null ? void 0 : t.reportLog) == null || i.call(t, {
|
||
name: "TUICallkit._handleCallStatusChange.start",
|
||
data: { bellParams: l }
|
||
}), this._bellContext.setBellProperties(l), e === h.CALLING)
|
||
(A = this == null ? void 0 : this._bellContext) == null || A.play();
|
||
else if ((o = (r = this._tuiCallEngine) == null ? void 0 : r.reportLog) == null || o.call(r, {
|
||
name: "TUICallkit._bellContext.stop"
|
||
}), (I = this == null ? void 0 : this._bellContext) == null || I.stop(), e === h.CONNECTED) {
|
||
const u = c.getData(s.CALL, a.IS_GROUP), L = c.getData(s.CALL, a.CALL_MEDIA_TYPE), g = c.getData(s.CALL, a.REMOTE_USER_INFO_LIST), _ = u ? G.DIALING_GROUP : G.DIALING_C2C;
|
||
c.update(s.CALL, a.CALL_TIPS, ""), this.statusChanged && this.statusChanged({ oldStatus: _, newStatus: ne() }), !u && L === d.VIDEO && this.switchScreen(g[0].domId);
|
||
}
|
||
} catch (l) {
|
||
console.warn(`${a.PREFIX}handleCallStatusChange, ${l}.`);
|
||
}
|
||
}, console.log(`${a.PREFIX}version: ${ye}`), this._wasmReadyPromise = new Promise((e) => {
|
||
this._wasmReadyResolve = e;
|
||
}), this._loadWasm(), this._watchTUIStore(), this._engineEventHandler = Vt.getInstance({ callService: this }), this._chatCombine = H.getInstance({ callService: this });
|
||
}
|
||
static getInstance() {
|
||
return $.instance || ($.instance = new $()), $.instance;
|
||
}
|
||
_loadWasm() {
|
||
Re.once("ready", () => this._wasmReadyResolve());
|
||
}
|
||
async init(e) {
|
||
if (this._isInitialized) {
|
||
console.warn("TUICallKit has already been initialized.");
|
||
return;
|
||
}
|
||
await this._wasmReadyPromise, this._isInitialized || (this._doInit(e), this._isInitialized = !0);
|
||
}
|
||
async _doInit(e) {
|
||
var t, i, A;
|
||
try {
|
||
if (this._tuiCallEngine)
|
||
return;
|
||
let { userID: r, tim: o, userSig: I, sdkAppID: l, SDKAppID: u, isFromChat: L, component: g = de.TUI_CALL_KIT } = e;
|
||
this._TUICore && (l = this._TUICore.SDKAppID, o = this._TUICore.tim), this._tim = o, console.log(`${a.PREFIX}init sdkAppId: ${l || u}, userId: ${r}`);
|
||
let _ = "web", f = 2;
|
||
f = 3, _ = `wx-uniapp-vue${f}`, this._tuiCallEngine = Re.createInstance({
|
||
tim: o,
|
||
// @ts-ignore
|
||
sdkAppID: l || u,
|
||
// 兼容传入 SDKAppID 的问题
|
||
callkitVersion: ye,
|
||
isFromChat: L || !1,
|
||
component: g,
|
||
scene: _
|
||
}), Q.setEngineInstance(this._tuiCallEngine), this._addListenTuiCallEngineEvent(), this._bellContext && ((t = this._bellContext) == null || t.destroy()), this._bellContext = new Ot(), c.update(s.CALL, a.LOCAL_USER_INFO, { userId: r }), c.update(s.CALL, a.LOCAL_USER_INFO_EXCLUDE_VOLUMN, { userId: r }), Q.updateViewBackgroundUserId("local"), await this._tuiCallEngine.login({ userID: r, userSig: I, assetsPath: "" });
|
||
const S = c.getData(s.CALL, a.CUSTOM_UI_CONFIG);
|
||
(A = (i = this._tuiCallEngine) == null ? void 0 : i.reportLog) == null || A.call(i, {
|
||
name: "TUICallkit.init",
|
||
data: {
|
||
uiConfig: S
|
||
}
|
||
});
|
||
} catch (r) {
|
||
throw console.error(`${a.PREFIX}init failed, error: ${r}.`), r;
|
||
}
|
||
}
|
||
// component destroy
|
||
async destroyed() {
|
||
var e;
|
||
try {
|
||
this._isInitialized = !1;
|
||
const t = c.getData(s.CALL, a.CALL_STATUS);
|
||
if (t !== h.IDLE)
|
||
throw new Error(`please destroyed when status is idle, current status: ${t}`);
|
||
this._tuiCallEngine && (this._removeListenTuiCallEngineEvent(), await this._tuiCallEngine.destroyInstance(), this._tuiCallEngine = null), (e = this._bellContext) == null || e.destroy(), this._bellContext = null;
|
||
} catch (t) {
|
||
throw console.error(`${a.PREFIX}destroyed failed, error: ${t}.`), t;
|
||
}
|
||
}
|
||
async inviteUser(e) {
|
||
if (c.getData(s.CALL, a.CALL_STATUS) !== h.IDLE)
|
||
try {
|
||
const { userIDList: t } = e;
|
||
let i = await te(t, this.getTim());
|
||
const A = c.getData(s.CALL, a.REMOTE_USER_INFO_LIST);
|
||
if (t.filter((o) => !A.some((I) => I.userId === o)).length === 0)
|
||
return;
|
||
c.update(s.CALL, a.REMOTE_USER_INFO_LIST, [...A, ...i]), c.update(s.CALL, a.REMOTE_USER_INFO_EXCLUDE_VOLUMN_LIST, [...A, ...i]), this._tuiCallEngine && await this._tuiCallEngine.inviteUser(e);
|
||
} catch (t) {
|
||
console.error(`${a.PREFIX}inviteUser failed, error: ${t}.`);
|
||
}
|
||
}
|
||
async calls(e) {
|
||
if (c.getData(s.CALL, a.CALL_STATUS) === h.IDLE)
|
||
try {
|
||
c.update(s.CALL, a.PUSHER_ID, a.NEW_PUSHER);
|
||
const { userIDList: t, type: i, chatGroupID: A, offlinePushInfo: r } = e;
|
||
if (c.getData(s.CALL, a.CALL_STATUS) !== h.IDLE)
|
||
return;
|
||
const o = t.map((l) => ({ userId: l }));
|
||
await this._updateCallStoreBeforeCall(i, o, A), this.executeExternalBeforeCalling(), e.offlinePushInfo = { ...this.getDefaultOfflinePushInfo(), ...r };
|
||
const I = await this._tuiCallEngine.calls(e);
|
||
await this._updateCallStoreAfterCall(t, I);
|
||
} catch (t) {
|
||
this._handleCallError(t, "calls");
|
||
}
|
||
}
|
||
async join(e) {
|
||
if (c.getData(s.CALL, a.CALL_STATUS) !== h.CONNECTED)
|
||
try {
|
||
c.update(s.CALL, a.PUSHER_ID, a.NEW_PUSHER);
|
||
const t = {
|
||
[a.CALL_ROLE]: p.CALLEE,
|
||
[a.IS_GROUP]: !0,
|
||
[a.CALL_STATUS]: h.CONNECTED,
|
||
[a.CALL_MEDIA_TYPE]: c.getData(s.CALL, a.CALL_MEDIA_TYPE) || d.AUDIO
|
||
// default audio callMediaType
|
||
};
|
||
c.updateStore(t, s.CALL);
|
||
const i = await this._tuiCallEngine.join(e);
|
||
c.update(s.CALL, a.IS_CLICKABLE, !0), this.startTimer(), c.update(s.CALL, a.PUSHER, i), this.setSoundMode(e.type === d.AUDIO ? M.EAR : M.SPEAKER);
|
||
const A = c.getData(s.CALL, a.LOCAL_USER_INFO);
|
||
c.update(s.CALL, a.LOCAL_USER_INFO, { ...A, isEnter: !0 }), c.update(s.CALL, a.LOCAL_USER_INFO_EXCLUDE_VOLUMN, { ...A, isEnter: !0 }), await this.openMicrophone(), m(!0, a.AUDIO);
|
||
} catch (t) {
|
||
this._handleCallError(t, "join");
|
||
}
|
||
}
|
||
// ===============================【其它对外接口】===============================
|
||
getTUICallEngineInstance() {
|
||
return (this == null ? void 0 : this._tuiCallEngine) || null;
|
||
}
|
||
setLogLevel(e) {
|
||
var t;
|
||
(t = this == null ? void 0 : this._tuiCallEngine) == null || t.setLogLevel(e);
|
||
}
|
||
setLanguage(e) {
|
||
console.warn(`${a.PREFIX}The miniProgram does not support setLanguage`);
|
||
}
|
||
enableFloatWindow(e) {
|
||
c.update(s.CALL, a.ENABLE_FLOAT_WINDOW, e);
|
||
}
|
||
async setSelfInfo(e) {
|
||
const { nickName: t, avatar: i } = e;
|
||
try {
|
||
await this._tuiCallEngine.setSelfInfo(t, i);
|
||
} catch (A) {
|
||
console.error(`${a.PREFIX}setSelfInfo failed, error: ${A}.`);
|
||
}
|
||
}
|
||
async enableVirtualBackground(e) {
|
||
c.update(s.CALL, a.IS_SHOW_ENABLE_VIRTUAL_BACKGROUND, e);
|
||
}
|
||
// 修改默认铃声:只支持本地铃声文件,不支持在线铃声文件;修改铃声修改的是被叫的铃声
|
||
async setCallingBell(e) {
|
||
const t = { calleeBellFilePath: e };
|
||
this._bellContext.setBellProperties(t);
|
||
}
|
||
async enableMuteMode(e) {
|
||
try {
|
||
const t = { isMuteBell: e };
|
||
this._bellContext.setBellProperties(t), await this._bellContext.setBellMute(e);
|
||
} catch (t) {
|
||
console.warn(`${a.PREFIX}enableMuteMode failed, error: ${t}.`);
|
||
}
|
||
}
|
||
hideFeatureButton(e) {
|
||
Q.hideFeatureButton(e);
|
||
}
|
||
setLocalViewBackgroundImage(e) {
|
||
Q.setLocalViewBackgroundImage(e);
|
||
}
|
||
setRemoteViewBackgroundImage(e, t) {
|
||
Q.setRemoteViewBackgroundImage(e, t);
|
||
}
|
||
setLayoutMode(e) {
|
||
Q.setLayoutMode(e);
|
||
}
|
||
setCameraDefaultState(e) {
|
||
Q.setCameraDefaultState(e);
|
||
}
|
||
// =============================【实验性接口】=============================
|
||
callExperimentalAPI(e) {
|
||
var r, o;
|
||
const t = JSON.parse(e);
|
||
if (t === e)
|
||
return;
|
||
const { api: i, params: A } = t;
|
||
if (!(!i || !A))
|
||
try {
|
||
switch (i) {
|
||
case "forceUseV2API":
|
||
const { enable: I } = A;
|
||
c.update(s.CALL, a.IS_FORCE_USE_V2_API, !!I);
|
||
break;
|
||
default:
|
||
break;
|
||
}
|
||
} catch (I) {
|
||
(o = (r = this._tuiCallEngine) == null ? void 0 : r.reportLog) == null || o.call(r, { name: "TUICallKit.callExperimentalAPI.fail", data: { error: I } });
|
||
}
|
||
}
|
||
async accept() {
|
||
var t, i, A, r;
|
||
const e = c.getData(s.CALL, a.CALL_STATUS);
|
||
if ((i = (t = this._tuiCallEngine) == null ? void 0 : t.reportLog) == null || i.call(t, {
|
||
name: "TUICallKit.accept.start",
|
||
data: { callStatus: e }
|
||
}), e !== h.CONNECTED)
|
||
try {
|
||
const I = {
|
||
microphone: !0,
|
||
camera: c.getData(s.CALL, a.CALL_MEDIA_TYPE) === d.VIDEO
|
||
};
|
||
if (!await this._tuiCallEngine.deviceCheck(I)) {
|
||
const L = c.getData(s.CALL, a.CALL_MEDIA_TYPE);
|
||
typeof Ne == "function" && await Ne(L);
|
||
}
|
||
c.update(s.CALL, a.PUSHER_ID, a.NEW_PUSHER);
|
||
const u = await this._tuiCallEngine.accept();
|
||
await this._handleAcceptResponse(u);
|
||
} catch (o) {
|
||
if ((r = (A = this._tuiCallEngine) == null ? void 0 : A.reportLog) == null || r.call(A, {
|
||
name: "TUICallKit.accept.fail",
|
||
level: "error",
|
||
error: o
|
||
}), Me(o))
|
||
return;
|
||
he(o, d.AUDIO, this._tuiCallEngine), this._resetCallStore();
|
||
}
|
||
}
|
||
async _handleAcceptResponse(e) {
|
||
var t, i, A;
|
||
if (e) {
|
||
if (c.getData(s.CALL, a.CALL_STATUS) === h.CONNECTED)
|
||
return;
|
||
this.openMicrophone(), (t = this._bellContext) == null || t.stop(), c.update(s.CALL, a.CALL_STATUS, h.CONNECTED), (A = this._chatCombine) == null || A.callTUIService({ message: (i = e == null ? void 0 : e.data) == null ? void 0 : i.message }), c.update(s.CALL, a.IS_CLICKABLE, !0), this.startTimer();
|
||
const r = c.getData(s.CALL, a.CALL_MEDIA_TYPE), o = this._getFeatureButtonDefaultState(x.Camera) === ee.Close;
|
||
r === d.VIDEO && !o && await this.openCamera(a.LOCAL_VIDEO), e.pusher && c.update(s.CALL, a.PUSHER, e.pusher), this.setSoundMode(r === d.AUDIO ? M.EAR : M.SPEAKER);
|
||
const I = c.getData(s.CALL, a.LOCAL_USER_INFO);
|
||
c.update(s.CALL, a.LOCAL_USER_INFO, { ...I, isEnter: !0 }), c.update(s.CALL, a.LOCAL_USER_INFO_EXCLUDE_VOLUMN, { ...I, isEnter: !0 }), m(!0, a.AUDIO);
|
||
}
|
||
}
|
||
async hangup() {
|
||
if (c.getData(s.CALL, a.CALL_STATUS) !== h.IDLE) {
|
||
try {
|
||
const e = await this._tuiCallEngine.hangup();
|
||
e == null || e.forEach((t) => {
|
||
var i, A;
|
||
(t == null ? void 0 : t.code) === 0 && ((A = this._chatCombine) == null || A.callTUIService({ message: (i = t == null ? void 0 : t.data) == null ? void 0 : i.message }));
|
||
});
|
||
} catch (e) {
|
||
console.debug(e);
|
||
}
|
||
this._resetCallStore();
|
||
}
|
||
}
|
||
async reject() {
|
||
var e, t;
|
||
if (c.getData(s.CALL, a.CALL_STATUS) !== h.IDLE) {
|
||
try {
|
||
const i = await this._tuiCallEngine.reject();
|
||
(i == null ? void 0 : i.code) === 0 && ((t = this._chatCombine) == null || t.callTUIService({ message: (e = i == null ? void 0 : i.data) == null ? void 0 : e.message }));
|
||
} catch (i) {
|
||
console.debug(i);
|
||
}
|
||
this._resetCallStore();
|
||
}
|
||
}
|
||
async openCamera(e) {
|
||
try {
|
||
if (Qe.isH5 || Qe.isWeChat) {
|
||
const i = c.getData(s.CALL, a.CAMERA_POSITION) === V.FRONT;
|
||
this._tuiCallEngine.openCamera(e, i);
|
||
} else
|
||
await this._tuiCallEngine.openCamera(e);
|
||
m(!0, a.VIDEO);
|
||
} catch (t) {
|
||
he(t, d.VIDEO, this._tuiCallEngine), console.error(`${a.PREFIX}openCamera error: ${t}.`);
|
||
}
|
||
}
|
||
async closeCamera() {
|
||
try {
|
||
await this._tuiCallEngine.closeCamera(), m(!1, a.VIDEO);
|
||
} catch (e) {
|
||
console.error(`${a.PREFIX}closeCamera error: ${e}.`);
|
||
}
|
||
}
|
||
async openMicrophone() {
|
||
try {
|
||
await this._tuiCallEngine.openMicrophone(), m(!0, a.AUDIO);
|
||
} catch (e) {
|
||
console.error(`${a.PREFIX}openMicrophone failed, error: ${e}.`);
|
||
}
|
||
}
|
||
async closeMicrophone() {
|
||
try {
|
||
await this._tuiCallEngine.closeMicrophone(), m(!1, a.AUDIO);
|
||
} catch (e) {
|
||
console.error(`${a.PREFIX}closeMicrophone failed, error: ${e}.`);
|
||
}
|
||
}
|
||
switchScreen(e) {
|
||
e && c.update(s.CALL, a.BIG_SCREEN_USER_ID, e);
|
||
}
|
||
async switchCallMediaType() {
|
||
var e, t;
|
||
try {
|
||
const i = c.getData(s.CALL, a.CALL_MEDIA_TYPE);
|
||
if (i === d.AUDIO) {
|
||
console.warn(`${a.PREFIX}switchCallMediaType failed, ${i} not support.`);
|
||
return;
|
||
}
|
||
const A = await this._tuiCallEngine.switchCallMediaType(d.AUDIO);
|
||
(A == null ? void 0 : A.code) === 0 && ((t = this._chatCombine) == null || t.callTUIService({ message: (e = A == null ? void 0 : A.data) == null ? void 0 : e.message })), c.update(s.CALL, a.CALL_MEDIA_TYPE, d.AUDIO);
|
||
const o = c.getData(s.CALL, a.IS_GROUP) ? G.CALLING_GROUP_VIDEO : G.CALLING_C2C_VIDEO, I = ne();
|
||
this.statusChanged && this.statusChanged({ oldStatus: o, newStatus: I }), this.setSoundMode(M.EAR);
|
||
} catch (i) {
|
||
console.error(`${a.PREFIX}switchCallMediaType failed, error: ${i}.`);
|
||
}
|
||
}
|
||
async switchCamera() {
|
||
const t = c.getData(s.CALL, a.CAMERA_POSITION) === V.BACK ? V.FRONT : V.BACK;
|
||
try {
|
||
await this._tuiCallEngine.switchCamera(t), c.update(s.CALL, a.CAMERA_POSITION, t);
|
||
} catch (i) {
|
||
console.error(`${a.PREFIX}_switchCamera failed, error: ${i}.`);
|
||
}
|
||
}
|
||
setSoundMode(e) {
|
||
var t;
|
||
try {
|
||
let i = c.getData(s.CALL, a.IS_EAR_PHONE);
|
||
const A = e || (i ? M.SPEAKER : M.EAR);
|
||
(t = this._tuiCallEngine) == null || t.selectAudioPlaybackDevice(A), e ? i = e === M.EAR : i = !i, c.update(s.CALL, a.IS_EAR_PHONE, i);
|
||
} catch (i) {
|
||
console.error(`${a.PREFIX}setSoundMode failed, error: ${i}.`);
|
||
}
|
||
}
|
||
async setBlurBackground(e) {
|
||
try {
|
||
c.update(s.CALL, a.ENABLE_VIRTUAL_BACKGROUND, e);
|
||
} catch (t) {
|
||
console.error(`${a.PREFIX}_setBlurBackground failed, error: ${t}.`);
|
||
}
|
||
}
|
||
// ==========================【TUICallEngine 事件处理】==========================
|
||
_addListenTuiCallEngineEvent() {
|
||
this._engineEventHandler.addListenTuiCallEngineEvent();
|
||
}
|
||
_removeListenTuiCallEngineEvent() {
|
||
this._engineEventHandler.removeListenTuiCallEngineEvent();
|
||
}
|
||
setCallback(e) {
|
||
const { beforeCalling: t, afterCalling: i, onMinimized: A, onMessageSentByMe: r, kickedOut: o, statusChanged: I } = e;
|
||
t && (this.beforeCalling = t), i && (this.afterCalling = i), A && (this.onMinimized = A), r && (this.onMessageSentByMe = r), o && (this.kickedOut = o), I && (this.statusChanged = I);
|
||
}
|
||
toggleMinimize() {
|
||
const e = c.getData(s.CALL, a.IS_MINIMIZED);
|
||
c.update(s.CALL, a.IS_MINIMIZED, !e), console.log(`${a.PREFIX}toggleMinimize: ${e} -> ${!e}.`), this.onMinimized && this.onMinimized(e, !e);
|
||
}
|
||
executeExternalBeforeCalling() {
|
||
this.beforeCalling && this.beforeCalling();
|
||
}
|
||
executeExternalAfterCalling() {
|
||
this.afterCalling && this.afterCalling();
|
||
}
|
||
// 处理用户异常退出的情况, 小程序 ”右滑“、"左上角退出"; web 页面关闭浏览器或关闭 tab 页面
|
||
async handleExceptionExit(e) {
|
||
var t, i;
|
||
try {
|
||
const A = c.getData(s.CALL, a.CALL_STATUS), r = c.getData(s.CALL, a.CALL_ROLE);
|
||
if ((i = (t = this._tuiCallEngine) == null ? void 0 : t.reportLog) == null || i.call(t, { name: "TUICallkit.handleExceptionExit", data: { callStatus: A, callRole: r } }), A === h.IDLE)
|
||
return;
|
||
A === h.CALLING && (r === p.CALLER ? await (this == null ? void 0 : this.hangup()) : await (this == null ? void 0 : this.reject())), A === h.CONNECTED && await (this == null ? void 0 : this.hangup()), this == null || this._resetCallStore();
|
||
} catch (A) {
|
||
console.error(`${a.PREFIX} handleExceptionExit failed, error: ${A}.`);
|
||
}
|
||
e && (e.returnValue = "");
|
||
}
|
||
// 处理 pusher 内部错误,没有 live-pusher 能力时做出弹窗提示。
|
||
handlePusherError(e) {
|
||
var t;
|
||
((t = e == null ? void 0 : e.detail) == null ? void 0 : t.errMsg) === "fail:access denied" && lt();
|
||
}
|
||
// ========================【TUICallKit 组件属性设置方法】========================
|
||
setVideoDisplayMode(e) {
|
||
c.update(s.CALL, a.DISPLAY_MODE, e);
|
||
}
|
||
async setVideoResolution(e) {
|
||
var t;
|
||
try {
|
||
if (!e)
|
||
return;
|
||
c.update(s.CALL, a.VIDEO_RESOLUTION, e), await ((t = this._tuiCallEngine) == null ? void 0 : t.setVideoQuality(e));
|
||
} catch (i) {
|
||
console.warn(`${a.PREFIX}setVideoResolution failed, error: ${i}.`);
|
||
}
|
||
}
|
||
// 通话时长更新
|
||
startTimer() {
|
||
this._timerId === -1 && (this._startTimeStamp = Le(), this._timerId = Ce.run(a.TIMEOUT, this._updateCallDuration.bind(this), { delay: 1e3 }));
|
||
}
|
||
// =========================【private methods for service use】=========================
|
||
// 处理 “呼叫” 抛出的异常
|
||
_handleCallError(e, t) {
|
||
if (this._permissionCheckTimer && clearInterval(this._permissionCheckTimer), !Me(e))
|
||
throw ot(e), he(e, d.AUDIO, this._tuiCallEngine), console.error(`${a.PREFIX}${t} failed, error: ${e}.`), this._resetCallStore(), e;
|
||
}
|
||
async _updateCallStoreBeforeCall(e, t, i) {
|
||
let A = N.CALLER_CALLING_MSG;
|
||
(i || c.getData(s.CALL, a.IS_MINIMIZED) || t.length > 1) && (A = N.CALLER_GROUP_CALLING_MSG), console.warn(`呼叫前更新 call status: ${!!i || t.length > 1}, ${i}, ${JSON.stringify(t)}`);
|
||
let r = {
|
||
[a.CALL_MEDIA_TYPE]: e,
|
||
[a.CALL_ROLE]: p.CALLER,
|
||
[a.REMOTE_USER_INFO_LIST]: t,
|
||
[a.REMOTE_USER_INFO_EXCLUDE_VOLUMN_LIST]: t,
|
||
[a.IS_GROUP]: !!i || t.length > 1,
|
||
[a.CALL_TIPS]: A,
|
||
[a.GROUP_ID]: i
|
||
};
|
||
const o = { enableCamera: e === d.VIDEO, enableMic: !0 };
|
||
r = { ...r, [a.PUSHER]: o }, c.updateStore(r, s.CALL);
|
||
const I = await rt(e, this);
|
||
console.log(`${a.PREFIX}mini beforeCall return callStatus: ${I}.`), c.update(s.CALL, a.CALL_STATUS, I);
|
||
const l = await te(t.map((g) => g.userId), this.getTim());
|
||
l.length > 0 && (c.update(s.CALL, a.REMOTE_USER_INFO_LIST, l), c.update(s.CALL, a.REMOTE_USER_INFO_EXCLUDE_VOLUMN_LIST, l));
|
||
const u = {
|
||
microphone: !0,
|
||
camera: e === d.VIDEO
|
||
};
|
||
let L = await this._tuiCallEngine.deviceCheck(u);
|
||
L || (this._permissionCheckTimer && clearInterval(this._permissionCheckTimer), this._permissionCheckTimer = setInterval(async () => {
|
||
L = await this._tuiCallEngine.deviceCheck(u), L && this._permissionCheckTimer && (clearInterval(this._permissionCheckTimer), c.update(s.CALL, a.CALL_STATUS, h.CALLING));
|
||
}, 500));
|
||
}
|
||
async _updateCallStoreAfterCall(e, t) {
|
||
var i, A;
|
||
if (t) {
|
||
c.update(s.CALL, a.IS_CLICKABLE, !0), je(t == null ? void 0 : t.roomID, t == null ? void 0 : t.strRoomID);
|
||
const r = c.getData(s.CALL, a.CALL_MEDIA_TYPE);
|
||
(A = this._chatCombine) == null || A.callTUIService({ message: (i = t == null ? void 0 : t.data) == null ? void 0 : i.message }), t.pusher && c.update(s.CALL, a.PUSHER, t.pusher), this.setSoundMode(r === d.AUDIO ? M.EAR : M.SPEAKER), c.update(s.CALL, a.CALL_STATUS, h.CALLING);
|
||
const o = this._getFeatureButtonDefaultState(x.Camera) === ee.Close;
|
||
r === d.VIDEO && !o && await this.openCamera(a.LOCAL_VIDEO);
|
||
const I = c.getData(s.CALL, a.LOCAL_USER_INFO);
|
||
c.update(s.CALL, a.LOCAL_USER_INFO, { ...I, isEnter: !0 }), c.update(s.CALL, a.LOCAL_USER_INFO_EXCLUDE_VOLUMN, { ...I, isEnter: !0 }), m(!0, a.AUDIO);
|
||
} else
|
||
this._permissionCheckTimer && clearInterval(this._permissionCheckTimer), this._permissionCheckTimer = null, this._resetCallStore();
|
||
}
|
||
_getFeatureButtonDefaultState(e) {
|
||
var i;
|
||
const { button: t } = c.getData(s.CALL, a.CUSTOM_UI_CONFIG);
|
||
return (i = t == null ? void 0 : t[e]) == null ? void 0 : i.state;
|
||
}
|
||
_updateCallDuration() {
|
||
const e = Math.round((Le() - this._startTimeStamp) / 1e3), t = Xe(e);
|
||
c.update(s.CALL, a.CALL_DURATION, t);
|
||
}
|
||
_stopTimer() {
|
||
this._timerId !== -1 && (Ce.clearTask(this._timerId), this._timerId = -1);
|
||
}
|
||
// clear all use avoidRepeatCall decorator state
|
||
_cleanupAvoidRepeatCallState(e) {
|
||
var i, A;
|
||
(A = (i = this._tuiCallEngine) == null ? void 0 : i.reportLog) == null || A.call(i, { name: "TUICallkit._cleanupAvoidRepeatCallState", data: {} });
|
||
let t = [];
|
||
e ? t = [this[e]] : t = [
|
||
this.calls,
|
||
this.accept,
|
||
this.hangup,
|
||
this.reject
|
||
], t == null || t.forEach((r) => {
|
||
var o;
|
||
(o = r == null ? void 0 : r.clearCallState) == null || o.call(r, this);
|
||
});
|
||
}
|
||
_resetCallStore() {
|
||
var r;
|
||
this._cleanupAvoidRepeatCallState(), (r = this._bellContext) == null || r.stop();
|
||
const e = ne();
|
||
this._stopTimer();
|
||
let t = Object.keys(re).filter((o) => {
|
||
switch (re[o]) {
|
||
case a.CALL_STATUS:
|
||
case a.LANGUAGE:
|
||
case a.IS_GROUP:
|
||
case a.DISPLAY_MODE:
|
||
case a.VIDEO_RESOLUTION:
|
||
case a.ENABLE_FLOAT_WINDOW:
|
||
case a.LOCAL_USER_INFO:
|
||
case a.IS_SHOW_ENABLE_VIRTUAL_BACKGROUND:
|
||
case a.IS_FORCE_USE_V2_API:
|
||
case a.LOCAL_USER_INFO_EXCLUDE_VOLUMN:
|
||
return !1;
|
||
default:
|
||
return !0;
|
||
}
|
||
});
|
||
t = t.map((o) => re[o]), c.reset(s.CALL, t), c.getData(s.CALL, a.CALL_STATUS) !== h.IDLE && c.reset(s.CALL, [a.CALL_STATUS], !0), c.reset(s.CALL, [a.IS_MINIMIZED], !0), c.reset(s.CALL, [a.IS_EAR_PHONE], !0), c.reset(s.CALL, [a.PUSHER_ID], !0), c.reset(s.CALL, [a.ENABLE_VIRTUAL_BACKGROUND], !0), c.reset(s.CALL, [a.IS_MUTE_SPEAKER], !0), c.update(s.CALL, a.LOCAL_USER_INFO, {
|
||
...c.getData(s.CALL, a.LOCAL_USER_INFO),
|
||
isVideoAvailable: !1,
|
||
isAudioAvailable: !1
|
||
}), c.update(s.CALL, a.LOCAL_USER_INFO_EXCLUDE_VOLUMN, {
|
||
...c.getData(s.CALL, a.LOCAL_USER_INFO_EXCLUDE_VOLUMN),
|
||
isVideoAvailable: !1,
|
||
isAudioAvailable: !1
|
||
}), c.update(s.CALL, a.REMOTE_USER_INFO_LIST, []), c.update(s.CALL, a.REMOTE_USER_INFO_EXCLUDE_VOLUMN_LIST, []), c.update(s.CALL, a.CAMERA_POSITION, V.FRONT);
|
||
const A = ne();
|
||
e !== A && this.statusChanged && this.statusChanged({ oldStatus: e, newStatus: A });
|
||
}
|
||
// =========================【Calling the Chat SDK APi】=========================
|
||
// 获取群成员
|
||
async getGroupMemberList(e, t) {
|
||
const i = c.getData(s.CALL, a.GROUP_ID);
|
||
return await Tt(i, this.getTim(), e, t);
|
||
}
|
||
// 获取群信息
|
||
async getGroupProfile() {
|
||
const e = c.getData(s.CALL, a.GROUP_ID);
|
||
return await wt(e, this.getTim());
|
||
}
|
||
_watchTUIStore() {
|
||
c == null || c.watch(s.CALL, {
|
||
[a.CALL_STATUS]: this._handleCallStatusChange
|
||
});
|
||
}
|
||
_unwatchTUIStore() {
|
||
c == null || c.unwatch(s.CALL, {
|
||
[a.CALL_STATUS]: this._handleCallStatusChange
|
||
});
|
||
}
|
||
// =========================【融合 chat 】=========================
|
||
bindTUICore(e) {
|
||
this._TUICore = e;
|
||
}
|
||
// =========================【set、get methods】=========================
|
||
getTim() {
|
||
var e, t;
|
||
return this._tim ? this._tim : this._tuiCallEngine ? ((e = this._tuiCallEngine) == null ? void 0 : e.tim) || ((t = this._tuiCallEngine) == null ? void 0 : t.getTim()) : (console.warn(`${a.PREFIX}getTim warning: _tuiCallEngine Instance is not available.`), null);
|
||
}
|
||
setIsFromChat(e) {
|
||
this._isFromChat = e;
|
||
}
|
||
setCurrentGroupId(e) {
|
||
this._currentGroupId = e;
|
||
}
|
||
getCurrentGroupId() {
|
||
return this._currentGroupId;
|
||
}
|
||
setDefaultOfflinePushInfo(e) {
|
||
this._offlinePushInfo = e;
|
||
}
|
||
getDefaultOfflinePushInfo() {
|
||
const e = c.getData(s.CALL, a.LOCAL_USER_INFO);
|
||
return this._offlinePushInfo ? this._offlinePushInfo : {
|
||
title: (e == null ? void 0 : e.displayUserInfo) || "",
|
||
description: ie("you have a new call")
|
||
};
|
||
}
|
||
async getCallMessage(e) {
|
||
return await this._chatCombine.getCallKitMessage(e, this.getTim());
|
||
}
|
||
};
|
||
w([
|
||
T()
|
||
], R.prototype, "init", 1);
|
||
w([
|
||
T()
|
||
], R.prototype, "inviteUser", 1);
|
||
w([
|
||
T()
|
||
], R.prototype, "calls", 1);
|
||
w([
|
||
T()
|
||
], R.prototype, "join", 1);
|
||
w([
|
||
T()
|
||
], R.prototype, "accept", 1);
|
||
w([
|
||
T()
|
||
], R.prototype, "hangup", 1);
|
||
w([
|
||
T()
|
||
], R.prototype, "reject", 1);
|
||
w([
|
||
T()
|
||
], R.prototype, "openCamera", 1);
|
||
w([
|
||
T()
|
||
], R.prototype, "closeCamera", 1);
|
||
w([
|
||
T()
|
||
], R.prototype, "openMicrophone", 1);
|
||
w([
|
||
T()
|
||
], R.prototype, "closeMicrophone", 1);
|
||
w([
|
||
T()
|
||
], R.prototype, "switchScreen", 1);
|
||
w([
|
||
T()
|
||
], R.prototype, "switchCallMediaType", 1);
|
||
w([
|
||
T()
|
||
], R.prototype, "switchCamera", 1);
|
||
w([
|
||
T()
|
||
], R.prototype, "setSoundMode", 1);
|
||
w([
|
||
T()
|
||
], R.prototype, "setBlurBackground", 1);
|
||
let kt = R;
|
||
const Jt = kt.getInstance(), Wt = "4.2.7";
|
||
export {
|
||
d as CallMediaType,
|
||
p as CallRole,
|
||
x as FeatureButton,
|
||
Ke as LayoutMode,
|
||
a as NAME,
|
||
G as STATUS,
|
||
s as StoreName,
|
||
Jt as TUICallKitAPI,
|
||
Qe as TUIGlobal,
|
||
c as TUIStore,
|
||
Wt as Version,
|
||
me as VideoDisplayMode,
|
||
Ve as VideoResolution,
|
||
ie as t,
|
||
Q as uiDesign
|
||
};
|