agora-appbuilder-core 4.0.13 → 4.0.14
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/template/_package-lock.json +1364 -1576
- package/template/android/app/src/main/assets/fonts/icomoon.ttf +0 -0
- package/template/customization-api/sub-components.ts +6 -4
- package/template/customization-api/types.ts +0 -6
- package/template/defaultConfig.js +0 -3
- package/template/global.d.ts +0 -3
- package/template/ios/Podfile.lock +0 -10
- package/template/package-lock.json +1364 -1576
- package/template/package.json +0 -4
- package/template/src/SDKAppWrapper.tsx +8 -2
- package/template/src/app-state/useMessages.ts +9 -49
- package/template/src/assets/font-styles.css +125 -289
- package/template/src/assets/fonts/icomoon.ttf +0 -0
- package/template/src/assets/selection.json +1 -1
- package/template/src/atoms/ActionMenu.tsx +2 -5
- package/template/src/atoms/CustomIcon.tsx +1 -17
- package/template/src/atoms/ImageIcon.tsx +3 -19
- package/template/src/atoms/Popup.tsx +4 -13
- package/template/src/atoms/ToolbarPreset.tsx +57 -6
- package/template/src/auth/AuthProvider.tsx +0 -5
- package/template/src/auth/config.ts +3 -12
- package/template/src/components/Chat.tsx +1 -7
- package/template/src/components/ChatContext.ts +0 -12
- package/template/src/components/CommonStyles.ts +2 -2
- package/template/src/components/Controls.tsx +57 -29
- package/template/src/components/Leftbar.tsx +4 -4
- package/template/src/components/Navbar.tsx +54 -29
- package/template/src/components/NavbarMobile.tsx +23 -33
- package/template/src/components/PinnedVideo.tsx +1 -1
- package/template/src/components/RTMConfigure.tsx +0 -1
- package/template/src/components/SdkApiContext.tsx +4 -1
- package/template/src/components/chat-messages/useChatMessages.tsx +607 -411
- package/template/src/components/chat-ui/useChatUIControls.tsx +0 -53
- package/template/src/components/meeting-info-invite/MeetingInfoGridTile.tsx +1 -4
- package/template/src/components/participants/Participant.tsx +1 -0
- package/template/src/components/precall/joinWaitingRoomBtn.native.tsx +1 -6
- package/template/src/components/precall/joinWaitingRoomBtn.tsx +1 -6
- package/template/src/components/room-info/useRoomInfo.tsx +5 -5
- package/template/src/language/default-labels/videoCallScreenLabels.ts +6 -86
- package/template/src/pages/VideoCall.tsx +4 -3
- package/template/src/pages/video-call/ActionSheetContent.tsx +32 -3
- package/template/src/pages/video-call/VideoCallScreenWrapper.tsx +12 -22
- package/template/src/pages/video-call/VideoComponent.tsx +11 -5
- package/template/src/pages/video-call/index.ts +0 -8
- package/template/src/subComponents/ChatBubble.tsx +32 -252
- package/template/src/subComponents/ChatContainer.tsx +4 -14
- package/template/src/subComponents/ChatInput.ios.tsx +184 -0
- package/template/src/subComponents/ChatInput.tsx +100 -276
- package/template/src/subComponents/RemoteMutePopup.tsx +131 -12
- package/template/src/subComponents/caption/CaptionContainer.tsx +2 -6
- package/template/src/subComponents/recording/useRecording.tsx +1 -3
- package/template/src/utils/SdkMethodEvents.ts +1 -0
- package/template/src/utils/common.tsx +17 -0
- package/template/src/utils/index.tsx +0 -30
- package/template/src/utils/useEndCall.ts +0 -7
- package/template/src/utils/useJoinRoom.ts +7 -33
- package/template/android/link-assets-manifest.json +0 -13
- package/template/ios/link-assets-manifest.json +0 -13
- package/template/src/atoms/InlinePopup.tsx +0 -185
- package/template/src/components/chat/chatConfigure.native.tsx +0 -488
- package/template/src/components/chat/chatConfigure.tsx +0 -473
- package/template/src/subComponents/ChatInput.native.tsx +0 -269
- package/template/src/subComponents/chat/ChatActionMenu.tsx +0 -224
- package/template/src/subComponents/chat/ChatAttachment.native.tsx +0 -234
- package/template/src/subComponents/chat/ChatAttachment.tsx +0 -145
- package/template/src/subComponents/chat/ChatEmoji.native.tsx +0 -75
- package/template/src/subComponents/chat/ChatEmoji.tsx +0 -181
- package/template/src/subComponents/chat/ChatSendButton.tsx +0 -141
- package/template/src/subComponents/chat/ChatUploadStatus.tsx +0 -65
- package/template/src/subComponents/chat/ImagePopup.tsx +0 -400
|
@@ -10,86 +10,24 @@
|
|
|
10
10
|
*********************************************
|
|
11
11
|
*/
|
|
12
12
|
import React, {useContext} from 'react';
|
|
13
|
-
import {
|
|
14
|
-
View,
|
|
15
|
-
Text,
|
|
16
|
-
StyleSheet,
|
|
17
|
-
Linking,
|
|
18
|
-
Image,
|
|
19
|
-
Pressable,
|
|
20
|
-
TouchableOpacity,
|
|
21
|
-
ActivityIndicator,
|
|
22
|
-
} from 'react-native';
|
|
13
|
+
import {View, Text, StyleSheet, Linking} from 'react-native';
|
|
23
14
|
import Hyperlink from 'react-native-hyperlink';
|
|
24
15
|
import {useString} from '../utils/useString';
|
|
25
16
|
import {ChatBubbleProps} from '../components/ChatContext';
|
|
17
|
+
import ColorContext from '../components/ColorContext';
|
|
26
18
|
import {isWebInternal, trimText} from '../utils/common';
|
|
27
19
|
import {useChatUIControls, useContent} from 'customization-api';
|
|
28
20
|
import ThemeConfig from '../theme';
|
|
29
21
|
import hexadecimalTransparency from '../utils/hexadecimalTransparency';
|
|
30
|
-
import
|
|
31
|
-
import {
|
|
32
|
-
import
|
|
33
|
-
import {
|
|
34
|
-
import ImagePopup from './chat/ImagePopup';
|
|
35
|
-
import {ChatMessageType} from '../components/chat-messages/useChatMessages';
|
|
36
|
-
import {
|
|
37
|
-
chatMsgDeletedText,
|
|
38
|
-
videoRoomUserFallbackText,
|
|
39
|
-
} from '../language/default-labels/videoCallScreenLabels';
|
|
40
|
-
|
|
41
|
-
export const AttachmentBubble = ({
|
|
42
|
-
fileName,
|
|
43
|
-
fileExt,
|
|
44
|
-
isFullWidth = false,
|
|
45
|
-
fileType = '',
|
|
46
|
-
secondaryComponent,
|
|
47
|
-
}) => {
|
|
48
|
-
const {uploadStatus} = useChatUIControls();
|
|
49
|
-
|
|
50
|
-
return (
|
|
51
|
-
<View
|
|
52
|
-
style={[
|
|
53
|
-
style.fileContainer,
|
|
54
|
-
isFullWidth && {width: '100%'},
|
|
55
|
-
uploadStatus === UploadStatus.FAILURE && {
|
|
56
|
-
borderColor: $config.SEMANTIC_ERROR + hexadecimalTransparency['40%'],
|
|
57
|
-
},
|
|
58
|
-
]}>
|
|
59
|
-
<View style={[style.fileBlock]}>
|
|
60
|
-
<ImageIcon
|
|
61
|
-
base64={true}
|
|
62
|
-
iconSize={24}
|
|
63
|
-
iconType="plain"
|
|
64
|
-
name={
|
|
65
|
-
fileType === ChatMessageType.IMAGE
|
|
66
|
-
? 'chat_attachment_image'
|
|
67
|
-
: fileExt === 'pdf'
|
|
68
|
-
? 'chat_attachment_pdf'
|
|
69
|
-
: fileExt === 'doc' || fileExt === 'docx'
|
|
70
|
-
? 'chat_attachment_doc'
|
|
71
|
-
: 'chat_attachment_unknown'
|
|
72
|
-
}
|
|
73
|
-
tintColor={$config.SEMANTIC_NEUTRAL}
|
|
74
|
-
/>
|
|
75
|
-
<Text style={style.fileName} numberOfLines={1} ellipsizeMode="tail">
|
|
76
|
-
{fileName}
|
|
77
|
-
</Text>
|
|
78
|
-
</View>
|
|
79
|
-
{secondaryComponent}
|
|
80
|
-
</View>
|
|
81
|
-
);
|
|
82
|
-
};
|
|
22
|
+
import Spacer from '../atoms/Spacer';
|
|
23
|
+
import {formatAMPM, isURL} from '../utils';
|
|
24
|
+
import {ChatType} from '../components/chat-ui/useChatUIControls';
|
|
25
|
+
import {videoRoomUserFallbackText} from '../language/default-labels/videoCallScreenLabels';
|
|
83
26
|
|
|
84
27
|
const ChatBubble = (props: ChatBubbleProps) => {
|
|
85
28
|
const {defaultContent} = useContent();
|
|
29
|
+
const {primaryColor} = useContext(ColorContext);
|
|
86
30
|
const {chatType, privateChatUser} = useChatUIControls();
|
|
87
|
-
const [actionMenuVisible, setActionMenuVisible] =
|
|
88
|
-
React.useState<boolean>(false);
|
|
89
|
-
const [lightboxVisible, setLightboxVisible] = React.useState(false);
|
|
90
|
-
const [isLoading, setIsLoading] = React.useState(true);
|
|
91
|
-
const moreIconRef = React.useRef<View>(null);
|
|
92
|
-
|
|
93
31
|
let {
|
|
94
32
|
isLocal,
|
|
95
33
|
isSameUser,
|
|
@@ -100,17 +38,10 @@ const ChatBubble = (props: ChatBubbleProps) => {
|
|
|
100
38
|
msgId,
|
|
101
39
|
updatedTimestamp,
|
|
102
40
|
previousMessageCreatedTimestamp,
|
|
103
|
-
type,
|
|
104
|
-
url,
|
|
105
|
-
thumb,
|
|
106
|
-
fileName,
|
|
107
|
-
ext,
|
|
108
41
|
} = props;
|
|
109
42
|
|
|
110
43
|
let time = formatAMPM(new Date(parseInt(createdTimestamp)));
|
|
111
44
|
|
|
112
|
-
const chatMsgDeletedTxt = useString(chatMsgDeletedText);
|
|
113
|
-
|
|
114
45
|
let forceShowUserNameandTimeStamp = false;
|
|
115
46
|
//calculate time difference between current message and last message
|
|
116
47
|
//if difference over 2 minutes passed from previous message
|
|
@@ -138,12 +69,6 @@ const ChatBubble = (props: ChatBubbleProps) => {
|
|
|
138
69
|
Linking.openURL(url);
|
|
139
70
|
}
|
|
140
71
|
};
|
|
141
|
-
|
|
142
|
-
const handleImageLoad = () => {
|
|
143
|
-
setIsLoading(false);
|
|
144
|
-
};
|
|
145
|
-
//commented for v1 release
|
|
146
|
-
//const remoteUserDefaultLabel = useString('remoteUserDefaultLabel')();
|
|
147
72
|
const remoteUserDefaultLabel = useString(videoRoomUserFallbackText)();
|
|
148
73
|
|
|
149
74
|
return props?.render ? (
|
|
@@ -156,11 +81,6 @@ const ChatBubble = (props: ChatBubbleProps) => {
|
|
|
156
81
|
isDeleted,
|
|
157
82
|
updatedTimestamp,
|
|
158
83
|
isSameUser,
|
|
159
|
-
type,
|
|
160
|
-
thumb,
|
|
161
|
-
url,
|
|
162
|
-
fileName,
|
|
163
|
-
ext,
|
|
164
84
|
previousMessageCreatedTimestamp,
|
|
165
85
|
)
|
|
166
86
|
) : (
|
|
@@ -171,9 +91,9 @@ const ChatBubble = (props: ChatBubbleProps) => {
|
|
|
171
91
|
style={{
|
|
172
92
|
flexDirection: 'row',
|
|
173
93
|
justifyContent: isLocal ? 'flex-end' : 'flex-start',
|
|
174
|
-
marginBottom:
|
|
175
|
-
marginTop:
|
|
176
|
-
marginHorizontal:
|
|
94
|
+
marginBottom: 8,
|
|
95
|
+
marginTop: 14,
|
|
96
|
+
marginHorizontal: 20,
|
|
177
97
|
}}>
|
|
178
98
|
<Text style={style.userNameStyle}>
|
|
179
99
|
{isLocal
|
|
@@ -191,9 +111,9 @@ const ChatBubble = (props: ChatBubbleProps) => {
|
|
|
191
111
|
style={{
|
|
192
112
|
flexDirection: 'row',
|
|
193
113
|
justifyContent: isLocal ? 'flex-end' : 'flex-start',
|
|
194
|
-
marginBottom:
|
|
195
|
-
marginTop:
|
|
196
|
-
marginHorizontal:
|
|
114
|
+
marginBottom: 8,
|
|
115
|
+
marginTop: 14,
|
|
116
|
+
marginHorizontal: 20,
|
|
197
117
|
}}>
|
|
198
118
|
<Text style={style.timestampStyle}>{time}</Text>
|
|
199
119
|
</View>
|
|
@@ -206,108 +126,21 @@ const ChatBubble = (props: ChatBubbleProps) => {
|
|
|
206
126
|
//isURL(message) ? {maxWidth: '88%'} : {},
|
|
207
127
|
]}>
|
|
208
128
|
<View
|
|
209
|
-
style={
|
|
129
|
+
style={
|
|
210
130
|
isLocal
|
|
211
131
|
? style.chatBubbleLocalViewLayer2
|
|
212
|
-
: style.chatBubbleRemoteViewLayer2
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
style={[
|
|
225
|
-
style.messageStyle,
|
|
226
|
-
{color: $config.SEMANTIC_NEUTRAL, marginLeft: 5},
|
|
227
|
-
]}>
|
|
228
|
-
{chatMsgDeletedTxt(isLocal ? 'You' : defaultContent[uid]?.name)}
|
|
229
|
-
</Text>
|
|
230
|
-
</View>
|
|
231
|
-
) : (
|
|
232
|
-
<Hyperlink
|
|
233
|
-
onPress={handleUrl}
|
|
234
|
-
linkStyle={{
|
|
235
|
-
color: $config.FONT_COLOR,
|
|
236
|
-
textDecorationLine: 'underline',
|
|
237
|
-
}}>
|
|
238
|
-
{type === ChatMessageType.TXT && (
|
|
239
|
-
<Text
|
|
240
|
-
style={[
|
|
241
|
-
style.messageStyle,
|
|
242
|
-
containsOnlyEmojis(message)
|
|
243
|
-
? {fontSize: 24, lineHeight: 32}
|
|
244
|
-
: {fontSize: 14, lineHeight: 20},
|
|
245
|
-
]}
|
|
246
|
-
selectable={true}>
|
|
247
|
-
{message}
|
|
248
|
-
</Text>
|
|
249
|
-
)}
|
|
250
|
-
{type === ChatMessageType.IMAGE && (
|
|
251
|
-
<View>
|
|
252
|
-
<TouchableOpacity
|
|
253
|
-
style={{justifyContent: 'center', alignItems: 'center'}}
|
|
254
|
-
onPress={() => {
|
|
255
|
-
!isLoading && setLightboxVisible(true);
|
|
256
|
-
}}>
|
|
257
|
-
{isLoading ? (
|
|
258
|
-
<View style={style.spinnerContainer}>
|
|
259
|
-
<ActivityIndicator
|
|
260
|
-
size="small"
|
|
261
|
-
color={$config.PRIMARY_ACTION_BRAND_COLOR}
|
|
262
|
-
/>
|
|
263
|
-
</View>
|
|
264
|
-
) : null}
|
|
265
|
-
<Image
|
|
266
|
-
source={{uri: thumb}}
|
|
267
|
-
style={style.previewImg}
|
|
268
|
-
onLoad={handleImageLoad}
|
|
269
|
-
/>
|
|
270
|
-
</TouchableOpacity>
|
|
271
|
-
{lightboxVisible ? (
|
|
272
|
-
<ImagePopup
|
|
273
|
-
modalVisible={lightboxVisible}
|
|
274
|
-
setModalVisible={setLightboxVisible}
|
|
275
|
-
imageUrl={url}
|
|
276
|
-
msgId={msgId}
|
|
277
|
-
fileName={fileName}
|
|
278
|
-
senderName={isLocal ? 'You' : defaultContent[uid]?.name}
|
|
279
|
-
timestamp={createdTimestamp}
|
|
280
|
-
isLocal={isLocal}
|
|
281
|
-
/>
|
|
282
|
-
) : null}
|
|
283
|
-
</View>
|
|
284
|
-
)}
|
|
285
|
-
{type === ChatMessageType.FILE && (
|
|
286
|
-
<AttachmentBubble
|
|
287
|
-
fileName={fileName}
|
|
288
|
-
fileExt={ext}
|
|
289
|
-
secondaryComponent={
|
|
290
|
-
<View>
|
|
291
|
-
<MoreMenu
|
|
292
|
-
ref={moreIconRef}
|
|
293
|
-
setActionMenuVisible={setActionMenuVisible}
|
|
294
|
-
/>
|
|
295
|
-
<ChatActionMenu
|
|
296
|
-
actionMenuVisible={actionMenuVisible}
|
|
297
|
-
setActionMenuVisible={setActionMenuVisible}
|
|
298
|
-
btnRef={moreIconRef}
|
|
299
|
-
fileName={fileName}
|
|
300
|
-
fileUrl={url}
|
|
301
|
-
msgId={msgId}
|
|
302
|
-
privateChatUser={privateChatUser}
|
|
303
|
-
isLocal={isLocal}
|
|
304
|
-
/>
|
|
305
|
-
</View>
|
|
306
|
-
}
|
|
307
|
-
/>
|
|
308
|
-
)}
|
|
309
|
-
</Hyperlink>
|
|
310
|
-
)}
|
|
132
|
+
: style.chatBubbleRemoteViewLayer2
|
|
133
|
+
}>
|
|
134
|
+
<Hyperlink
|
|
135
|
+
onPress={handleUrl}
|
|
136
|
+
linkStyle={{
|
|
137
|
+
color: $config.FONT_COLOR,
|
|
138
|
+
textDecorationLine: 'underline',
|
|
139
|
+
}}>
|
|
140
|
+
<Text style={style.messageStyle} selectable={true}>
|
|
141
|
+
{message}
|
|
142
|
+
</Text>
|
|
143
|
+
</Hyperlink>
|
|
311
144
|
</View>
|
|
312
145
|
</View>
|
|
313
146
|
</>
|
|
@@ -332,7 +165,7 @@ const style = StyleSheet.create({
|
|
|
332
165
|
backgroundColor: $config.CARD_LAYER_2_COLOR,
|
|
333
166
|
alignSelf: 'flex-start',
|
|
334
167
|
marginVertical: 2,
|
|
335
|
-
marginHorizontal:
|
|
168
|
+
marginHorizontal: 20,
|
|
336
169
|
borderBottomLeftRadius: 8,
|
|
337
170
|
borderBottomRightRadius: 8,
|
|
338
171
|
borderTopLeftRadius: 0,
|
|
@@ -343,7 +176,8 @@ const style = StyleSheet.create({
|
|
|
343
176
|
backgroundColor: 'transparent',
|
|
344
177
|
// width: '100%',
|
|
345
178
|
// height: '100%',
|
|
346
|
-
|
|
179
|
+
paddingVertical: 8,
|
|
180
|
+
paddingHorizontal: 12,
|
|
347
181
|
borderBottomLeftRadius: 8,
|
|
348
182
|
borderBottomRightRadius: 8,
|
|
349
183
|
borderTopLeftRadius: 8,
|
|
@@ -352,7 +186,8 @@ const style = StyleSheet.create({
|
|
|
352
186
|
chatBubbleLocalViewLayer2: {
|
|
353
187
|
//width: '100%',
|
|
354
188
|
//height: '100%',
|
|
355
|
-
|
|
189
|
+
paddingVertical: 8,
|
|
190
|
+
paddingHorizontal: 12,
|
|
356
191
|
borderBottomLeftRadius: 8,
|
|
357
192
|
borderBottomRightRadius: 8,
|
|
358
193
|
borderTopLeftRadius: 8,
|
|
@@ -365,7 +200,7 @@ const style = StyleSheet.create({
|
|
|
365
200
|
$config.CARD_LAYER_5_COLOR + hexadecimalTransparency['20%'],
|
|
366
201
|
alignSelf: 'flex-end',
|
|
367
202
|
marginVertical: 2,
|
|
368
|
-
marginHorizontal:
|
|
203
|
+
marginHorizontal: 20,
|
|
369
204
|
borderBottomLeftRadius: 8,
|
|
370
205
|
borderBottomRightRadius: 8,
|
|
371
206
|
borderTopLeftRadius: 8,
|
|
@@ -379,61 +214,6 @@ const style = StyleSheet.create({
|
|
|
379
214
|
lineHeight: ThemeConfig.FontSize.small * 1.45,
|
|
380
215
|
color: $config.FONT_COLOR,
|
|
381
216
|
},
|
|
382
|
-
previewImg: {
|
|
383
|
-
width: 256,
|
|
384
|
-
height: 160,
|
|
385
|
-
resizeMode: 'cover',
|
|
386
|
-
borderRadius: 8,
|
|
387
|
-
},
|
|
388
|
-
chatBubbleViewImg: {
|
|
389
|
-
paddingHorizontal: 6,
|
|
390
|
-
paddingVertical: 6,
|
|
391
|
-
justifyContent: 'center',
|
|
392
|
-
alignItems: 'center',
|
|
393
|
-
},
|
|
394
|
-
fileName: {
|
|
395
|
-
color: $config.FONT_COLOR,
|
|
396
|
-
fontSize: 14,
|
|
397
|
-
lineHeight: 20,
|
|
398
|
-
fontFamily: ThemeConfig.FontFamily.sansPro,
|
|
399
|
-
},
|
|
400
|
-
fileContainer: {
|
|
401
|
-
flexDirection: 'row',
|
|
402
|
-
gap: 2,
|
|
403
|
-
alignItems: 'center',
|
|
404
|
-
justifyContent: 'space-between',
|
|
405
|
-
padding: 8,
|
|
406
|
-
backgroundColor: $config.CARD_LAYER_4_COLOR,
|
|
407
|
-
borderRadius: 4,
|
|
408
|
-
borderWidth: 1,
|
|
409
|
-
borderColor: $config.CARD_LAYER_5_COLOR + hexadecimalTransparency['10%'],
|
|
410
|
-
width: 240,
|
|
411
|
-
shadowColor: '#000',
|
|
412
|
-
shadowOffset: {
|
|
413
|
-
width: 0,
|
|
414
|
-
height: 4,
|
|
415
|
-
},
|
|
416
|
-
shadowOpacity: 0.05,
|
|
417
|
-
shadowRadius: 4,
|
|
418
|
-
elevation: 1, // For Android
|
|
419
|
-
},
|
|
420
|
-
fileBlock: {
|
|
421
|
-
flexDirection: 'row',
|
|
422
|
-
alignItems: 'center',
|
|
423
|
-
gap: 8,
|
|
424
|
-
flex: 0.8,
|
|
425
|
-
},
|
|
426
|
-
spinnerContainer: {
|
|
427
|
-
position: 'absolute',
|
|
428
|
-
justifyContent: 'center',
|
|
429
|
-
alignItems: 'center',
|
|
430
|
-
zIndex: 1,
|
|
431
|
-
},
|
|
432
|
-
deleteMsgContainer: {
|
|
433
|
-
flexDirection: 'row',
|
|
434
|
-
justifyContent: 'flex-start',
|
|
435
|
-
alignItems: 'center',
|
|
436
|
-
},
|
|
437
217
|
});
|
|
438
218
|
|
|
439
219
|
export default ChatBubble;
|
|
@@ -42,12 +42,12 @@ import {
|
|
|
42
42
|
useChatUIControls,
|
|
43
43
|
} from '../components/chat-ui/useChatUIControls';
|
|
44
44
|
import {useContent} from 'customization-api';
|
|
45
|
+
import {useChatMessages} from '../components/chat-messages/useChatMessages';
|
|
45
46
|
import hexadecimalTransparency from '../utils/hexadecimalTransparency';
|
|
46
47
|
import ThemeConfig from '../theme';
|
|
47
48
|
import UserAvatar from '../atoms/UserAvatar';
|
|
48
49
|
import Spacer from '../atoms/Spacer';
|
|
49
50
|
import {useChatNotification} from '../components/chat-notification/useChatNotification';
|
|
50
|
-
import {useChatMessages} from '../components/chat-messages/useChatMessages';
|
|
51
51
|
import {
|
|
52
52
|
chatPanelUnreadMessageText,
|
|
53
53
|
chatPanelUserOfflineText,
|
|
@@ -68,7 +68,7 @@ const ChatContainer = (props?: {
|
|
|
68
68
|
const [grpUnreadCount, setGrpUnreadCount] = useState(0);
|
|
69
69
|
const [privateUnreadCount, setPrivateUnreadCount] = useState(0);
|
|
70
70
|
const {defaultContent} = useContent();
|
|
71
|
-
const {
|
|
71
|
+
const {messageStore, privateMessageStore} = useChatMessages();
|
|
72
72
|
const messageStoreLengthRef = useRef(messageStore.length);
|
|
73
73
|
const {height, width} = useWindowDimensions();
|
|
74
74
|
const {chatType, setChatType, privateChatUser, inputActive} =
|
|
@@ -240,14 +240,9 @@ const ChatContainer = (props?: {
|
|
|
240
240
|
createdTimestamp={message.createdTimestamp}
|
|
241
241
|
updatedTimestamp={message.updatedTimestamp}
|
|
242
242
|
uid={message.uid}
|
|
243
|
-
key={message.
|
|
243
|
+
key={message.ts}
|
|
244
244
|
msgId={message.msgId}
|
|
245
245
|
isDeleted={message.isDeleted}
|
|
246
|
-
type={message.type}
|
|
247
|
-
url={message?.url}
|
|
248
|
-
thumb={message?.thumb}
|
|
249
|
-
fileName={message?.fileName}
|
|
250
|
-
ext={message?.ext}
|
|
251
246
|
/>
|
|
252
247
|
{messageStore?.length - 1 === index ? (
|
|
253
248
|
<Spacer size={10} />
|
|
@@ -298,11 +293,6 @@ const ChatContainer = (props?: {
|
|
|
298
293
|
key={message.ts}
|
|
299
294
|
msgId={message.msgId}
|
|
300
295
|
isDeleted={message.isDeleted}
|
|
301
|
-
type={message.type}
|
|
302
|
-
url={message?.url}
|
|
303
|
-
thumb={message?.thumb}
|
|
304
|
-
fileName={message?.fileName}
|
|
305
|
-
ext={message?.ext}
|
|
306
296
|
/>
|
|
307
297
|
{privateMessageStore[privateChatUser]?.length - 1 === index ? (
|
|
308
298
|
<Spacer size={10} />
|
|
@@ -343,7 +333,7 @@ const style = StyleSheet.create({
|
|
|
343
333
|
borderRadius: 8,
|
|
344
334
|
padding: 12,
|
|
345
335
|
marginTop: 20,
|
|
346
|
-
marginHorizontal:
|
|
336
|
+
marginHorizontal: 20,
|
|
347
337
|
marginBottom: 0,
|
|
348
338
|
},
|
|
349
339
|
defaultMessageText: {
|
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
/*
|
|
2
|
+
********************************************
|
|
3
|
+
Copyright © 2021 Agora Lab, Inc., all rights reserved.
|
|
4
|
+
AppBuilder and all associated components, source code, APIs, services, and documentation
|
|
5
|
+
(the “Materials”) are owned by Agora Lab, Inc. and its licensors. The Materials may not be
|
|
6
|
+
accessed, used, modified, or distributed for any purpose without a license from Agora Lab, Inc.
|
|
7
|
+
Use without a license or in violation of any license terms and conditions (including use for
|
|
8
|
+
any purpose competitive to Agora Lab, Inc.’s business) is strictly prohibited. For more
|
|
9
|
+
information visit https://appbuilder.agora.io.
|
|
10
|
+
*********************************************
|
|
11
|
+
*/
|
|
12
|
+
import React, {useContext, useEffect, useRef} from 'react';
|
|
13
|
+
import {View, TouchableOpacity, StyleSheet, Image} from 'react-native';
|
|
14
|
+
import ColorContext from '../components/ColorContext';
|
|
15
|
+
import TextInput from '../atoms/TextInput';
|
|
16
|
+
import {useString} from '../utils/useString';
|
|
17
|
+
import {useChatMessages} from '../components/chat-messages/useChatMessages';
|
|
18
|
+
import {isIOS, isValidReactComponent, isWebInternal} from '../utils/common';
|
|
19
|
+
import {useCustomization} from 'customization-implementation';
|
|
20
|
+
import {
|
|
21
|
+
ChatType,
|
|
22
|
+
useChatUIControls,
|
|
23
|
+
} from '../components/chat-ui/useChatUIControls';
|
|
24
|
+
import {useContent, useUserName} from 'customization-api';
|
|
25
|
+
import ImageIcon from '../atoms/ImageIcon';
|
|
26
|
+
import ThemeConfig from '../theme';
|
|
27
|
+
import {BottomSheetTextInput} from '@gorhom/bottom-sheet';
|
|
28
|
+
import {
|
|
29
|
+
groupChatInputPlaceHolderText,
|
|
30
|
+
privateChatInputPlaceHolderText,
|
|
31
|
+
} from '../language/default-labels/videoCallScreenLabels';
|
|
32
|
+
|
|
33
|
+
export interface ChatSendButtonProps {
|
|
34
|
+
render?: (onPress: () => void) => JSX.Element;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export const ChatSendButton = (props: ChatSendButtonProps) => {
|
|
38
|
+
const {privateChatUser, message, setMessage, inputActive} =
|
|
39
|
+
useChatUIControls();
|
|
40
|
+
const {sendChatMessage} = useChatMessages();
|
|
41
|
+
const onPress = () => {
|
|
42
|
+
if (!privateChatUser) {
|
|
43
|
+
sendChatMessage(message);
|
|
44
|
+
setMessage && setMessage('');
|
|
45
|
+
} else {
|
|
46
|
+
sendChatMessage(message, privateChatUser);
|
|
47
|
+
setMessage && setMessage('');
|
|
48
|
+
}
|
|
49
|
+
};
|
|
50
|
+
return props?.render ? (
|
|
51
|
+
props.render(onPress)
|
|
52
|
+
) : (
|
|
53
|
+
<TouchableOpacity style={[style.chatInputButton]} onPress={onPress}>
|
|
54
|
+
<ImageIcon
|
|
55
|
+
iconType="plain"
|
|
56
|
+
tintColor={
|
|
57
|
+
inputActive
|
|
58
|
+
? $config.PRIMARY_ACTION_BRAND_COLOR
|
|
59
|
+
: $config.SEMANTIC_NEUTRAL
|
|
60
|
+
}
|
|
61
|
+
name={'send'}
|
|
62
|
+
/>
|
|
63
|
+
</TouchableOpacity>
|
|
64
|
+
);
|
|
65
|
+
};
|
|
66
|
+
export interface ChatTextInputProps {
|
|
67
|
+
render?: (
|
|
68
|
+
message: string,
|
|
69
|
+
onChangeText: (text: string) => void,
|
|
70
|
+
onSubmitEditing: () => void,
|
|
71
|
+
chatMessageInputPlaceholder: string,
|
|
72
|
+
) => JSX.Element;
|
|
73
|
+
}
|
|
74
|
+
export const ChatTextInput = (props: ChatTextInputProps) => {
|
|
75
|
+
let chatInputRef = useRef(null);
|
|
76
|
+
const {privateChatUser, message, setMessage, chatType, inputActive} =
|
|
77
|
+
useChatUIControls();
|
|
78
|
+
const {sendChatMessage} = useChatMessages();
|
|
79
|
+
const {defaultContent} = useContent();
|
|
80
|
+
//commented for v1 release
|
|
81
|
+
// const chatMessageInputPlaceholder = useString(
|
|
82
|
+
// 'chatMessageInputPlaceholder',
|
|
83
|
+
// )();
|
|
84
|
+
const [name] = useUserName();
|
|
85
|
+
const groupChatInputPlaceHolder = useString(groupChatInputPlaceHolderText);
|
|
86
|
+
const privateChatInputPlaceHolder = useString(
|
|
87
|
+
privateChatInputPlaceHolderText,
|
|
88
|
+
);
|
|
89
|
+
|
|
90
|
+
const chatMessageInputPlaceholder =
|
|
91
|
+
chatType === ChatType.Private
|
|
92
|
+
? privateChatInputPlaceHolder(defaultContent[privateChatUser]?.name)
|
|
93
|
+
: groupChatInputPlaceHolder(name);
|
|
94
|
+
const onChangeText = (text: string) => setMessage(text);
|
|
95
|
+
const onSubmitEditing = () => {
|
|
96
|
+
if (!privateChatUser) {
|
|
97
|
+
sendChatMessage(message);
|
|
98
|
+
setMessage('');
|
|
99
|
+
} else {
|
|
100
|
+
sendChatMessage(message, privateChatUser);
|
|
101
|
+
setMessage('');
|
|
102
|
+
}
|
|
103
|
+
};
|
|
104
|
+
const {setInputActive} = useChatUIControls();
|
|
105
|
+
|
|
106
|
+
useEffect(() => {
|
|
107
|
+
setTimeout(() => {
|
|
108
|
+
if (isWebInternal()) {
|
|
109
|
+
chatInputRef?.current?.focus();
|
|
110
|
+
}
|
|
111
|
+
});
|
|
112
|
+
}, []);
|
|
113
|
+
|
|
114
|
+
return props?.render ? (
|
|
115
|
+
props.render(
|
|
116
|
+
message,
|
|
117
|
+
onChangeText,
|
|
118
|
+
onSubmitEditing,
|
|
119
|
+
chatMessageInputPlaceholder,
|
|
120
|
+
)
|
|
121
|
+
) : (
|
|
122
|
+
<BottomSheetTextInput
|
|
123
|
+
onFocus={() => setInputActive(true)}
|
|
124
|
+
onBlur={() => setInputActive(false)}
|
|
125
|
+
value={message}
|
|
126
|
+
onChangeText={onChangeText}
|
|
127
|
+
style={{
|
|
128
|
+
minHeight: 56,
|
|
129
|
+
borderRadius: 0,
|
|
130
|
+
borderBottomLeftRadius: 12,
|
|
131
|
+
borderWidth: 0,
|
|
132
|
+
color: $config.FONT_COLOR,
|
|
133
|
+
textAlign: 'left',
|
|
134
|
+
paddingVertical: 21,
|
|
135
|
+
paddingLeft: 20,
|
|
136
|
+
flex: 1,
|
|
137
|
+
alignSelf: 'center',
|
|
138
|
+
fontFamily: ThemeConfig.FontFamily.sansPro,
|
|
139
|
+
fontWeight: '400',
|
|
140
|
+
}}
|
|
141
|
+
blurOnSubmit={false}
|
|
142
|
+
onSubmitEditing={onSubmitEditing}
|
|
143
|
+
placeholder={chatMessageInputPlaceholder}
|
|
144
|
+
placeholderTextColor={
|
|
145
|
+
$config.FONT_COLOR + ThemeConfig.EmphasisPlus.disabled
|
|
146
|
+
}
|
|
147
|
+
autoCorrect={false}
|
|
148
|
+
/>
|
|
149
|
+
);
|
|
150
|
+
};
|
|
151
|
+
|
|
152
|
+
/**
|
|
153
|
+
* Input component for the Chat interface
|
|
154
|
+
*/
|
|
155
|
+
export const ChatInput = () => {
|
|
156
|
+
const {inputActive} = useChatUIControls();
|
|
157
|
+
return (
|
|
158
|
+
<View style={[style.inputView, inputActive ? style.inputActiveView : {}]}>
|
|
159
|
+
<ChatTextInput />
|
|
160
|
+
<ChatSendButton />
|
|
161
|
+
</View>
|
|
162
|
+
);
|
|
163
|
+
};
|
|
164
|
+
|
|
165
|
+
const style = StyleSheet.create({
|
|
166
|
+
inputActiveView: {
|
|
167
|
+
borderTopWidth: 1,
|
|
168
|
+
borderTopColor: $config.PRIMARY_ACTION_BRAND_COLOR,
|
|
169
|
+
},
|
|
170
|
+
inputView: {
|
|
171
|
+
flex: 1,
|
|
172
|
+
flexDirection: 'row',
|
|
173
|
+
backgroundColor: $config.CARD_LAYER_2_COLOR,
|
|
174
|
+
borderTopWidth: 1,
|
|
175
|
+
borderTopColor: 'transparent',
|
|
176
|
+
},
|
|
177
|
+
chatInputButton: {
|
|
178
|
+
flex: 0.1,
|
|
179
|
+
borderBottomRightRadius: 12,
|
|
180
|
+
alignSelf: 'center',
|
|
181
|
+
marginRight: 16,
|
|
182
|
+
},
|
|
183
|
+
});
|
|
184
|
+
export default ChatInput;
|