@trtc/calls-uikit-vue2 4.4.8 → 4.5.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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@trtc/calls-uikit-vue2",
3
- "version": "4.4.8",
3
+ "version": "4.5.0",
4
4
  "main": "./tuicall-uikit-vue2.umd.js",
5
5
  "module": "./tuicall-uikit-vue2.es.js",
6
6
  "types": "./types/index.d.ts",
@@ -13,9 +13,10 @@
13
13
  "directory": "Web"
14
14
  },
15
15
  "dependencies": {
16
- "@tencentcloud/tui-core-lite": "1.0.0",
17
- "@trtc/call-engine-lite-js": "~3.5.8",
18
- "@tencentcloud/lite-chat": "^1.6.3"
16
+ "@tencentcloud/tui-core-lite": "~1.0.1",
17
+ "@trtc/call-engine-lite-js": "~4.0.0",
18
+ "@tencentcloud/lite-chat": "^1.6.3",
19
+ "@trtc/call-engine-lite-wx": "~4.0.0"
19
20
  },
20
21
  "bugs": {
21
22
  "url": "https://github.com/tencentyun/TUICallKit/issues"
@@ -151,11 +151,19 @@ const visibleStreamIdList = computed(() => {
151
151
  }
152
152
  });
153
153
  });
154
- const showStream = computed(() => !(
155
- callRole.value === CallRole.CALLEE
156
- && callStatus.value === CallStatus.CALLING
157
- && !isFloatWindow.value
158
- ));
154
+ const showStream = computed(() => {
155
+ // HarmonyOS: keep stream visible during CALLEE CALLING state to avoid join room timeout
156
+ if (TUIGlobal.isWxHarmony && callRole.value === CallRole.CALLEE && callStatus.value === CallStatus.CALLING) {
157
+ console.warn('HarmonyOS: keeping stream visible during CALLEE CALLING state');
158
+ return true;
159
+ }
160
+
161
+ return !(
162
+ callRole.value === CallRole.CALLEE
163
+ && callStatus.value === CallStatus.CALLING
164
+ && !isFloatWindow.value
165
+ );
166
+ });
159
167
 
