@trtc/calls-uikit-react 4.2.3 → 4.2.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +3 -3
- package/src/Components/TUICallKit/TUICallKit.tsx +2 -0
- package/src/Components/components/common/AIAssistant/AIAssistant.ts +132 -0
- package/src/Components/components/common/AIAssistant/AISubtitle.tsx +89 -0
- package/src/Components/components/common/AIAssistant/index.ts +10 -0
- package/src/Components/components/common/AIAssistant/utils/index.ts +5 -0
- package/src/Components/components/common/AIAssistant/utils/mitt.ts +85 -0
- package/src/TUICallService/CallService/AIAssistant.ts +51 -0
- package/src/TUICallService/CallService/engineEventHandler.ts +1 -1
- package/src/TUICallService/CallService/index.ts +29 -3
- package/src/TUICallService/utils/validate/avoidRepeatedCall.ts +5 -0
- package/src/index.ts +1 -1
- package/tuicall-uikit-react.es.js +4032 -3841
- package/tuicall-uikit-react.umd.js +11 -11
- package/types/Components/components/common/AIAssistant/AIAssistant.d.ts +40 -0
- package/types/Components/components/common/AIAssistant/AISubtitle.d.ts +7 -0
- package/types/Components/components/common/AIAssistant/index.d.ts +4 -0
- package/types/Components/components/common/AIAssistant/utils/index.d.ts +2 -0
- package/types/Components/components/common/AIAssistant/utils/mitt.d.ts +16 -0
- package/types/TUICallService/CallService/AIAssistant.d.ts +15 -0
- package/types/TUICallService/CallService/index.d.ts +4 -2
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@trtc/calls-uikit-react",
|
|
3
|
-
"version": "4.2.
|
|
3
|
+
"version": "4.2.5",
|
|
4
4
|
"main": "./tuicall-uikit-react.umd.js",
|
|
5
5
|
"module": "./tuicall-uikit-react.es.js",
|
|
6
6
|
"types": "./types/index.d.ts",
|
|
@@ -14,9 +14,9 @@
|
|
|
14
14
|
},
|
|
15
15
|
"dependencies": {
|
|
16
16
|
"@tencentcloud/tui-core-lite": "1.0.0",
|
|
17
|
-
"@trtc/call-engine-lite-js": "~3.4.
|
|
17
|
+
"@trtc/call-engine-lite-js": "~3.4.7",
|
|
18
18
|
"@tencentcloud/lite-chat": "^1.5.0",
|
|
19
|
-
"@trtc/call-engine-lite-wx": "~3.4.
|
|
19
|
+
"@trtc/call-engine-lite-wx": "~3.4.7"
|
|
20
20
|
},
|
|
21
21
|
"bugs": {
|
|
22
22
|
"url": "https://github.com/tencentyun/TUICallKit/issues"
|
|
@@ -14,6 +14,7 @@ import {
|
|
|
14
14
|
} from '../../TUICallService';
|
|
15
15
|
import SingleCall from '../components/SingleCall/SingleCall';
|
|
16
16
|
import GroupCall from '../components/GroupCall/GroupCall';
|
|
17
|
+
import { AISubtitle } from '../components/common/AIAssistant';
|
|
17
18
|
import { classNames } from '../util/classnames';
|
|
18
19
|
import {
|
|
19
20
|
CallInfoContext,
|
|
@@ -248,6 +249,7 @@ export default function TUICallKit(props: ITUICallKitProps) {
|
|
|
248
249
|
<div style={{ ...style }} className={classnames} id='tuicallkit-id'>
|
|
249
250
|
{!isGroupCall && <SingleCall />}
|
|
250
251
|
{isGroupCall && <GroupCall />}
|
|
252
|
+
<AISubtitle />
|
|
251
253
|
</div>
|
|
252
254
|
<Portal attach="body">
|
|
253
255
|
<FloatingWindow
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
import { mitt } from "./utils/index";
|
|
2
|
+
|
|
3
|
+
interface IInitASRParams {
|
|
4
|
+
trtcCloudInstance: any;
|
|
5
|
+
getNickName?: (userId: string) => Promise<userInfo>;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
interface ITranslationContent {
|
|
9
|
+
language: string;
|
|
10
|
+
content: string;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
interface ITranslationInfo {
|
|
14
|
+
roundId: string;
|
|
15
|
+
sender: string;
|
|
16
|
+
nick?: string;
|
|
17
|
+
text: string;
|
|
18
|
+
end: boolean;
|
|
19
|
+
translation: ITranslationContent[];
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
export const ASREvent = {
|
|
23
|
+
TRANSCRIPTION: 'transcription',
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
const NAME = {
|
|
27
|
+
ON_RECV_CUSTOM_CMD_MESSAGE: 'onRecvCustomCmdMsg',
|
|
28
|
+
CUSTOM_MESSAGE_ASR_ID: 1,
|
|
29
|
+
USER_SPEAK: 10000,
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
interface userInfo {
|
|
33
|
+
userId: string;
|
|
34
|
+
nick: string;
|
|
35
|
+
avatar?: string;
|
|
36
|
+
[key: string]: any;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export default class AIAssistant {
|
|
40
|
+
emitter: any;
|
|
41
|
+
trtcCloudInstance: any;
|
|
42
|
+
getNickName: (userId: string) => Promise<userInfo>;
|
|
43
|
+
translationInfoList: ITranslationInfo[] = [];
|
|
44
|
+
|
|
45
|
+
constructor() {
|
|
46
|
+
this.emitter = mitt();
|
|
47
|
+
this.trtcCloudInstance = null;
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
initASR(params: IInitASRParams) {
|
|
51
|
+
const { trtcCloudInstance, getNickName } = params;
|
|
52
|
+
this.getNickName = getNickName;
|
|
53
|
+
this.trtcCloudInstance = trtcCloudInstance;
|
|
54
|
+
this.trtcCloudInstance.on(NAME.ON_RECV_CUSTOM_CMD_MESSAGE, this.handleCustomMessage, this);
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
on(type: string, handler: (event: any) => void) {
|
|
58
|
+
this.emitter.on(type, handler);
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
emit(type: string, events: any) {
|
|
62
|
+
this.emitter.emit(type, events)
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
off(type: string, handler: (event: any) => void) {
|
|
66
|
+
this.emitter.off(type, handler);
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
destroyASR() {
|
|
70
|
+
this.trtcCloudInstance.off(NAME.ON_RECV_CUSTOM_CMD_MESSAGE, this.handleCustomMessage, this);
|
|
71
|
+
this.translationInfoList = [];
|
|
72
|
+
this.trtcCloudInstance = null;
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
handleAIMessage = (data: any) => {
|
|
76
|
+
if (data?.type !== NAME.USER_SPEAK) return;
|
|
77
|
+
const { sender = '', payload } = data;
|
|
78
|
+
const { text = '', translation_text: translationText = '', end, roundid: roundId, translation_language: language = '' } = payload;
|
|
79
|
+
|
|
80
|
+
if (!roundId) return;
|
|
81
|
+
const translationInfo = this.translationInfoList.find(obj => obj.roundId === roundId);
|
|
82
|
+
|
|
83
|
+
if (translationInfo) {
|
|
84
|
+
translationInfo.text = text ? text : translationInfo.text;
|
|
85
|
+
translationInfo.end = end; // not change sender
|
|
86
|
+
const translationContent = (translationInfo.translation || []).find(obj => obj.language === language);
|
|
87
|
+
if (translationContent) {
|
|
88
|
+
translationContent.content = translationText;
|
|
89
|
+
} else if (language) {
|
|
90
|
+
translationInfo.translation.push({ language, content: translationText });
|
|
91
|
+
}
|
|
92
|
+
} else {
|
|
93
|
+
const translationContent: ITranslationContent = { language, content: translationText };
|
|
94
|
+
const translationValue: ITranslationInfo = {
|
|
95
|
+
roundId,
|
|
96
|
+
sender,
|
|
97
|
+
text,
|
|
98
|
+
end,
|
|
99
|
+
translation: language ? [translationContent] : [],
|
|
100
|
+
};
|
|
101
|
+
this.translationInfoList.push(translationValue);
|
|
102
|
+
|
|
103
|
+
// 异步获取昵称
|
|
104
|
+
this.getNickName?.(sender)?.then((res) => {
|
|
105
|
+
const item = this.translationInfoList.find(item => item.roundId === roundId);
|
|
106
|
+
if (item) {
|
|
107
|
+
item.nick = res?.nick || '';
|
|
108
|
+
this.emit(ASREvent.TRANSCRIPTION, { subtitleInfoList: this.translationInfoList });
|
|
109
|
+
}
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
this.emit(ASREvent.TRANSCRIPTION, { subtitleInfoList: this.translationInfoList });
|
|
113
|
+
|
|
114
|
+
if (end) {
|
|
115
|
+
const id = roundId;
|
|
116
|
+
setTimeout(() => {
|
|
117
|
+
if (this?.translationInfoList?.length > 0) {
|
|
118
|
+
this.translationInfoList = this.translationInfoList.filter(obj => obj.roundId !== id);
|
|
119
|
+
this.emit(ASREvent.TRANSCRIPTION, { subtitleInfoList: this.translationInfoList });
|
|
120
|
+
}
|
|
121
|
+
}, 8000);
|
|
122
|
+
}
|
|
123
|
+
};
|
|
124
|
+
|
|
125
|
+
handleCustomMessage = (userId: string, cmdId: number, seq: number, data: any) => {
|
|
126
|
+
if (cmdId === NAME.CUSTOM_MESSAGE_ASR_ID) {
|
|
127
|
+
const decodeData = new TextDecoder().decode(data);
|
|
128
|
+
const jsonData = JSON.parse(decodeData || '');
|
|
129
|
+
this.handleAIMessage(jsonData);
|
|
130
|
+
}
|
|
131
|
+
};
|
|
132
|
+
}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import React, { useEffect, useState } from 'react';
|
|
2
|
+
import { aiAssistant, ASREvent } from './index';
|
|
3
|
+
|
|
4
|
+
interface TranslationContent {
|
|
5
|
+
language: string;
|
|
6
|
+
content: string;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
interface SubtitleInfo {
|
|
10
|
+
roundId: string;
|
|
11
|
+
sender: string;
|
|
12
|
+
nick?: string;
|
|
13
|
+
text: string;
|
|
14
|
+
end: boolean;
|
|
15
|
+
translation: TranslationContent[];
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
interface AISubtitleProps {
|
|
19
|
+
customClass?: string;
|
|
20
|
+
customStyle?: React.CSSProperties;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
const AISubtitle: React.FC<AISubtitleProps> = ({ customClass, customStyle }) => {
|
|
24
|
+
const [subtitleInfoList, setSubtitleInfoList] = useState<SubtitleInfo[]>([]);
|
|
25
|
+
|
|
26
|
+
const handleAISubtitle = (data: any) => {
|
|
27
|
+
if (!data?.subtitleInfoList) return;
|
|
28
|
+
setSubtitleInfoList(JSON.parse(JSON.stringify(data.subtitleInfoList)));
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
useEffect(() => {
|
|
32
|
+
aiAssistant.on(ASREvent.TRANSCRIPTION, handleAISubtitle);
|
|
33
|
+
|
|
34
|
+
return () => {
|
|
35
|
+
aiAssistant.off(ASREvent.TRANSCRIPTION, handleAISubtitle);
|
|
36
|
+
};
|
|
37
|
+
}, []);
|
|
38
|
+
|
|
39
|
+
// 内联样式定义
|
|
40
|
+
const styles = {
|
|
41
|
+
subtitleContainer: {
|
|
42
|
+
position: 'absolute' as const,
|
|
43
|
+
zIndex: 100,
|
|
44
|
+
bottom: '120px',
|
|
45
|
+
left: '50%',
|
|
46
|
+
padding: '10px 12px',
|
|
47
|
+
color: '#fff',
|
|
48
|
+
backgroundColor: 'rgba(79, 88, 107, 0.7)',
|
|
49
|
+
borderRadius: '8px',
|
|
50
|
+
transform: 'translateX(-50%)',
|
|
51
|
+
width: '260px',
|
|
52
|
+
maxHeight: '280px',
|
|
53
|
+
overflowY: 'auto' as const,
|
|
54
|
+
overflowX: 'hidden' as const,
|
|
55
|
+
},
|
|
56
|
+
spacer: {
|
|
57
|
+
height: '16px',
|
|
58
|
+
},
|
|
59
|
+
senderName: {
|
|
60
|
+
color: 'yellow',
|
|
61
|
+
}
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
if (!subtitleInfoList.length) {
|
|
65
|
+
return null;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
return (
|
|
69
|
+
<div
|
|
70
|
+
className={`ai-subtitle ${customClass || ''}`}
|
|
71
|
+
style={{ ...styles.subtitleContainer, ...customStyle }}
|
|
72
|
+
>
|
|
73
|
+
{subtitleInfoList.map((subtitleInfo, index) => (
|
|
74
|
+
<div key={subtitleInfo.roundId}>
|
|
75
|
+
{index !== 0 && <div style={{ height: '16px' }} />}
|
|
76
|
+
<div style={styles.senderName}>{`${subtitleInfo?.nick || subtitleInfo?.sender}:`}</div>
|
|
77
|
+
<div>{subtitleInfo?.text}</div>
|
|
78
|
+
{subtitleInfo?.translation?.map((translationContent, transIndex) => (
|
|
79
|
+
<div key={transIndex}>
|
|
80
|
+
<span>{`[${translationContent?.language}]: ${translationContent?.content}`}</span>
|
|
81
|
+
</div>
|
|
82
|
+
))}
|
|
83
|
+
</div>
|
|
84
|
+
))}
|
|
85
|
+
</div>
|
|
86
|
+
);
|
|
87
|
+
};
|
|
88
|
+
|
|
89
|
+
export default AISubtitle;
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
export type EventType = string | symbol;
|
|
2
|
+
export type Handler<T = unknown> = (event: T) => void;
|
|
3
|
+
export type WildcardHandler<T = Record<string, unknown>> = (
|
|
4
|
+
type: keyof T,
|
|
5
|
+
event: T[keyof T]
|
|
6
|
+
) => void;
|
|
7
|
+
export type EventHandlerList<T = unknown> = Array<Handler<T>>;
|
|
8
|
+
export type WildCardEventHandlerList<T = Record<string, unknown>> = Array<
|
|
9
|
+
WildcardHandler<T>
|
|
10
|
+
>;
|
|
11
|
+
export type EventHandlerMap<Events extends Record<EventType, unknown>> = Map<
|
|
12
|
+
keyof Events | '*',
|
|
13
|
+
EventHandlerList<Events[keyof Events]> | WildCardEventHandlerList<Events>
|
|
14
|
+
>;
|
|
15
|
+
|
|
16
|
+
export interface Emitter<Events extends Record<EventType, unknown>> {
|
|
17
|
+
all: EventHandlerMap<Events>;
|
|
18
|
+
|
|
19
|
+
on<Key extends keyof Events>(type: Key, handler: Handler<Events[Key]>): void;
|
|
20
|
+
on(type: '*', handler: WildcardHandler<Events>): void;
|
|
21
|
+
|
|
22
|
+
off<Key extends keyof Events>(
|
|
23
|
+
type: Key,
|
|
24
|
+
handler?: Handler<Events[Key]>
|
|
25
|
+
): void;
|
|
26
|
+
off(type: '*', handler: WildcardHandler<Events>): void;
|
|
27
|
+
|
|
28
|
+
emit<Key extends keyof Events>(type: Key, event: Events[Key]): void;
|
|
29
|
+
emit<Key extends keyof Events>(
|
|
30
|
+
type: undefined extends Events[Key] ? Key : never
|
|
31
|
+
): void;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export default function mitt<Events extends Record<EventType, unknown>>(
|
|
35
|
+
all?: EventHandlerMap<Events>
|
|
36
|
+
): Emitter<Events> {
|
|
37
|
+
type GenericEventHandler =
|
|
38
|
+
| Handler<Events[keyof Events]>
|
|
39
|
+
| WildcardHandler<Events>;
|
|
40
|
+
all = all || new Map();
|
|
41
|
+
|
|
42
|
+
return {
|
|
43
|
+
all,
|
|
44
|
+
|
|
45
|
+
on<Key extends keyof Events>(type: Key, handler: GenericEventHandler) {
|
|
46
|
+
const handlers: Array<GenericEventHandler> | undefined = all!.get(type);
|
|
47
|
+
if (handlers) {
|
|
48
|
+
handlers.push(handler);
|
|
49
|
+
} else {
|
|
50
|
+
all!.set(type, [handler] as EventHandlerList<Events[keyof Events]>);
|
|
51
|
+
}
|
|
52
|
+
},
|
|
53
|
+
|
|
54
|
+
off<Key extends keyof Events>(type: Key, handler?: GenericEventHandler) {
|
|
55
|
+
const handlers: Array<GenericEventHandler> | undefined = all!.get(type);
|
|
56
|
+
if (handlers) {
|
|
57
|
+
if (handler) {
|
|
58
|
+
handlers.splice(handlers.indexOf(handler) >>> 0, 1);
|
|
59
|
+
} else {
|
|
60
|
+
all!.set(type, []);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
},
|
|
64
|
+
|
|
65
|
+
emit<Key extends keyof Events>(type: Key, evt?: Events[Key]) {
|
|
66
|
+
let handlers = all!.get(type);
|
|
67
|
+
if (handlers) {
|
|
68
|
+
(handlers as EventHandlerList<Events[keyof Events]>)
|
|
69
|
+
.slice()
|
|
70
|
+
.map((handler) => {
|
|
71
|
+
handler(evt!);
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
handlers = all!.get('*');
|
|
76
|
+
if (handlers) {
|
|
77
|
+
(handlers as WildCardEventHandlerList<Events>)
|
|
78
|
+
.slice()
|
|
79
|
+
.map((handler) => {
|
|
80
|
+
handler(type, evt!);
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
};
|
|
85
|
+
}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
// @ts-ignore
|
|
2
|
+
import { aiAssistant } from '../../Components/components/common/AIAssistant/index';
|
|
3
|
+
import { getRemoteUserProfile } from './utils';
|
|
4
|
+
|
|
5
|
+
interface IAIAssistant {
|
|
6
|
+
enableAISubtitle: (enable: boolean) => void;
|
|
7
|
+
setEngineInstance: (engineInstance: any) => void;
|
|
8
|
+
setImInstance: (imInstance: any) => void;
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
export class AIAssistant implements IAIAssistant {
|
|
12
|
+
static instance: IAIAssistant;
|
|
13
|
+
private _tuiCallEngine: any = null;
|
|
14
|
+
private _imInstance: any = null;
|
|
15
|
+
|
|
16
|
+
static getInstance() {
|
|
17
|
+
if (!AIAssistant.instance) {
|
|
18
|
+
AIAssistant.instance = new AIAssistant();
|
|
19
|
+
}
|
|
20
|
+
return AIAssistant.instance;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
public enableAISubtitle(enable: boolean): void {
|
|
24
|
+
this._tuiCallEngine?.reportLog?.({
|
|
25
|
+
name: 'TUICallKit.enableAISubtitle.start',
|
|
26
|
+
data: { enable },
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
const trtcCloudInstance = this._tuiCallEngine.getTRTCCloudInstance();
|
|
30
|
+
const getNickName = async(userId: string) => {
|
|
31
|
+
const res = await getRemoteUserProfile([userId], this._imInstance);
|
|
32
|
+
return res.length ? res[0] : [];
|
|
33
|
+
}
|
|
34
|
+
if (enable) {
|
|
35
|
+
aiAssistant.initASR({
|
|
36
|
+
trtcCloudInstance,
|
|
37
|
+
// @ts-ignore
|
|
38
|
+
getNickName,
|
|
39
|
+
});
|
|
40
|
+
} else {
|
|
41
|
+
aiAssistant.destroyASR();
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
public setEngineInstance(engineInstance: any): void {
|
|
46
|
+
this._tuiCallEngine = engineInstance;
|
|
47
|
+
}
|
|
48
|
+
public setImInstance(imInstance: any): void {
|
|
49
|
+
this._imInstance = imInstance;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
@@ -226,6 +226,7 @@ export default class EngineEventHandler {
|
|
|
226
226
|
this._unNormalEventsManager(event, TUICallEvent.LINE_BUSY);
|
|
227
227
|
}
|
|
228
228
|
private _handleCallNotConnected(event: any): void {
|
|
229
|
+
this?._callService?._cleanupAvoidRepeatCallState?.();
|
|
229
230
|
this._callService?.executeExternalAfterCalling();
|
|
230
231
|
this._unNormalEventsManager(event, TUICallEvent.ON_CALL_NOT_CONNECTED);
|
|
231
232
|
}
|
|
@@ -239,7 +240,6 @@ export default class EngineEventHandler {
|
|
|
239
240
|
}
|
|
240
241
|
private _handleCallingEnd(event: any): void {
|
|
241
242
|
console.log(`${NAME.PREFIX}callEnd event data: ${JSON.stringify(event)}.`);
|
|
242
|
-
|
|
243
243
|
this._callService?.executeExternalAfterCalling();
|
|
244
244
|
this._callService?._resetCallStore();
|
|
245
245
|
}
|
|
@@ -21,12 +21,14 @@ import TuiGlobal from '../TUIGlobal/tuiGlobal';
|
|
|
21
21
|
import TuiStore from '../TUIStore/tuiStore';
|
|
22
22
|
import { UIDesign } from './UIDesign';
|
|
23
23
|
import ChatCombine from './chatCombine';
|
|
24
|
+
import { AIAssistant } from './AIAssistant';
|
|
24
25
|
import EngineEventHandler from './engineEventHandler';
|
|
25
26
|
const TUIGlobal: ITUIGlobal = TuiGlobal.getInstance();
|
|
26
27
|
const TUIStore: ITUIStore = TuiStore.getInstance();
|
|
27
28
|
const uiDesign = UIDesign.getInstance();
|
|
28
29
|
uiDesign.setTUIStore(TUIStore);
|
|
29
|
-
const
|
|
30
|
+
const aiAssistant = AIAssistant.getInstance();
|
|
31
|
+
const version = '4.2.5';
|
|
30
32
|
const frameWork = 'react';
|
|
31
33
|
export { TUIGlobal, TUIStore, uiDesign };
|
|
32
34
|
|
|
@@ -67,7 +69,7 @@ export default class TUICallService {
|
|
|
67
69
|
}
|
|
68
70
|
return TUICallService.instance;
|
|
69
71
|
}
|
|
70
|
-
|
|
72
|
+
private _loadWasm() {
|
|
71
73
|
TUICallEngine.once('ready', () => this._wasmReadyResolve());
|
|
72
74
|
}
|
|
73
75
|
@avoidRepeatedCall()
|
|
@@ -83,7 +85,7 @@ export default class TUICallService {
|
|
|
83
85
|
this._isInitialized = true;
|
|
84
86
|
}
|
|
85
87
|
}
|
|
86
|
-
|
|
88
|
+
private async _doInit(params: IInitParams) {
|
|
87
89
|
try {
|
|
88
90
|
if (this._tuiCallEngine) return;
|
|
89
91
|
// @ts-ignore
|
|
@@ -116,6 +118,11 @@ export default class TUICallService {
|
|
|
116
118
|
TUIStore.update(StoreName.CALL, NAME.LOCAL_USER_INFO, { userId: userID });
|
|
117
119
|
TUIStore.update(StoreName.CALL, NAME.LOCAL_USER_INFO_EXCLUDE_VOLUMN, { userId: userID });
|
|
118
120
|
uiDesign.updateViewBackgroundUserId('local');
|
|
121
|
+
|
|
122
|
+
aiAssistant.setEngineInstance(this._tuiCallEngine);
|
|
123
|
+
aiAssistant.setImInstance(this.getTim());
|
|
124
|
+
|
|
125
|
+
this.enableAISubtitle(true);
|
|
119
126
|
await this._tuiCallEngine.login({ userID, userSig, assetsPath: '' }); // web && mini
|
|
120
127
|
const uiConfig = TUIStore.getData(StoreName.CALL, NAME.CUSTOM_UI_CONFIG);
|
|
121
128
|
this._tuiCallEngine?.reportLog?.({
|
|
@@ -291,6 +298,9 @@ export default class TUICallService {
|
|
|
291
298
|
public setCameraDefaultState(isOpen: boolean) {
|
|
292
299
|
uiDesign.setCameraDefaultState(isOpen);
|
|
293
300
|
}
|
|
301
|
+
public enableAISubtitle(enable: boolean): void {
|
|
302
|
+
aiAssistant.enableAISubtitle(enable);
|
|
303
|
+
}
|
|
294
304
|
// =============================【实验性接口】=============================
|
|
295
305
|
public callExperimentalAPI(jsonStr: string) {
|
|
296
306
|
const jsonObj = JSON.parse(jsonStr);
|
|
@@ -674,7 +684,23 @@ export default class TUICallService {
|
|
|
674
684
|
this._timerId = -1;
|
|
675
685
|
}
|
|
676
686
|
}
|
|
687
|
+
// clear all use avoidRepeatCall decorator state
|
|
688
|
+
private _cleanupAllAvoidRepeatCallState() {
|
|
689
|
+
this._tuiCallEngine?.reportLog?.({ name: 'TUICallkit._cleanupAllAvoidRepeatCallState', data: { } });
|
|
690
|
+
const methodsToClean = [
|
|
691
|
+
(this as any).calls,
|
|
692
|
+
(this as any).accept,
|
|
693
|
+
(this as any).hangup,
|
|
694
|
+
(this as any).reject,
|
|
695
|
+
];
|
|
696
|
+
|
|
697
|
+
methodsToClean.forEach(method => {
|
|
698
|
+
method?.clearCallState?.(this);
|
|
699
|
+
});
|
|
700
|
+
}
|
|
677
701
|
private _resetCallStore() {
|
|
702
|
+
this._cleanupAllAvoidRepeatCallState();
|
|
703
|
+
|
|
678
704
|
const oldStatusStr = generateStatusChangeText();
|
|
679
705
|
this._stopTimer();
|
|
680
706
|
// localUserInfo, language 在通话结束后不需要清除
|