@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.
- package/index.js +4 -0
- package/index.js.map +1 -1
- package/package.json +1 -1
- package/resource/doc/chatuikit/faq/web_sdk/faq.md +125 -0
- package/resource/doc/chatuikit/flutter/faq.md +17 -114
- package/resource/doc/chatuikit/flutter/integrate_tuikit_Flutter.md +86 -722
- package/resource/doc/livekit/live/android/live-audience-list.md +334 -0
- package/resource/doc/livekit/live/android/live-audio-effect.md +380 -0
- package/resource/doc/livekit/live/android/live-barrage.md +565 -0
- package/resource/doc/livekit/live/android/live-base-beauty.md +275 -0
- package/resource/doc/livekit/live/android/live-co-guest-interaction.md +629 -0
- package/resource/doc/livekit/live/android/live-gift.md +822 -0
- package/resource/doc/livekit/live/android/live-host-interaction.md +888 -0
- package/resource/doc/livekit/live/android/live-integration.md +972 -0
- package/resource/doc/livekit/live/android/live-live-list.md +575 -0
- package/resource/doc/livekit/live/android/workflow.md +189 -0
- package/resource/doc/roomkit/vue/features/call-user-to-room.md +256 -0
- package/resource/doc/roomkit/vue/features/device-detection.md +388 -0
- package/resource/doc/roomkit/vue/features/device-state.md +480 -0
- package/resource/doc/roomkit/vue/features/free-beauty-panel.md +238 -0
- package/resource/doc/roomkit/vue/features/room-chat.md +427 -0
- package/resource/doc/roomkit/vue/features/room-participant-state.md +407 -0
- package/resource/doc/roomkit/vue/features/room-state.md +291 -0
- package/resource/doc/roomkit/vue/features/room-view.md +338 -0
- package/resource/doc/roomkit/vue/features/schedule-room.md +349 -0
- package/resource/doc/roomkit/vue/features/screen-share.md +333 -0
- package/resource/doc/roomkit/vue/features/virtual-background.md +287 -0
- package/resource/doc/roomkit/vue/features/workflow.md +553 -0
- package/resource/doc/roomkit/vue/integration.md +479 -0
- package/resource/doc/roomkit/vue/workflow.md +487 -0
- package/resource/doc/tuicallkit/react/api.md +21 -0
- package/resource/doc/tuicallkit/vue/api.md +21 -0
- package/tools/common/record-prompt.js +2 -2
- package/tools/common/record-prompt.js.map +1 -1
- package/tools/definitions/get_native_live_extra_features_def.js +87 -0
- package/tools/definitions/get_native_live_extra_features_def.js.map +1 -0
- package/tools/definitions/get_native_live_interaction_def.js +74 -0
- package/tools/definitions/get_native_live_interaction_def.js.map +1 -0
- package/tools/definitions/get_native_live_uikit_integration_def.js +49 -0
- package/tools/definitions/get_native_live_uikit_integration_def.js.map +1 -0
- package/tools/definitions/get_web_room_feature_detail_def.js +95 -0
- package/tools/definitions/get_web_room_feature_detail_def.js.map +1 -0
- package/tools/definitions/get_web_room_uikit_integration_def.js +44 -0
- package/tools/definitions/get_web_room_uikit_integration_def.js.map +1 -0
- package/tools/definitions/record_prompt_def.js +1 -1
- package/tools/definitions/record_prompt_def.js.map +1 -1
- package/tools/index.js +10 -2
- package/tools/index.js.map +1 -1
- package/tools/live/get-native-live-uikit-integration.js +101 -0
- package/tools/live/get-native-live-uikit-integration.js.map +1 -0
- package/tools/live/get-web-live-component-detail.js +1 -1
- package/tools/live/get-web-live-component-detail.js.map +1 -1
- package/tools/live/get-web-live-state-detail.js +1 -1
- package/tools/live/get-web-live-state-detail.js.map +1 -1
- package/tools/live/get-web-live-uikit-integration.js +6 -6
- package/tools/live/get-web-live-uikit-integration.js.map +1 -1
- package/tools/live/get_native_live_extra_features.js +105 -0
- package/tools/live/get_native_live_extra_features.js.map +1 -0
- package/tools/live/get_native_live_interaction.js +101 -0
- package/tools/live/get_native_live_interaction.js.map +1 -0
- package/tools/room/get-web-room-feature-detail.js +68 -0
- package/tools/room/get-web-room-feature-detail.js.map +1 -0
- package/tools/room/get-web-room-integration.js +43 -0
- package/tools/room/get-web-room-integration.js.map +1 -0
- package/utils/report-cls-client.js +1 -1
- package/utils/report-es-client.js +1 -1
- package/resource/doc/chatuikit/flutter/integrate_only_tuichat_Flutter.md +0 -333
- package/resource/doc/chatuikit/flutter/quick_start_Flutter.md +0 -217
- package/resource/doc/roomkit/vue/states/device-state.md +0 -369
- package/resource/doc/roomkit/vue/states/login-state.md +0 -59
- package/resource/doc/roomkit/vue/states/room-list-state.md +0 -355
- package/resource/doc/roomkit/vue/states/room-participant-state.md +0 -388
- package/tools/room/get-web-room-state-detail.js +0 -31
- package/tools/room/get-web-room-state-detail.js.map +0 -1
- /package/resource/doc/livekit/{vue → live/vue}/components/barrage.md +0 -0
- /package/resource/doc/livekit/{vue → live/vue}/components/co-guest-panel.md +0 -0
- /package/resource/doc/livekit/{vue → live/vue}/components/live-audience-list.md +0 -0
- /package/resource/doc/livekit/{vue → live/vue}/components/live-scene-panel.md +0 -0
- /package/resource/doc/livekit/{vue → live/vue}/components/live-view.md +0 -0
- /package/resource/doc/livekit/{vue → live/vue}/components/stream-mixer.md +0 -0
- /package/resource/doc/livekit/{vue → live/vue}/faq.md +0 -0
- /package/resource/doc/livekit/{vue → live/vue}/live-list-integration.md +0 -0
- /package/resource/doc/livekit/{vue → live/vue}/live-player-desk-integration.md +0 -0
- /package/resource/doc/livekit/{vue → live/vue}/live-player-h5-integration.md +0 -0
- /package/resource/doc/livekit/{vue → live/vue}/live-pusher-integration.md +0 -0
- /package/resource/doc/livekit/{vue → live/vue}/states/live-state.md +0 -0
- /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
|
+

|
|
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>
|