@trtc/calls-uikit-react 4.2.4 → 4.4.0
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/index.ts +16 -1
- package/src/TUICallService/locales/en.ts +2 -0
- package/src/TUICallService/locales/ja_JP.ts +2 -0
- package/src/TUICallService/locales/zh-cn.ts +2 -0
- package/src/TUICallService/utils/common-utils.ts +1 -1
- package/src/index.ts +1 -1
- package/tuicall-uikit-react.es.js +3561 -3377
- 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 +1 -0
- package/types/TUICallService/locales/en.d.ts +2 -0
- package/types/TUICallService/locales/ja_JP.d.ts +2 -0
- package/types/TUICallService/locales/zh-cn.d.ts +2 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@trtc/calls-uikit-react",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.4.0",
|
|
4
4
|
"main": "./tuicall-uikit-react.umd.js",
|
|
5
5
|
"module": "./tuicall-uikit-react.es.js",
|
|
6
6
|
"types": "./types/index.d.ts",
|
|
@@ -14,8 +14,8 @@
|
|
|
14
14
|
},
|
|
15
15
|
"dependencies": {
|
|
16
16
|
"@tencentcloud/tui-core-lite": "1.0.0",
|
|
17
|
-
"@trtc/call-engine-lite-js": "~3.
|
|
18
|
-
"@tencentcloud/lite-chat": "^1.
|
|
17
|
+
"@trtc/call-engine-lite-js": "~3.5.0",
|
|
18
|
+
"@tencentcloud/lite-chat": "^1.6.3",
|
|
19
19
|
"@trtc/call-engine-lite-wx": "~3.4.7"
|
|
20
20
|
},
|
|
21
21
|
"bugs": {
|
|
@@ -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
|
+
}
|
|
@@ -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.4.0';
|
|
30
32
|
const frameWork = 'react';
|
|
31
33
|
export { TUIGlobal, TUIStore, uiDesign };
|
|
32
34
|
|
|
@@ -116,8 +118,18 @@ 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);
|
|
128
|
+
// close auto play dialog
|
|
129
|
+
const trtcCloudInstance = this._tuiCallEngine?.getTRTCCloudInstance?.()
|
|
130
|
+
trtcCloudInstance?.callExperimentalAPI(JSON.stringify(
|
|
131
|
+
{ "api": "enableAutoPlayDialog","params": { "enable": 0 } }
|
|
132
|
+
));
|
|
121
133
|
this._tuiCallEngine?.reportLog?.({
|
|
122
134
|
name: 'TUICallkit.init',
|
|
123
135
|
data: {
|
|
@@ -291,6 +303,9 @@ export default class TUICallService {
|
|
|
291
303
|
public setCameraDefaultState(isOpen: boolean) {
|
|
292
304
|
uiDesign.setCameraDefaultState(isOpen);
|
|
293
305
|
}
|
|
306
|
+
public enableAISubtitle(enable: boolean): void {
|
|
307
|
+
aiAssistant.enableAISubtitle(enable);
|
|
308
|
+
}
|
|
294
309
|
// =============================【实验性接口】=============================
|
|
295
310
|
public callExperimentalAPI(jsonStr: string) {
|
|
296
311
|
const jsonObj = JSON.parse(jsonStr);
|
|
@@ -66,6 +66,8 @@ export const en = {
|
|
|
66
66
|
"The network is poor during your current call": "The network is poor during your current call",
|
|
67
67
|
"The other user network is poor during the current call": "The other party's network is poor during the current call",
|
|
68
68
|
"TUICallKit init is not complete": "TUICallKit init is not complete. You need to use this API after the init API is finished.",
|
|
69
|
+
"auto play failed": "Audio playback was blocked",
|
|
70
|
+
"click to resume": "Resume playback",
|
|
69
71
|
// combine chat
|
|
70
72
|
"Video call": "Video call",
|
|
71
73
|
"Voice call": "Voice call",
|
|
@@ -77,6 +77,8 @@ export const ja_JP = {
|
|
|
77
77
|
"The network is poor during your current call": "現在の通話で、あなたのネットワークは不良です",
|
|
78
78
|
"The other user network is poor during the current call": "現在の通話で、相手側のネットワークが不良です",
|
|
79
79
|
"TUICallKit init is not complete": "TUICallKitの初期化ログインが完了していません。init が完了した後にこのAPIを使用する必要があります。",
|
|
80
|
+
"auto play failed": "オーディオ再生がブロックされました",
|
|
81
|
+
"click to resume": "再生を再開",
|
|
80
82
|
// 待废弃文案
|
|
81
83
|
'timeout': '{{ userList }} タイムアウト',
|
|
82
84
|
'kick out': 'キックアウトされました',
|
|
@@ -66,6 +66,8 @@ export const zh = {
|
|
|
66
66
|
"The network is poor during your current call": "当前通话你的网络不佳",
|
|
67
67
|
"The other user network is poor during the current call": "当前通话对方网络不佳",
|
|
68
68
|
"TUICallKit init is not complete": "TUICallKit 初始化登录未完成,需要在 init 完成后使用此 API",
|
|
69
|
+
"auto play failed": "音频播放被拦截,请点击恢复播放",
|
|
70
|
+
"click to resume": "恢复播放",
|
|
69
71
|
// combine chat
|
|
70
72
|
"Video call": "发起视频通话",
|
|
71
73
|
"Voice call": "发起语音通话",
|
|
@@ -143,7 +143,7 @@ export const retryPromise = (promise: Promise<any>, num: number = 6, time: numbe
|
|
|
143
143
|
* @returns {Boolean}
|
|
144
144
|
*/
|
|
145
145
|
export function handleRepeatedCallError(error: any) {
|
|
146
|
-
if (error?.message
|
|
146
|
+
if (error?.message?.indexOf('is ongoing, please avoid repeated calls') !== -1) {
|
|
147
147
|
return true;
|
|
148
148
|
}
|
|
149
149
|
return false;
|