agora-appbuilder-core 4.0.31-beta-1 → 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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agora-appbuilder-core",
3
- "version": "4.0.31-beta-1",
3
+ "version": "4.0.31-beta-2",
4
4
  "description": "React Native template for RTE app builder",
5
5
  "main": "index.js",
6
6
  "files": [
@@ -604,6 +604,12 @@ const MoreButton = (props: {fields: ToolbarMoreButtonDefaultFields}) => {
604
604
  });
605
605
 
606
606
  if ($config.CHAT) {
607
+ //disable chat button when BE sends error on chat
608
+ const ChatError =
609
+ data?.chat?.error &&
610
+ (data?.chat?.error?.code || data?.chat?.error?.message)
611
+ ? true
612
+ : false;
607
613
  actionMenuitems.push({
608
614
  hide: w => {
609
615
  return w >= BREAKPOINTS.lg ? true : false;
@@ -615,9 +621,32 @@ const MoreButton = (props: {fields: ToolbarMoreButtonDefaultFields}) => {
615
621
  textColor: $config.FONT_COLOR,
616
622
  title: chatLabel,
617
623
  onPress: () => {
618
- setActionMenuVisible(false);
619
- setChatType(ChatType.Group);
620
- setSidePanel(SidePanelType.Chat);
624
+ if (ChatError) {
625
+ setActionMenuVisible(false);
626
+ Toast.show({
627
+ leadingIconName: 'alert',
628
+ type: 'error',
629
+ text1: 'Failed to enable Chat Service.',
630
+ text2: data?.chat?.error?.message,
631
+ visibilityTime: 1000 * 10,
632
+ primaryBtn: null,
633
+ secondaryBtn: null,
634
+ leadingIcon: null,
635
+ });
636
+ logger.error(
637
+ LogSource.Internals,
638
+ 'JOIN_MEETING',
639
+ 'Failed to enable Chat Service',
640
+ {
641
+ message: data?.chat?.error?.message,
642
+ code: data?.chat?.error?.code,
643
+ },
644
+ );
645
+ } else {
646
+ setActionMenuVisible(false);
647
+ setChatType(ChatType.Group);
648
+ setSidePanel(SidePanelType.Chat);
649
+ }
621
650
  },
622
651
  });
623
652
  }
@@ -98,6 +98,7 @@ export interface messageInterface {
98
98
  ext?: string;
99
99
  reactions?: Reaction[];
100
100
  replyToMsgId?: string;
101
+ hide?: boolean;
101
102
  }
102
103
 
103
104
  export enum SDKChatType {
@@ -346,6 +347,7 @@ const ChatMessagesProvider = (props: ChatMessagesProviderProps) => {
346
347
  ext: body?.ext,
347
348
  fileName: body?.fileName,
348
349
  replyToMsgId: body?.replyToMsgId,
350
+ hide: false,
349
351
  },
350
352
  ];
351
353
  });
@@ -373,6 +375,7 @@ const ChatMessagesProvider = (props: ChatMessagesProviderProps) => {
373
375
  ext: body?.ext,
374
376
  fileName: body?.fileName,
375
377
  replyToMsgId: body?.replyToMsgId,
378
+ hide: false,
376
379
  },
377
380
  ])
378
381
  : (newState = {
@@ -390,6 +393,7 @@ const ChatMessagesProvider = (props: ChatMessagesProviderProps) => {
390
393
  ext: body?.ext,
391
394
  fileName: body?.fileName,
392
395
  replyToMsgId: body?.replyToMsgId,
396
+ hide: false,
393
397
  },
394
398
  ],
395
399
  });
@@ -398,56 +402,40 @@ const ChatMessagesProvider = (props: ChatMessagesProviderProps) => {
398
402
  };
399
403
 
