@trtc/calls-uikit-vue 4.4.2 → 4.4.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.
Files changed (57) hide show
  1. package/package.json +2 -2
  2. package/src/Components/TUICallKit.vue +1 -1
  3. package/src/Components/assets/aiAssistant/desktop/subtitleSettings.svg +4 -0
  4. package/src/Components/assets/aiAssistant/mobile/close-aiAssistant.svg +7 -0
  5. package/src/Components/assets/aiAssistant/mobile/open-aiAssistant.svg +7 -0
  6. package/src/Components/assets/aiAssistant/mobile/subtitleSettings.svg +3 -0
  7. package/src/Components/components/base/CustomSelect/CustomSelect.ts +45 -0
  8. package/src/Components/components/base/CustomSelect/CustomSelect.vue +199 -0
  9. package/src/Components/components/common/AIAssistant/AISubtitle.vue +155 -37
  10. package/src/Components/components/common/AIAssistant/components/AITranscriberSwitchH5.vue +35 -0
  11. package/src/Components/components/common/AIAssistant/components/AITranscriberSwitchPC.vue +89 -0
  12. package/src/Components/components/common/AIAssistant/components/SubtitleContent.vue +234 -0
  13. package/src/Components/components/common/AIAssistant/components/SubtitleSettingsH5.vue +534 -0
  14. package/src/Components/components/common/AIAssistant/components/SubtitleSettingsPC.vue +294 -0
  15. package/src/Components/components/common/TopBar/TopBar.vue +41 -15
  16. package/src/Components/hooks/index.ts +1 -0
  17. package/src/Components/hooks/useAIAssistant.ts +142 -0
  18. package/src/Components/hooks/useGetVolumeMap.ts +2 -2
  19. package/src/TUICallService/CallService/AIAssistant.ts +285 -39
  20. package/src/TUICallService/CallService/UIKitModal.ts +14 -6
  21. package/src/TUICallService/CallService/bellContext.ts +25 -2
  22. package/src/TUICallService/CallService/engineEventHandler.ts +6 -1
  23. package/src/TUICallService/CallService/index.ts +72 -39
  24. package/src/TUICallService/CallService/miniProgram.ts +0 -12
  25. package/src/TUICallService/TUIStore/callStore.ts +6 -1
  26. package/src/TUICallService/UIKitModal/UIKitModal.ts +117 -0
  27. package/src/TUICallService/UIKitModal/index.ts +2 -0
  28. package/src/TUICallService/UIKitModal/type.ts +15 -0
  29. package/src/TUICallService/const/index.ts +4 -0
  30. package/src/TUICallService/interface/ICallStore.ts +5 -0
  31. package/src/TUICallService/locales/en.ts +15 -0
  32. package/src/TUICallService/locales/ja_JP.ts +15 -0
  33. package/src/TUICallService/locales/zh-cn.ts +15 -0
  34. package/src/TUICallService/utils/common-utils.ts +1 -1
  35. package/src/index.ts +1 -1
  36. package/stats.html +1 -1
  37. package/tuicall-uikit-vue.es.js +4199 -3474
  38. package/tuicall-uikit-vue.umd.js +2 -2
  39. package/types/Components/components/base/CustomSelect/CustomSelect.d.ts +41 -0
  40. package/types/Components/hooks/index.d.ts +1 -0
  41. package/types/Components/hooks/useAIAssistant.d.ts +19 -0
  42. package/types/TUICallService/CallService/AIAssistant.d.ts +72 -15
  43. package/types/TUICallService/CallService/bellContext.d.ts +3 -0
  44. package/types/TUICallService/CallService/index.d.ts +4 -3
  45. package/types/TUICallService/CallService/miniProgram.d.ts +0 -1
  46. package/types/TUICallService/UIKitModal/UIKitModal.d.ts +4 -0
  47. package/types/TUICallService/UIKitModal/index.d.ts +2 -0
  48. package/types/TUICallService/UIKitModal/type.d.ts +13 -0
  49. package/types/TUICallService/interface/ICallStore.d.ts +4 -0
  50. package/types/TUICallService/locales/en.d.ts +14 -0
  51. package/types/TUICallService/locales/ja_JP.d.ts +14 -0
  52. package/types/TUICallService/locales/zh-cn.d.ts +14 -0
  53. package/types/tsconfig.tsbuildinfo +1 -1
  54. package/src/Components/components/common/AIAssistant/AIAssistant.ts +0 -130
  55. package/src/Components/components/common/AIAssistant/index.ts +0 -11
  56. package/types/Components/components/common/AIAssistant/AIAssistant.d.ts +0 -40
  57. package/types/Components/components/common/AIAssistant/index.d.ts +0 -4
