@tencentcloud/chat-uikit-react 1.0.0 → 1.0.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/CHANGELOG.md +22 -0
- package/README.md +34 -84
- package/dist/cjs/components/ConversationPreview/utils.js +1 -1
- package/dist/cjs/components/Icon/images/union.png.js +1 -1
- package/dist/cjs/components/Icon/images/ununion.png.js +1 -1
- package/dist/cjs/components/TUIChat/hooks/useMessageReceviedListener.js +1 -1
- package/dist/cjs/components/TUIChatHeader/TUIChatHeaderDefault.js +1 -1
- package/dist/cjs/components/TUIConversation/TUIConversation.d.ts +2 -0
- package/dist/cjs/components/TUIConversation/TUIConversation.js +1 -1
- package/dist/cjs/components/TUIConversationList/TUIConversationList.d.ts +1 -0
- package/dist/cjs/components/TUIConversationList/TUIConversationList.js +1 -1
- package/dist/cjs/components/TUIConversationList/hooks/useConversationList.js +1 -1
- package/dist/cjs/components/TUIConversationList/hooks/useConversationUpdate.js +1 -1
- package/dist/cjs/components/TUIMessage/MessageCustom.js +1 -1
- package/dist/cjs/components/TUIMessageInput/InputQuoteDefalut.js +1 -1
- package/dist/cjs/components/TUIMessageInput/TUIMessageInput.js +1 -1
- package/dist/cjs/components/TUIMessageInput/TUIMessageInputDefault.js +1 -1
- package/dist/cjs/components/TUIMessageInput/hooks/useHandleQuoteMessage.js +1 -1
- package/dist/cjs/components/TUIMessageList/TUIMessageList.js +1 -1
- package/dist/cjs/components/TUIMessageList/hooks/useMessageListElement.js +1 -1
- package/dist/cjs/components/untils.js +1 -1
- package/dist/cjs/index.css +1 -1
- package/dist/cjs/index.d.css +10 -216
- package/dist/esm/components/ConversationPreview/utils.js +1 -1
- package/dist/esm/components/Icon/images/union.png.js +1 -1
- package/dist/esm/components/Icon/images/ununion.png.js +1 -1
- package/dist/esm/components/TUIChat/hooks/useMessageReceviedListener.js +1 -1
- package/dist/esm/components/TUIChatHeader/TUIChatHeaderDefault.js +1 -1
- package/dist/esm/components/TUIConversation/TUIConversation.d.ts +2 -0
- package/dist/esm/components/TUIConversation/TUIConversation.js +1 -1
- package/dist/esm/components/TUIConversationList/TUIConversationList.d.ts +1 -0
- package/dist/esm/components/TUIConversationList/TUIConversationList.js +1 -1
- package/dist/esm/components/TUIConversationList/hooks/useConversationList.js +1 -1
- package/dist/esm/components/TUIConversationList/hooks/useConversationUpdate.js +1 -1
- package/dist/esm/components/TUIMessage/MessageCustom.js +1 -1
- package/dist/esm/components/TUIMessageInput/InputQuoteDefalut.js +1 -1
- package/dist/esm/components/TUIMessageInput/TUIMessageInput.js +1 -1
- package/dist/esm/components/TUIMessageInput/TUIMessageInputDefault.js +1 -1
- package/dist/esm/components/TUIMessageInput/hooks/useHandleQuoteMessage.js +1 -1
- package/dist/esm/components/TUIMessageList/TUIMessageList.js +1 -1
- package/dist/esm/components/TUIMessageList/hooks/useMessageListElement.js +1 -1
- package/dist/esm/components/untils.js +1 -1
- package/dist/esm/index.css +1 -1
- package/dist/esm/index.d.css +10 -216
- package/package.json +2 -2
- package/readme.zh_cn.md +60 -0
- package/src/components/ConversationPreview/utils.tsx +2 -1
- package/src/components/Icon/images/union.png +0 -0
- package/src/components/Icon/images/ununion.png +0 -0
- package/src/components/TUIChat/hooks/useMessageReceviedListener.tsx +2 -2
- package/src/components/TUIChatHeader/TUIChatHeaderDefault.tsx +2 -3
- package/src/components/TUIConversation/TUIConversation.tsx +5 -0
- package/src/components/TUIConversationList/TUIConversationList.tsx +14 -2
- package/src/components/TUIConversationList/hooks/useConversationList.tsx +9 -3
- package/src/components/TUIConversationList/hooks/useConversationUpdate.tsx +8 -3
- package/src/components/TUIKit/hooks/useTUIKit.tsx +7 -1
- package/src/components/TUIMessage/MessageCustom.tsx +13 -1
- package/src/components/TUIMessage/styles/layout.scss +11 -3
- package/src/components/TUIMessage/utils/index.ts +3 -0
- package/src/components/TUIMessageInput/InputPluginsDefalut.tsx +0 -25
- package/src/components/TUIMessageInput/InputQuoteDefalut.tsx +3 -3
- package/src/components/TUIMessageInput/TUIMessageInput.tsx +7 -2
- package/src/components/TUIMessageInput/TUIMessageInputDefault.tsx +1 -1
- package/src/components/TUIMessageInput/hooks/useHandleQuoteMessage.tsx +1 -0
- package/src/components/TUIMessageList/TUIMessageList.tsx +1 -1
- package/src/components/TUIMessageList/hooks/useMessageListElement.tsx +1 -1
- package/src/components/index.ts +1 -0
- package/src/components/untils.ts +10 -12
- package/src/context/TUIConversationContext.tsx +2 -0
- package/src/context/TUIKitContext.tsx +5 -1
- package/dist/cjs/_virtual/_rollupPluginBabelHelpers.js +0 -1
- package/dist/cjs/components/TUILive/TUILive.d.ts +0 -29
- package/dist/cjs/components/TUILive/TUILive.js +0 -1
- package/dist/cjs/components/TUILive/TUILiveContent.d.ts +0 -13
- package/dist/cjs/components/TUILive/TUILiveContent.js +0 -1
- package/dist/cjs/components/TUILive/TUILiveFooter.d.ts +0 -29
- package/dist/cjs/components/TUILive/TUILiveFooter.js +0 -1
- package/dist/cjs/components/TUILive/TUILiveHeader.d.ts +0 -20
- package/dist/cjs/components/TUILive/TUILiveHeader.js +0 -1
- package/dist/cjs/components/TUILive/TUILiveMemberList.d.ts +0 -11
- package/dist/cjs/components/TUILive/TUILiveMemberList.js +0 -1
- package/dist/cjs/components/TUILive/hooks/useLiveAtiveElements.js +0 -1
- package/dist/cjs/components/TUILive/hooks/useLivePlayer.js +0 -1
- package/dist/cjs/components/TUILive/hooks/useLiveState.js +0 -1
- package/dist/cjs/components/TUILive/untils.js +0 -1
- package/dist/cjs/context/TUILiveContext.d.ts +0 -51
- package/dist/cjs/context/TUILiveContext.js +0 -1
- package/dist/esm/_virtual/_rollupPluginBabelHelpers.js +0 -1
- package/dist/esm/components/TUILive/TUILive.d.ts +0 -29
- package/dist/esm/components/TUILive/TUILive.js +0 -1
- package/dist/esm/components/TUILive/TUILiveContent.d.ts +0 -13
- package/dist/esm/components/TUILive/TUILiveContent.js +0 -1
- package/dist/esm/components/TUILive/TUILiveFooter.d.ts +0 -29
- package/dist/esm/components/TUILive/TUILiveFooter.js +0 -1
- package/dist/esm/components/TUILive/TUILiveHeader.d.ts +0 -20
- package/dist/esm/components/TUILive/TUILiveHeader.js +0 -1
- package/dist/esm/components/TUILive/TUILiveMemberList.d.ts +0 -11
- package/dist/esm/components/TUILive/TUILiveMemberList.js +0 -1
- package/dist/esm/components/TUILive/hooks/useLiveAtiveElements.js +0 -1
- package/dist/esm/components/TUILive/hooks/useLivePlayer.js +0 -1
- package/dist/esm/components/TUILive/hooks/useLiveState.js +0 -1
- package/dist/esm/components/TUILive/untils.js +0 -1
- package/dist/esm/context/TUILiveContext.d.ts +0 -51
- package/dist/esm/context/TUILiveContext.js +0 -1
package/dist/esm/index.d.css
CHANGED
|
@@ -1,217 +1,3 @@
|
|
|
1
|
-
.tui-live {
|
|
2
|
-
display: flex;
|
|
3
|
-
flex-direction: column;
|
|
4
|
-
justify-content: space-between;
|
|
5
|
-
}
|
|
6
|
-
.tui-live video {
|
|
7
|
-
width: 100%;
|
|
8
|
-
}
|
|
9
|
-
.tui-live-list {
|
|
10
|
-
display: flex;
|
|
11
|
-
}
|
|
12
|
-
.tui-live-item {
|
|
13
|
-
display: flex;
|
|
14
|
-
margin: 0 10px;
|
|
15
|
-
gap: 10px;
|
|
16
|
-
}
|
|
17
|
-
.tui-live-item .list-item-text {
|
|
18
|
-
display: inline-flex;
|
|
19
|
-
min-width: 22px;
|
|
20
|
-
font-family: "Roboto";
|
|
21
|
-
font-style: normal;
|
|
22
|
-
font-weight: 400;
|
|
23
|
-
font-size: 12px;
|
|
24
|
-
line-height: 14px;
|
|
25
|
-
display: flex;
|
|
26
|
-
align-items: center;
|
|
27
|
-
color: #000000;
|
|
28
|
-
}
|
|
29
|
-
.tui-live .tag-list {
|
|
30
|
-
flex: 1;
|
|
31
|
-
flex-wrap: wrap;
|
|
32
|
-
}
|
|
33
|
-
.tui-live .tag-item {
|
|
34
|
-
position: relative;
|
|
35
|
-
padding: 4px 8px 4px 26px;
|
|
36
|
-
background: #7187D3;
|
|
37
|
-
border-radius: 47px;
|
|
38
|
-
font-family: "Roboto";
|
|
39
|
-
font-style: normal;
|
|
40
|
-
font-weight: 400;
|
|
41
|
-
font-size: 12px;
|
|
42
|
-
line-height: 14px;
|
|
43
|
-
display: flex;
|
|
44
|
-
align-items: center;
|
|
45
|
-
color: #FFFFFF;
|
|
46
|
-
}
|
|
47
|
-
.tui-live .tag-item::before {
|
|
48
|
-
position: absolute;
|
|
49
|
-
content: "#";
|
|
50
|
-
color: #FFFFFF;
|
|
51
|
-
left: 11px;
|
|
52
|
-
display: flex;
|
|
53
|
-
align-items: center;
|
|
54
|
-
}
|
|
55
|
-
.tui-live-header {
|
|
56
|
-
padding: 12px 20px;
|
|
57
|
-
display: flex;
|
|
58
|
-
flex-direction: column;
|
|
59
|
-
}
|
|
60
|
-
.tui-live-header-name {
|
|
61
|
-
padding: 8px 0;
|
|
62
|
-
display: flex;
|
|
63
|
-
align-items: center;
|
|
64
|
-
justify-content: space-between;
|
|
65
|
-
}
|
|
66
|
-
.tui-live-header-name h1 {
|
|
67
|
-
font-family: "Roboto";
|
|
68
|
-
font-style: normal;
|
|
69
|
-
font-weight: 700;
|
|
70
|
-
font-size: 16px;
|
|
71
|
-
line-height: 19px;
|
|
72
|
-
color: #000000;
|
|
73
|
-
}
|
|
74
|
-
.tui-live-header-content {
|
|
75
|
-
display: flex;
|
|
76
|
-
align-items: flex-start;
|
|
77
|
-
}
|
|
78
|
-
.tui-live-header-label {
|
|
79
|
-
display: flex;
|
|
80
|
-
align-items: center;
|
|
81
|
-
gap: 4px;
|
|
82
|
-
padding: 4px 8px;
|
|
83
|
-
background: #FF0000;
|
|
84
|
-
border-radius: 47px;
|
|
85
|
-
font-family: "Roboto";
|
|
86
|
-
font-style: normal;
|
|
87
|
-
font-weight: 400;
|
|
88
|
-
font-size: 12px;
|
|
89
|
-
line-height: 14px;
|
|
90
|
-
display: flex;
|
|
91
|
-
align-items: center;
|
|
92
|
-
color: #FFFFFF;
|
|
93
|
-
}
|
|
94
|
-
.tui-live-content {
|
|
95
|
-
width: 100%;
|
|
96
|
-
height: 100%;
|
|
97
|
-
}
|
|
98
|
-
.tui-live-footer {
|
|
99
|
-
padding: 20px 20px 30px;
|
|
100
|
-
display: flex;
|
|
101
|
-
align-items: center;
|
|
102
|
-
}
|
|
103
|
-
.tui-live-footer .owner-avatar {
|
|
104
|
-
display: inline-block;
|
|
105
|
-
width: 40px;
|
|
106
|
-
height: 40px;
|
|
107
|
-
border-radius: 40px;
|
|
108
|
-
}
|
|
109
|
-
.tui-live-footer-main {
|
|
110
|
-
flex: 1;
|
|
111
|
-
display: flex;
|
|
112
|
-
flex-direction: column;
|
|
113
|
-
}
|
|
114
|
-
.tui-live-footer-main .owner-name {
|
|
115
|
-
display: flex;
|
|
116
|
-
align-items: center;
|
|
117
|
-
gap: 7px;
|
|
118
|
-
padding: 0 10px 8px;
|
|
119
|
-
}
|
|
120
|
-
.tui-live-footer-main .owner-name h1 {
|
|
121
|
-
font-family: "Roboto";
|
|
122
|
-
font-style: normal;
|
|
123
|
-
font-weight: 700;
|
|
124
|
-
font-size: 16px;
|
|
125
|
-
line-height: 19px;
|
|
126
|
-
display: flex;
|
|
127
|
-
align-items: center;
|
|
128
|
-
color: #000000;
|
|
129
|
-
}
|
|
130
|
-
.tui-live-footer .opate-list {
|
|
131
|
-
height: 100%;
|
|
132
|
-
display: flex;
|
|
133
|
-
align-items: flex-end;
|
|
134
|
-
}
|
|
135
|
-
.tui-live-footer .opate-item {
|
|
136
|
-
display: flex;
|
|
137
|
-
align-items: center;
|
|
138
|
-
padding: 4px 8px;
|
|
139
|
-
gap: 10px;
|
|
140
|
-
background: rgba(249, 249, 249, 0.94);
|
|
141
|
-
border-radius: 40px;
|
|
142
|
-
}
|
|
143
|
-
.tui-live-footer .opate-item .opate-box {
|
|
144
|
-
display: flex;
|
|
145
|
-
align-items: center;
|
|
146
|
-
gap: 10px;
|
|
147
|
-
cursor: pointer;
|
|
148
|
-
}
|
|
149
|
-
.tui-live-footer .opate-item-suffix {
|
|
150
|
-
padding-left: 10px;
|
|
151
|
-
}
|
|
152
|
-
.tui-live-footer .tag-item {
|
|
153
|
-
background: rgba(20, 122, 255, 0.5);
|
|
154
|
-
padding: 4px 8px;
|
|
155
|
-
}
|
|
156
|
-
.tui-live-footer .tag-item::before {
|
|
157
|
-
content: "";
|
|
158
|
-
}
|
|
159
|
-
.tui-live-members {
|
|
160
|
-
display: flex;
|
|
161
|
-
flex-direction: column;
|
|
162
|
-
width: 100%;
|
|
163
|
-
height: 100%;
|
|
164
|
-
overflow: auto;
|
|
165
|
-
}
|
|
166
|
-
.tui-live-members .list-header {
|
|
167
|
-
display: flex;
|
|
168
|
-
align-items: center;
|
|
169
|
-
gap: 8px;
|
|
170
|
-
padding: 8px 10px;
|
|
171
|
-
background: rgba(0, 0, 0, 0.05);
|
|
172
|
-
cursor: pointer;
|
|
173
|
-
}
|
|
174
|
-
.tui-live-members .list-header h1 {
|
|
175
|
-
flex: 1;
|
|
176
|
-
font-family: "Roboto";
|
|
177
|
-
font-style: normal;
|
|
178
|
-
font-weight: 700;
|
|
179
|
-
font-size: 12px;
|
|
180
|
-
line-height: 14px;
|
|
181
|
-
color: #000000;
|
|
182
|
-
display: flex;
|
|
183
|
-
align-items: center;
|
|
184
|
-
gap: 8px;
|
|
185
|
-
}
|
|
186
|
-
.tui-live-members .list-item {
|
|
187
|
-
display: flex;
|
|
188
|
-
align-items: center;
|
|
189
|
-
padding: 8px 10px;
|
|
190
|
-
gap: 4px;
|
|
191
|
-
}
|
|
192
|
-
.tui-live-members .list-item .nick {
|
|
193
|
-
font-family: "Roboto";
|
|
194
|
-
font-style: normal;
|
|
195
|
-
font-weight: 400;
|
|
196
|
-
font-size: 12px;
|
|
197
|
-
line-height: 14px;
|
|
198
|
-
color: #000000;
|
|
199
|
-
}
|
|
200
|
-
|
|
201
|
-
.line {
|
|
202
|
-
position: relative;
|
|
203
|
-
}
|
|
204
|
-
.line::before {
|
|
205
|
-
content: "";
|
|
206
|
-
position: absolute;
|
|
207
|
-
left: 0;
|
|
208
|
-
height: 90%;
|
|
209
|
-
width: 1px;
|
|
210
|
-
background: #EEEEEE;
|
|
211
|
-
top: 0;
|
|
212
|
-
bottom: 0;
|
|
213
|
-
margin: auto 0;
|
|
214
|
-
}
|
|
215
1
|
html, body, div, span, applet, object, iframe,
|
|
216
2
|
h1, h2, h3, h4, h5, h6, p, blockquote, pre,
|
|
217
3
|
a, abbr, acronym, address, big, cite, code,
|
|
@@ -332,7 +118,6 @@ table {
|
|
|
332
118
|
width: 45px;
|
|
333
119
|
}
|
|
334
120
|
.message-default .content {
|
|
335
|
-
padding: 0 10px;
|
|
336
121
|
display: flex;
|
|
337
122
|
flex-direction: column;
|
|
338
123
|
align-items: flex-start;
|
|
@@ -347,6 +132,7 @@ table {
|
|
|
347
132
|
display: flex;
|
|
348
133
|
flex-direction: row;
|
|
349
134
|
justify-self: flex-start;
|
|
135
|
+
gap: 10px;
|
|
350
136
|
}
|
|
351
137
|
.in .content {
|
|
352
138
|
align-items: flex-start;
|
|
@@ -356,6 +142,7 @@ table {
|
|
|
356
142
|
.out {
|
|
357
143
|
flex: 1;
|
|
358
144
|
display: flex;
|
|
145
|
+
gap: 10px;
|
|
359
146
|
flex-direction: row-reverse;
|
|
360
147
|
justify-self: flex-end;
|
|
361
148
|
}
|
|
@@ -592,7 +379,7 @@ table {
|
|
|
592
379
|
.meesage-bubble-context {
|
|
593
380
|
display: flex;
|
|
594
381
|
align-items: center;
|
|
595
|
-
|
|
382
|
+
gap: 10px;
|
|
596
383
|
}
|
|
597
384
|
.meesage-bubble-context .message-context {
|
|
598
385
|
flex: 1;
|
|
@@ -722,6 +509,13 @@ table {
|
|
|
722
509
|
font-size: 14px;
|
|
723
510
|
line-height: 17px;
|
|
724
511
|
}
|
|
512
|
+
.message-custom p {
|
|
513
|
+
font-family: PingFangSC-Regular;
|
|
514
|
+
font-size: 14px;
|
|
515
|
+
font-style: normal;
|
|
516
|
+
font-weight: 500;
|
|
517
|
+
line-height: 17px;
|
|
518
|
+
}
|
|
725
519
|
|
|
726
520
|
.message-revoke {
|
|
727
521
|
color: #999999;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tencentcloud/chat-uikit-react",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.2",
|
|
4
4
|
"main": "dist/cjs/index.js",
|
|
5
5
|
"module": "dist/esm/index.js",
|
|
6
6
|
"license": "MIT",
|
|
@@ -60,7 +60,7 @@
|
|
|
60
60
|
"dependencies": {
|
|
61
61
|
"date-fns": "^2.29.3",
|
|
62
62
|
"react-date-picker": "^9.0.0",
|
|
63
|
-
"tim-js-sdk": "^2.
|
|
63
|
+
"tim-js-sdk": "^2.26.1",
|
|
64
64
|
"tim-upload-plugin": "^1.0.5"
|
|
65
65
|
},
|
|
66
66
|
"peerDependencies": {
|
package/readme.zh_cn.md
ADDED
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
_[English](README.md) | 简体中文_
|
|
2
|
+
# [chat-uikit-react](https://www.tencentcloud.com/document/product/1047/34279/)
|
|
3
|
+
>Chat UIKit 是基于腾讯云 IM SDK 的一款 UI 组件库,它提供了一些通用的 UI 组件,包含会话、聊天、关系链、群组、音视频通话等功能。
|
|
4
|
+
基于 UI 组件您可以像搭积木一样快速搭建起自己的业务逻辑。
|
|
5
|
+
Chat UIKit 中的组件在实现 UI 功能的同时,会调用 IM SDK 相应的接口实现 IM 相关逻辑和数据的处理,因而开发者在使用 Chat UIKit 时只需关注自身业务或个性化扩展即可。
|
|
6
|
+
|
|
7
|
+
## Demos
|
|
8
|
+
我们已经构建了用于展示聊天功能的实例演示程序,您可以在我们的网站上预览这些
|
|
9
|
+
|
|
10
|
+
| | sample-chat | live-chat |
|
|
11
|
+
| ------ | ------ | ------ |
|
|
12
|
+
| |  |  |
|
|
13
|
+
| demo 在线体验地址 | [sample-chat](https://web.sdk.qcloud.com/im/demo/intl/index.html) | [live-chat](https://web.sdk.qcloud.com/im/demo/intl/index.html?scene=live) |
|
|
14
|
+
| 源码地址 | [sample-chat-code](https://github.com/TencentCloud/chat-uikit-react/tree/main/examples/sample-chat) | [live-chat-code](https://github.com/TencentCloud/chat-uikit-react/tree/main/examples/live-chat) |
|
|
15
|
+
|
|
16
|
+
您可以通过 [demos](https://web.sdk.qcloud.com/im/demo/intl/index.html) 体验效果, 并可以通过 [open source code](https://github.com/TencentCloud/chat-uikit-react) 获取源码
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
## Running Demo
|
|
20
|
+
|
|
21
|
+
### 步骤一:下载源码
|
|
22
|
+
```
|
|
23
|
+
# Run the code in CLI
|
|
24
|
+
$ git clone https://github.com/TencentCloud/chat-uikit-react
|
|
25
|
+
# Go to the project
|
|
26
|
+
$ cd chat-uikit-react
|
|
27
|
+
# Install dependencies of the demo
|
|
28
|
+
$ npm install && cd examples/sample-chat && npm install
|
|
29
|
+
```
|
|
30
|
+
### 步骤二:配置 demo
|
|
31
|
+
1. 打开`examples/sample-chat`项目,通过路径`./examples/sample-chat/src/debug/GenerateTestUserSig.js`找到`GenerateTestUserSig.js`文件。
|
|
32
|
+
2. 在`GenerateTestUserSig.js`文件中设置 `SDKAPPID` 和 `SECRETKEY` ,其值可以在[IM控制台](https://console.tencentcloud.com/im)中获取。 点击目标应用卡片,进入其配置页面。
|
|
33
|
+

|
|
34
|
+
3. 在 **Basic Information** 区域,点击 **Display key**,将密钥信息复制并保存到 GenerateTestUserSig 文件中。
|
|
35
|
+
>!
|
|
36
|
+
>- 本文提到的生成 UserSig 的方案是在客户端代码中配置 SECRETKEY,该方法中 SECRETKEY 很容易被反编译逆向破解,一旦您的密钥泄露,攻击者就可以盗用您的腾讯云流量,因此**该方法仅适合本地跑通 Demo 和功能调试。**
|
|
37
|
+
>- 正确的 UserSig 签发方式是将 UserSig 的计算代码集成到您的服务端,并提供面向 App 的接口,在需要 UserSig 时由您的 App 向业务服务器发起请求获取动态 UserSig。更多详情请参见 [服务端生成 UserSig](https://www.tencentcloud.com/document/product/1047/34385)。
|
|
38
|
+
|
|
39
|
+
### 步骤三:启动项目
|
|
40
|
+
```
|
|
41
|
+
# Launch the project
|
|
42
|
+
$ cd examples/sample-chat
|
|
43
|
+
$ npm run start
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
### 步骤四:发送您的第一条消息
|
|
47
|
+
1. 项目启动成功后,点击“+”图标,进行创建会话。
|
|
48
|
+
2. 在输入框中搜索另一个用户的 userID。
|
|
49
|
+
3. 点击用户头像发起会话。
|
|
50
|
+
4. 在输入框输入消息,按下"enter"键发送。
|
|
51
|
+

|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
### Quick links
|
|
55
|
+
- [Web demo](https://web.sdk.qcloud.com/im/demo/intl/index.html)
|
|
56
|
+
- [Client APIs](https://www.tencentcloud.com/document/product/1047/33999)
|
|
57
|
+
- [Free demo download](https://www.tencentcloud.com/document/product/1047/34279)
|
|
58
|
+
- [FAQs](https://www.tencentcloud.com/document/product/1047/34455)
|
|
59
|
+
- [Source code in GitHub](https://github.com/TencentCloud/chat-uikit-react)
|
|
60
|
+
- [Generating UserSig](https://www.tencentcloud.com/document/product/1047/34385)
|
|
@@ -65,7 +65,8 @@ export const getDisplayMessage = (conversation:Conversation, myProfile:Profile)
|
|
|
65
65
|
let from = '';
|
|
66
66
|
switch (type) {
|
|
67
67
|
case TIM.TYPES.CONV_GROUP:
|
|
68
|
-
from = lastMessage?.fromAccount === myProfile?.userID ? 'You
|
|
68
|
+
from = lastMessage?.fromAccount === myProfile?.userID ? 'You' : `${nameCard || nick || fromAccount || ''}`;
|
|
69
|
+
from = `${from ? `${from}:` : ''}`;
|
|
69
70
|
break;
|
|
70
71
|
case TIM.TYPES.CONV_C2C:
|
|
71
72
|
from = isRevoked ? 'you ' : '';
|
|
Binary file
|
|
Binary file
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { useEffect } from 'react';
|
|
2
2
|
import TIM, { Message } from 'tim-js-sdk';
|
|
3
3
|
import { useTUIKitContext } from '../../../context';
|
|
4
4
|
|
|
@@ -10,7 +10,7 @@ export function useMessageReceviedListener(
|
|
|
10
10
|
) => void,
|
|
11
11
|
) {
|
|
12
12
|
const { tim } = useTUIKitContext('useMessageReceviedListener');
|
|
13
|
-
|
|
13
|
+
useEffect(() => {
|
|
14
14
|
const handleMessageRecevied = (event: any) => {
|
|
15
15
|
if (customHandler && typeof customHandler === 'function') {
|
|
16
16
|
customHandler(setMessageList, event);
|
|
@@ -13,7 +13,6 @@ export interface TUIChatHeaderDefaultProps {
|
|
|
13
13
|
isOnline?: boolean,
|
|
14
14
|
conversation?: Conversation,
|
|
15
15
|
pluginComponentList?: Array<React.ComponentType>,
|
|
16
|
-
|
|
17
16
|
}
|
|
18
17
|
|
|
19
18
|
export interface TUIChatHeaderBasicProps extends TUIChatHeaderDefaultProps {
|
|
@@ -25,7 +24,7 @@ function TUIChatHeaderDefaultWithContext <T extends TUIChatHeaderBasicProps>(
|
|
|
25
24
|
props: PropsWithChildren<T>,
|
|
26
25
|
):React.ReactElement {
|
|
27
26
|
const {
|
|
28
|
-
title: propTitle,
|
|
27
|
+
title: propTitle = '',
|
|
29
28
|
avatar: propAvatar,
|
|
30
29
|
isOnline,
|
|
31
30
|
conversation,
|
|
@@ -33,7 +32,7 @@ function TUIChatHeaderDefaultWithContext <T extends TUIChatHeaderBasicProps>(
|
|
|
33
32
|
opateIcon,
|
|
34
33
|
} = props;
|
|
35
34
|
|
|
36
|
-
const [title, setTitle] = useState(
|
|
35
|
+
const [title, setTitle] = useState(propTitle);
|
|
37
36
|
const [avatar, setAvatar] = useState<React.ReactElement | string>('');
|
|
38
37
|
|
|
39
38
|
useEffect(() => {
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import React, { PropsWithChildren, useMemo } from 'react';
|
|
2
|
+
import { Conversation } from 'tim-js-sdk';
|
|
2
3
|
import { TUIConversationProvider, TUIConversationContextValue } from '../../context/TUIConversationContext';
|
|
3
4
|
import { TUIConversationList } from '../TUIConversationList';
|
|
4
5
|
import { TUIProfile } from '../TUIProfile';
|
|
@@ -6,6 +7,7 @@ import { TUIProfile } from '../TUIProfile';
|
|
|
6
7
|
interface TUIConversationProps {
|
|
7
8
|
createConversation?:(conversationID:string) => Promise<any>,
|
|
8
9
|
deleteConversation?:(conversationID:string) => Promise<any>,
|
|
10
|
+
filterConversation?:(conversationList: Array<Conversation>) => Array<Conversation>,
|
|
9
11
|
}
|
|
10
12
|
|
|
11
13
|
export function UnMemoizedTUIConversation<T extends TUIConversationProps>(
|
|
@@ -15,15 +17,18 @@ export function UnMemoizedTUIConversation<T extends TUIConversationProps>(
|
|
|
15
17
|
children,
|
|
16
18
|
createConversation,
|
|
17
19
|
deleteConversation,
|
|
20
|
+
filterConversation,
|
|
18
21
|
} = props;
|
|
19
22
|
const TUIConversationValue: TUIConversationContextValue = useMemo(
|
|
20
23
|
() => ({
|
|
21
24
|
createConversation,
|
|
22
25
|
deleteConversation,
|
|
26
|
+
filterConversation,
|
|
23
27
|
}),
|
|
24
28
|
[
|
|
25
29
|
createConversation,
|
|
26
30
|
deleteConversation,
|
|
31
|
+
filterConversation,
|
|
27
32
|
],
|
|
28
33
|
);
|
|
29
34
|
|
|
@@ -14,6 +14,7 @@ import { ConversationCreate } from '../ConversationCreate';
|
|
|
14
14
|
import { Icon, IconTypes } from '../Icon';
|
|
15
15
|
import { getDisplayTitle } from '../ConversationPreview/utils';
|
|
16
16
|
import { useConversationUpdate } from './hooks/useConversationUpdate';
|
|
17
|
+
import { useTUIConversationContext } from '../../context/TUIConversationContext';
|
|
17
18
|
|
|
18
19
|
interface Props {
|
|
19
20
|
filters?: object,
|
|
@@ -25,16 +26,22 @@ interface Props {
|
|
|
25
26
|
setConversationList: React.Dispatch<React.SetStateAction<Array<Conversation>>>,
|
|
26
27
|
event: () => void
|
|
27
28
|
) => void,
|
|
29
|
+
filterConversation?:(conversationList: Array<Conversation>) => Array<Conversation>,
|
|
28
30
|
}
|
|
29
31
|
export function UnMemoTUIConversationList<T extends Props>(props: T):React.ReactElement {
|
|
30
32
|
const {
|
|
31
33
|
Preview,
|
|
32
34
|
Container = ConversationListContainer,
|
|
33
35
|
onConversationListUpdated,
|
|
36
|
+
filterConversation: propsFilterConversation,
|
|
34
37
|
} = props;
|
|
35
38
|
const {
|
|
36
39
|
tim, customClasses, conversation, setActiveConversation, setTUIProfileShow,
|
|
37
40
|
} = useTUIKitContext('TUIConversationList');
|
|
41
|
+
const {
|
|
42
|
+
filterConversation: contextFilterConversation,
|
|
43
|
+
} = useTUIConversationContext('TUIConversationList');
|
|
44
|
+
const filterConversation = propsFilterConversation || contextFilterConversation;
|
|
38
45
|
const [conversationUpdateCount, setConversationUpdateCount] = useState(0);
|
|
39
46
|
const forceUpdate = () => setConversationUpdateCount((count) => count + 1);
|
|
40
47
|
|
|
@@ -50,8 +57,13 @@ export function UnMemoTUIConversationList<T extends Props>(props: T):React.React
|
|
|
50
57
|
const {
|
|
51
58
|
conversationList,
|
|
52
59
|
setConversationList,
|
|
53
|
-
} = useConversationList(tim, activeConversationHandler);
|
|
54
|
-
useConversationUpdate(
|
|
60
|
+
} = useConversationList(tim, activeConversationHandler, filterConversation);
|
|
61
|
+
useConversationUpdate(
|
|
62
|
+
setConversationList,
|
|
63
|
+
onConversationListUpdated,
|
|
64
|
+
forceUpdate,
|
|
65
|
+
filterConversation,
|
|
66
|
+
);
|
|
55
67
|
const [searchValue, setSearchValue] = useState('');
|
|
56
68
|
const [searchResult, setSearchResult] = useState(conversationList);
|
|
57
69
|
const [conversationCreated, setConversationCreated] = useState(false);
|
|
@@ -7,6 +7,7 @@ function useConversationList(
|
|
|
7
7
|
conversationList: Array<Conversation>,
|
|
8
8
|
setConversationList: React.Dispatch<React.SetStateAction<Array<Conversation>>>,
|
|
9
9
|
) => void,
|
|
10
|
+
filterConversation?:(conversationList: Array<Conversation>) => Array<Conversation>,
|
|
10
11
|
) {
|
|
11
12
|
const [conversationList, setConversationList] = useState<Array<Conversation>>([]);
|
|
12
13
|
const queryConversation = async (queryType?: string) => {
|
|
@@ -17,9 +18,14 @@ function useConversationList(
|
|
|
17
18
|
|
|
18
19
|
const res = await tim?.getConversationList();
|
|
19
20
|
if (res?.code === 0) {
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
21
|
+
let resConversationList = [];
|
|
22
|
+
if (filterConversation) {
|
|
23
|
+
resConversationList = filterConversation(res.data.conversationList);
|
|
24
|
+
} else {
|
|
25
|
+
resConversationList = res.data.conversationList.filter(
|
|
26
|
+
(item) => item.type !== TIM.TYPES.CONV_SYSTEM,
|
|
27
|
+
);
|
|
28
|
+
}
|
|
23
29
|
const newConversationList = queryType === 'reload'
|
|
24
30
|
? resConversationList
|
|
25
31
|
: [...conversationList, resConversationList];
|
|
@@ -9,14 +9,19 @@ export const useConversationUpdate = (
|
|
|
9
9
|
event: any
|
|
10
10
|
) => void,
|
|
11
11
|
forceUpdate?: () => void,
|
|
12
|
+
filterConversation?:(conversationList: Array<Conversation>) => Array<Conversation>,
|
|
12
13
|
) => {
|
|
13
14
|
const { tim } = useTUIKitContext('useConversationUpdate');
|
|
14
15
|
useEffect(() => {
|
|
15
16
|
const onConversationListUpdated = (event:any) => {
|
|
16
17
|
if (setConversationList) {
|
|
17
|
-
|
|
18
|
-
(
|
|
19
|
-
|
|
18
|
+
if (filterConversation) {
|
|
19
|
+
setConversationList(filterConversation(event.data));
|
|
20
|
+
} else {
|
|
21
|
+
setConversationList(event.data.filter(
|
|
22
|
+
(item) => item.type !== TIM.TYPES.CONV_SYSTEM,
|
|
23
|
+
));
|
|
24
|
+
}
|
|
20
25
|
}
|
|
21
26
|
if (forceUpdate) {
|
|
22
27
|
forceUpdate();
|
|
@@ -1,5 +1,10 @@
|
|
|
1
1
|
import React, { useState, useCallback, useEffect } from 'react';
|
|
2
|
-
import
|
|
2
|
+
import TIM, {
|
|
3
|
+
ChatSDK,
|
|
4
|
+
Conversation,
|
|
5
|
+
Group,
|
|
6
|
+
Profile,
|
|
7
|
+
} from 'tim-js-sdk';
|
|
3
8
|
|
|
4
9
|
export interface UseChatParams{
|
|
5
10
|
tim: ChatSDK,
|
|
@@ -29,6 +34,7 @@ export const useTUIKit = ({ tim, activeConversation: paramsActiveConversation }:
|
|
|
29
34
|
},
|
|
30
35
|
[tim],
|
|
31
36
|
);
|
|
37
|
+
|
|
32
38
|
useEffect(() => {
|
|
33
39
|
setConversation(paramsActiveConversation);
|
|
34
40
|
}, [paramsActiveConversation]);
|
|
@@ -15,7 +15,19 @@ function MessageCustomWithContext <T extends MessageContextProps>(
|
|
|
15
15
|
const handleContext = (data) => {
|
|
16
16
|
if (data.data === 'Hyperlink') {
|
|
17
17
|
const extension = JSONStringToParse(data?.extension);
|
|
18
|
-
|
|
18
|
+
if (extension?.item) {
|
|
19
|
+
return extension?.item.map((item) => <a target="_blank" key={item.value} href={item.value} rel="noreferrer">{item.value}</a>);
|
|
20
|
+
}
|
|
21
|
+
if (extension?.hyperlinks_text) {
|
|
22
|
+
const hyperlinks = extension.hyperlinks_text;
|
|
23
|
+
return (
|
|
24
|
+
<>
|
|
25
|
+
{extension.title}
|
|
26
|
+
{' '}
|
|
27
|
+
<a target="_blank" key={hyperlinks?.value} href={hyperlinks?.value} rel="noreferrer">{hyperlinks.key}</a>
|
|
28
|
+
</>
|
|
29
|
+
);
|
|
30
|
+
}
|
|
19
31
|
}
|
|
20
32
|
if (data.data === 'group_create') {
|
|
21
33
|
return `${message?.nick || message?.from} Create a group`;
|
|
@@ -17,7 +17,6 @@
|
|
|
17
17
|
}
|
|
18
18
|
}
|
|
19
19
|
.content {
|
|
20
|
-
padding: 0 10px;
|
|
21
20
|
display: flex;
|
|
22
21
|
flex-direction: column;
|
|
23
22
|
align-items: flex-start;
|
|
@@ -33,6 +32,7 @@
|
|
|
33
32
|
display: flex;
|
|
34
33
|
flex-direction: row;
|
|
35
34
|
justify-self: flex-start;
|
|
35
|
+
gap: 10px;
|
|
36
36
|
.content {
|
|
37
37
|
align-items: flex-start;
|
|
38
38
|
flex: 1;
|
|
@@ -41,6 +41,7 @@
|
|
|
41
41
|
.out {
|
|
42
42
|
flex: 1;
|
|
43
43
|
display: flex;
|
|
44
|
+
gap: 10px;
|
|
44
45
|
flex-direction: row-reverse;
|
|
45
46
|
justify-self: flex-end;
|
|
46
47
|
.content {
|
|
@@ -274,7 +275,7 @@
|
|
|
274
275
|
&-context {
|
|
275
276
|
display: flex;
|
|
276
277
|
align-items: center;
|
|
277
|
-
|
|
278
|
+
gap: 10px;
|
|
278
279
|
.message-context{
|
|
279
280
|
flex: 1;
|
|
280
281
|
}
|
|
@@ -401,6 +402,13 @@
|
|
|
401
402
|
font-size: 14px;
|
|
402
403
|
line-height: 17px;
|
|
403
404
|
}
|
|
405
|
+
p {
|
|
406
|
+
font-family: PingFangSC-Regular;
|
|
407
|
+
font-size: 14px;
|
|
408
|
+
font-style: normal;
|
|
409
|
+
font-weight: 500;
|
|
410
|
+
line-height: 17px;
|
|
411
|
+
}
|
|
404
412
|
}
|
|
405
413
|
|
|
406
414
|
.message-revoke {
|
|
@@ -476,4 +484,4 @@
|
|
|
476
484
|
border-radius: 2px;
|
|
477
485
|
box-shadow: 0px 0px 10px rgba(0, 0, 0, 0.25);
|
|
478
486
|
}
|
|
479
|
-
}
|
|
487
|
+
}
|
|
@@ -74,6 +74,9 @@ export function handleShowLastMessage(item: Conversation) {
|
|
|
74
74
|
&& conversation.messageRemindType === TIM.TYPES.MSG_REMIND_ACPT_NOT_NOTE
|
|
75
75
|
? t(`[${conversation.unreadCount > 99 ? '99+' : conversation.unreadCount}条]`)
|
|
76
76
|
: '';
|
|
77
|
+
if (!lastMessage.lastTime) {
|
|
78
|
+
return '';
|
|
79
|
+
}
|
|
77
80
|
// Determine the lastmessage sender of the group.
|
|
78
81
|
// Namecard / Nick / userid is displayed by priority
|
|
79
82
|
if (conversation.type === TIM.TYPES.CONV_GROUP) {
|
|
@@ -12,36 +12,11 @@ import { useTUIChatStateContext } from '../../context';
|
|
|
12
12
|
export function InputPluginsDefalut():React.ReactElement {
|
|
13
13
|
const {
|
|
14
14
|
sendUploadMessage,
|
|
15
|
-
// pluginConfig: {
|
|
16
|
-
// plugins: propsPlugins,
|
|
17
|
-
// showNumber: propsShowNumber,
|
|
18
|
-
// MoreIcon: propsMoreIcon,
|
|
19
|
-
// isEmojiPicker: porpsIsEmojiPicker,
|
|
20
|
-
// isImagePicker: porpsIsImagePicker,
|
|
21
|
-
// isVideoPicker: porpsIsVideoPicker,
|
|
22
|
-
// isFilePicker: porpsIsFilePicker,
|
|
23
|
-
// },
|
|
24
15
|
pluginConfig: propsPluginConfig,
|
|
25
16
|
} = useTUIMessageInputContext('TUIMessageInputDefault');
|
|
26
17
|
|
|
27
18
|
const { TUIMessageInputConfig } = useTUIChatStateContext('TUIMessageInput');
|
|
28
19
|
|
|
29
|
-
// const {
|
|
30
|
-
// pluginConfig: {
|
|
31
|
-
// plugins: contextPlugins,
|
|
32
|
-
// showNumber: contextShowNumber,
|
|
33
|
-
// MoreIcon: contextMoreIcon,
|
|
34
|
-
// isEmojiPicker: contextIsEmojiPicker,
|
|
35
|
-
// isImagePicker: contextIsImagePicker,
|
|
36
|
-
// isVideoPicker: contextIsVideoPicker,
|
|
37
|
-
// isFilePicker: contextIsFilePicker,
|
|
38
|
-
// },
|
|
39
|
-
// } = TUIMessageInputConfig;
|
|
40
|
-
|
|
41
|
-
// const propPlugins = propsPlugins || contextPlugins || [];
|
|
42
|
-
// const showNumber = propsShowNumber || contextShowNumber || 1;
|
|
43
|
-
// const MoreIcon = propsMoreIcon || contextMoreIcon;
|
|
44
|
-
|
|
45
20
|
const propPlugins = propsPluginConfig?.plugins
|
|
46
21
|
|| TUIMessageInputConfig?.pluginConfig?.plugins || [];
|
|
47
22
|
const showNumber = propsPluginConfig?.showNumber
|