400
404
  const removeMessageFromStore = (msgID, isMsgRecalled) => {
401
- console.warn('msg delete native', msgID);
402
405
  setMessageStore(prev => {
403
- if (isMsgRecalled) {
404
- const recalledMsgIndex = prev.findIndex(msg => msg.msgId === msgID);
405
- if (recalledMsgIndex !== -1) {
406
- const updatedMessages = [...prev];
407
- updatedMessages[recalledMsgIndex].isDeleted = true;
408
- return updatedMessages;
409
- } else {
410
- return prev;
411
- }
412
- } else {
413
- return prev.filter(msg => msg.msgId !== msgID);
414
- }
406
+ const recalledMsgIndex = prev.findIndex(msg => msg.msgId === msgID);
407
+ if (recalledMsgIndex === -1) return prev;
408
+
409
+ const updatedMessages = [...prev];
410
+ updatedMessages[recalledMsgIndex][isMsgRecalled ? 'isDeleted' : 'hide'] =
411
+ true;
412
+ return updatedMessages;
415
413
  });
416
414
  };
417
415
 
418
- // const removeMessageFromPrivateStore = (msgID, isMsgRecalled) => {
419
- // setPrivateMessageStore(prev => {
420
- // const state = {...prev};
421
- // const filteredData = prev[localUid].filter(msg => msg.msgId !== msgID);
422
- // const newState = {...state, [localUid]: filteredData};
423
- // return {...newState};
424
- // });
425
- // };
426
-
427
416
  const removeMessageFromPrivateStore = (msgID, isMsgRecalled) => {
428
417
  setPrivateMessageStore(state => {
429
418
  const newState = {...state};
430
419
 
431
- if (isMsgRecalled) {
432
- Object.keys(newState).forEach(uid => {
433
- const messages = newState[uid];
434
- if (messages) {
435
- const recalledMsg = messages.find(msg => msg.msgId === msgID);
436
- if (recalledMsg) {
437
- recalledMsg.isDeleted = true;
420
+ Object.keys(newState).forEach(uid => {
421
+ const messages = newState[uid];
422
+ if (messages) {
423
+ const recalledMsgIndex = messages.findIndex(
424
+ msg => msg.msgId === msgID,
425
+ );
426
+ if (recalledMsgIndex !== -1) {
427
+ const updatedMessages = [...messages];
428
+ if (isMsgRecalled) {
429
+ updatedMessages[recalledMsgIndex].isDeleted = true;
430
+ } else {
431
+ updatedMessages[recalledMsgIndex].hide = true;
438
432
  }
433
+ newState[uid] = updatedMessages;
439
434
  }
440
- });
441
- } else {
442
- Object.keys(newState).forEach(uid => {
443
- const messages = newState[uid];
444
- if (messages) {
445
- newState[uid] = messages.filter(msg => msg.msgId !== msgID);
446
- }
447
- });
448
- }
435
+ }
436
+ });
449
437
 
450
- return {...newState};
438
+ return newState;
451
439
  });
452
440
  };
453
441
 
@@ -132,12 +132,31 @@ const JoinWaitingRoomBtn = (props: PreCallJoinWaitingRoomBtnProps) => {
132
132
  token: mainUser.rtc,
133
133
  screenShareToken: screenShare.rtc,
134
134
  screenShareUid: screenShare.uid,
135
- whiteboard,
136
- chat: {
137
- user_token: chat?.userToken,
138
- group_id: chat?.groupId,
139
- is_group_owner: chat?.isGroupOwner,
140
- },
135
+ whiteboard: whiteboard?.error
136
+ ? {
137
+ room_token: '',
138
+ room_uuid: '',
139
+ error: {
140
+ code: whiteboard?.error?.code,
141
+ message: whiteboard?.error?.message,
142
+ },
143
+ }
144
+ : whiteboard,
145
+ chat: chat?.error
146
+ ? {
147
+ user_token: '',
148
+ group_id: '',
149
+ is_group_owner: false,
150
+ error: {
151
+ code: chat?.error?.code,
152
+ message: chat?.error?.message,
153
+ },
154
+ }
155
+ : {
156
+ user_token: chat?.userToken,
157
+ group_id: chat?.groupId,
158
+ is_group_owner: chat?.isGroupOwner,
159
+ },
141
160
  },
142
161
  };
143
162
  });
