@tencent-rtc/mcp 1.3.0 → 1.3.2
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 +2 -2
- 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/chatuikit/react/integration.md +430 -49
- package/resource/doc/chatuikit/react/workflow.md +258 -0
- package/resource/doc/chatuikit/vue/integration.md +355 -144
- package/resource/doc/chatuikit/vue/workflow.md +395 -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/chat/get-web-chat-integration.js +31 -14
- package/tools/chat/get-web-chat-integration.js.map +1 -1
- package/tools/definitions/get_web_chat_uikit_integration_def.js +19 -12
- package/tools/definitions/get_web_chat_uikit_integration_def.js.map +1 -1
- 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/index.js +4 -4
- package/tools/index.js.map +1 -1
- package/tools/live/get-web-live-uikit-integration.js +1 -1
- 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/generate-structured-result.js +2 -2
- package/utils/generate-structured-result.js.map +1 -1
- 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/chatuikit/react/chat_window_integration.md +0 -94
- package/resource/doc/chatuikit/vue/chat_window_integration.md +0 -156
- 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/chat/get-web-chat-window-integration.js +0 -28
- package/tools/chat/get-web-chat-window-integration.js.map +0 -1
- package/tools/definitions/get_web_chat_window_integration_def.js +0 -26
- package/tools/definitions/get_web_chat_window_integration_def.js.map +0 -1
- package/tools/room/get-web-room-state-detail.js +0 -31
- package/tools/room/get-web-room-state-detail.js.map +0 -1
|
@@ -1,218 +1,429 @@
|
|
|
1
|
-
|
|
2
|
-
* **Strictly follow the documentation steps for integration:** When integrating components, the steps and instructions in the documentation must be followed. In section 1.1, it is not necessary to execute `npm run dev` or `pnpm run dev`. After integration, start the project as described in section 1.4.
|
|
3
|
-
* **Strictly use the example code in the documentation:** When creating files, the example code in the documentation must be strictly used to populate the files. It is strongly recommended not to use the `scoped` attribute for the `style` tag.
|
|
4
|
-
* **Open Default Conversation:** The `C2Cadministrator` conversation must be opened using `setActiveConversation`.
|
|
5
|
-
* **Retrieve userSig using a tool:** The TUIKit code must be downloaded and integrated according to the documentation before automatically generating a test userID and calling the `get_usersig` tool to retrieve the userSig. The userID does not need to be appended with a timestamp to avoid errors in dynamic calculation.
|
|
6
|
-
* **Account Information Filling:** After obtaining the userSig, the SDKAppID, userID, and userSig will be automatically filled into the code.
|
|
7
|
-
* **Prohibit Creating User Information Configuration Files:** The `config` directory or file for filling in SDKAppID, userID, and userSig must not be automatically created.
|
|
1
|
+
# Vue Chat TUIKit Integration Guide
|
|
8
2
|
|
|
3
|
+
TUIKit is a Vue3 UI component library built on top of Tencent Cloud Chat SDK. It provides common UI components for instant messaging features including conversations, chat, groups, and more. This guide explains how to quickly integrate TUIKit and implement core functionality.
|
|
9
4
|
|
|
5
|
+
> **Note:**
|
|
6
|
+
>
|
|
7
|
+
> Hello! We are developing an instant messaging product called UIKit, based on Tencent Cloud Chat SDK. It is a Vue 3 UI component library that helps you quickly integrate and implement core instant messaging features.
|
|
8
|
+
>
|
|
10
9
|
|
|
11
|
-
|
|
10
|
+
## Key Concepts
|
|
12
11
|
|
|
12
|
+
The `chat-uikit-vue3` library consists of core UI components including ConversationList, Chat, MessageList, ChatHeader, MessageInput, ChatSetting, Search, and Contact. Each component is responsible for displaying different content:
|
|
13
13
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
14
|
+
1. **ConversationList** - Provides the conversation list component.
|
|
15
|
+
2. **Chat** - Provides the container component for conversations.
|
|
16
|
+
3. **MessageList** - Provides the message list component for conversations.
|
|
17
|
+
4. **ChatHeader** - Provides the header information component for conversations.
|
|
18
|
+
5. **MessageInput** - Provides the input box component.
|
|
19
|
+
6. **ChatSetting** - Provides management components for one-on-one and group chats.
|
|
20
|
+
7. **Search** - Provides cloud-based search component.
|
|
21
|
+
8. **Contact** - Provides contacts component.
|
|
17
22
|
|
|
23
|
+
## Prerequisites
|
|
18
24
|
|
|
25
|
+
- Vue.js@^3.0.0
|
|
26
|
+
- TypeScript@^5.0.0
|
|
27
|
+
- Node.js (Node.js ≥ 20.0.0, LTS v22 recommended)
|
|
19
28
|
|
|
29
|
+
## Create Project
|
|
20
30
|
|
|
21
|
-
|
|
31
|
+
Create a new Vue 3 project named **chat-example** using Vite.
|
|
22
32
|
|
|
33
|
+
> **Note:**
|
|
34
|
+
>
|
|
35
|
+
> Higher versions of Vite require the latest Node.js version.
|
|
36
|
+
>
|
|
23
37
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
requirement: vue3: ^3.0.0, nodejs: ^22.0.0.
|
|
31
|
-
|
|
38
|
+
**[shell]**
|
|
39
|
+
```bash
|
|
40
|
+
npm create vite@latest
|
|
41
|
+
```
|
|
32
42
|
|
|
33
|
-
|
|
43
|
+
## Download and Import Components
|
|
34
44
|
|
|
45
|
+
After creating the project, navigate to the project directory.
|
|
35
46
|
|
|
47
|
+
**[shell]**
|
|
36
48
|
```bash
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
cd ${your-vue-project-name}
|
|
40
|
-
pnpm install
|
|
49
|
+
cd chat-example
|
|
50
|
+
npm install
|
|
41
51
|
```
|
|
42
52
|
|
|
53
|
+
### Step 1: Install Dependencies
|
|
43
54
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
55
|
+
**[shell]**
|
|
56
|
+
```bash
|
|
57
|
+
npm i @tencentcloud/chat-uikit-vue3
|
|
58
|
+
```
|
|
48
59
|
|
|
60
|
+
### Step 2: Import Components
|
|
49
61
|
|
|
50
|
-
|
|
62
|
+
#### 2.1 Build the Main Interface
|
|
51
63
|
|
|
64
|
+
For example, add the following code to `src/App.vue`:
|
|
52
65
|
|
|
53
|
-
```
|
|
66
|
+
```typescript
|
|
54
67
|
<template>
|
|
55
|
-
<UIKitProvider language="
|
|
68
|
+
<UIKitProvider language="en-US" theme="light">
|
|
56
69
|
<div class="chat-layout">
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
</button>
|
|
65
|
-
<button
|
|
66
|
-
:class="['tab-button', { active: activeTab === 'contacts' }]"
|
|
67
|
-
@click="activeTab = 'contacts'"
|
|
68
|
-
>
|
|
69
|
-
Contact person
|
|
70
|
-
</button>
|
|
71
|
-
</div>
|
|
72
|
-
|
|
73
|
-
<div class="tab-content">
|
|
74
|
-
<ConversationList v-if="activeTab === 'conversations'" />
|
|
75
|
-
<ContactList v-else />
|
|
76
|
-
</div>
|
|
70
|
+
<!-- Left Navigation -->
|
|
71
|
+
<SideTab :active-tab="activeTab" @tab-change="handleTabChange" />
|
|
72
|
+
|
|
73
|
+
<!-- Middle List Panel -->
|
|
74
|
+
<div class="conversation-list-panel">
|
|
75
|
+
<ConversationList v-show="activeTab === 'conversations'" />
|
|
76
|
+
<ContactList v-show="activeTab === 'contacts'" />
|
|
77
77
|
</div>
|
|
78
78
|
|
|
79
|
-
|
|
80
|
-
|
|
79
|
+
<!-- Right Chat Panel -->
|
|
80
|
+
<Chat
|
|
81
|
+
v-show="activeTab === 'conversations'"
|
|
82
|
+
class="chat-content-panel"
|
|
83
|
+
:PlaceholderEmpty="EmptyChatTpl"
|
|
84
|
+
>
|
|
85
|
+
<ChatHeader>
|
|
86
|
+
<template #ChatHeaderRight>
|
|
87
|
+
<button class="icon-button" @click="isChatSettingShow = !isChatSettingShow">
|
|
88
|
+
<IconMenu size="20" />
|
|
89
|
+
</button>
|
|
90
|
+
</template>
|
|
91
|
+
</ChatHeader>
|
|
81
92
|
<MessageList />
|
|
82
|
-
<MessageInput
|
|
93
|
+
<MessageInput class="message-input-container">
|
|
94
|
+
<template #headerToolbar>
|
|
95
|
+
<div class="message-toolbar">
|
|
96
|
+
<div class="message-toolbar-actions">
|
|
97
|
+
<EmojiPicker />
|
|
98
|
+
<FilePicker />
|
|
99
|
+
<VideoPicker />
|
|
100
|
+
<ImagePicker />
|
|
101
|
+
<!-- Refer to documentation to enable audio/video call services -->
|
|
102
|
+
<!-- <AudioCallPicker />
|
|
103
|
+
<VideoCallPicker /> -->
|
|
104
|
+
</div>
|
|
105
|
+
<button class="icon-button" @click="isSearchInChatShow = !isSearchInChatShow">
|
|
106
|
+
<IconSearch size="20" />
|
|
107
|
+
</button>
|
|
108
|
+
</div>
|
|
109
|
+
</template>
|
|
110
|
+
</MessageInput>
|
|
111
|
+
|
|
112
|
+
<!-- Chat Settings Sidebar -->
|
|
113
|
+
<div v-show="isChatSettingShow" class="chat-sidebar" :class="{ dark: theme === 'dark' }">
|
|
114
|
+
<div class="chat-sidebar-header">
|
|
115
|
+
<span class="chat-sidebar-title">Settings</span>
|
|
116
|
+
<button class="icon-button" @click="isChatSettingShow = false">✕</button>
|
|
117
|
+
</div>
|
|
118
|
+
<ChatSetting />
|
|
119
|
+
</div>
|
|
120
|
+
|
|
121
|
+
<!-- In-Chat Search Sidebar -->
|
|
122
|
+
<div v-show="isSearchInChatShow" class="chat-sidebar" :class="{ dark: theme === 'dark' }">
|
|
123
|
+
<div class="chat-sidebar-header">
|
|
124
|
+
<span class="chat-sidebar-title">Group Search</span>
|
|
125
|
+
<button class="icon-button" @click="isSearchInChatShow = false">✕</button>
|
|
126
|
+
</div>
|
|
127
|
+
<Search :variant="VariantType.EMBEDDED" />
|
|
128
|
+
</div>
|
|
83
129
|
</Chat>
|
|
84
|
-
|
|
130
|
+
|
|
131
|
+
<!-- Contact Details -->
|
|
132
|
+
<ContactInfo
|
|
133
|
+
v-show="activeTab === 'contacts'"
|
|
134
|
+
class="contact-detail-panel"
|
|
135
|
+
@send-message="handleSendMessage"
|
|
136
|
+
/>
|
|
85
137
|
</div>
|
|
86
|
-
<Teleport to="body">
|
|
87
|
-
<TUICallKit style="position: fixed; z-index: 1000;"/>
|
|
88
|
-
</Teleport>
|
|
89
138
|
</UIKitProvider>
|
|
90
139
|
</template>
|
|
91
140
|
|
|
92
|
-
|
|
93
141
|
<script setup lang="ts">
|
|
94
|
-
import { ref } from 'vue';
|
|
142
|
+
import { ref, h, watch } from 'vue';
|
|
95
143
|
import {
|
|
96
|
-
ConversationList,
|
|
97
|
-
Chat,
|
|
98
|
-
MessageList,
|
|
99
|
-
MessageInput,
|
|
100
|
-
ChatHeader,
|
|
101
|
-
ContactList,
|
|
102
|
-
ContactInfo,
|
|
103
|
-
UIKitProvider,
|
|
104
|
-
useLoginState,
|
|
105
|
-
useConversationListState,
|
|
144
|
+
Chat, Search, ChatHeader, MessageList, MessageInput, ContactList, ContactInfo, ChatSetting, UIKitProvider, ConversationList, useUIKit, useLoginState, useConversationListState, EmojiPicker, FilePicker, VideoPicker, ImagePicker, VariantType, AudioCallPicker, VideoCallPicker,
|
|
106
145
|
} from '@tencentcloud/chat-uikit-vue3';
|
|
107
|
-
import {
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
const userID = ''; // TODO: Replace with your userID
|
|
111
|
-
const SDKAppID = 0; // TODO: Replace with your SDKAppID (Notice: SDKAppID is of type number)
|
|
112
|
-
const userSig = ''; // TODO: Replace with your userSig
|
|
113
|
-
|
|
146
|
+
import { IconMenu, IconSearch, TUIToast } from '@tencentcloud/uikit-base-component-vue3';
|
|
147
|
+
import SideTab from './components/SideTab.vue';
|
|
114
148
|
|
|
149
|
+
const { theme } = useUIKit();
|
|
115
150
|
const { login } = useLoginState();
|
|
116
|
-
const { setActiveConversation } = useConversationListState();
|
|
117
|
-
|
|
151
|
+
const { setActiveConversation, activeConversation } = useConversationListState();
|
|
118
152
|
|
|
119
153
|
const activeTab = ref<'conversations' | 'contacts'>('conversations');
|
|
120
|
-
|
|
121
|
-
|
|
154
|
+
const isChatSettingShow = ref(false);
|
|
155
|
+
const isSearchInChatShow = ref(false);
|
|
156
|
+
|
|
157
|
+
// Close in-chat sidebars when switching conversations
|
|
158
|
+
watch(() => activeConversation.value?.conversationID, (newVal, oldVal) => {
|
|
159
|
+
if (newVal !== oldVal) {
|
|
160
|
+
isChatSettingShow.value = false;
|
|
161
|
+
isSearchInChatShow.value = false;
|
|
162
|
+
}
|
|
163
|
+
});
|
|
164
|
+
|
|
165
|
+
// Login
|
|
122
166
|
login({
|
|
123
|
-
sdkAppId
|
|
124
|
-
userId:
|
|
125
|
-
userSig: userSig,
|
|
167
|
+
sdkAppId: 0, // SDKAppID, number type
|
|
168
|
+
userId: '', // UserID, string type
|
|
169
|
+
userSig: '', // userSig, string type
|
|
126
170
|
})
|
|
127
171
|
.then(() => {
|
|
128
|
-
|
|
129
|
-
|
|
172
|
+
const userID = 'administrator';
|
|
173
|
+
const conversationID = `C2C${userID}`;
|
|
174
|
+
setActiveConversation(conversationID);
|
|
130
175
|
})
|
|
131
|
-
.catch(() => {
|
|
176
|
+
.catch((err) => {
|
|
177
|
+
TUIToast.error({
|
|
178
|
+
message: err.message,
|
|
179
|
+
duration: 5000,
|
|
180
|
+
});
|
|
181
|
+
});
|
|
182
|
+
|
|
183
|
+
const handleTabChange = (tab: 'conversations' | 'contacts') => {
|
|
184
|
+
activeTab.value = tab;
|
|
185
|
+
};
|
|
186
|
+
|
|
132
187
|
const handleSendMessage = () => {
|
|
133
188
|
activeTab.value = 'conversations';
|
|
134
|
-
}
|
|
189
|
+
};
|
|
190
|
+
|
|
191
|
+
// Empty conversation placeholder component
|
|
192
|
+
const EmptyChatTpl = h('div', { class: 'empty-placeholder' }, [
|
|
193
|
+
h('div', { class: 'empty-icon' }, '💬'),
|
|
194
|
+
h('div', { class: 'empty-title' }, 'No conversation'),
|
|
195
|
+
h('div', { class: 'empty-subtitle' }, 'Select a conversation to start chatting'),
|
|
196
|
+
]);
|
|
135
197
|
</script>
|
|
136
198
|
|
|
199
|
+
<style scoped>
|
|
200
|
+
.chat-layout{width:calc(100vw - 64px);height:calc(100vh - 64px);max-width:1600px;max-height:900px;display:flex;border-radius:16px;box-shadow:0 20px 60px rgba(0,0,0,0.3),0 0 0 1px rgba(255,255,255,0.1);overflow:hidden;backdrop-filter:blur(10px);}.conversation-list-panel{width:300px;display:flex;flex-direction:column;border-right:1px solid var(--stroke-color-primary);overflow:hidden;}.chat-content-panel{flex:1;}.contact-detail-panel{flex:1;}.icon-button{padding:4px 6px;display:flex;align-items:center;justify-content:center;border:none;background:transparent;border-radius:4px;font-size:20px;color:var(--text-color-primary);cursor:pointer;transition:background-color 0.2s;outline:none;}.icon-button:focus{outline:none;}.icon-button:hover{background-color:var(--button-color-secondary-hover);}.icon-button:active{background-color:var(--button-color-secondary-active);}.message-toolbar{display:flex;justify-content:space-between;align-items:center;}.message-toolbar-actions{display:flex;align-items:center;gap:4px;}.chat-sidebar{position:absolute;right:0;top:0;bottom:0;min-width:300px;max-width:400px;display:flex;flex-direction:column;background-color:var(--bg-color-operate);box-shadow:var(--shadow-color) 0 0 10px;overflow:auto;z-index:1000;}.chat-sidebar.dark{box-shadow:-4px 0 16px rgba(0,0,0,0.4),-1px 0 0 rgba(255,255,255,0.1);}.chat-sidebar-header{position:sticky;top:0;display:flex;align-items:center;justify-content:space-between;padding:12px 16px;background-color:var(--bg-color-operate);border-bottom:1px solid var(--stroke-color-primary);z-index:10;}.chat-sidebar-title{font-size:16px;font-weight:500;color:var(--text-color-primary);}.empty-placeholder{flex:1;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:12px;background-color:var(--bg-color-operate);border-left:1px solid rgba(0,0,0,0.08);color:#adb5bd;}.empty-icon{font-size:64px;opacity:0.3;}.empty-title{font-size:16px;font-weight:600;color:#6c757d;}.empty-subtitle{font-size:14px;color:#868e96;}img[alt="empty"]{display:none;}.message-input-container{border-top:1px solid var(--stroke-color-primary);}.call-kit{position:fixed;top:50%;left:50%;z-index:999;transform:translate(-50%,-50%);max-width:800px;max-height:600px;}
|
|
201
|
+
</style>
|
|
137
202
|
|
|
138
203
|
<style>
|
|
139
|
-
#app{
|
|
204
|
+
#app{background:linear-gradient(135deg,#667eea 0%,#764ba2 100%) !important;width:100vw !important;height:100vh !important;text-align:start !important;max-width:none !important;display:flex !important;align-items:center !important;justify-content:center !important}
|
|
140
205
|
</style>
|
|
141
206
|
```
|
|
142
207
|
|
|
208
|
+
#### 2.2 Add Side Navigation
|
|
143
209
|
|
|
144
|
-
|
|
145
|
-
```bash
|
|
146
|
-
pnpm run dev
|
|
147
|
-
```
|
|
210
|
+
Create a new file `SideTab.vue` in the `src/component` folder and add the following content:
|
|
148
211
|
|
|
212
|
+
```typescript
|
|
213
|
+
<template>
|
|
214
|
+
<div class="side-tab" :class="{ dark: isDark }">
|
|
215
|
+
<!-- User Avatar -->
|
|
216
|
+
<div class="avatar-wrapper">
|
|
217
|
+
<Avatar class="avatar" :src="loginUserInfo?.avatarUrl" />
|
|
218
|
+
<div class="tooltip">
|
|
219
|
+
<div class="tooltip-name">{{ loginUserInfo?.userName || 'Unnamed' }}</div>
|
|
220
|
+
<div class="tooltip-id">ID: {{ loginUserInfo?.userId }}</div>
|
|
221
|
+
</div>
|
|
222
|
+
</div>
|
|
223
|
+
<!-- Tab Switcher -->
|
|
224
|
+
<div class="tabs">
|
|
225
|
+
<div
|
|
226
|
+
class="tab-item"
|
|
227
|
+
:class="{ active: props.activeTab === 'conversations' }"
|
|
228
|
+
@click="handleTabChange('conversations')"
|
|
229
|
+
title="Conversations"
|
|
230
|
+
>
|
|
231
|
+
<IconChatNew size="24" />
|
|
232
|
+
</div>
|
|
233
|
+
<div
|
|
234
|
+
class="tab-item"
|
|
235
|
+
:class="{ active: props.activeTab === 'contacts' }"
|
|
236
|
+
@click="handleTabChange('contacts')"
|
|
237
|
+
title="Contacts"
|
|
238
|
+
>
|
|
239
|
+
<IconContacts size="24" />
|
|
240
|
+
</div>
|
|
241
|
+
</div>
|
|
242
|
+
</div>
|
|
243
|
+
</template>
|
|
149
244
|
|
|
150
|
-
Best Practice 2
|
|
151
245
|
|
|
246
|
+
<script lang="ts" setup>
|
|
247
|
+
import { computed } from 'vue';
|
|
248
|
+
import { useLoginState, useUIKit, Avatar } from '@tencentcloud/chat-uikit-vue3';
|
|
249
|
+
import { IconChatNew, IconContacts } from '@tencentcloud/uikit-base-component-vue3';
|
|
152
250
|
|
|
153
|
-
|
|
154
|
-
|
|
251
|
+
const { theme } = useUIKit();
|
|
252
|
+
const { loginUserInfo } = useLoginState();
|
|
155
253
|
|
|
254
|
+
const isDark = computed(() => theme.value === 'dark' || theme.value === 'serious');
|
|
156
255
|
|
|
157
|
-
|
|
256
|
+
interface Props {
|
|
257
|
+
activeTab?: 'conversations' | 'contacts';
|
|
258
|
+
}
|
|
158
259
|
|
|
260
|
+
const props = withDefaults(defineProps<Props>(), {
|
|
261
|
+
activeTab: 'conversations'
|
|
262
|
+
});
|
|
159
263
|
|
|
160
|
-
|
|
264
|
+
const emit = defineEmits<{
|
|
265
|
+
tabChange: [tab: 'conversations' | 'contacts'];
|
|
266
|
+
}>();
|
|
161
267
|
|
|
268
|
+
const handleTabChange = (tab: 'conversations' | 'contacts') => {
|
|
269
|
+
emit('tabChange', tab);
|
|
270
|
+
};
|
|
271
|
+
</script>
|
|
162
272
|
|
|
163
|
-
|
|
164
|
-
1.
|
|
273
|
+
<style scoped>
|
|
274
|
+
.side-tab{width:72px;height:100vh;background:var(--bg-color-function);display:flex;flex-direction:column;align-items:center;padding:20px 0;transition:background 0.3s;}.avatar-wrapper{position:relative;margin-bottom:24px;cursor:pointer;}.avatar-wrapper:hover:deep(.avatar){transform:scale(1.05);box-shadow:0 4px 12px rgba(0,0,0,0.15);}.tooltip{position:absolute;left:60px;top:50%;transform:translateY(-50%);padding:8px 12px;background:rgba(0,0,0,0.85);color:#fff;border-radius:6px;white-space:nowrap;opacity:0;visibility:hidden;pointer-events:none;transition:all 0.3s;z-index:1000;}.tooltip::before{content:'';position:absolute;left:-6px;top:50%;transform:translateY(-50%);border:6px solid transparent;border-right-color:rgba(0,0,0,0.85);}.avatar-wrapper:hover .tooltip{opacity:1;visibility:visible;}.tooltip-name{font-size:14px;font-weight:500;margin-bottom:4px;}.tooltip-id{font-size:12px;opacity:0.8;}.tabs{display:flex;flex-direction:column;gap:16px;}.tab-item{width:48px;height:48px;display:flex;align-items:center;justify-content:center;border-radius:12px;cursor:pointer;transition:all 0.3s;color:var(--text-color-primary);}.tab-item:hover{background:rgba(0,0,0,0.05);}.tab-item.active{background:var(--button-color-primary-default);color:var(--text-color-button);}.side-tab.dark{background:#1a1a1a;}.side-tab.dark .avatar-wrapper:hover:deep(.avatar){box-shadow:0 4px 12px rgba(255,255,255,0.2);}.side-tab.dark .tooltip{background:rgba(255,255,255,0.95);color:#1a1a1a;}.side-tab.dark .tooltip::before{border-right-color:rgba(255,255,255,0.95);}.side-tab.dark .tab-item:hover{background:rgba(255,255,255,0.1);}.side-tab.dark .tab-item.active{background:#1890ff;color:#fff;}
|
|
275
|
+
</style>
|
|
276
|
+
```
|
|
165
277
|
|
|
278
|
+
### Step 3: Obtain SDKAppID, userID, and userSig
|
|
166
279
|
|
|
167
|
-
|
|
280
|
+
Fill in the login credentials SDKAppID, userID, and userSig in the login function in the `src/App.vue` file from the previous step.
|
|
168
281
|
|
|
282
|
+
```typescript
|
|
283
|
+
// Login
|
|
284
|
+
login({
|
|
285
|
+
sdkAppId: 0, // SDKAppID, number type
|
|
286
|
+
userId: '', // UserID, string type
|
|
287
|
+
userSig: '', // userSig, string type
|
|
288
|
+
});
|
|
289
|
+
```
|
|
169
290
|
|
|
170
|
-
|
|
291
|
+
| Parameter | Type | Description |
|
|
292
|
+
|-----------|------|-------------|
|
|
293
|
+
| SDKAppID | Number | SDKAppID is the unique identifier for Tencent Cloud Chat client applications. You can create a new application in the [Tencent Cloud Chat Console](https://console.trtc.io/) to obtain the SDKAppID.<br>**Note:**<br>SDKAppID is the unique identifier for Tencent Cloud Chat client applications. We recommend that each independent App apply for a new SDKAppID. Messages between different SDKAppIDs are naturally isolated and cannot communicate with each other. |
|
|
294
|
+
| userID | String | The unique identifier for the user, defined by you. It can only contain uppercase and lowercase letters (a-z, A-Z), numbers (0-9), underscores, and hyphens. |
|
|
295
|
+
| userSig | String | The password for users to log in to Tencent Cloud Chat, which is essentially a ciphertext obtained by encrypting UserID and other information.<br>**Note:**<br>Development environment: To quickly run the demo, you can obtain UserSig through the [Tencent Cloud Chat Console](https://console.trtc.io/).<br>Production environment: Integrate the UserSig calculation code into your server and provide a project-facing interface. For the correct UserSig issuance method, please refer to [Generating UserSig on the Server](https://trtc.io/document/34385). |
|
|
171
296
|
|
|
297
|
+
## Run and Test
|
|
172
298
|
|
|
173
|
-
|
|
174
|
-
```vue
|
|
175
|
-
<script setup lang="ts">
|
|
176
|
-
import { TUICallKit } from '@tencentcloud/call-uikit-vue';
|
|
177
|
-
</script>
|
|
178
|
-
```
|
|
299
|
+
Use the following command to run the project:
|
|
179
300
|
|
|
301
|
+
**[shell]**
|
|
302
|
+
```bash
|
|
303
|
+
npm run dev
|
|
304
|
+
```
|
|
180
305
|
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
306
|
+
> **Note:**
|
|
307
|
+
>
|
|
308
|
+
> 1. Please ensure that SDKAppID, userID, and userSig in [Step 3] have been successfully replaced. Failure to replace them will cause the project to behave abnormally.
|
|
309
|
+
> 2. userID and userSig have a one-to-one correspondence.
|
|
310
|
+
> 3. If the project fails to start, please check whether the development environment requirements are met.
|
|
311
|
+
|
|
312
|
+
## Integrate Advanced Features
|
|
313
|
+
|
|
314
|
+
### Audio/Video Calling
|
|
315
|
+
|
|
316
|
+
> **Note:**
|
|
317
|
+
>
|
|
318
|
+
> TUICallKit is an audio/video calling UI component launched by Tencent Cloud. By integrating this component, you only need to write a few lines of code to experience audio/video calling functionality in your chat application.
|
|
319
|
+
>
|
|
320
|
+
|
|
321
|
+
1. Install the `@tencentcloud/call-uikit-vue` dependency.
|
|
322
|
+
|
|
323
|
+
```bash
|
|
324
|
+
npm install @tencentcloud/call-uikit-vue
|
|
325
|
+
```
|
|
326
|
+
|
|
327
|
+
2. Export `TUICallKit` from `@tencentcloud/call-uikit-vue` and mount it to a DOM node.
|
|
328
|
+
|
|
329
|
+
Continue to add the following code in the `src/App.vue` file:
|
|
330
|
+
|
|
331
|
+
```typescript
|
|
332
|
+
// src/App.vue
|
|
333
|
+
<template>
|
|
334
|
+
<UIKitProvider language="en-US" theme="light">
|
|
335
|
+
<!-- Mount audio/video call core component -->
|
|
336
|
+
<TUICallKit class="call-kit" />
|
|
337
|
+
...
|
|
338
|
+
</UIKitProvider>
|
|
339
|
+
<template>
|
|
340
|
+
|
|
341
|
+
<script setup lang="ts">
|
|
342
|
+
// Import audio/video call core component
|
|
343
|
+
import { TUICallKit } from '@tencentcloud/call-uikit-vue';
|
|
344
|
+
</script>
|
|
345
|
+
```
|
|
346
|
+
|
|
347
|
+
3. Uncomment the code in the `#headerToolbar` slot of the `<MessageInput />` component.
|
|
348
|
+
|
|
349
|
+
```typescript
|
|
350
|
+
<MessageInput class="message-input-container">
|
|
351
|
+
<template #headerToolbar>
|
|
352
|
+
<div class="message-toolbar">
|
|
353
|
+
<div class="message-toolbar-actions">
|
|
354
|
+
<EmojiPicker />
|
|
355
|
+
<FilePicker />
|
|
356
|
+
<VideoPicker />
|
|
357
|
+
<ImagePicker />
|
|
358
|
+
<AudioCallPicker />
|
|
359
|
+
<VideoCallPicker />
|
|
360
|
+
</div>
|
|
361
|
+
<button class="icon-button" @click="isSearchInChatShow = !isSearchInChatShow">
|
|
362
|
+
<IconSearch size="20" />
|
|
363
|
+
</button>
|
|
364
|
+
</div>
|
|
365
|
+
</template>
|
|
366
|
+
</MessageInput>
|
|
367
|
+
```
|
|
368
|
+
|
|
369
|
+
### Cloud Search
|
|
370
|
+
|
|
371
|
+
> **Note:**
|
|
372
|
+
>
|
|
373
|
+
> Search is an essential feature in customer service, social, online education, online medical, OA and other scenarios. It helps users quickly find groups, users, and messages, improving product user experience and user stickiness.
|
|
374
|
+
>
|
|
375
|
+
> Due to the special nature of local storage on the Web platform, Vue **cannot implement local search**. To better meet the demand for search capabilities, a **cloud search capability** has been launched. **Cloud search functionality supports global search and in-conversation search, and supports searching for groups, users, and messages.**
|
|
376
|
+
>
|
|
377
|
+
> This feature is a value-added service that requires you to purchase the cloud search plugin.
|
|
378
|
+
>
|
|
379
|
+
|
|
380
|
+
Cloud search is integrated by default in "Step 2". If you need to disable the cloud search functionality, please refer to the following code:
|
|
381
|
+
|
|
382
|
+
1. Set the `enableSearch` property of `ConversationList` to `false`
|
|
383
|
+
|
|
384
|
+
```typescript
|
|
385
|
+
<template>
|
|
386
|
+
<ConversationList v-show="activeTab === 'conversations'" :enable-search="false" />
|
|
387
|
+
</template>
|
|
388
|
+
```
|
|
389
|
+
|
|
390
|
+
2. Comment out the code related to the in-conversation search sidebar
|
|
391
|
+
|
|
392
|
+
```typescript
|
|
393
|
+
<template>
|
|
394
|
+
<Chat>
|
|
395
|
+
<!-- <div v-show="isSearchInChatShow" class="chat-sidebar" :class="{ dark: theme === 'dark' }">
|
|
396
|
+
<div class="chat-sidebar-header">
|
|
397
|
+
<span class="chat-sidebar-title">Search</span>
|
|
398
|
+
<button class="icon-button" @click="isSearchInChatShow = false">✕</button>
|
|
399
|
+
</div>
|
|
400
|
+
<Search :variant="VariantType.EMBEDDED" />
|
|
401
|
+
</div> -->
|
|
402
|
+
</Chat>
|
|
403
|
+
</template>
|
|
404
|
+
```
|
|
405
|
+
|
|
406
|
+
## FAQ
|
|
407
|
+
|
|
408
|
+
### Can I use third-party component libraries, such as Element-Plus?
|
|
409
|
+
|
|
410
|
+
You can use other component libraries for the glue code between core components, as shown in the example code. For example, you can wrap `<ChatSetting />` as a full-screen drawer component. However, components that already exist within core components are not currently supported for modification.
|
|
411
|
+
|
|
412
|
+
```typescript
|
|
413
|
+
const isChatSettingShow = ref(false);
|
|
414
|
+
|
|
415
|
+
<el-drawer
|
|
416
|
+
v-model="isChatSettingShow"
|
|
417
|
+
title="Settings"
|
|
418
|
+
>
|
|
419
|
+
<ChatSetting />
|
|
420
|
+
</el-drawer>
|
|
186
421
|
```
|
|
187
422
|
|
|
423
|
+
### NPM Package
|
|
424
|
+
|
|
425
|
+
[chat-uikit-vue3 npm](https://www.npmjs.com/package/@tencentcloud/chat-uikit-vue3)
|
|
426
|
+
|
|
427
|
+
### GitHub
|
|
188
428
|
|
|
189
|
-
|
|
190
|
-
1. Add a call button to the ChatHeaderRight slot in the ChatHeader component.
|
|
191
|
-
2. Click the call button to call the following method:
|
|
192
|
-
2.1 Read the ConversationListState document and use activeConversation to judge whether it is a private chat or group chat.
|
|
193
|
-
2.2 If it is a one-to-one chat, use `import { TUICallKitServer, TUICallType } from '@tencentcloud/call-uikit-vue';` to introduce the TUICallKitService service. Initiate call using the `calls` method of TUICallKitService.
|
|
194
|
-
```ts
|
|
195
|
-
try {
|
|
196
|
-
await TUICallKitServer.calls({
|
|
197
|
-
userIDList: [activeConversation.value.userProfile.userID],
|
|
198
|
-
type: TUICallType.VIDEO_CALL, // or TUICallType.AUDIO_CALL
|
|
199
|
-
});
|
|
200
|
-
} catch (error: any) {
|
|
201
|
-
console.error(`[TUICallKit] Failed to call the groupCall API. Reason:${error}`);
|
|
202
|
-
}
|
|
203
|
-
```
|
|
204
|
-
2.3 If it is a group chat, read the UserPicker component document. It is advisable to combine it with the Dialog component to pop up the UserPicker component.
|
|
205
|
-
Read the GroupSettingState document, combine the `getGroupMemberList` and `allMembers` attributes of GroupSettingState to get the group member list.
|
|
206
|
-
```ts
|
|
207
|
-
try {
|
|
208
|
-
await TUICallKitServer.calls({
|
|
209
|
-
userIDList: selectedItems.map((item: any) => item.key),
|
|
210
|
-
type: TUICallType.VIDEO_CALL, // or TUICallType.AUDIO_CALL
|
|
211
|
-
});
|
|
212
|
-
} catch (error: any) {
|
|
213
|
-
console.error(`[TUICallKit] Failed to call the groupCall API. Reason:${error}`);
|
|
214
|
-
}
|
|
215
|
-
```
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
Recommendation: Combine the `reachEnd` event of UserPicker with paged pull for group members, and use traffic throttling to control the call frequency of `getGroupMemberList`.
|
|
429
|
+
[GitHub Demo](https://github.com/Tencent-RTC/TUIKit_Vue3/tree/main/demos/rtcube-vite-vue3)
|