@tencent-rtc/mcp 1.3.1 → 1.3.3

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 (87) hide show
  1. package/index.js +4 -0
  2. package/index.js.map +1 -1
  3. package/package.json +1 -1
  4. package/resource/doc/chatuikit/faq/web_sdk/faq.md +125 -0
  5. package/resource/doc/chatuikit/flutter/faq.md +17 -114
  6. package/resource/doc/chatuikit/flutter/integrate_tuikit_Flutter.md +86 -722
  7. package/resource/doc/livekit/live/android/live-audience-list.md +334 -0
  8. package/resource/doc/livekit/live/android/live-audio-effect.md +380 -0
  9. package/resource/doc/livekit/live/android/live-barrage.md +565 -0
  10. package/resource/doc/livekit/live/android/live-base-beauty.md +275 -0
  11. package/resource/doc/livekit/live/android/live-co-guest-interaction.md +629 -0
  12. package/resource/doc/livekit/live/android/live-gift.md +822 -0
  13. package/resource/doc/livekit/live/android/live-host-interaction.md +888 -0
  14. package/resource/doc/livekit/live/android/live-integration.md +972 -0
  15. package/resource/doc/livekit/live/android/live-live-list.md +575 -0
  16. package/resource/doc/livekit/live/android/workflow.md +189 -0
  17. package/resource/doc/roomkit/vue/features/call-user-to-room.md +256 -0
  18. package/resource/doc/roomkit/vue/features/device-detection.md +388 -0
  19. package/resource/doc/roomkit/vue/features/device-state.md +480 -0
  20. package/resource/doc/roomkit/vue/features/free-beauty-panel.md +238 -0
  21. package/resource/doc/roomkit/vue/features/room-chat.md +427 -0
  22. package/resource/doc/roomkit/vue/features/room-participant-state.md +407 -0
  23. package/resource/doc/roomkit/vue/features/room-state.md +291 -0
  24. package/resource/doc/roomkit/vue/features/room-view.md +338 -0
  25. package/resource/doc/roomkit/vue/features/schedule-room.md +349 -0
  26. package/resource/doc/roomkit/vue/features/screen-share.md +333 -0
  27. package/resource/doc/roomkit/vue/features/virtual-background.md +287 -0
  28. package/resource/doc/roomkit/vue/features/workflow.md +553 -0
  29. package/resource/doc/roomkit/vue/integration.md +479 -0
  30. package/resource/doc/roomkit/vue/workflow.md +487 -0
  31. package/resource/doc/tuicallkit/react/api.md +21 -0
  32. package/resource/doc/tuicallkit/vue/api.md +21 -0
  33. package/tools/common/record-prompt.js +2 -2
  34. package/tools/common/record-prompt.js.map +1 -1
  35. package/tools/definitions/get_native_live_extra_features_def.js +87 -0
  36. package/tools/definitions/get_native_live_extra_features_def.js.map +1 -0
  37. package/tools/definitions/get_native_live_interaction_def.js +74 -0
  38. package/tools/definitions/get_native_live_interaction_def.js.map +1 -0
  39. package/tools/definitions/get_native_live_uikit_integration_def.js +49 -0
  40. package/tools/definitions/get_native_live_uikit_integration_def.js.map +1 -0
  41. package/tools/definitions/get_web_room_feature_detail_def.js +95 -0
  42. package/tools/definitions/get_web_room_feature_detail_def.js.map +1 -0
  43. package/tools/definitions/get_web_room_uikit_integration_def.js +44 -0
  44. package/tools/definitions/get_web_room_uikit_integration_def.js.map +1 -0
  45. package/tools/definitions/record_prompt_def.js +1 -1
  46. package/tools/definitions/record_prompt_def.js.map +1 -1
  47. package/tools/index.js +10 -2
  48. package/tools/index.js.map +1 -1
  49. package/tools/live/get-native-live-uikit-integration.js +101 -0
  50. package/tools/live/get-native-live-uikit-integration.js.map +1 -0
  51. package/tools/live/get-web-live-component-detail.js +1 -1
  52. package/tools/live/get-web-live-component-detail.js.map +1 -1
  53. package/tools/live/get-web-live-state-detail.js +1 -1
  54. package/tools/live/get-web-live-state-detail.js.map +1 -1
  55. package/tools/live/get-web-live-uikit-integration.js +6 -6
  56. package/tools/live/get-web-live-uikit-integration.js.map +1 -1
  57. package/tools/live/get_native_live_extra_features.js +105 -0
  58. package/tools/live/get_native_live_extra_features.js.map +1 -0
  59. package/tools/live/get_native_live_interaction.js +101 -0
  60. package/tools/live/get_native_live_interaction.js.map +1 -0
  61. package/tools/room/get-web-room-feature-detail.js +68 -0
  62. package/tools/room/get-web-room-feature-detail.js.map +1 -0
  63. package/tools/room/get-web-room-integration.js +43 -0
  64. package/tools/room/get-web-room-integration.js.map +1 -0
  65. package/utils/report-cls-client.js +1 -1
  66. package/utils/report-es-client.js +1 -1
  67. package/resource/doc/chatuikit/flutter/integrate_only_tuichat_Flutter.md +0 -333
  68. package/resource/doc/chatuikit/flutter/quick_start_Flutter.md +0 -217
  69. package/resource/doc/roomkit/vue/states/device-state.md +0 -369
  70. package/resource/doc/roomkit/vue/states/login-state.md +0 -59
  71. package/resource/doc/roomkit/vue/states/room-list-state.md +0 -355
  72. package/resource/doc/roomkit/vue/states/room-participant-state.md +0 -388
  73. package/tools/room/get-web-room-state-detail.js +0 -31
  74. package/tools/room/get-web-room-state-detail.js.map +0 -1
  75. /package/resource/doc/livekit/{vue → live/vue}/components/barrage.md +0 -0
  76. /package/resource/doc/livekit/{vue → live/vue}/components/co-guest-panel.md +0 -0
  77. /package/resource/doc/livekit/{vue → live/vue}/components/live-audience-list.md +0 -0
  78. /package/resource/doc/livekit/{vue → live/vue}/components/live-scene-panel.md +0 -0
  79. /package/resource/doc/livekit/{vue → live/vue}/components/live-view.md +0 -0
  80. /package/resource/doc/livekit/{vue → live/vue}/components/stream-mixer.md +0 -0
  81. /package/resource/doc/livekit/{vue → live/vue}/faq.md +0 -0
  82. /package/resource/doc/livekit/{vue → live/vue}/live-list-integration.md +0 -0
  83. /package/resource/doc/livekit/{vue → live/vue}/live-player-desk-integration.md +0 -0
  84. /package/resource/doc/livekit/{vue → live/vue}/live-player-h5-integration.md +0 -0
  85. /package/resource/doc/livekit/{vue → live/vue}/live-pusher-integration.md +0 -0
  86. /package/resource/doc/livekit/{vue → live/vue}/states/live-state.md +0 -0
  87. /package/resource/doc/livekit/{vue → live/vue}/workflow.md +0 -0