160
168
  const mediaContainerStyle = computed(() => {
161
169
  let visibility = '';
@@ -21,9 +21,11 @@
21
21
  <div class="control-item">
22
22
  <Minimize v-if="!isPC && showMinimize" />
23
23
  </div>
24
+ <!-- @if process.env.BUILD_TARGET!='MINI' -->
24
25
  <div class="control-item">
25
26
  <AITranscriberSwitchH5 v-if="showAITranscriberSwitch" />
26
27
  </div>
28
+ <!-- @endif -->
27
29
  </div>
28
30
  </Col>
29
31
  <Col :span="8" justify="center" align="center">
@@ -62,8 +64,10 @@ import FullScreen from '../Button/FullScreen.vue';
62
64
  // @endif
63
65
  import InviteUser from '../Button/InviteUser.vue';
64
66
  import Timer from '../Timer/Timer.vue';
67
+ // @if process.env.BUILD_TARGET!='MINI'
65
68
  import AITranscriberSwitch from '../AIAssistant/components/AITranscriberSwitchPC.vue';
66
69
  import AITranscriberSwitchH5 from '../AIAssistant/components/AITranscriberSwitchH5.vue';
70
+ // @endif
67
71
 
68
72
  defineProps(TopBarProps);
69
73
  const isPC = TUIGlobal.isPC;
@@ -0,0 +1,182 @@
1
+ /**
2
+ * BackgroundHandler - Mini Program background detection and auto hangup handler
3
+ *
4
+ * When mini program goes to background for more than 4s, automatically hang up the call
5
+ * to avoid issues caused by WeChat disconnecting WebSocket after 5s.
6
+ */
7
+
8
+ import { CallStatus, CallRole, StoreName, NAME } from '../const/index';
9
+ import TuiStore from '../TUIStore/tuiStore';
10
+ import { ITUIStore } from '../interface/index';
11
+ const TUIStore: ITUIStore = TuiStore.getInstance();
12
+
13
+ export interface IBackgroundConfig {
14
+ enableAutoHangup: boolean; // Enable auto hangup on background (default: true)
15
+ hangupTimeout: number; // Auto hangup timeout in ms (default: 4000)
16
+ }
17
+ const DEFAULT_BACKGROUND_CONFIG: IBackgroundConfig = {
18
+ enableAutoHangup: true,
19
+ hangupTimeout: 4000, // 4s auto hangup (before ws disconnects at 5s)
20
+ };
21
+
22
+ export default class BackgroundHandler {
23
+ private _callService: any;
24
+ private _hangupTimer: ReturnType<typeof setTimeout> | null = null;
25
+ private _backgroundTimestamp: number = 0;
26
+ private _isInBackground: boolean = false;
27
+ private _config: IBackgroundConfig = { ...DEFAULT_BACKGROUND_CONFIG };
28
+ private _isInitialized: boolean = false;
29
+
30
+ constructor(callService: any) {
31
+ this._callService = callService;
32
+ }
33
+
34
+ // Initialize background detection for mini program; Listen to wx.onAppHide/onAppShow events
35
+ public initBackgroundDetection(): void {
36
+ if (this._isInitialized) return;
37
+
38
+ try {
39
+ // @ts-ignore
40
+ if (typeof wx !== 'undefined' && wx.onAppHide && wx.onAppShow) {
41
+ // @ts-ignore
42
+ wx.onAppHide(this._handleAppHide);
43
+ // @ts-ignore
44
+ wx.onAppShow(this._handleAppShow);
45
+ this._isInitialized = true;
46
+ console.log('[TUICallKit] BackgroundHandler initialized');
47
+ }
48
+ } catch (error) {
49
+ console.warn('[TUICallKit] BackgroundHandler init failed:', error);
50
+ }
51
+ }
52
+
53
+ // Destroy background detection; Remove event listeners and clear timers
54
+ public destroyBackgroundDetection(): void {
55
+ if (!this._isInitialized) return;
56
+
57
+ try {
58
+ // @ts-ignore
59
+ if (typeof wx !== 'undefined' && wx.offAppHide && wx.offAppShow) {
60
+ // @ts-ignore
61
+ wx.offAppHide(this._handleAppHide);
62
+ // @ts-ignore
63
+ wx.offAppShow(this._handleAppShow);
64
+ }
65
+ this._clearTimers();
66
+ this._isInitialized = false;
67
+ console.log('[TUICallKit] BackgroundHandler destroyed');
68
+ } catch (error) {
69
+ console.warn('[TUICallKit] BackgroundHandler destroy failed:', error);
70
+ }
71
+ }
72
+
73
+ // Handle app hide event (going to background)
74
+ private _handleAppHide = (): void => {
75
+ const callStatus = TUIStore.getData(StoreName.CALL, NAME.CALL_STATUS) || CallStatus.IDLE;
76
+ const callRole = TUIStore.getData(StoreName.CALL, NAME.CALL_ROLE) || CallRole.UNKNOWN;
77
+
78
+ // Only handle when in connected state (as per requirement: only for connected calls)
79
+ if ((callStatus !== CallStatus.CONNECTED) || !this._config.enableAutoHangup) return;
80
+
81
+ this._isInBackground = true;
82
+ this._backgroundTimestamp = Date.now();
83
+ this._callService?._tuiCallEngine?.reportLog?.({
84
+ name: 'TUICallkit.background.appHide',
85
+ data: { callStatus, callRole, timestamp: this._backgroundTimestamp, config: this._config },
86
+ });
87
+
88
+ this._hangupTimer = setTimeout(() => {
89
+ this._handleBackgroundTimeout();
90
+ }, this._config.hangupTimeout);
91
+ };
92
+
93
+ // Handle app show event (returning from background)
94
+ private _handleAppShow = (): void => {
95
+ if (!this._isInBackground) return;
96
+
97
+ const backgroundDuration = Date.now() - this._backgroundTimestamp;
98
+ const callStatus = TUIStore.getData(StoreName.CALL, NAME.CALL_STATUS) || CallStatus.IDLE;
99
+ const callRole = TUIStore.getData(StoreName.CALL, NAME.CALL_ROLE) || CallRole.UNKNOWN;
100
+
101
+ this._callService?._tuiCallEngine?.reportLog?.({
102
+ name: 'TUICallkit.background.appShow',
103
+ data: { callStatus, callRole, backgroundDuration, timestamp: Date.now() },
104
+ });
105
+
106
+ this._isInBackground = false;
107
+ this._clearTimers();
108
+
109
+ // If background time exceeded hangup timeout, show toast to explain why call ended
110
+ if (backgroundDuration >= this._config.hangupTimeout) {
111
+ this._showToast('后台超时,通话已结束');
112
+ this._checkCallStatusAfterBackground();
113
+ }
114
+ };
115
+
116
+ // Show toast - compatible with both UniApp and native mini program
117
+ private _showToast(title: string): void {
118
+ try {
119
+ // @ts-ignore - UniApp API
120
+ if (typeof uni !== 'undefined' && uni?.showToast) {
121
+ // @ts-ignore
122
+ uni.showToast({ title, icon: 'none', duration: 2500 });
123
+ // @ts-ignore - Native mini program API
124
+ } else if (typeof wx !== 'undefined' && wx?.showToast) {
125
+ // @ts-ignore
126
+ wx.showToast({ title, icon: 'none', duration: 2500 });
127
+ }
128
+ } catch (error) {}
129
+ }
130
+
131
+ // Handle background timeout - auto hangup
132
+ private async _handleBackgroundTimeout(): Promise<void> {
133
+ try {
134
+ const callStatus = TUIStore.getData(StoreName.CALL, NAME.CALL_STATUS) || CallStatus.IDLE;
135
+ const callRole = TUIStore.getData(StoreName.CALL, NAME.CALL_ROLE) || CallRole.UNKNOWN;
136
+ const backgroundDuration = Date.now() - this._backgroundTimestamp;
137
+
138
+ // Report timeout event before hangup
139
+ this._callService?._tuiCallEngine?.reportLog?.({
140
+ name: 'TUICallkit.background.timeout',
141
+ data: { callStatus, callRole, backgroundDuration, hangupTimeout: this._config.hangupTimeout },
142
+ });
143
+
144
+ // Only handle CONNECTED state (CALLING state is filtered in _handleAppHide)
145
+ if (callStatus === CallStatus.CONNECTED) {
146
+ this._callService?._tuiCallEngine?.reportLog?.({
147
+ name: 'TUICallkit.background.hangup',
148
+ data: { callStatus, callRole, action: 'hangup' },
149
+ });
150
+ await this._callService?.hangup?.();
151
+ }
152
+ } catch (error) {
153
+ this._callService?._tuiCallEngine?.reportLog?.({
154
+ name: 'TUICallkit.background.hangup.fail',
155
+ data: { error: String(error) },
156
+ });
157
+ }
158
+ }
159
+
160
+ // Check call status after returning from long background; Handle case where call should have ended
161
+ private _checkCallStatusAfterBackground(): void {
162
+ try {
163
+ const callStatus = TUIStore.getData(StoreName.CALL, NAME.CALL_STATUS) || CallStatus.IDLE;
164
+ // If still in call state after exceeding timeout, something went wrong
165
+ // The call should have been ended by _handleBackgroundTimeout
166
+ if (callStatus !== CallStatus.IDLE) {
167
+ // Force reset if needed
168
+ this._callService?._resetCallStore?.();
169
+ }
170
+ } catch (error) {
171
+ console.warn('[TUICallKit] Check call status after background failed:', error);
172
+ }
173
+ }
174
+
175
+ // Clear hangup timer
176
+ private _clearTimers(): void {
177
+ if (this._hangupTimer) {
178
+ clearTimeout(this._hangupTimer);
179
+ this._hangupTimer = null;
180
+ }
181
+ }
182
+ }
@@ -27,7 +27,7 @@ const TUIGlobal: ITUIGlobal = TuiGlobal.getInstance();
27
27
  const TUIStore: ITUIStore = TuiStore.getInstance();
28
28
  const uiDesign = UIDesign.getInstance();
29
29
  uiDesign.setTUIStore(TUIStore);
30
- const version = '4.4.8';
30
+ const version = '4.5.0';
31
31
  import AIAssistant from './AIAssistant'; // 仅 web 支持 AI 实时字幕
32
32
  const frameWork = 'vue2.7';
33
33
  export { TUIGlobal, TUIStore, uiDesign };
@@ -1,4 +1,4 @@
1
- import { APP_NAMESPACE, IS_PC, IS_H5, IN_WX_MINI_APP, IN_UNI_NATIVE_APP, IN_UNI_APP, IS_MAC, IS_WIN } from '../utils/env';
1
+ import { APP_NAMESPACE, IS_PC, IS_H5, IN_WX_MINI_APP, IN_UNI_NATIVE_APP, IN_UNI_APP, IS_MAC, IS_WIN, IS_WX_HARMONY } from '../utils/env';
2
2
  import { ITUIGlobal } from '../interface/ITUIGlobal';
3
3
 
4
4
  export default class TUIGlobal implements ITUIGlobal {
@@ -12,6 +12,7 @@ export default class TUIGlobal implements ITUIGlobal {
12
12
  public isOfficial: boolean = false;
13
13
  public isWIN: boolean = false;
14
14
  public isMAC: boolean = false;
15
+ public isWxHarmony: boolean = false;
15
16
  constructor() {
16
17
  this.initEnv();
17
18
  }
@@ -35,6 +36,7 @@ export default class TUIGlobal implements ITUIGlobal {
35
36
  this.isUniPlatform = IN_UNI_APP;
36
37
  this.isWIN = IS_WIN;
37
38
  this.isMAC = IS_MAC;
39
+ this.isWxHarmony = IS_WX_HARMONY;
38
40
  }
39
41
 
40
42
  initOfficial(SDKAppID: number) {
@@ -9,6 +9,7 @@
9
9
  * @property {Boolean} isOfficial true 标识是腾讯云官网 Demo 应用
10
10
  * @property {Boolean} isWIN true 标识是window系统pc
11
11
  * @property {Boolean} isMAC true 标识是mac os系统pc
12
+ * @property {Boolean} isWxHarmony true 标识是微信小程序运行在鸿蒙系统
12
13
  */
13
14
  export interface ITUIGlobal {
14
15
  global: any; // 挂在 wx、uni、window 对象
@@ -20,6 +21,7 @@ export interface ITUIGlobal {
20
21
  isOfficial: boolean;
21
22
  isWIN: boolean;
22
23
  isMAC: boolean;
24
+ isWxHarmony: boolean;
23
25
  /**
24
26
  * 初始化 TUIGlobal 环境变量
25
27
  * @function
@@ -49,3 +49,9 @@ export const IS_H5 = IS_ANDROID || IS_WIN_PHONE || IS_SYMBIAN || IS_IOS;
49
49
  export const IS_PC = IN_BROWSER && !IS_H5;
50
50
  export const IS_WIN = IS_PC && USER_AGENT.includes('Windows NT');
51
51
  export const IS_MAC = IS_PC && USER_AGENT.includes('Mac');
52
+
53
+ let IS_WX_HARMONY = false;
54
+ if (IN_WX_MINI_APP) {
55
+ IS_WX_HARMONY = (wx.getSystemInfoSync()?.system || '').includes('Harmony');
56
+ }
57
+ export { IS_WX_HARMONY };
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.8'; // basic-demo 原来上报使用
40
+ const Version = '4.5.0'; // basic-demo 原来上报使用
41
41
 
42
42
  // 输出产物
43
43
  export {