agora-appbuilder-core 4.0.30 → 4.0.31-beta-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/package.json +1 -1
- package/template/customization-api/sub-components.ts +1 -0
- package/template/defaultConfig.js +2 -2
- package/template/package.json +1 -1
- package/template/src/components/ChatContext.ts +3 -0
- package/template/src/components/Controls.tsx +80 -18
- package/template/src/components/Navbar.tsx +29 -1
- package/template/src/components/chat/chatConfigure.native.tsx +85 -25
- package/template/src/components/chat/chatConfigure.tsx +99 -9
- package/template/src/components/chat-messages/useChatMessages.tsx +32 -39
- package/template/src/components/chat-ui/useChatUIControls.tsx +21 -0
- package/template/src/components/precall/joinWaitingRoomBtn.tsx +25 -6
- package/template/src/components/room-info/useRoomInfo.tsx +12 -0
- package/template/src/pages/Create.tsx +26 -1
- package/template/src/pages/video-call/VideoCallMobileView.tsx +3 -2
- package/template/src/pages/video-call/VideoCallScreen.tsx +3 -1
- package/template/src/subComponents/ChatBubble.tsx +388 -110
- package/template/src/subComponents/ChatContainer.tsx +76 -53
- package/template/src/subComponents/ChatInput.native.tsx +93 -14
- package/template/src/subComponents/ChatInput.tsx +41 -7
- package/template/src/subComponents/caption/Caption.tsx +14 -2
- package/template/src/subComponents/caption/CaptionContainer.tsx +24 -3
- package/template/src/subComponents/caption/CaptionText.tsx +13 -1
- package/template/src/subComponents/chat/ChatActionMenu.tsx +40 -3
- package/template/src/subComponents/chat/ChatAttachment.native.tsx +4 -2
- package/template/src/subComponents/chat/ChatEmoji.native.tsx +181 -22
- package/template/src/subComponents/chat/ChatEmoji.tsx +4 -3
- package/template/src/subComponents/chat/ChatQuickActionsMenu.tsx +70 -34
- package/template/src/subComponents/chat/ChatSendButton.tsx +42 -1
- package/template/src/subComponents/chat/PinnedMessage.tsx +207 -0
- package/template/src/utils/useCreateRoom.ts +23 -4
- package/template/src/utils/useJoinRoom.ts +76 -23
|
@@ -43,11 +43,12 @@ interface ExtendedChatMessage extends ChatMessage {
|
|
|
43
43
|
attributes: {
|
|
44
44
|
file_ext?: string;
|
|
45
45
|
file_name?: string;
|
|
46
|
+
replyToMsgId?: string;
|
|
46
47
|
};
|
|
47
48
|
}
|
|
48
49
|
|
|
49
50
|
export const ChatAttachmentButton = (props: ChatAttachmentButtonProps) => {
|
|
50
|
-
const {privateChatUser, setUploadStatus} = useChatUIControls();
|
|
51
|
+
const {privateChatUser, setUploadStatus, replyToMsgId} = useChatUIControls();
|
|
51
52
|
const {sendChatSDKMessage} = useChatConfigure();
|
|
52
53
|
const {data} = useRoomInfo();
|
|
53
54
|
|
|
@@ -140,6 +141,7 @@ export const ChatAttachmentButton = (props: ChatAttachmentButtonProps) => {
|
|
|
140
141
|
file_name: result[0].name,
|
|
141
142
|
file_url: filePath,
|
|
142
143
|
from_platform: 'native',
|
|
144
|
+
replyToMsgId,
|
|
143
145
|
},
|
|
144
146
|
};
|
|
145
147
|
console.warn('chatOPtion', option);
|
|
@@ -166,8 +168,8 @@ export const ChatAttachmentButton = (props: ChatAttachmentButtonProps) => {
|
|
|
166
168
|
url: message.body?.remotePath,
|
|
167
169
|
ext: message.attributes?.file_ext,
|
|
168
170
|
fileName: message.attributes?.file_name,
|
|
171
|
+
replyToMsgId: message.attributes?.replyToMsgId,
|
|
169
172
|
};
|
|
170
|
-
console.warn('message data', messageData);
|
|
171
173
|
|
|
172
174
|
// this is local user messages
|
|
173
175
|
if (message.chatType === ChatMessageChatType.PeerChat) {
|
|
@@ -1,9 +1,11 @@
|
|
|
1
|
-
import {StyleSheet, Text, View} from 'react-native';
|
|
1
|
+
import {Button, StyleSheet, Text, TouchableOpacity, View} from 'react-native';
|
|
2
2
|
import React from 'react';
|
|
3
3
|
import {useChatUIControls} from '../../components/chat-ui/useChatUIControls';
|
|
4
4
|
import IconButton from '../../../src/atoms/IconButton';
|
|
5
|
-
|
|
6
|
-
import {
|
|
5
|
+
import {useChatConfigure} from '../../../src/components/chat/chatConfigure';
|
|
6
|
+
import {MoreMessageOptions} from './ChatQuickActionsMenu';
|
|
7
|
+
import {hexadecimalTransparency} from 'customization-api';
|
|
8
|
+
import EmojiPicker, {type EmojiType} from 'rn-emoji-keyboard';
|
|
7
9
|
|
|
8
10
|
export interface ChatEmojiButtonProps {
|
|
9
11
|
render?: (onPress: () => void) => JSX.Element;
|
|
@@ -32,7 +34,7 @@ export const ChatEmojiButton = (props: ChatEmojiButtonProps) => {
|
|
|
32
34
|
},
|
|
33
35
|
iconSize: 24,
|
|
34
36
|
name: 'chat_emoji',
|
|
35
|
-
tintColor: $config.
|
|
37
|
+
tintColor: $config.SEMANTIC_NEUTRAL,
|
|
36
38
|
}}
|
|
37
39
|
onPress={onPress}
|
|
38
40
|
/>
|
|
@@ -40,28 +42,150 @@ export const ChatEmojiButton = (props: ChatEmojiButtonProps) => {
|
|
|
40
42
|
);
|
|
41
43
|
};
|
|
42
44
|
|
|
43
|
-
export const ChatEmojiPicker = (
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
45
|
+
export const ChatEmojiPicker = ({
|
|
46
|
+
isEmojiPickerOpen,
|
|
47
|
+
setIsEmojiPickerOpen,
|
|
48
|
+
onEmojiSelect,
|
|
49
|
+
}) => {
|
|
50
|
+
const handleEmojiClick = ({emoji}) => {
|
|
51
|
+
onEmojiSelect(emoji);
|
|
47
52
|
};
|
|
48
53
|
return (
|
|
49
54
|
<View style={styles.emojiContainer} testID={'emoji-container'}>
|
|
50
|
-
<
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
$config.
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
55
|
+
<EmojiPicker
|
|
56
|
+
onEmojiSelected={handleEmojiClick}
|
|
57
|
+
open={isEmojiPickerOpen}
|
|
58
|
+
categoryPosition="top" // floating' | 'top' | 'bottom'
|
|
59
|
+
onClose={() => setIsEmojiPickerOpen(false)}
|
|
60
|
+
theme={{
|
|
61
|
+
backdrop:
|
|
62
|
+
$config.HARD_CODED_BLACK_COLOR + hexadecimalTransparency['60%'], // need design input
|
|
63
|
+
knob: $config.SECONDARY_ACTION_COLOR,
|
|
64
|
+
container: $config.CARD_LAYER_3_COLOR,
|
|
65
|
+
header: $config.FONT_COLOR,
|
|
66
|
+
category: {
|
|
67
|
+
icon: $config.SECONDARY_ACTION_COLOR,
|
|
68
|
+
iconActive: $config.SECONDARY_ACTION_COLOR, // need design input
|
|
69
|
+
container: $config.CARD_LAYER_2_COLOR,
|
|
70
|
+
containerActive: $config.PRIMARY_ACTION_BRAND_COLOR, // need design input
|
|
71
|
+
},
|
|
72
|
+
}}
|
|
73
|
+
/>
|
|
74
|
+
</View>
|
|
75
|
+
);
|
|
76
|
+
};
|
|
77
|
+
|
|
78
|
+
export const ReactionPicker = props => {
|
|
79
|
+
const {setMessage, showEmojiPicker, setShowEmojiPicker} = useChatUIControls();
|
|
80
|
+
const {addReaction} = useChatConfigure();
|
|
81
|
+
const {messageId, isLocal, userId, type, message, setIsHovered} = props;
|
|
82
|
+
|
|
83
|
+
// Controls the reactions to display in the reactions picker. Takes unified emoji ids
|
|
84
|
+
const reactions = [
|
|
85
|
+
{emoji: '❤️', unified: '2665-fe0f'},
|
|
86
|
+
{emoji: '👍', unified: '1f44d'},
|
|
87
|
+
{emoji: '🎉', unified: '1f389'},
|
|
88
|
+
{
|
|
89
|
+
emoji: '🤣',
|
|
90
|
+
unified: '1f923',
|
|
91
|
+
},
|
|
92
|
+
];
|
|
93
|
+
|
|
94
|
+
const handleReactionClick = emoji => {
|
|
95
|
+
addReaction(messageId, emoji);
|
|
96
|
+
setIsHovered(false);
|
|
97
|
+
};
|
|
98
|
+
|
|
99
|
+
return (
|
|
100
|
+
<View
|
|
101
|
+
style={[styles.reactionsContainer, isLocal ? {right: 0} : {left: 0}]}
|
|
102
|
+
testID={'reaction-container'}>
|
|
103
|
+
{reactions.map((emojiObject, index) => (
|
|
104
|
+
<React.Fragment key={emojiObject.unified}>
|
|
105
|
+
<TouchableOpacity
|
|
106
|
+
style={styles.emojiWrapper}
|
|
107
|
+
onPress={() => handleReactionClick(emojiObject.emoji)}>
|
|
108
|
+
<Text style={{fontSize: 16}}>{emojiObject.emoji}</Text>
|
|
109
|
+
</TouchableOpacity>
|
|
110
|
+
{index === reactions.length - 1 && (
|
|
111
|
+
<>
|
|
112
|
+
<CustomReactionPicker
|
|
113
|
+
isLocal={isLocal}
|
|
114
|
+
messageId={messageId}
|
|
115
|
+
setIsHovered={setIsHovered}
|
|
116
|
+
/>
|
|
117
|
+
|
|
118
|
+
<MoreMessageOptions
|
|
119
|
+
userId={userId}
|
|
120
|
+
isLocal={isLocal}
|
|
121
|
+
messageId={messageId}
|
|
122
|
+
type={type}
|
|
123
|
+
message={message}
|
|
124
|
+
setIsHovered={setIsHovered}
|
|
125
|
+
/>
|
|
126
|
+
</>
|
|
127
|
+
)}
|
|
128
|
+
</React.Fragment>
|
|
129
|
+
))}
|
|
130
|
+
</View>
|
|
131
|
+
);
|
|
132
|
+
};
|
|
133
|
+
|
|
134
|
+
export const CustomReactionPicker = ({isLocal, setIsHovered, messageId}) => {
|
|
135
|
+
const [isEmojiPickerOpen, setIsEmojiPickerOpen] = React.useState(false);
|
|
136
|
+
const {addReaction} = useChatConfigure();
|
|
137
|
+
const handleCustomReactionClick = (emoji: string) => {
|
|
138
|
+
addReaction(messageId, emoji);
|
|
139
|
+
setIsHovered(false);
|
|
140
|
+
};
|
|
141
|
+
|
|
142
|
+
return (
|
|
143
|
+
<View>
|
|
144
|
+
<IconButton
|
|
145
|
+
hoverEffect={false}
|
|
146
|
+
hoverEffectStyle={{
|
|
147
|
+
backgroundColor: $config.ICON_BG_COLOR,
|
|
148
|
+
borderRadius: 24,
|
|
149
|
+
}}
|
|
150
|
+
iconProps={{
|
|
151
|
+
iconType: 'plain',
|
|
152
|
+
base64: false,
|
|
153
|
+
iconContainerStyle: {
|
|
154
|
+
padding: 2,
|
|
155
|
+
marginHorizontal: 4,
|
|
156
|
+
},
|
|
157
|
+
iconSize: 20,
|
|
158
|
+
name: 'add_reaction',
|
|
159
|
+
tintColor:
|
|
160
|
+
$config.SECONDARY_ACTION_COLOR + hexadecimalTransparency['75%'],
|
|
161
|
+
}}
|
|
162
|
+
onPress={() => {
|
|
163
|
+
setIsEmojiPickerOpen(true);
|
|
164
|
+
}}
|
|
64
165
|
/>
|
|
166
|
+
{isEmojiPickerOpen ? (
|
|
167
|
+
<ChatEmojiPicker
|
|
168
|
+
isEmojiPickerOpen={isEmojiPickerOpen}
|
|
169
|
+
setIsEmojiPickerOpen={setIsEmojiPickerOpen}
|
|
170
|
+
onEmojiSelect={handleCustomReactionClick}
|
|
171
|
+
/>
|
|
172
|
+
) : (
|
|
173
|
+
<></>
|
|
174
|
+
)}
|
|
175
|
+
{/* {isEmojiPickerOpen && (
|
|
176
|
+
<CustomEmojiPicker
|
|
177
|
+
containerStyle={[
|
|
178
|
+
styles.customEmojiPickerContainer,
|
|
179
|
+
isLocal ? {right: 0} : {left: 0},
|
|
180
|
+
]}
|
|
181
|
+
isReactionPicker={true}
|
|
182
|
+
handleEmojiClick={handleCustomReactionClick}
|
|
183
|
+
handleEmojiClose={() => {
|
|
184
|
+
setIsEmojiPickerOpen(false);
|
|
185
|
+
setIsHovered(false);
|
|
186
|
+
}}
|
|
187
|
+
/>
|
|
188
|
+
)} */}
|
|
65
189
|
</View>
|
|
66
190
|
);
|
|
67
191
|
};
|
|
@@ -72,4 +196,39 @@ const styles = StyleSheet.create({
|
|
|
72
196
|
flexDirection: 'row',
|
|
73
197
|
position: 'relative',
|
|
74
198
|
},
|
|
199
|
+
emojiWrapper: {
|
|
200
|
+
width: 20,
|
|
201
|
+
height: 20,
|
|
202
|
+
marginHorizontal: 5,
|
|
203
|
+
justifyContent: 'center',
|
|
204
|
+
alignItems: 'center',
|
|
205
|
+
display: 'flex',
|
|
206
|
+
},
|
|
207
|
+
reactionsContainer: {
|
|
208
|
+
flexDirection: 'row',
|
|
209
|
+
position: 'absolute',
|
|
210
|
+
bottom: '100%',
|
|
211
|
+
padding: 4,
|
|
212
|
+
justifyContent: 'space-evenly',
|
|
213
|
+
alignItems: 'center',
|
|
214
|
+
backgroundColor: $config.CARD_LAYER_4_COLOR,
|
|
215
|
+
borderWidth: 1,
|
|
216
|
+
borderColor: $config.CARD_LAYER_5_COLOR + hexadecimalTransparency['25%'],
|
|
217
|
+
borderRadius: 4,
|
|
218
|
+
zIndex: 1,
|
|
219
|
+
shadowColor: $config.HARD_CODED_BLACK_COLOR,
|
|
220
|
+
shadowOffset: {
|
|
221
|
+
width: 0,
|
|
222
|
+
height: 4,
|
|
223
|
+
},
|
|
224
|
+
shadowOpacity: 0.35,
|
|
225
|
+
shadowRadius: 10,
|
|
226
|
+
elevation: 5,
|
|
227
|
+
},
|
|
228
|
+
customEmojiPickerContainer: {
|
|
229
|
+
position: 'absolute',
|
|
230
|
+
top: 30,
|
|
231
|
+
right: 0,
|
|
232
|
+
width: 350,
|
|
233
|
+
},
|
|
75
234
|
});
|
|
@@ -157,7 +157,7 @@ const CustomEmojiPicker = ({
|
|
|
157
157
|
);
|
|
158
158
|
};
|
|
159
159
|
|
|
160
|
-
const
|
|
160
|
+
export const CustomReactionPicker = ({isLocal, setIsHovered, messageId}) => {
|
|
161
161
|
const [isEmojiPickerOpen, setIsEmojiPickerOpen] = React.useState(false);
|
|
162
162
|
const {addReaction} = useChatConfigure();
|
|
163
163
|
const handleCustomReactionClick = (emojiObject: {
|
|
@@ -181,7 +181,7 @@ const CustomReactioPicker = ({isLocal, setIsHovered, messageId}) => {
|
|
|
181
181
|
iconType: 'plain',
|
|
182
182
|
base64: false,
|
|
183
183
|
iconContainerStyle: {
|
|
184
|
-
padding:
|
|
184
|
+
padding: 2,
|
|
185
185
|
marginHorizontal: 4,
|
|
186
186
|
},
|
|
187
187
|
iconSize: 20,
|
|
@@ -245,7 +245,7 @@ export const ReactionPicker = props => {
|
|
|
245
245
|
</TouchableOpacity>
|
|
246
246
|
{index === reactions.length - 1 && (
|
|
247
247
|
<>
|
|
248
|
-
<
|
|
248
|
+
<CustomReactionPicker
|
|
249
249
|
isLocal={isLocal}
|
|
250
250
|
messageId={messageId}
|
|
251
251
|
setIsHovered={setIsHovered}
|
|
@@ -256,6 +256,7 @@ export const ReactionPicker = props => {
|
|
|
256
256
|
messageId={messageId}
|
|
257
257
|
type={type}
|
|
258
258
|
message={message}
|
|
259
|
+
setIsHovered={setIsHovered}
|
|
259
260
|
/>
|
|
260
261
|
</>
|
|
261
262
|
)}
|
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
import {StyleSheet, Text, useWindowDimensions, View} from 'react-native';
|
|
2
2
|
import React from 'react';
|
|
3
3
|
import ActionMenu, {ActionMenuItem} from '../../../src/atoms/ActionMenu';
|
|
4
|
-
import {
|
|
4
|
+
import {
|
|
5
|
+
calculatePosition,
|
|
6
|
+
isWebInternal,
|
|
7
|
+
trimText,
|
|
8
|
+
} from '../../../src/utils/common';
|
|
5
9
|
import IconButton from '../../../src/atoms/IconButton';
|
|
6
10
|
import hexadecimalTransparency from '../../../src/utils/hexadecimalTransparency';
|
|
7
11
|
import {
|
|
@@ -37,6 +41,8 @@ interface ChatQuickActionsMenuProps {
|
|
|
37
41
|
messageId?: string;
|
|
38
42
|
type: ChatMessageType;
|
|
39
43
|
message: string;
|
|
44
|
+
showReplyOption?: boolean;
|
|
45
|
+
setIsHovered?: (isHover: boolean) => void;
|
|
40
46
|
}
|
|
41
47
|
|
|
42
48
|
const ChatQuickActionsMenu = (props: ChatQuickActionsMenuProps) => {
|
|
@@ -49,17 +55,28 @@ const ChatQuickActionsMenu = (props: ChatQuickActionsMenuProps) => {
|
|
|
49
55
|
messageId,
|
|
50
56
|
type,
|
|
51
57
|
message: msg,
|
|
58
|
+
showReplyOption,
|
|
59
|
+
setIsHovered,
|
|
52
60
|
} = props;
|
|
53
61
|
const [isPosCalculated, setIsPosCalculated] = React.useState(false);
|
|
54
62
|
const {width: globalWidth, height: globalHeight} = useWindowDimensions();
|
|
55
63
|
const [modalPosition, setModalPosition] = React.useState({});
|
|
56
|
-
const {
|
|
57
|
-
|
|
64
|
+
const {
|
|
65
|
+
setChatType,
|
|
66
|
+
setPrivateChatUser,
|
|
67
|
+
showEmojiPicker,
|
|
68
|
+
privateChatUser,
|
|
69
|
+
replyToMsgId,
|
|
70
|
+
pinMsgId,
|
|
71
|
+
setPinMsgId,
|
|
72
|
+
setReplyToMsgId,
|
|
73
|
+
pinnedByUser,
|
|
74
|
+
} = useChatUIControls();
|
|
58
75
|
const {removeMessageFromPrivateStore, removeMessageFromStore} =
|
|
59
76
|
useChatMessages();
|
|
60
77
|
const [showDeleteMessageModal, setShowDeleteMessageModal] =
|
|
61
78
|
React.useState(false);
|
|
62
|
-
const {deleteAttachment} = useChatConfigure();
|
|
79
|
+
const {deleteAttachment, pinMessage, unPinMessage} = useChatConfigure();
|
|
63
80
|
|
|
64
81
|
const actionMenuitems: ActionMenuItem[] = [];
|
|
65
82
|
const {defaultContent} = useContent();
|
|
@@ -69,16 +86,21 @@ const ChatQuickActionsMenu = (props: ChatQuickActionsMenuProps) => {
|
|
|
69
86
|
} = useRoomInfo();
|
|
70
87
|
|
|
71
88
|
const groupID = chat.group_id;
|
|
89
|
+
const isGroupOwner = chat.is_group_owner;
|
|
90
|
+
const isMsgPinned = pinMsgId === messageId;
|
|
72
91
|
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
92
|
+
showReplyOption &&
|
|
93
|
+
actionMenuitems.push({
|
|
94
|
+
icon: 'reply',
|
|
95
|
+
iconColor: $config.SECONDARY_ACTION_COLOR,
|
|
96
|
+
textColor: $config.FONT_COLOR,
|
|
97
|
+
title: 'Reply',
|
|
98
|
+
onPress: () => {
|
|
99
|
+
setReplyToMsgId(messageId);
|
|
100
|
+
setActionMenuVisible(false);
|
|
101
|
+
setIsHovered(false);
|
|
102
|
+
},
|
|
103
|
+
});
|
|
82
104
|
|
|
83
105
|
const cancelTxt = useString(cancelText)();
|
|
84
106
|
const cancelLabel =
|
|
@@ -108,9 +130,11 @@ const ChatQuickActionsMenu = (props: ChatQuickActionsMenuProps) => {
|
|
|
108
130
|
iconSize: 14,
|
|
109
131
|
title: 'Private Reply',
|
|
110
132
|
onPress: () => {
|
|
133
|
+
setReplyToMsgId(messageId);
|
|
111
134
|
setPrivateChatUser(userId);
|
|
112
135
|
setChatType(ChatType.Private);
|
|
113
136
|
setActionMenuVisible(false);
|
|
137
|
+
setIsHovered(false);
|
|
114
138
|
},
|
|
115
139
|
});
|
|
116
140
|
|
|
@@ -123,41 +147,50 @@ const ChatQuickActionsMenu = (props: ChatQuickActionsMenuProps) => {
|
|
|
123
147
|
onPress: () => {
|
|
124
148
|
Clipboard.setString(msg);
|
|
125
149
|
setActionMenuVisible(false);
|
|
150
|
+
setIsHovered(false);
|
|
151
|
+
},
|
|
152
|
+
});
|
|
153
|
+
|
|
154
|
+
// native pin message to be released with 1.3.0 chat sdk
|
|
155
|
+
isWebInternal() &&
|
|
156
|
+
chatType == SDKChatType.GROUP_CHAT &&
|
|
157
|
+
actionMenuitems.push({
|
|
158
|
+
icon: isMsgPinned ? 'unpin-outlined' : 'pin-outlined',
|
|
159
|
+
iconColor: $config.SECONDARY_ACTION_COLOR,
|
|
160
|
+
textColor: $config.FONT_COLOR,
|
|
161
|
+
title: isMsgPinned ? 'UnPin Message' : 'Pin Message',
|
|
162
|
+
onPress: () => {
|
|
163
|
+
isMsgPinned ? unPinMessage(messageId) : pinMessage(messageId);
|
|
164
|
+
setActionMenuVisible(false);
|
|
165
|
+
setIsHovered(false);
|
|
126
166
|
},
|
|
127
167
|
});
|
|
128
|
-
// actionMenuitems.push({
|
|
129
|
-
// icon: 'pin-outlined',
|
|
130
|
-
// iconColor: $config.SECONDARY_ACTION_COLOR,
|
|
131
|
-
// textColor: $config.FONT_COLOR,
|
|
132
|
-
// title: 'Pin Message',
|
|
133
|
-
// onPress: () => {
|
|
134
|
-
// setActionMenuVisible(false);
|
|
135
|
-
// },
|
|
136
|
-
// });
|
|
137
168
|
|
|
138
|
-
//
|
|
139
|
-
//
|
|
140
|
-
//
|
|
141
|
-
//
|
|
142
|
-
//
|
|
143
|
-
//
|
|
144
|
-
//
|
|
145
|
-
//
|
|
146
|
-
//
|
|
147
|
-
//
|
|
169
|
+
//Only Chat Group Owner and Admin can block a user
|
|
170
|
+
// isGroupOwner &&
|
|
171
|
+
// actionMenuitems.push({
|
|
172
|
+
// icon: 'block_user',
|
|
173
|
+
// iconColor: $config.SEMANTIC_ERROR,
|
|
174
|
+
// textColor: $config.SEMANTIC_ERROR,
|
|
175
|
+
// title: 'Block User',
|
|
176
|
+
// onPress: () => {
|
|
177
|
+
// // block user can be done only by group owner and admins
|
|
178
|
+
// setActionMenuVisible(false);
|
|
179
|
+
// },
|
|
180
|
+
// });
|
|
148
181
|
|
|
149
182
|
actionMenuitems.push({
|
|
150
183
|
icon: 'delete',
|
|
151
184
|
iconColor: $config.SEMANTIC_ERROR,
|
|
152
185
|
textColor: $config.SEMANTIC_ERROR,
|
|
153
186
|
title: 'Delete Message',
|
|
187
|
+
disabled: isMsgPinned,
|
|
154
188
|
onPress: () => {
|
|
155
189
|
if (isLocal) {
|
|
156
190
|
// confirm dialog : user is deleting for all
|
|
157
191
|
setShowDeleteMessageModal(true);
|
|
158
192
|
//deleteAttachment(msgId, recallFromUser.toString(), chatType);
|
|
159
193
|
} else {
|
|
160
|
-
debugger;
|
|
161
194
|
if (chatType === SDKChatType.GROUP_CHAT) {
|
|
162
195
|
removeMessageFromStore(messageId, isLocal);
|
|
163
196
|
}
|
|
@@ -238,6 +271,8 @@ export const MoreMessageOptions = ({
|
|
|
238
271
|
messageId,
|
|
239
272
|
type,
|
|
240
273
|
message,
|
|
274
|
+
showReplyOption = true,
|
|
275
|
+
setIsHovered,
|
|
241
276
|
}) => {
|
|
242
277
|
const moreIconRef = React.useRef(null);
|
|
243
278
|
const [messageOptionsMenuVisible, setMessageOptionsMenuVisible] =
|
|
@@ -256,6 +291,8 @@ export const MoreMessageOptions = ({
|
|
|
256
291
|
messageId={messageId}
|
|
257
292
|
type={type}
|
|
258
293
|
message={message}
|
|
294
|
+
showReplyOption={showReplyOption}
|
|
295
|
+
setIsHovered={setIsHovered}
|
|
259
296
|
/>
|
|
260
297
|
|
|
261
298
|
<View
|
|
@@ -278,7 +315,6 @@ export const MoreMessageOptions = ({
|
|
|
278
315
|
borderRadius: 4,
|
|
279
316
|
padding: 2,
|
|
280
317
|
}}
|
|
281
|
-
containerStyle={{margin: 4}}
|
|
282
318
|
iconProps={{
|
|
283
319
|
iconType: 'plain',
|
|
284
320
|
name: 'more-menu',
|
|
@@ -12,6 +12,7 @@ import {useRoomInfo} from 'customization-api';
|
|
|
12
12
|
import {
|
|
13
13
|
ChatMessageType,
|
|
14
14
|
SDKChatType,
|
|
15
|
+
useChatMessages,
|
|
15
16
|
} from '../../components/chat-messages/useChatMessages';
|
|
16
17
|
import {useString} from '../../utils/useString';
|
|
17
18
|
import {
|
|
@@ -21,6 +22,7 @@ import {
|
|
|
21
22
|
} from '../../language/default-labels/videoCallScreenLabels';
|
|
22
23
|
import {isMobileUA, isWeb} from '../../utils/common';
|
|
23
24
|
import Toast from '../../../react-native-toast-message';
|
|
25
|
+
import {ChatMessageChatType} from 'react-native-agora-chat';
|
|
24
26
|
|
|
25
27
|
export interface ChatSendButtonProps {
|
|
26
28
|
render?: (onPress: () => void) => JSX.Element;
|
|
@@ -41,6 +43,10 @@ export const handleChatSend = ({
|
|
|
41
43
|
toastHeadingSize,
|
|
42
44
|
errorSubHeadingSize,
|
|
43
45
|
_resetTextareaHeight,
|
|
46
|
+
replyToMsgId,
|
|
47
|
+
setReplyToMsgId,
|
|
48
|
+
addMessageToStore,
|
|
49
|
+
addMessageToPrivateStore,
|
|
44
50
|
}) => {
|
|
45
51
|
const isAllFilesUploaded =
|
|
46
52
|
uploadedFiles.length > 0 &&
|
|
@@ -76,9 +82,35 @@ export const handleChatSend = ({
|
|
|
76
82
|
to: selectedUserId ? selectedUserId.toString() : groupID,
|
|
77
83
|
ext: {
|
|
78
84
|
from_platform: isWeb() ? 'web' : 'native',
|
|
85
|
+
replyToMsgId: replyToMsgId,
|
|
79
86
|
},
|
|
80
87
|
};
|
|
81
|
-
|
|
88
|
+
const onProgress = (localMsgId: string, progress: number) => {
|
|
89
|
+
console.warn('chat msg in progress', progress);
|
|
90
|
+
};
|
|
91
|
+
const onError = (localMsgId: string, error: any) => {
|
|
92
|
+
console.warn('chat msg in error', error);
|
|
93
|
+
};
|
|
94
|
+
const onSuccess = (message: any) => {
|
|
95
|
+
console.warn('chat msg in success', message);
|
|
96
|
+
// Text message added here , attachments are added in ChatAttachment.native
|
|
97
|
+
const messageData = {
|
|
98
|
+
msg: option.msg.replace(/^(\n)+|(\n)+$/g, ''),
|
|
99
|
+
createdTimestamp: message.localTime,
|
|
100
|
+
msgId: message.msgId,
|
|
101
|
+
isDeleted: false,
|
|
102
|
+
type: message.body.type,
|
|
103
|
+
replyToMsgId: message.attributes?.replyToMsgId,
|
|
104
|
+
};
|
|
105
|
+
console.warn('message data', messageData);
|
|
106
|
+
// this is local user messages
|
|
107
|
+
if (message.chatType === ChatMessageChatType.PeerChat) {
|
|
108
|
+
addMessageToPrivateStore(Number(message.to), messageData, true);
|
|
109
|
+
} else {
|
|
110
|
+
addMessageToStore(Number(message.from), messageData);
|
|
111
|
+
}
|
|
112
|
+
};
|
|
113
|
+
sendChatSDKMessage(option, {onProgress, onError, onSuccess});
|
|
82
114
|
};
|
|
83
115
|
|
|
84
116
|
if (uploadedFiles.length > 0) {
|
|
@@ -106,6 +138,7 @@ export const handleChatSend = ({
|
|
|
106
138
|
file_name,
|
|
107
139
|
from_platform: isWeb() ? 'web' : 'native',
|
|
108
140
|
msg: uploadedFiles.length === 1 ? message : '',
|
|
141
|
+
replyToMsgId: replyToMsgId,
|
|
109
142
|
},
|
|
110
143
|
};
|
|
111
144
|
sendChatSDKMessage(option);
|
|
@@ -120,6 +153,7 @@ export const handleChatSend = ({
|
|
|
120
153
|
}
|
|
121
154
|
|
|
122
155
|
setMessage && setMessage('');
|
|
156
|
+
setReplyToMsgId('');
|
|
123
157
|
setInputHeight && setInputHeight(MIN_HEIGHT);
|
|
124
158
|
setUploadedFiles && setUploadedFiles(prev => []);
|
|
125
159
|
isWeb() && setShowEmojiPicker(false);
|
|
@@ -128,6 +162,7 @@ export const handleChatSend = ({
|
|
|
128
162
|
const ChatSendButton = (props: ChatSendButtonProps) => {
|
|
129
163
|
const {sendChatSDKMessage} = useChatConfigure();
|
|
130
164
|
const {setShowEmojiPicker} = useChatUIControls();
|
|
165
|
+
const {addMessageToPrivateStore, addMessageToStore} = useChatMessages();
|
|
131
166
|
const {
|
|
132
167
|
privateChatUser: selectedUserId,
|
|
133
168
|
message,
|
|
@@ -138,6 +173,8 @@ const ChatSendButton = (props: ChatSendButtonProps) => {
|
|
|
138
173
|
setUploadedFiles,
|
|
139
174
|
setInputHeight,
|
|
140
175
|
_resetTextareaHeight,
|
|
176
|
+
replyToMsgId,
|
|
177
|
+
setReplyToMsgId,
|
|
141
178
|
} = useChatUIControls();
|
|
142
179
|
|
|
143
180
|
const {data} = useRoomInfo();
|
|
@@ -166,6 +203,10 @@ const ChatSendButton = (props: ChatSendButtonProps) => {
|
|
|
166
203
|
toastHeadingSize,
|
|
167
204
|
errorSubHeadingSize,
|
|
168
205
|
_resetTextareaHeight,
|
|
206
|
+
replyToMsgId,
|
|
207
|
+
setReplyToMsgId,
|
|
208
|
+
addMessageToPrivateStore,
|
|
209
|
+
addMessageToStore,
|
|
169
210
|
});
|
|
170
211
|
|
|
171
212
|
return props?.render ? (
|