@@ -0,0 +1,189 @@
1
+ # Native Live AtomicXCore Code Generation Workflow Instructions (Android)
2
+
3
+ ## 🚨 Core Principles (Highest Priority)
4
+
5
+ **The Agent MUST ensure that the generated code compiles and runs successfully. Delivering uncompilable code to the user is strictly prohibited!**
6
+
7
+ ### ⚠️ Mandatory Compilation Verification
8
+ **After every code generation or modification, a full Gradle compilation MUST be executed**:
9
+ ```bash
10
+ ./gradlew assembleDebug --stacktrace
11
+ ```
12
+
13
+ **Prohibited Actions**:
14
+ - ❌ DO NOT assume code is correct based only on `read_lints` checks.
15
+ - ❌ DO NOT use `grep` to filter compilation output (this may miss critical error context).
16
+
17
+ **Compilation Error Classification & Handling**:
18
+ | Error Type | Example | Handling Strategy |
19
+ |------------|---------|-------------------|
20
+ | Dependency Resolution Failure | `Could not find xxx` | Check repository configurations (JitPack/Maven). |
21
+ | Missing Dependency | `Unresolved reference` | Add missing dependency to `build.gradle`. |
22
+ | Missing Import | `Unresolved reference: xxx` | Add the required `import` statement. |
23
+ | Missing Resource | `cannot find symbol R.xxx` | Create the corresponding resource file. |
24
+ | Missing Manifest Entry | `Activity not found` | Register the activity in `AndroidManifest.xml`. |
25
+
26
+ **Validation Process**:
27
+ 1. Execute `./gradlew assembleDebug` (Full output, DO NOT filter).
28
+ 2. If it fails -> Analyze the full error -> **Auto-fix** -> Recompile.
29
+ 3. Repeat until `BUILD SUCCESSFUL`.
30
+
31
+ **Key Point**: Emphasize that `read_lints != Full Compilation Verification`. Gradle dependency and configuration errors can only be detected through a full build.
32
+
33
+ **Processing Flow**:
34
+ 1. **Compilation Successful (BUILD SUCCESSFUL)** -> Deliver code.
35
+ 2. **Compilation Failed** -> Analyze error -> **Auto-fix** -> Recompile.
36
+ * ✅ **Auto-fixable**: Missing dependencies, missing imports, missing AndroidManifest permissions/registrations.
37
+ * ❌ **Unfixable**: Internal SDK errors, network environment issues (inform the user).
38
+
39
+ ---
40
+
41
+ ## 📋 Instruction Purpose & Architecture
42
+
43
+ Provides the Agent with a **code generation blueprint** for implementing core features of Native (Android) Live AtomicXCore.
44
+
45
+ **Core Architecture**:
46
+ * **Container**: `LiveCoreView` (View layer)
47
+ * **State**: `Store` (Data-driven)
48
+ * **Events**: `Listener` (Callback handling)
49
+
50
+ **Feature Dependency Logic (Important)**:
51
+ 1. **Base First**: Basic live streaming (Broadcasting/Viewing/List) must be completed first using the base tool (`get_native_live_uikit_integration`).
52
+ 2. **Interaction Overlay**: If requirements include "Co-guesting", "PK", or "Audience List", the interaction tool (`get_native_live_interaction`) must be called **after** basic features are completed.
53
+ 3. **Empty Project Handling**: If the user requests interaction features in an empty project, the Agent **MUST implement basic features first**, then add interaction capabilities.
54
+
55
+ ---
56
+
57
+ ## ⚙️ Automated Workflow Steps
58
+
59
+ ### Step 0: Preparation (Automated)
60
+ 1. **Generate Credentials**: Call the `get_usersig` tool to generate test credentials.
61
+ * Host: `anchor001`, `anchor002`, `anchor003`
62
+ * Audience: `user001`, `user002`, `user003`
63
+ 2. **Environment Check**: Check `build.gradle` and add the following dependencies if missing:
64
+ ```gradle
65
+ api 'io.trtc.uikit:atomicx-core:latest.release'
66
+ api "io.trtc.uikit:rtc_room_engine:latest.release"
67
+ api "com.tencent.liteav:LiteAVSDK_Professional:latest.release"
68
+ api "com.tencent.imsdk:imsdk-plus:latest.release"
69
+ ```
70
+ 3. **Permission Injection**: Add Camera, Microphone, and Network permissions in `AndroidManifest.xml`.
71
+
72
+ ### Step 1: Retrieval & Generation
73
+ **PRIORITIZE and EXCLUSIVELY** use the **real-time documentation content** returned by this tool for code generation.
74
+ * **Host Only**: Generate `AnchorActivity`.
75
+ * **Audience Only**: Generate `AudienceActivity`.
76
+ * **Host + Audience**: Generate `MainActivity` (Entry selection) + `AnchorActivity` + `AudienceActivity`.
77
+
78
+ ### Step 2: Verification & Delivery
79
+ Execute `./gradlew assembleDebug` and deliver once verified.
80
+
81
+ ---
82
+
83
+ ## 🚫 Code Generation Constraints (Strictly Follow)
84
+
85
+ ### 1. General Code Constraints
86
+ * **Strictly Prohibited to Modify Imports**: Import paths in the documentation are verified; DO NOT modify them.
87
+ * **Strictly Prohibited to Fabricate APIs**: If an API is not in the documentation, DO NOT invent method or parameter names.
88
+ * **MUST Consult API Docs**: For data model fields (e.g., `LiveInfo`), visit the documentation to confirm field names (e.g., confirm it's `liveOwner.userName` and not `name`).
89
+
90
+ ### 2. 🧩 Store & Listener Management Constraints (Lifecycle Safety)
91
+ **Core Reason**: SDK `Store.create(liveId)` often returns a singleton or reusable instance. Using anonymous inner classes causes listener instances to be duplicated or overwritten, leading to bugs like "UI not updating on host side" or "only the first event being triggered."
92
+
93
+ * **Member Variable Principle**: All Listeners (e.g., `GiftListener`, `CoGuestListener`, `BarrageListener`) **MUST be declared as member variables** of the Activity or Fragment.
94
+ * **No Anonymous Inner Classes**: Prohibited to use anonymous objects directly inside `addXXXListener(object : ...)`.
95
+ * **Pairing Principle**: If `addListener` is called in `onCreate/onStart`, `removeListener` **MUST** be called in `onDestroy/onStop` to prevent memory leaks and listener failure.
96
+
97
+ ### 3. ⏱️ Timeout Limits (Critical)
98
+ **Strictly adhere to the following parameter limits, prioritizing values from documentation examples:**
99
+
100
+ #### A. Co-guesting (`CoGuestStore`)
101
+ * **Rules**:
102
+ * Optional parameter; if not filled, timeout is not checked.
103
+ * If filled, the range MUST be between **5 - 1800 seconds**.
104
+ * **Correct Examples**:
105
+ ```kotlin
106
+ // ✅ Recommended: Follow doc examples (e.g., 30s)
107
+ applyForSeat(seatIndex = -1, timeout = 30, ...)
108
+ // ✅ Valid: No timeout check
109
+ applyForSeat(seatIndex = -1, timeout = 0, ...)
110
+ ```
111
+ * **Incorrect Examples**: ❌ `timeout = 3` (too short), ❌ `timeout = 2000` (too long).
112
+
113
+ #### B. Co-hosting/PK (`CoHostStore`)
114
+ * **Rules**:
115
+ * **Maximum 30 seconds** (Hard limit).
116
+ * **Correct Examples**:
117
+ ```kotlin
118
+ // ✅ Recommended: Use maximum value
119
+ requestHostConnection(..., timeout = 30, ...)
120
+ ```
121
+ * **Incorrect Examples**: ❌ `timeout = 60` (will cause request failure).
122
+
123
+ ### 4. 🎨 Extra Feature Constraints (Beauty/Audio/UI)
124
+
125
+ #### A. Audio Effects
126
+ * **Voice Changer Enum (`AudioChangerType`)**:
127
+ * ✅ **Allowed**: `CHILD, LITTLE_GIRL, MAN, ETHEREAL`, etc.
128
+ * ❌ **Prohibited**: `UNCLE, LOLI, GIRL, BOY` (deprecated or incorrect).
129
+ * **Reverb Enum (`AudioReverbType`)**:
130
+ * ✅ **Allowed**: `KTV, SMALL_ROOM, METALLIC`, etc.
131
+ * ❌ **Prohibited**: `ROOM, HALL, LOW`.
132
+
133
+ #### B. Beauty
134
+ * **Parameter Range**: **0.0 - 9.0** (Float).
135
+ * ❌ NOT 0-1 (Float), and NOT 0-100 (Int).
136
+ * **UI Mapping Formula**: `progress / 100.0f * 9.0f`.
137
+
138
+ #### C. Barrage, Gift & Layout
139
+ * **Layering Requirements**: Barrage list and full-screen gift animations MUST overlay **on top** of the video layer using `FrameLayout` or `RelativeLayout`.
140
+ * **Split Screen Prohibited**: Strictly prohibited to split the screen (e.g., video on top, barrage at bottom); MUST use overlay mode.
141
+ * **Keyboard Adaptation**: Set `android:windowSoftInputMode="adjustNothing"` or `adjustPan` in the Manifest to **prevent video distortion or shifting when the keyboard appears**.
142
+ * **Gift Barrage**: **If the user needs gift barrage integration**, when `onReceiveGift` is triggered, a gift message MUST be inserted into the barrage list on **both host and audience sides**. DO NOT display only on the audience side.
143
+ * **Full-screen Gift**: **If the user needs full-screen gift integration**, upon receiving the gift callback, the full-screen animation MUST be played on the top-level video view on **both host and audience sides**. Hosts MUST also see the special effects of gifts sent by viewers.
144
+
145
+ ---
146
+
147
+ ## 🎯 Implementation Details
148
+
149
+ ### 1. Host Broadcasting (`host_streaming`)
150
+ * **Core**: `LiveCoreView(viewType = PUSH_VIEW)`
151
+ * **Flow**: `LiveListStore.createLive()`
152
+ * **Cleanup**: `endLive()` MUST be called in `onDestroy`.
153
+
154
+ ### 2. Audience Viewing (`audience_streaming`)
155
+ * **Core**: `LiveCoreView(viewType = PLAY_VIEW)`
156
+ * **Flow**: `LiveListStore.joinLive()`
157
+ * **Cleanup**: `leaveLive()` MUST be called in `onDestroy`.
158
+
159
+ ### 3. Live List (`live_list`)
160
+ * **Core**: `LiveListStore.fetchLiveList()` + `RecyclerView`
161
+ * **Data**: Subscribe to `liveState.liveList`.
162
+ * **Navigation**: Clicking a list item navigates to the audience page, passing the `liveID`.
163
+
164
+ ---
165
+
166
+ ## 📋 Agent Final Checklist
167
+
168
+ - [ ] **Build Verification**: Full `./gradlew assembleDebug` executed and result is SUCCESS.
169
+ - [ ] **API Accuracy**: Imports not modified, APIs not fabricated, `LiveInfo` field names verified.
170
+ - [ ] **Store & Listener Compliance**: Listeners are member variables, properly added and removed.
171
+ - [ ] **Timeout Compliance**: Co-guesting 5-1800s, Co-hosting ≤30s.
172
+ - [ ] **Extra Feature Compliance**: Audio enums correct, beauty range 0-9, barrage layout overlays, and keyboard adaptation.
173
+ - [ ] **Gift Compliance**: Full-screen gift animations implemented on both host and audience sides.
174
+ - [ ] **Credential Injection**: Test UserSig automatically injected.
175
+ - [ ] **Dependencies Complete**: `build.gradle` and permissions checked/fixed.
176
+
177
+ ---
178
+
179
+ ## 🚨 Security Reminder (Code Comment Template)
180
+
181
+ ```kotlin
182
+ /**
183
+ * ⚠️ Test Credential Warning
184
+ * - This UserSig is automatically generated by development tools and is valid for 7 days.
185
+ * - ❌ PROHIBITED from generating UserSig on the client side in production.
186
+ * - ✅ UserSig MUST be generated on a backend service before official launch.
187
+ * - Reference: https://trtc.io/document/35166?product=live&menulabel=uikit&platform=android
188
+ */
189
+ ```
@@ -0,0 +1,256 @@
1
+ The in-room call feature allows users within a meeting (inviter) to send real-time invitations to users outside the room (invitees). This feature is implemented based on `Atomicx State Hooks` and helps developers quickly build interactive scenarios with proactive invitation capabilities.
2
+
3
+ ## Use Cases
4
+ - **Collaborative Office:** During remote meetings, if cross-departmental decisions are involved, you can invite external experts to join the meeting with one click, shortening communication paths.
5
+
6
+ - **Live Teaching:** During the teaching process, if teachers find that some students are absent, they can directly invite them to join the class.
7
+
8
+ - **Internet Medical Consultation:** During case analysis, the primary physician can invite senior doctors to enter the virtual consultation room for multi-party consultation through the call feature, or doctors can call patients in the waiting room for consultations.
9
+
10
+
11
+ ## Prerequisites
12
+
13
+ Before integrating this feature, please ensure the following conditions are met:
14
+ - **Inviter (User A):** The user has completed login authentication through `useLoginState`, refer to [Integration Overview](https://write.woa.com/document/197379797539790848), and is already in a room as the room owner or member, refer to [Room Lifecycle](https://write.woa.com/document/197379861957083136).
15
+
16
+ - **Invitee (User B):** The user has completed login authentication through `useLoginState`, refer to [Integration Overview](https://write.woa.com/document/197379797539790848), to receive signaling events.
17
+
18
+ - **Environment Dependencies:** The project has correctly installed and imported `tuikit-atomicx-vue3`.
19
+
20
+
21
+ ## Implementing In-Room Call Feature
22
+
23
+ The core process for implementing in-room calls is as follows:
24
+
25
+ ![In-room call sequence diagram](https://write-document-release-1258344699.cos.ap-guangzhou.tencentcos.cn/100027160512/82ba8603dee611f0a4f35254007c27c5.png)
26
+
27
+ In-room call sequence diagram
28
+
29
+
30
+ ### Step 1: Initiate Call (Inviter)
31
+
32
+ The inviter calls the [callUserToRoom](https://web.sdk.qcloud.com/trtc/live/web/doc/zh/index.html#callUserToRoom) interface to initiate an invitation. Please ensure the inviter is currently in the room (i.e., [currentRoom](https://web.sdk.qcloud.com/trtc/live/web/doc/zh/index.html#currentRoom) is not empty), otherwise the call cannot be initiated.
33
+ ``` typescript
34
+ import { useRoomState } from 'tuikit-atomicx-vue3/room';
35
+
36
+ const { currentRoom, callUserToRoom } = useRoomState();
37
+
38
+ const inviteUser = async () => {
39
+ // In-room calls must be associated with an existing roomId, so check the current user's room status first
40
+ if (!currentRoom.value) {
41
+ console.warn('Please enter a room first before initiating an invitation');
42
+ return;
43
+ }
44
+
45
+ try {
46
+ const resultMap = await callUserToRoom({
47
+ roomId: currentRoom.value.roomId, // Room ID the invitee will join
48
+ userIdList: ['user1', 'user2'], // Target user ID array, supports single or multiple users
49
+ timeout: 60, // Invitation validity period (seconds), both parties will trigger onCallTimeout after timeout
50
+ // extensionInfo can be used to pass business custom data, such as invitation type, additional messages, etc.
51
+ extensionInfo: JSON.stringify({ type: 'emergency', priority: 'high' })
52
+ });
53
+
54
+ // resultMap returns the status corresponding to each userId, such as Success, AlreadyInRoom (already in room) or AlreadyInCalling (in call)
55
+ console.log('Invitation sent successfully, detailed status map:', resultMap);
56
+ } catch (error) {
57
+ console.error('Failed to send call request, please check network or login status:', error);
58
+ }
59
+ };
60
+ ```
61
+
62
+ ### Step 2: Listen for Call Events (Invitee)
63
+
64
+ The invitee needs to listen for the `onCallReceived` event. It is recommended to implement this in long-lived components such as `App.vue` to ensure the user can respond regardless of which page they are on.
65
+ ``` typescript
66
+ import { ref, onMounted, onUnmounted } from 'vue';
67
+ import { useRoomState, RoomEvent } from 'tuikit-atomicx-vue3/room';
68
+
69
+ const {
70
+ subscribeEvent,
71
+ unsubscribeEvent,
72
+ acceptCall,
73
+ rejectCall,
74
+ joinRoom,
75
+ currentRoom
76
+ } = useRoomState();
77
+
78
+ const showInviteDialog = ref(false); // Control UI dialog visibility
79
+ const currentCallInfo = ref(null); // Cache the received invitation context
80
+
81
+ const handleCallReceived = async ({ roomInfo, call, extensionInfo }) => {
82
+ // Conflict handling: If the user is currently in a meeting, according to business policy, usually should directly reject new invitations to prevent interference
83
+ if (currentRoom.value?.roomId) {
84
+ await rejectCall({ roomId: roomInfo.roomId });
85
+ return;
86
+ }
87
+
88
+ // Record invitation details for displaying inviter name or business transparent data in UI
89
+ currentCallInfo.value = { roomInfo, call };
90
+ showInviteDialog.value = true;
91
+ };
92
+
93
+ // Accept invitation logic
94
+ const onUserAccept = async () => {
95
+ if (!currentCallInfo.value) return;
96
+ const { roomId } = currentCallInfo.value.roomInfo;
97
+
98
+ try {
99
+ // Key process A: Respond to signaling. Inform the inviter that it has been accepted so they can update UI (e.g., display "Other party answered")
100
+ await acceptCall({ roomId });
101
+
102
+ // Key process B: Execute room entry. Only by calling joinRoom will the audio and video push-pull stream link be truly opened
103
+ await joinRoom({ roomId });
104
+ } catch (error) {
105
+ console.error('Room entry operation failed after accepting call:', error);
106
+ } finally {
107
+ closeDialog();
108
+ }
109
+ };
110
+
111
+ // Reject invitation logic
112
+ const onUserReject = async () => {
113
+ if (currentCallInfo.value) {
114
+ // Inform the inviter that it has been rejected, the inviter will receive onCallRejected event
115
+ await rejectCall({ roomId: currentCallInfo.value.roomInfo.roomId });
116
+ }
117
+ closeDialog();
118
+ };
119
+
120
+ const closeDialog = () => {
121
+ showInviteDialog.value = false;
122
+ currentCallInfo.value = null;
123
+ };
124
+
125
+ // Event full lifecycle management: Ensure listening on component mount and removal on destroy to prevent event overflow
126
+ onMounted(() => {
127
+ subscribeEvent(RoomEvent.onCallReceived, handleCallReceived);
128
+
129
+ // Listen for various exceptions/sync events that cause invitation to end, ensuring UI dialog can close in time
130
+ subscribeEvent(RoomEvent.onCallCancelled, closeDialog); // Inviter cancelled the call
131
+ subscribeEvent(RoomEvent.onCallTimeout, closeDialog); // Call timed out without response
132
+ subscribeEvent(RoomEvent.onCallHandledByOtherDevice, closeDialog); // User already handled the call on another device
133
+ });
134
+
135
+ onUnmounted(() => {
136
+ // Remove all listeners to avoid continuing to execute handleCallReceived after component destruction, causing memory leaks or errors
137
+ unsubscribeEvent(RoomEvent.onCallReceived, handleCallReceived);
138
+ unsubscribeEvent(RoomEvent.onCallCancelled, closeDialog);
139
+ unsubscribeEvent(RoomEvent.onCallTimeout, closeDialog);
140
+ unsubscribeEvent(RoomEvent.onCallHandledByOtherDevice, closeDialog);
141
+ });
142
+ ```
143
+
144
+ ## Practical Tutorial: Improving Call Connection Rate
145
+
146
+ To achieve higher call connection rates in business scenarios, in addition to implementing basic functions, it is recommended to refer to the following strategies to optimize user experience:
147
+
148
+ ### 1. Enhanced Call Awareness (Avoid Users Missing Calls)
149
+
150
+ Due to Web characteristics, browser mute or page running in background state may cause users to miss calls.
151
+ - **Visual Reminder**: Use [Page Visibility API](https://developer.mozilla.org/en-US/docs/Web/API/Page_Visibility_API) to detect page visibility status. If the page is in the background, you can implement title bar flashing prompts by cyclically modifying `document.title` (e.g.: "【New Invitation】UserA invites you to the meeting...") to attract user attention.
152
+
153
+ - **Audio Reminder**: Play high-priority alert ringtone when the `onCallReceived` event is triggered. Note: Must comply with browser's [Autoplay Policy](https://developer.mozilla.org/zh-CN/docs/Web/Media/Guides/Autoplay), most browsers will restrict audio autoplay in the absence of user interaction (such as clicks, touches, or key presses).
154
+
155
+
156
+ ### 2. Enrich Invitation Context (Improve Answering Willingness)
157
+
158
+ Invitations lacking clear intent are easily rejected by users. It is recommended to fully utilize the `extensionInfo` field to pass key business information to improve users' willingness to answer.
159
+ - **Pass Business Context**: Use `extensionInfo` to transparently pass business fields such as `reason` (e.g.: "Project emergency review"), `level` (e.g.: "P0 troubleshooting"), etc., to inform users of the urgency and importance of the call.
160
+
161
+
162
+ ### 3. Multi-Channel Reach Backup (Ensure Message Delivery)
163
+
164
+ Limited by Web mechanisms, when the browser process ends, real-time signaling cannot be received. It is recommended to adopt the following alternative solutions to ensure reach:
165
+ - **Browser System Notifications**: Guide users to authorize [Web Notification API](https://developer.mozilla.org/en-US/docs/Web/API/Notification). As long as the browser process is not closed (including minimized or in background tabs), OS-level pop-up notifications can be triggered to effectively remind users.
166
+
167
+ - **Multi-Channel Reach**: It is recommended to combine backend business logic to send meeting links through **SMS**, **Email**, or **Enterprise WeChat** and other external channels when detecting that users are offline or timeout without response, achieving all-around reach.
168
+
169
+
170
+ ### 4. Intelligent Retry Mechanism (Solve "Room Entry Failed After Accepting Invitation")
171
+
172
+ In weak network or other unstable environments, calling `joinRoom` after users click accept invitation may experience occasional failures.
173
+ - **Automatic Retry**: It is recommended to introduce 2-3 automatic retry mechanisms (recommended combined with exponential backoff strategy) in the exception handling logic (`catch`) of `onUserAccept` to maximize ensuring users can successfully join the meeting after clicking "accept".
174
+
175
+
176
+ ## Development Notes
177
+ 1. **Accepting Invitation Does Not Equal Entering Room**
178
+
179
+
180
+ `acceptCall` is only a signaling layer reply (informing the other party that the call has been answered). Users must manually call `await joinRoom({ roomId })` immediately after calling `acceptCall` to truly enter the audio and video room.
181
+
182
+ 2. **Lifecycle Management**
183
+
184
+
185
+ Please be sure to call `unsubscribeEvent` in the component destruction cycle (`onUnmounted`). If listeners are not cleaned up, when users switch pages, listeners from old pages will remain in memory, causing one invitation to pop up multiple windows or logic to execute repeatedly.
186
+
187
+ 3. **Timeout Settings**
188
+
189
+
190
+ If the `timeout` parameter is not set, in some network exceptions or program crash situations, invitations may remain in a suspended state for a long time, making it impossible to initiate another call to that user. It is recommended to set it to 30-60 seconds.
191
+
192
+
193
+ ## Common Questions
194
+ 1. **How to pass custom parameters when calling (e.g., "Emergency meeting from XX")?**
195
+
196
+
197
+ Use the `extensionInfo` parameter of `callUserToRoom` to pass a JSON string. The invitee can parse the string to obtain business information in the `extensionInfo` field of the `onCallReceived` event.
198
+
199
+ 2. **If the invitee is not online, can they receive the invitation after coming online?**
200
+
201
+
202
+ No. The invitation event is an instantaneous signaling action, and the SDK currently does not resend call notifications received while offline.
203
+
204
+ 3. **Can issued invitations be cancelled?**
205
+
206
+
207
+ Yes. Call `cancelCall({ roomId, userIdList })` to cancel. At this time, the invitee will receive the `onCallCancelled` event, and you need to listen to this event to close the UI dialog on the invitee side.
208
+
209
+ 4. **What to do if room entry fails after accepting?**
210
+
211
+
212
+ Check if you have logged in to `TUIRoomEngine`, retry `joinRoom({ roomId })` and capture error prompts to the user; if necessary, provide a "retry" button on the UI.
213
+
214
+ 5. **How to prompt when the other party is busy or already in another room?**
215
+
216
+
217
+ If `AlreadyInRoom` / `AlreadyInCalling` appears in the return value `resultMap` of `callUserToRoom`, you should prompt on the inviter UI "The other party is busy/already in a meeting" and decide whether to retry later.
218
+
219
+ 6. **Dialog not closing after timeout/cancellation?**
220
+
221
+
222
+ Make sure to listen to `onCallTimeout`, `onCallCancelled`, `onCallHandledByOtherDevice`, and uniformly close the dialog and clear current invitation data in the callback.
223
+
224
+ 7. **How to handle simultaneous ringing on multiple devices?**
225
+
226
+
227
+ After accepting/rejecting on any device, other devices will receive `onCallHandledByOtherDevice`, and you need to close dialogs on other ends to avoid repeated processing.
228
+
229
+ 8. **How should extensionInfo be agreed upon?**
230
+
231
+
232
+ It is recommended to use a JSON string and agree on fields (e.g., `type`, `priority`, `from`), parse and display friendly text (e.g., "Emergency meeting from XX") in `handleCallReceived`.
233
+
234
+
235
+ ## **Sample Project**
236
+
237
+ Tencent Cloud provides a sample project [atomicx-vite-vue3-ts](https://github.com/Tencent-RTC/TUIRoomKit/tree/main/Web/example/atomicx-vite-vue3-ts) on GitHub, which you can refer to for implementing complete RoomKit functionality.
238
+
239
+ ## API Documentation
240
+ <table>
241
+ <tr>
242
+ <td rowspan="1" colSpan="1" >**State/Component**</td>
243
+
244
+ <td rowspan="1" colSpan="1" >**Feature Description**</td>
245
+
246
+ <td rowspan="1" colSpan="1" >**API Documentation**</td>
247
+ </tr>
248
+
249
+ <tr>
250
+ <td rowspan="1" colSpan="1" >**useRoomState**</td>
251
+
252
+ <td rowspan="1" colSpan="1" >Room state management (create, join, schedule, etc.)</td>
253
+
254
+ <td rowspan="1" colSpan="1" >[API Documentation](https://web.sdk.qcloud.com/trtc/live/web/doc/zh/index.html#module-RoomState)</td>
255
+ </tr>
256
+ </table>