@@ -163,7 +163,8 @@ const Create = () => {
163
163
  Toast.show({
164
164
  leadingIconName: 'alert',
165
165
  type: 'error',
166
- text1: data?.pstn?.error?.message,
166
+ text1: 'Failed to enable PSTN Service',
167
+ text2: data?.pstn?.error?.message,
167
168
  visibilityTime: 1000 * 10,
168
169
  primaryBtn: null,
169
170
  secondaryBtn: null,
@@ -200,7 +200,7 @@ export const ReplyMessageBubble = ({
200
200
  {fileName + ' ' + text}
201
201
  </Text>
202
202
  ) : (
203
- <Text style={style.messageStyle}>{text}</Text>
203
+ <Text style={[style.messageStyle, {maxWidth: 265}]}>{text}</Text>
204
204
  )}
205
205
  </View>
206
206
  </View>
@@ -797,6 +797,7 @@ const style = StyleSheet.create({
797
797
  fontSize: ThemeConfig.FontSize.small,
798
798
  lineHeight: ThemeConfig.FontSize.small * 1.45,
799
799
  color: $config.FONT_COLOR,
800
+ flexWrap: 'wrap',
800
801
  },
801
802
  replyMessageStyle: {
802
803
  fontFamily: ThemeConfig.FontFamily.sansPro,
@@ -253,36 +253,38 @@ const ChatContainer = (props?: {
253
253
  ) : (
254
254
  <></>
255
255
  )}
256
- <ChatBubbleComponent
257
- isLocal={localUid === message.uid}
258
- isSameUser={
259
- index !== 0 && messageStore[index - 1].uid === message.uid
260
- ? true
261
- : false
262
- }
263
- previousMessageCreatedTimestamp={
264
- index !== 0
265
- ? (messageStore[index - 1]
266
- .createdTimestamp as unknown as string)
267
- : ''
268
- }
269
- message={message.msg}
270
- createdTimestamp={message.createdTimestamp}
271
- updatedTimestamp={message.updatedTimestamp}
272
- uid={message.uid}
273
- key={message.msgId}
274
- msgId={message.msgId}
275
- isDeleted={message.isDeleted}
276
- type={message.type}
277
- url={message?.url}
278
- thumb={message?.thumb}
279
- fileName={message?.fileName}
280
- ext={message?.ext}
281
- reactions={message?.reactions}
282
- scrollOffset={scrollOffset}
283
- replyToMsgId={message?.replyToMsgId}
284
- isLastMsg={messageStore.length - 1 === index}
285
- />
256
+ {!message?.hide ? (
257
+ <ChatBubbleComponent
258
+ isLocal={localUid === message.uid}
259
+ isSameUser={
260
+ index !== 0 && messageStore[index - 1].uid === message.uid
261
+ ? true
262
+ : false
263
+ }
264
+ previousMessageCreatedTimestamp={
265
+ index !== 0
266
+ ? (messageStore[index - 1]
267
+ .createdTimestamp as unknown as string)
268
+ : ''
269
+ }
270
+ message={message.msg}
271
+ createdTimestamp={message.createdTimestamp}
272
+ updatedTimestamp={message.updatedTimestamp}
273
+ uid={message.uid}
274
+ key={message.msgId}
275
+ msgId={message.msgId}
276
+ isDeleted={message.isDeleted}
277
+ type={message.type}
278
+ url={message?.url}
279
+ thumb={message?.thumb}
280
+ fileName={message?.fileName}
281
+ ext={message?.ext}
282
+ reactions={message?.reactions}
283
+ scrollOffset={scrollOffset}
284
+ replyToMsgId={message?.replyToMsgId}
285
+ isLastMsg={messageStore.length - 1 === index}
286
+ />
287
+ ) : null}
286
288
  {messageStore?.length - 1 === index ? (
287
289
  <Spacer size={10} />
288
290
  ) : (
@@ -320,33 +322,36 @@ const ChatContainer = (props?: {
320
322
  ) : (
321
323
  <></>
322
324
  )}
323
- <ChatBubbleComponent
324
- isLocal={localUid === message.uid}
325
- isSameUser={
326
- index !== 0 &&
327
- privateMessageStore[privateChatUser][index - 1].uid ===
328
- message.uid
329
- ? true
330
- : false
331
- }
332
- message={message.msg}
333
- createdTimestamp={message.createdTimestamp}
334
- updatedTimestamp={message.updatedTimestamp}
335
- uid={message.uid}
336
- key={message.msgId}
337
- msgId={message.msgId}
338
- isDeleted={message.isDeleted}
339
- type={message.type}
340
- url={message?.url}
341
- thumb={message?.thumb}
342
- fileName={message?.fileName}
343
- ext={message?.ext}
344
- reactions={message?.reactions}
345
- replyToMsgId={message?.replyToMsgId}
346
- isLastMsg={
347
- privateMessageStore[privateChatUser].length - 1 === index
348
- }
349
- />
325
+ {!message?.hide ? (
326
+ <ChatBubbleComponent
327
+ isLocal={localUid === message.uid}
328
+ isSameUser={
329
+ index !== 0 &&
330
+ privateMessageStore[privateChatUser][index - 1].uid ===
331
+ message.uid
332
+ ? true
333
+ : false
334
+ }
335
+ message={message.msg}
336
+ createdTimestamp={message.createdTimestamp}
337
+ updatedTimestamp={message.updatedTimestamp}
338
+ uid={message.uid}
339
+ key={message.msgId}
340
+ msgId={message.msgId}
341
+ isDeleted={message.isDeleted}
342
+ type={message.type}
343
+ url={message?.url}
344
+ thumb={message?.thumb}
345
+ fileName={message?.fileName}
346
+ ext={message?.ext}
347
+ reactions={message?.reactions}
348
+ replyToMsgId={message?.replyToMsgId}
349
+ isLastMsg={
350
+ privateMessageStore[privateChatUser].length - 1 ===
351
+ index
352
+ }
353
+ />
354
+ ) : null}
350
355
  {privateMessageStore[privateChatUser]?.length - 1 ===
351
356
  index ? (
352
357
  <Spacer size={10} />
@@ -87,7 +87,7 @@ const ChatQuickActionsMenu = (props: ChatQuickActionsMenuProps) => {
87
87
 
88
88
  const groupID = chat.group_id;
89
89
  const isGroupOwner = chat.is_group_owner;
90
- const isMsgPinned = pinMsgId === messageId && pinnedByUser === userId;
90
+ const isMsgPinned = pinMsgId === messageId;
91
91
 
92
92
  showReplyOption &&
93
93
  actionMenuitems.push({
@@ -153,6 +153,7 @@ const ChatQuickActionsMenu = (props: ChatQuickActionsMenuProps) => {
153
153
 
154
154
  // native pin message to be released with 1.3.0 chat sdk
155
155
  isWebInternal() &&
156
+ chatType == SDKChatType.GROUP_CHAT &&
156
157
  actionMenuitems.push({
157
158
  icon: isMsgPinned ? 'unpin-outlined' : 'pin-outlined',
158
159
  iconColor: $config.SECONDARY_ACTION_COLOR,
@@ -183,13 +184,13 @@ const ChatQuickActionsMenu = (props: ChatQuickActionsMenuProps) => {
183
184
  iconColor: $config.SEMANTIC_ERROR,
184
185
  textColor: $config.SEMANTIC_ERROR,
185
186
  title: 'Delete Message',
187
+ disabled: isMsgPinned,
186
188
  onPress: () => {
187
189
  if (isLocal) {
188
190
  // confirm dialog : user is deleting for all
189
191
  setShowDeleteMessageModal(true);
190
192
  //deleteAttachment(msgId, recallFromUser.toString(), chatType);
191
193
  } else {
192
- debugger;
193
194
  if (chatType === SDKChatType.GROUP_CHAT) {
194
195
  removeMessageFromStore(messageId, isLocal);
195
196
  }
@@ -198,7 +199,6 @@ const ChatQuickActionsMenu = (props: ChatQuickActionsMenuProps) => {
198
199
  }
199
200
  }
200
201
  setActionMenuVisible(false);
201
- setIsHovered(false);
202
202
  },
203
203
  });
204
204
 
@@ -16,6 +16,7 @@ import {
16
16
  import {useContent, useLocalUid, UidType} from 'customization-api';
17
17
  import {trimText} from '../../../src/utils/common';
18
18
  import {formatAMPM} from '../../../src/utils';
19
+ import {useChatConfigure} from '../../components/chat/chatConfigure';
19
20
 
20
21
  interface PinnedMessageProps {
21
22
  pinMsgId: string;
@@ -31,6 +32,7 @@ const PinnedMessage: React.FC<PinnedMessageProps> = ({
31
32
  const {defaultContent} = useContent();
32
33
  const [isExpanded, setIsExpanded] = useState(false);
33
34
  const [showMoreIcon, setShowMoreIcon] = useState(false);
35
+ const {unPinMessage} = useChatConfigure();
34
36
 
35
37
  const pinnedMsg = messageStore.filter(msg => msg.msgId === pinMsgId);
36
38
  if (pinnedMsg.length === 0) return null;
@@ -48,7 +50,7 @@ const PinnedMessage: React.FC<PinnedMessageProps> = ({
48
50
  const fileName = pinnedMsg[0].fileName;
49
51
 
50
52
  const toggleExpanded = () => {
51
- setIsExpanded(!isExpanded);
53
+ setIsExpanded(prev => !prev);
52
54
  };
53
55
  const handleTextLayout = e => {
54
56
  let textHeight = e.nativeEvent.layout?.height;
@@ -59,20 +61,26 @@ const PinnedMessage: React.FC<PinnedMessageProps> = ({
59
61
  }
60
62
  };
61
63
 
64
+ const handleMessageUnpin = () => {
65
+ unPinMessage(pinMsgId);
66
+ };
67
+
62
68
  return (
63
- <View style={styles.container}>
69
+ <View
70
+ style={[styles.container, {overflow: isExpanded ? 'scroll' : 'hidden'}]}>
64
71
  <View style={styles.pinUserContainer}>
65
- <ImageIcon
66
- iconType="plain"
67
- name="pin-filled"
68
- iconSize={20}
69
- iconContainerStyle={styles.pinIcon}
70
- tintColor={$config.FONT_COLOR + hexadecimalTransparency['40%']}
71
- />
72
+ <Pressable onPress={handleMessageUnpin}>
73
+ <ImageIcon
74
+ iconType="plain"
75
+ name="unpin-filled"
76
+ iconSize={20}
77
+ tintColor={$config.FONT_COLOR + hexadecimalTransparency['40%']}
78
+ />
79
+ </Pressable>
72
80
  <Text style={styles.pinnedUser}> Pinned By {msgPinnedUser}</Text>
73
81
  </View>
74
82
 
75
- <Pressable style={styles.msgContainer} onPress={toggleExpanded}>
83
+ <View style={styles.msgContainer}>
76
84
  <View
77
85
  style={{
78
86
  flexDirection: 'row',
@@ -121,14 +129,16 @@ const PinnedMessage: React.FC<PinnedMessageProps> = ({
121
129
  </View>
122
130
 
123
131
  {showMoreIcon && (
124
- <ImageIcon
125
- iconType="plain"
126
- name={isExpanded ? 'arrow-up' : 'arrow-down'}
127
- iconSize={20}
128
- tintColor={$config.SECONDARY_ACTION_COLOR}
129
- />
132
+ <Pressable onPress={toggleExpanded}>
133
+ <ImageIcon
134
+ iconType="plain"
135
+ name={isExpanded ? 'arrow-up' : 'arrow-down'}
136
+ iconSize={20}
137
+ tintColor={$config.SECONDARY_ACTION_COLOR}
138
+ />
139
+ </Pressable>
130
140
  )}
131
- </Pressable>
141
+ </View>
132
142
 
133
143
  <Text style={styles.user}>
134
144
  {name} <Text style={styles.pinnedUser}>sent at {time}</Text>
@@ -159,7 +169,6 @@ const styles = StyleSheet.create({
159
169
  gap: 4,
160
170
  alignItems: 'flex-start',
161
171
  maxHeight: 120,
162
- overflow: 'scroll',
163
172
  },
164
173
  pinIcon: {
165
174
  transform: [{rotate: '-45deg'}],