@@ -22,20 +22,20 @@ import TuiGlobal from '../TUIGlobal/tuiGlobal';
22
22
  import TuiStore from '../TUIStore/tuiStore';
23
23
  import { UIDesign } from './UIDesign';
24
24
  import ChatCombine from './chatCombine';
25
- import { AIAssistant } from './AIAssistant';
26
25
  import EngineEventHandler from './engineEventHandler';
27
26
  const TUIGlobal: ITUIGlobal = TuiGlobal.getInstance();
28
27
  const TUIStore: ITUIStore = TuiStore.getInstance();
29
28
  const uiDesign = UIDesign.getInstance();
30
29
  uiDesign.setTUIStore(TUIStore);
31
- const aiAssistant = AIAssistant.getInstance();
32
- const version = '4.4.2';
30
+ const version = '4.4.5';
31
+ import AIAssistant from './AIAssistant'; // 仅 web 支持 AI 实时字幕
33
32
  const frameWork = 'vue3';
34
33
  export { TUIGlobal, TUIStore, uiDesign };
35
34
 
36
35
  export default class TUICallService {
37
36
  static instance: TUICallService;
38
37
  public _tuiCallEngine: any;
38
+ public _aiAssistant: any = null;
39
39
  private _tim: any = null;
40
40
  private _TUICore: any = null;
41
41
  private _timerId: number = -1;
@@ -62,6 +62,7 @@ export default class TUICallService {
62
62
  this._engineEventHandler = EngineEventHandler.getInstance({ callService: this });
63
63
 
64
64
  this._chatCombine = ChatCombine.getInstance({ callService: this });
65
+ this._aiAssistant = AIAssistant.getInstance({ callService: this });
65
66
  initBrowserCloseDetection(this.handleExceptionExit.bind(this));
66
67
  }
67
68
  static getInstance() {
@@ -115,15 +116,15 @@ export default class TUICallService {
115
116
  });
116
117
  uiDesign.setEngineInstance(this._tuiCallEngine);
117
118
  this._addListenTuiCallEngineEvent();
118
- this._bellContext = new BellContext();
119
+ if (this._bellContext) {
120
+ this._bellContext?.destroy();
121
+ }
122
+ this._bellContext = new BellContext();
119
123
  TUIStore.update(StoreName.CALL, NAME.LOCAL_USER_INFO, { userId: userID });
120
124
  TUIStore.update(StoreName.CALL, NAME.LOCAL_USER_INFO_EXCLUDE_VOLUMN, { userId: userID });
121
125
  uiDesign.updateViewBackgroundUserId('local');
122
-
123
- aiAssistant.setEngineInstance(this._tuiCallEngine);
124
- aiAssistant.setImInstance(this.getTim());
126
+ this._aiAssistant?.bindEvent();
125
127
 
126
- this.enableAISubtitle(true);
127
128
  await this._tuiCallEngine.login({ userID, userSig, assetsPath: '' }); // web && mini
128
129
  const uiConfig = TUIStore.getData(StoreName.CALL, NAME.CUSTOM_UI_CONFIG);
129
130
  // close auto play dialog
@@ -155,6 +156,8 @@ export default class TUICallService {
155
156
  await this._tuiCallEngine.destroyInstance();
156
157
  this._tuiCallEngine = null;
157
158
  }
159
+ this._aiAssistant?.unbindEvent();
160
+ this._aiAssistant?.reset();
158
161
  this._bellContext?.destroy();
159
162
  this._bellContext = null;
160
163
  } catch (error) {
@@ -187,6 +190,7 @@ export default class TUICallService {
187
190
  public async calls(callsParams: ICallsParams) {
188
191
  if (TUIStore.getData(StoreName.CALL, NAME.CALL_STATUS) !== CallStatus.IDLE) return; // avoid double click when application stuck
189
192
  try {
193
+ TUIStore.update(StoreName.CALL, NAME.PUSHER_ID, NAME.NEW_PUSHER);
190
194
  const { userIDList, type, chatGroupID, offlinePushInfo } = callsParams;
191
195
  if (TUIStore.getData(StoreName.CALL, NAME.CALL_STATUS) !== CallStatus.IDLE) return;
192
196
  const remoteUserInfoList = userIDList.map(userId => ({ userId }));
@@ -204,10 +208,7 @@ export default class TUICallService {
204
208
  public async join(params) {
205
209
  if (TUIStore.getData(StoreName.CALL, NAME.CALL_STATUS) === CallStatus.CONNECTED) return; // avoid double click when application stuck
206
210
  try {
207
- const response = await this._tuiCallEngine.join(params);
208
- TUIStore.update(StoreName.CALL, NAME.IS_CLICKABLE, true);
209
- this.startTimer();
210
-
211
+ TUIStore.update(StoreName.CALL, NAME.PUSHER_ID, NAME.NEW_PUSHER);
211
212
  const updateStoreParams = {
212
213
  [NAME.CALL_ROLE]: CallRole.CALLEE,
213
214
  [NAME.IS_GROUP]: true,
@@ -216,6 +217,10 @@ export default class TUICallService {
216
217
  };
217
218
  TUIStore.updateStore(updateStoreParams, StoreName.CALL);
218
219
 
220
+ const response = await this._tuiCallEngine.join(params);
221
+ TUIStore.update(StoreName.CALL, NAME.IS_CLICKABLE, true);
222
+ this.startTimer();
223
+
219
224
  updateDeviceList(this._tuiCallEngine);;
220
225
  await this._tuiCallEngine.setVideoQuality(TUIStore.getData(StoreName.CALL, NAME.VIDEO_RESOLUTION));
221
226
  const localUserInfo = TUIStore.getData(StoreName.CALL, NAME.LOCAL_USER_INFO);
@@ -271,6 +276,16 @@ export default class TUICallService {
271
276
  throw error;
272
277
  }
273
278
  }
279
+ public async enableAITranscriber(enable: boolean) {
280
+ try {
281
+ // Update store to control UI translation switch and translation area visibility
282
+ TUIStore.update(StoreName.CALL, NAME.IS_AI_TRANSCRIBER_ENABLED, enable);
283
+ console.log(`${NAME.PREFIX}enableAITranscriber: ${enable}.`);
284
+ } catch (error: any) {
285
+ console.error(`${NAME.PREFIX}enableAITranscriber failed, error: ${error}.`);
286
+ throw error;
287
+ }
288
+ }
274
289
  // 修改默认铃声:只支持本地铃声文件,不支持在线铃声文件;修改铃声修改的是被叫的铃声
275
290
  public async setCallingBell(filePath?: string) {
276
291
  let isCheckFileExist: boolean = true;
@@ -306,9 +321,7 @@ export default class TUICallService {
306
321
  public setCameraDefaultState(isOpen: boolean) {
307
322
  uiDesign.setCameraDefaultState(isOpen);
308
323
  }
309
- public enableAISubtitle(enable: boolean): void {
310
- aiAssistant.enableAISubtitle(enable);
311
- }
324
+ // AI Subtitle functionality removed, focusing on real-time transcriber
312
325
  // =============================【实验性接口】=============================
313
326
  public callExperimentalAPI(jsonStr: string) {
314
327
  const jsonObj = JSON.parse(jsonStr);
@@ -343,19 +356,7 @@ export default class TUICallService {
343
356
  TUIStore.update(StoreName.CALL, NAME.CALL_STATUS, CallStatus.CONNECTED);
344
357
  updateDeviceList(this._tuiCallEngine);;
345
358
  const response = await this._tuiCallEngine.accept();
346
- if (response) {
347
- this._chatCombine?.callTUIService({ message: response?.data?.message });
348
- TUIStore.update(StoreName.CALL, NAME.IS_CLICKABLE, true);
349
- this.startTimer();
350
- const callMediaType = TUIStore.getData(StoreName.CALL, NAME.CALL_MEDIA_TYPE);
351
- const isCameraDefaultStateClose = this._getFeatureButtonDefaultState(FeatureButton.Camera) === ButtonState.Close;
352
- (callMediaType === CallMediaType.VIDEO) && !isCameraDefaultStateClose && await this.openCamera(NAME.LOCAL_VIDEO);
353
- await this._tuiCallEngine.setVideoQuality(TUIStore.getData(StoreName.CALL, NAME.VIDEO_RESOLUTION));
354
- const localUserInfo = TUIStore.getData(StoreName.CALL, NAME.LOCAL_USER_INFO);
355
- TUIStore.update(StoreName.CALL, NAME.LOCAL_USER_INFO, { ...localUserInfo, isEnter: true });
356
- TUIStore.update(StoreName.CALL, NAME.LOCAL_USER_INFO_EXCLUDE_VOLUMN, { ...localUserInfo, isEnter: true });
357
- setLocalUserInfoAudioVideoAvailable(true, NAME.AUDIO); // web && mini default open audio
358
- }
359
+ await this._handleAcceptResponse(response);
359
360
  } catch (error) {
360
361
  this._tuiCallEngine?.reportLog?.({
361
362
  name: 'TUICallKit.accept.fail',
@@ -368,6 +369,21 @@ export default class TUICallService {
368
369
  this._resetCallStore();
369
370
  }
370
371
  }
372
+ private async _handleAcceptResponse(response) {
373
+ if (response) {
374
+ this._chatCombine?.callTUIService({ message: response?.data?.message });
375
+ TUIStore.update(StoreName.CALL, NAME.IS_CLICKABLE, true);
376
+ this.startTimer();
377
+ const callMediaType = TUIStore.getData(StoreName.CALL, NAME.CALL_MEDIA_TYPE);
378
+ const isCameraDefaultStateClose = this._getFeatureButtonDefaultState(FeatureButton.Camera) === ButtonState.Close;
379
+ (callMediaType === CallMediaType.VIDEO) && !isCameraDefaultStateClose && await this.openCamera(NAME.LOCAL_VIDEO);
380
+ await this._tuiCallEngine.setVideoQuality(TUIStore.getData(StoreName.CALL, NAME.VIDEO_RESOLUTION));
381
+ const localUserInfo = TUIStore.getData(StoreName.CALL, NAME.LOCAL_USER_INFO);
382
+ TUIStore.update(StoreName.CALL, NAME.LOCAL_USER_INFO, { ...localUserInfo, isEnter: true });
383
+ TUIStore.update(StoreName.CALL, NAME.LOCAL_USER_INFO_EXCLUDE_VOLUMN, { ...localUserInfo, isEnter: true });
384
+ setLocalUserInfoAudioVideoAvailable(true, NAME.AUDIO); // web && mini default open audio
385
+ }
386
+ }
371
387
  @avoidRepeatedCall()
372
388
  public async hangup() {
373
389
  if (TUIStore.getData(StoreName.CALL, NAME.CALL_STATUS) === CallStatus.IDLE) return; // avoid double click when application stuck
@@ -696,21 +712,29 @@ export default class TUICallService {
696
712
  }
697
713
  }
698
714
  // clear all use avoidRepeatCall decorator state
699
- private _cleanupAllAvoidRepeatCallState() {
700
- this._tuiCallEngine?.reportLog?.({ name: 'TUICallkit._cleanupAllAvoidRepeatCallState', data: { } });
701
- const methodsToClean = [
702
- (this as any).calls,
703
- (this as any).accept,
704
- (this as any).hangup,
705
- (this as any).reject,
706
- ];
715
+ private _cleanupAvoidRepeatCallState(methodName?: string) {
716
+ this._tuiCallEngine?.reportLog?.({ name: 'TUICallkit._cleanupAvoidRepeatCallState', data: { methodName } });
717
+ let methodsToClean = [];
718
+ if (methodName) {
719
+ methodsToClean = [(this as any)[methodName]];
720
+ } else {
721
+ methodsToClean = [
722
+ (this as any).calls,
723
+ (this as any).accept,
724
+ (this as any).hangup,
725
+ (this as any).reject,
726
+ (this as any).join,
727
+ (this as any).inviteUser,
728
+ ];
729
+ }
707
730
 
708
- methodsToClean.forEach(method => {
731
+ methodsToClean?.forEach(method => {
709
732
  method?.clearCallState?.(this);
710
733
  });
711
734
  }
712
735
  private _resetCallStore() {
713
- this._cleanupAllAvoidRepeatCallState();
736
+ this._cleanupAvoidRepeatCallState();
737
+ this._bellContext?.stop();
714
738
 
715
739
  const oldStatusStr = generateStatusChangeText();
716
740
  this._stopTimer();
@@ -729,6 +753,7 @@ export default class TUICallService {
729
753
  case NAME.ENABLE_FLOAT_WINDOW:
730
754
  case NAME.LOCAL_USER_INFO:
731
755
  case NAME.IS_SHOW_ENABLE_VIRTUAL_BACKGROUND:
756
+ case NAME.IS_AI_TRANSCRIBER_ENABLED:
732
757
  case NAME.IS_FORCE_USE_V2_API:
733
758
  case NAME.LOCAL_USER_INFO_EXCLUDE_VOLUMN: {
734
759
  return false;
@@ -744,6 +769,7 @@ export default class TUICallService {
744
769
  callStatus !== CallStatus.IDLE && TUIStore.reset(StoreName.CALL, [NAME.CALL_STATUS], true); // callStatus reset need notify
745
770
  TUIStore.reset(StoreName.CALL, [NAME.IS_MINIMIZED], true); // isMinimized reset need notify
746
771
  TUIStore.reset(StoreName.CALL, [NAME.IS_EAR_PHONE], true); // isEarPhone reset need notify
772
+ TUIStore.reset(StoreName.CALL, [NAME.PUSHER_ID], true); // pusher unload reset need notify
747
773
  TUIStore.reset(StoreName.CALL, [NAME.ENABLE_VIRTUAL_BACKGROUND], true); // ENABLE_VIRTUAL_BACKGROUND reset need notify
748
774
  TUIStore.reset(StoreName.CALL, [NAME.IS_MUTE_SPEAKER], true); // IS_MUTE_SPEAKER reset need notify
749
775
  TUIStore.update(StoreName.CALL, NAME.LOCAL_USER_INFO, {
@@ -784,10 +810,17 @@ export default class TUICallService {
784
810
  callRole: TUIStore.getData(StoreName.CALL, NAME.CALL_ROLE),
785
811
  callStatus: TUIStore.getData(StoreName.CALL, NAME.CALL_STATUS),
786
812
  };
813
+ this._tuiCallEngine?.reportLog?.({
814
+ name: 'TUICallkit._handleCallStatusChange.start',
815
+ data: { bellParams }
816
+ });
787
817
  this._bellContext.setBellProperties(bellParams);
788
818
  if (value === CallStatus.CALLING) {
789
- await this?._bellContext?.play();
819
+ this?._bellContext?.play();
790
820
  } else {
821
+ this._tuiCallEngine?.reportLog?.({
822
+ name: 'TUICallkit._bellContext.stop',
823
+ });
791
824
  // 状态变更通知
792
825
  if (value === CallStatus.CONNECTED) {
793
826
  const isGroup = TUIStore.getData(StoreName.CALL, NAME.IS_GROUP);
@@ -41,18 +41,6 @@ export async function beforeCall(type: CallMediaType, that: any) {
41
41
  return CallStatus.IDLE;
42
42
  }
43
43
  }
44
- // 套餐问题提示, 小程序最低需要群组通话版, 1v1 通话版本使用 TRTC 就会报错
45
- export function handlePackageError(error) {
46
- if (error?.code === -1002) {
47
- // @ts-ignore
48
- wx.showModal({
49
- icon: 'none',
50
- title: 'error',
51
- content: error?.message || '',
52
- showCancel: false,
53
- });
54
- }
55
- }
56
44
 
57
45
  export function handleNoPusherCapabilityError(){
58
46
  // @ts-ignore
@@ -41,7 +41,7 @@ export default class CallStore {
41
41
  pusher: {},
42
42
  player: [],
43
43
  isEarPhone: false, // 是否是听筒, 默认: false
44
- pusherId: NAME.INITIAL_PUSHER, // 重新渲染 live-Pusher 的标识位
44
+ pusherId: '', // 重新渲染 live-Pusher 的标识位
45
45
  // 是否开启虚拟背景, 目前仅 web 支持
46
46
  isShowEnableVirtualBackground: false, // 是否显示虚拟背景图标, 默认: false
47
47
  enableVirtualBackground: false, // 是否开启虚拟背景, 默认: false
@@ -54,6 +54,11 @@ export default class CallStore {
54
54
  // translate function
55
55
  translate: t,
56
56
  isForceUseV2API: false,
57
+ // AI Transcriber related fields
58
+ transcriberRobotId: null,
59
+ realtimeMessageList: [],
60
+ isAITranscriberEnabled: false,
61
+ isAITranscriberRunning: false,
57
62
  };
58
63
  public store: ICallStore = deepClone(this.defaultStore);
59
64
  public prevStore: ICallStore = deepClone(this.defaultStore);
@@ -0,0 +1,117 @@
1
+ // @ts-nocheck
2
+ import type { UIKitModalOptions, UIKitModalResult } from './type';
3
+ import TUICallKitServer from '../CallService';
4
+
5
+ const URL_REGEX = /^(https?:\/\/)?([\da-z.-]+)\.([a-z.]{2,6})([/\w .-]*)*\/?$/i;
6
+ const FULL_URL_REGEX = /(https?:\/\/[^\s]+)/g;
7
+
8
+ function isDevEnvironment(): boolean {
9
+ const accountInfo = uni.getAccountInfoSync?.();
10
+ const envVersion = accountInfo?.miniProgram?.envVersion;
11
+ return envVersion === 'develop' || envVersion === 'trial';
12
+ }
13
+
14
+ function extractUrlFromContent(content: string): string | null {
15
+ if (!content || typeof content !== 'string') {
16
+ return null;
17
+ }
18
+
19
+ if (content.includes('<a ') || content.includes('<a>')) {
20
+ const hrefMatch = content.match(/href=["']([^"']+)["']/);
21
+ return hrefMatch ? hrefMatch[1] : null;
22
+ }
23
+
24
+ if (URL_REGEX.test(content.trim())) {
25
+ return content.trim();
26
+ }
27
+
28
+ const urlMatch = content.match(FULL_URL_REGEX);
29
+ return urlMatch ? urlMatch[0] : null;
30
+ }
31
+
32
+ function processContent(content: string): string {
33
+ if (!content || typeof content !== 'string') {
34
+ return '';
35
+ }
36
+
37
+ let text = content.replace(/<[^>]+>/g, '');
38
+ text = text
39
+ .replace(/&nbsp;/g, ' ')
40
+ .replace(/&lt;/g, '<')
41
+ .replace(/&gt;/g, '>')
42
+ .replace(/&amp;/g, '&')
43
+ .replace(/&quot;/g, '"');
44
+ text = text.replace(/\s+/g, ' ').trim();
45
+
46
+ const url = extractUrlFromContent(content);
47
+ if (url && !text.includes(url)) {
48
+ return text ? `${text}\n${url}` : url;
49
+ }
50
+
51
+ return text;
52
+ }
53
+
54
+ function reportModalView(options: UIKitModalOptions): void {
55
+ try {
56
+ const tim = TUICallKitServer?.getTim?.();
57
+ if (tim && typeof tim.callExperimentalAPI === 'function') {
58
+ const reportData = {
59
+ id: options.id,
60
+ title: options.title,
61
+ type: options.type,
62
+ content: options.content,
63
+ platform: 'miniprogram',
64
+ };
65
+ tim.callExperimentalAPI('reportModalView', JSON.stringify(reportData));
66
+ }
67
+ } catch (error) {
68
+ console.warn('[UIKitModal] reportModalView failed:', error);
69
+ }
70
+ }
71
+
72
+ const createUIKitModal = (options: UIKitModalOptions): Promise<UIKitModalResult> => {
73
+ return new Promise((resolve) => {
74
+ reportModalView(options);
75
+
76
+ if (!isDevEnvironment()) {
77
+ resolve({ action: 'confirm' });
78
+ return;
79
+ }
80
+
81
+ const url = extractUrlFromContent(options.content);
82
+ const processedContent = processContent(options.content);
83
+ const hasLink = !!url;
84
+
85
+ uni.showModal({
86
+ title: options.title || '',
87
+ content: processedContent,
88
+ cancelText: '取消',
89
+ confirmText: hasLink ? '复制链接' : '确认',
90
+ success: (res) => {
91
+ const action = res.confirm ? 'confirm' : 'cancel';
92
+ if (res.confirm) {
93
+ if (hasLink && url) {
94
+ uni.setClipboardData({
95
+ data: url,
96
+ success: () => {
97
+ uni.showToast({ title: '链接已复制', icon: 'success' });
98
+ },
99
+ });
100
+ }
101
+ options.onConfirm?.();
102
+ } else {
103
+ options.onCancel?.();
104
+ }
105
+ resolve({ action, raw: res });
106
+ },
107
+ fail: () => {
108
+ options.onCancel?.();
109
+ resolve({ action: 'cancel' });
110
+ },
111
+ });
112
+ });
113
+ };
114
+
115
+ export const UIKitModal = {
116
+ openModal: (config: UIKitModalOptions) => createUIKitModal(config),
117
+ };
@@ -0,0 +1,2 @@
1
+ export { UIKitModal } from './UIKitModal';
2
+ export type { UIKitModalOptions, UIKitModalResult, ModalType } from './type';
@@ -0,0 +1,15 @@
1
+ export type ModalType = 'info' | 'warning' | 'error' | 'success';
2
+
3
+ export interface UIKitModalOptions {
4
+ id: number;
5
+ title: string;
6
+ content: string;
7
+ type: ModalType;
8
+ onConfirm?: () => void;
9
+ onCancel?: () => void;
10
+ }
11
+
12
+ export interface UIKitModalResult {
13
+ action: 'confirm' | 'cancel';
14
+ raw?: any;
15
+ }
@@ -39,6 +39,10 @@ export const CALL_DATA_KEY: any = {
39
39
  PUSHER_ID: 'pusherId',
40
40
  IS_FORCE_USE_V2_API: 'isForceUseV2API',
41
41
  MODAL_ERROR: 'modalError',
42
+ TRANSCRIBER_ROBOT_ID: 'transcriberRobotId',
43
+ REALTIME_MESSAGE_LIST: 'realtimeMessageList',
44
+ IS_AI_TRANSCRIBER_ENABLED: 'isAITranscriberEnabled', // Controls UI visibility
45
+ IS_AI_TRANSCRIBER_RUNNING: 'isAITranscriberRunning', // Controls AI transcriber running state
42
46
  };
43
47
 
44
48
  export const CHAT_DATA_KEY: any = {
@@ -52,4 +52,9 @@ export interface ICallStore {
52
52
  // translate function
53
53
  translate: Function,
54
54
  isForceUseV2API: boolean, // 是否使用 call/groupCall 接口, 默认: false
55
+ // AI Transcriber related fields
56
+ transcriberRobotId: string | null, // AI 转写机器人 ID
57
+ realtimeMessageList: [], // 实时转写消息列表
58
+ isAITranscriberEnabled: boolean, // AI 转写UI是否显示
59
+ isAITranscriberRunning: boolean, // AI transcriber running state
55
60
  }
@@ -146,4 +146,19 @@ export const en = {
146
146
  'error.10013': "Call failed: You have been blocked by the other party or you have blocked the other party",
147
147
  'error.10014': "Call initiation failed. User ID is invalid. Please confirm that the user is registered.",
148
148
  'error': 'Error',
149
+ // AI Subtitle Settings
150
+ 'ai-subtitle': 'AI Subtitle',
151
+ 'ai-subtitle-settings': 'AI Subtitle Settings',
152
+ 'recognition-language': 'Recognition Language',
153
+ 'translation-language': 'Translation Language',
154
+ 'subtitle-display-settings': 'Subtitle Display Settings',
155
+ 'subtitle-display-bilingual': 'Show Bilingual Subtitles',
156
+ 'no-translation': 'No Translation',
157
+ 'show-bilingual': 'Show Bilingual',
158
+ 'show-original-only': 'Show Original Only',
159
+ 'save': 'Save',
160
+ 'select-recognition-language': 'Please select recognition language',
161
+ 'select-translation-language': 'Please select translation language',
162
+ 'confirm': 'Confirm',
163
+ 'recognition-and-translation-settings': 'Recognition & Translation Settings',
149
164
  };
@@ -145,4 +145,19 @@ export const ja_JP = {
145
145
  'error.10013': "通話失敗:相手にブロックされているか、または相手をブロックしています",
146
146
  'error.10014': "通話の開始に失敗しました。ユーザーIDが無効です。ユーザーが登録されていることを確認してください。",
147
147
  'error': 'エラー',
148
+ // AI Subtitle Settings
149
+ 'ai-subtitle': 'AI字幕',
150
+ 'ai-subtitle-settings': 'AI字幕設定',
151
+ 'recognition-language': '認識言語',
152
+ 'translation-language': '翻訳言語',
153
+ 'subtitle-display-settings': '字幕表示設定',
154
+ 'subtitle-display-bilingual': 'バイリンガル字幕を表示',
155
+ 'no-translation': '翻訳しない',
156
+ 'show-bilingual': 'バイリンガル表示',
157
+ 'show-original-only': '原文のみ表示',
158
+ 'save': '保存',
159
+ 'select-recognition-language': '認識言語を選択してください',
160
+ 'select-translation-language': '翻訳言語を選択してください',
161
+ 'confirm': '確認',
162
+ 'recognition-and-translation-settings': '認識と翻訳の設定',
148
163
  };
@@ -141,4 +141,19 @@ export const zh = {
141
141
  'error.10013': "呼叫失败:您已被对方拉黑或您拉黑了对方",
142
142
  'error.10014': "发起通话失败,用户 ID 无效,请确认该用户已注册。",
143
143
  'error': '错误',
144
+ // AI Subtitle Settings
145
+ 'ai-subtitle': 'AI 字幕',
146
+ 'ai-subtitle-settings': 'AI 字幕设置',
147
+ 'recognition-language': '识别语言',
148
+ 'translation-language': '翻译语言',
149
+ 'subtitle-display-settings': '字幕显示设置',
150
+ 'subtitle-display-bilingual': '字幕显示双语',
151
+ 'no-translation': '不翻译',
152
+ 'show-bilingual': '显示双语',
153
+ 'show-original-only': '仅显示原文',
154
+ 'save': '保存',
155
+ 'select-recognition-language': '请选择识别语言',
156
+ 'select-translation-language': '请选择翻译语言',
157
+ 'confirm': '确定',
158
+ 'recognition-and-translation-settings': '识别与翻译设置',
144
159
  };
@@ -155,7 +155,7 @@ export function handleRepeatedCallError(error: any) {
155
155
  */
156
156
  export function handleNoDevicePermissionError(error: any) {
157
157
  const { message } = error;
158
- if (message.indexOf('NotAllowedError: Permission denied') !== -1) {
158
+ if (message?.indexOf('NotAllowedError: Permission denied') !== -1) {
159
159
  return true;
160
160
  }
161
161
  return false;
package/src/index.ts CHANGED
@@ -37,7 +37,7 @@ const TUICallType = {
37
37
  AUDIO_CALL: 1,
38
38
  VIDEO_CALL: 2,
39
39
  };
40
- const Version = '4.4.2'; // basic-demo 原来上报使用
40
+ const Version = '4.4.5'; // basic-demo 原来上报使用
41
41
 
42
42
  // 输出产物
43
43
  export {