agora-appbuilder-core 4.1.10-beta.1 → 4.1.11

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.
Files changed (132) hide show
  1. package/package.json +2 -2
  2. package/template/agora-rn-uikit/src/Utils/isBotUser.ts +1 -1
  3. package/template/android/app/build.gradle +0 -7
  4. package/template/bridge/rtc/webNg/RtcEngine.ts +2 -2
  5. package/template/bridge/rtm/web/Types.ts +0 -183
  6. package/template/bridge/rtm/web/index.ts +488 -450
  7. package/template/customization-api/typeDefinition.ts +0 -1
  8. package/template/defaultConfig.js +3 -4
  9. package/template/global.d.ts +0 -1
  10. package/template/ios/Podfile +0 -41
  11. package/template/package.json +5 -5
  12. package/template/src/AppRoutes.tsx +3 -3
  13. package/template/src/ai-agent/components/ControlButtons.tsx +1 -1
  14. package/template/src/assets/font-styles.css +1 -33
  15. package/template/src/assets/fonts/icomoon.ttf +0 -0
  16. package/template/src/assets/selection.json +1 -1
  17. package/template/src/atoms/ActionMenu.tsx +93 -13
  18. package/template/src/atoms/CustomIcon.tsx +1 -8
  19. package/template/src/atoms/DropDownMulti.tsx +80 -29
  20. package/template/src/atoms/Dropdown.tsx +0 -5
  21. package/template/src/atoms/Input.tsx +2 -1
  22. package/template/src/atoms/TertiaryButton.tsx +1 -1
  23. package/template/src/atoms/UserAvatar.tsx +1 -1
  24. package/template/src/components/ChatContext.ts +3 -5
  25. package/template/src/components/Controls.tsx +167 -208
  26. package/template/src/components/DeviceConfigure.tsx +1 -1
  27. package/template/src/components/EventsConfigure.tsx +168 -118
  28. package/template/src/components/Navbar.tsx +11 -14
  29. package/template/src/components/RTMConfigure.tsx +819 -32
  30. package/template/src/components/beauty-effect/useBeautyEffects.tsx +13 -50
  31. package/template/src/components/chat/chatConfigure.tsx +1 -7
  32. package/template/src/components/chat-messages/useChatMessages.tsx +11 -43
  33. package/template/src/components/controls/useControlPermissionMatrix.tsx +4 -32
  34. package/template/src/components/participants/AllHostParticipants.tsx +2 -10
  35. package/template/src/components/participants/Participant.tsx +1 -7
  36. package/template/src/components/participants/UserActionMenuOptions.tsx +2 -12
  37. package/template/src/components/precall/joinCallBtn.native.tsx +7 -2
  38. package/template/src/components/precall/joinCallBtn.tsx +7 -2
  39. package/template/src/components/precall/joinWaitingRoomBtn.native.tsx +16 -15
  40. package/template/src/components/precall/joinWaitingRoomBtn.tsx +31 -17
  41. package/template/src/components/precall/textInput.tsx +45 -22
  42. package/template/src/components/precall/usePreCall.tsx +7 -0
  43. package/template/src/components/recordings/RecordingsDateTable.tsx +2 -3
  44. package/template/src/components/room-info/useRoomInfo.tsx +5 -0
  45. package/template/src/components/useUserPreference.tsx +12 -39
  46. package/template/src/components/virtual-background/useVB.tsx +0 -18
  47. package/template/src/components/whiteboard/WhiteboardConfigure.tsx +0 -27
  48. package/template/src/language/default-labels/videoCallScreenLabels.ts +27 -11
  49. package/template/src/logger/AppBuilderLogger.tsx +3 -11
  50. package/template/src/pages/VideoCall.tsx +518 -171
  51. package/template/src/pages/video-call/ActionSheetContent.tsx +77 -77
  52. package/template/src/pages/video-call/SidePanelHeader.tsx +81 -53
  53. package/template/src/pages/video-call/VideoCallScreen.tsx +0 -18
  54. package/template/src/pages/video-call/VideoCallScreenWrapper.tsx +1 -0
  55. package/template/src/rtm/RTMEngine.ts +37 -262
  56. package/template/src/rtm/utils.ts +1 -68
  57. package/template/src/rtm-events/constants.ts +7 -40
  58. package/template/src/rtm-events-api/Events.ts +39 -158
  59. package/template/src/subComponents/ChatBubble.tsx +3 -3
  60. package/template/src/subComponents/ChatContainer.tsx +9 -19
  61. package/template/src/subComponents/LocalAudioMute.tsx +2 -2
  62. package/template/src/subComponents/LocalVideoMute.tsx +2 -2
  63. package/template/src/subComponents/SidePanelEnum.tsx +0 -1
  64. package/template/src/subComponents/caption/Caption.tsx +48 -7
  65. package/template/src/subComponents/caption/CaptionContainer.tsx +324 -51
  66. package/template/src/subComponents/caption/CaptionIcon.tsx +35 -34
  67. package/template/src/subComponents/caption/CaptionText.tsx +103 -2
  68. package/template/src/subComponents/caption/LanguageSelectorPopup.tsx +179 -69
  69. package/template/src/subComponents/caption/Transcript.tsx +46 -11
  70. package/template/src/subComponents/caption/TranscriptIcon.tsx +27 -35
  71. package/template/src/subComponents/caption/TranscriptText.tsx +78 -3
  72. package/template/src/subComponents/caption/proto/ptoto.js +38 -4
  73. package/template/src/subComponents/caption/proto/test.proto +34 -19
  74. package/template/src/subComponents/caption/useCaption.tsx +754 -11
  75. package/template/src/subComponents/caption/useSTTAPI.tsx +118 -205
  76. package/template/src/subComponents/caption/useStreamMessageUtils.native.ts +152 -33
  77. package/template/src/subComponents/caption/useStreamMessageUtils.ts +165 -34
  78. package/template/src/subComponents/caption/utils.ts +171 -3
  79. package/template/src/subComponents/chat/ChatSendButton.tsx +0 -1
  80. package/template/src/subComponents/screenshare/ScreenshareButton.tsx +0 -16
  81. package/template/src/subComponents/screenshare/ScreenshareConfigure.native.tsx +1 -1
  82. package/template/src/subComponents/waiting-rooms/WaitingRoomControls.tsx +4 -7
  83. package/template/src/utils/SdkEvents.ts +3 -0
  84. package/template/src/utils/useEndCall.ts +4 -4
  85. package/template/src/utils/useMuteToggleLocal.ts +10 -14
  86. package/template/src/utils/useSpeechToText.ts +31 -20
  87. package/template/bridge/rtm/web/index-legacy.ts +0 -540
  88. package/template/src/components/RTMConfigure-legacy.tsx +0 -848
  89. package/template/src/components/UserGlobalPreferenceProvider.tsx +0 -227
  90. package/template/src/components/breakout-room/BreakoutRoomPanel.tsx +0 -58
  91. package/template/src/components/breakout-room/context/BreakoutRoomContext.tsx +0 -2508
  92. package/template/src/components/breakout-room/events/BreakoutRoomEventsConfigure.tsx +0 -272
  93. package/template/src/components/breakout-room/events/constants.ts +0 -17
  94. package/template/src/components/breakout-room/hoc/BreakoutRoomNameRenderer.tsx +0 -68
  95. package/template/src/components/breakout-room/hooks/useBreakoutRoomExit.ts +0 -49
  96. package/template/src/components/breakout-room/state/reducer.ts +0 -522
  97. package/template/src/components/breakout-room/state/types.ts +0 -54
  98. package/template/src/components/breakout-room/ui/BreakoutMeetingTitle.tsx +0 -60
  99. package/template/src/components/breakout-room/ui/BreakoutRoomActionMenu.tsx +0 -136
  100. package/template/src/components/breakout-room/ui/BreakoutRoomAnnouncementModal.tsx +0 -135
  101. package/template/src/components/breakout-room/ui/BreakoutRoomGroupSettings.tsx +0 -588
  102. package/template/src/components/breakout-room/ui/BreakoutRoomMainRoomUsers.tsx +0 -142
  103. package/template/src/components/breakout-room/ui/BreakoutRoomMemberActionMenu.tsx +0 -122
  104. package/template/src/components/breakout-room/ui/BreakoutRoomParticipants.tsx +0 -124
  105. package/template/src/components/breakout-room/ui/BreakoutRoomRaiseHand.tsx +0 -65
  106. package/template/src/components/breakout-room/ui/BreakoutRoomRenameModal.tsx +0 -227
  107. package/template/src/components/breakout-room/ui/BreakoutRoomSettings.tsx +0 -140
  108. package/template/src/components/breakout-room/ui/BreakoutRoomTransition.tsx +0 -52
  109. package/template/src/components/breakout-room/ui/BreakoutRoomView.tsx +0 -193
  110. package/template/src/components/breakout-room/ui/ExitBreakoutRoomIconButton.tsx +0 -79
  111. package/template/src/components/breakout-room/ui/ParticipantManualAssignmentModal.tsx +0 -638
  112. package/template/src/components/breakout-room/ui/SelectParticipantAssignmentStrategy.tsx +0 -57
  113. package/template/src/components/common/Dividers.tsx +0 -53
  114. package/template/src/components/controls/toolbar-items/ExitBreakoutRoomToolbarItem.tsx +0 -13
  115. package/template/src/components/raise-hand/RaiseHandButton.tsx +0 -50
  116. package/template/src/components/raise-hand/RaiseHandProvider.tsx +0 -308
  117. package/template/src/components/raise-hand/index.ts +0 -14
  118. package/template/src/components/room-info/useCurrentRoomInfo.tsx +0 -42
  119. package/template/src/components/room-info/useSetBreakoutRoomInfo.tsx +0 -64
  120. package/template/src/pages/video-call/BreakoutVideoCall.tsx +0 -213
  121. package/template/src/pages/video-call/VideoCallContent.tsx +0 -211
  122. package/template/src/pages/video-call/VideoCallStateWrapper.tsx +0 -495
  123. package/template/src/rtm/RTMConfigureBreakoutRoomProvider.tsx +0 -882
  124. package/template/src/rtm/RTMConfigureMainRoomProvider.tsx +0 -757
  125. package/template/src/rtm/RTMCoreProvider.tsx +0 -419
  126. package/template/src/rtm/RTMGlobalStateProvider.tsx +0 -706
  127. package/template/src/rtm/RTMStatusBanner.tsx +0 -99
  128. package/template/src/rtm/constants.ts +0 -12
  129. package/template/src/rtm/hooks/useMainRoomUserDisplayName.ts +0 -45
  130. package/template/src/rtm/rtm-presence-utils.ts +0 -344
  131. package/template/src/subComponents/chat/ChatAnnouncementView.tsx +0 -65
  132. package/template/src/utils/useDebouncedCallback.tsx +0 -20
@@ -12,6 +12,7 @@ import {
12
12
  StyleProp,
13
13
  TextStyle,
14
14
  Pressable,
15
+ ScrollView,
15
16
  } from 'react-native';
16
17
  import React, {SetStateAction, useState} from 'react';
17
18
 
@@ -35,7 +36,10 @@ export interface ActionMenuItem {
35
36
  isBase64Icon?: boolean;
36
37
  icon?: keyof IconsInterface;
37
38
  onHoverIcon?: keyof IconsInterface;
39
+ endIcon?: keyof IconsInterface;
40
+ onHoverEndIcon?: keyof IconsInterface;
38
41
  iconColor?: string;
42
+ endIconColor?: string;
39
43
  textColor?: string;
40
44
  title?: string;
41
45
  titleStyle?: StyleProp<TextStyle>;
@@ -48,8 +52,10 @@ export interface ActionMenuItem {
48
52
  onHoverContent?: JSX.Element;
49
53
  disabled?: boolean;
50
54
  iconSize?: number;
55
+ endIconSize?: number;
51
56
  hide?: ToolbarItemHide;
52
57
  type?: string;
58
+ iconPosition?: 'start' | 'end';
53
59
  }
54
60
  export interface ActionMenuProps {
55
61
  from: string;
@@ -71,18 +77,23 @@ export interface UserActionMenuItemProps {
71
77
  label: string;
72
78
  icon?: keyof IconsInterface;
73
79
  onHoverIcon?: keyof IconsInterface;
80
+ endIcon?: keyof IconsInterface;
81
+ onHoverEndIcon?: keyof IconsInterface;
74
82
  toggleStatus?: boolean;
75
83
  iconColor: string;
84
+ endIconColor?: string;
76
85
  textColor: string;
77
86
  onPress?: () => void;
78
87
  onToggle?: () => void;
79
88
  disabled?: boolean;
80
89
  iconSize?: number;
90
+ endIconSize?: number;
81
91
  isHovered?: boolean;
82
92
  isExternalIcon?: boolean;
83
93
  isBase64Icon?: boolean;
84
94
  externalIconString?: string;
85
95
  titleStyle?: StyleProp<TextStyle>;
96
+ iconPosition?: 'start' | 'end';
86
97
  }
87
98
 
88
99
  export const UserActionMenuItem = ({
@@ -92,42 +103,77 @@ export const UserActionMenuItem = ({
92
103
  onPress,
93
104
  onToggle,
94
105
  iconColor,
106
+ endIconColor,
95
107
  textColor,
96
108
  iconSize = 20,
109
+ endIconSize = 20,
97
110
  titleStyle = {},
98
111
  disabled = false,
99
112
  isHovered = false,
100
113
  onHoverIcon,
114
+ endIcon,
115
+ onHoverEndIcon,
101
116
  isExternalIcon = false,
102
117
  isBase64Icon = false,
103
118
  externalIconString = '',
119
+ iconPosition = 'start',
104
120
  }: UserActionMenuItemProps) => {
105
121
  const iconToShow = isHovered && onHoverIcon && !disabled ? onHoverIcon : icon;
122
+ const endIconToShow =
123
+ isHovered && onHoverEndIcon && !disabled ? onHoverEndIcon : endIcon;
106
124
 
107
- const content = (
108
- <>
109
- <View style={styles.iconContainer}>
125
+ const renderIcon = (
126
+ iconName: keyof IconsInterface | undefined,
127
+ position: 'start' | 'end' = 'start',
128
+ size: number = 20,
129
+ color: string = iconColor,
130
+ ) => {
131
+ if (!iconName) return null;
132
+
133
+ return (
134
+ <View
135
+ style={[
136
+ styles.iconContainer,
137
+ position === 'end' && styles.iconContainerEnd,
138
+ ]}>
110
139
  {isExternalIcon ? (
111
140
  <ImageIcon
112
141
  base64={isBase64Icon}
113
- base64TintColor={iconColor}
142
+ base64TintColor={color}
114
143
  iconType="plain"
115
- iconSize={iconSize}
144
+ iconSize={size}
116
145
  icon={externalIconString}
117
- tintColor={iconColor}
146
+ tintColor={color}
118
147
  />
119
148
  ) : (
120
149
  <ImageIcon
121
150
  base64={isBase64Icon}
122
- base64TintColor={iconColor}
151
+ base64TintColor={color}
123
152
  iconType="plain"
124
- iconSize={iconSize}
125
- name={iconToShow}
126
- tintColor={iconColor}
153
+ iconSize={size}
154
+ name={iconName}
155
+ tintColor={color}
127
156
  />
128
157
  )}
129
158
  </View>
130
- <Text style={[styles.text, titleStyle, {color: textColor}]}>{label}</Text>
159
+ );
160
+ };
161
+
162
+ const content = (
163
+ <>
164
+ {renderIcon(iconToShow, 'start', iconSize, iconColor)}
165
+
166
+ <Text
167
+ style={[
168
+ styles.text,
169
+ titleStyle,
170
+ {color: textColor},
171
+ (iconPosition === 'end' || endIcon) && styles.textWithEndIcon,
172
+ ]}>
173
+ {label}
174
+ </Text>
175
+
176
+ {renderIcon(endIconToShow, 'end', endIconSize, endIconColor || iconColor)}
131
177
 
132
178
  {typeof toggleStatus === 'boolean' && (
133
179
  <View style={styles.toggleContainer}>
@@ -187,6 +233,8 @@ const ActionMenu = (props: ActionMenuProps) => {
187
233
  component: CustomActionItem = null,
188
234
  icon = '',
189
235
  onHoverIcon,
236
+ endIcon,
237
+ onHoverEndIcon,
190
238
  isBase64Icon = false,
191
239
  isExternalIcon = false,
192
240
  externalIconString = '',
@@ -195,13 +243,16 @@ const ActionMenu = (props: ActionMenuProps) => {
195
243
  closeActionMenu = () => {},
196
244
  uid,
197
245
  iconColor,
246
+ endIconColor,
198
247
  textColor,
199
248
  disabled = false,
200
249
  onHoverCallback = undefined,
201
250
  onHoverContent = undefined,
202
251
  iconSize = 20,
252
+ endIconSize = 20,
203
253
  titleStyle = {},
204
254
  type = '',
255
+ iconPosition = 'start',
205
256
  } = item;
206
257
  return (
207
258
  <PlatformWrapper key={props.from + '_' + title + index}>
@@ -262,18 +313,23 @@ const ActionMenu = (props: ActionMenuProps) => {
262
313
  <UserActionMenuItem
263
314
  label={label || title}
264
315
  icon={icon}
316
+ endIcon={endIcon}
265
317
  toggleStatus={toggleStatus}
266
318
  iconColor={iconColor}
319
+ endIconColor={endIconColor}
267
320
  textColor={textColor}
268
321
  iconSize={iconSize}
322
+ endIconSize={endIconSize}
269
323
  titleStyle={titleStyle}
270
324
  disabled={disabled}
271
325
  onToggle={onPress}
272
326
  isHovered={isHovered}
273
327
  isExternalIcon={isExternalIcon}
274
328
  externalIconString={externalIconString}
329
+ iconPosition={iconPosition}
275
330
  isBase64Icon={isBase64Icon}
276
331
  onHoverIcon={onHoverIcon}
332
+ onHoverEndIcon={onHoverEndIcon}
277
333
  />
278
334
  </TouchableOpacity>
279
335
  )}
@@ -284,6 +340,21 @@ const ActionMenu = (props: ActionMenuProps) => {
284
340
  });
285
341
  };
286
342
 
343
+ const shouldUseScrollView = props?.containerStyle?.maxHeight !== undefined;
344
+
345
+ const renderScrollableContent = () => {
346
+ return shouldUseScrollView ? (
347
+ <ScrollView
348
+ style={{maxHeight: props.containerStyle.maxHeight}}
349
+ showsVerticalScrollIndicator={true}
350
+ nestedScrollEnabled={true}>
351
+ {renderItems()}
352
+ </ScrollView>
353
+ ) : (
354
+ renderItems()
355
+ );
356
+ };
357
+
287
358
  return (
288
359
  <View>
289
360
  {hoverMode ? (
@@ -293,7 +364,7 @@ const ActionMenu = (props: ActionMenuProps) => {
293
364
  <div
294
365
  onMouseEnter={() => props?.onHover && props.onHover(true)}
295
366
  onMouseLeave={() => props?.onHover && props.onHover(false)}>
296
- {renderItems()}
367
+ {renderScrollableContent()}
297
368
  </div>
298
369
  </View>
299
370
  )
@@ -311,7 +382,7 @@ const ActionMenu = (props: ActionMenuProps) => {
311
382
  </TouchableWithoutFeedback>
312
383
  <View
313
384
  style={[styles.modalView, props?.containerStyle, modalPosition]}>
314
- {renderItems()}
385
+ {renderScrollableContent()}
315
386
  </View>
316
387
  </Modal>
317
388
  )}
@@ -388,6 +459,15 @@ const styles = StyleSheet.create({
388
459
  marginVertical: 12,
389
460
  marginLeft: 12,
390
461
  },
462
+ iconContainerEnd: {
463
+ marginLeft: 10,
464
+ display: 'flex',
465
+ justifyContent: 'center',
466
+ alignItems: 'center',
467
+ },
468
+ textWithEndIcon: {
469
+ marginRight: 0,
470
+ },
391
471
  toggleContainer: {
392
472
  justifyContent: 'center',
393
473
  alignItems: 'center',
@@ -91,6 +91,7 @@ export interface IconsInterface {
91
91
  'closed-caption': string;
92
92
  globe: string;
93
93
  'lang-select': string;
94
+ 'lang-translate': string;
94
95
  search: string;
95
96
  captions: string;
96
97
  'captions-off': string;
@@ -153,12 +154,4 @@ export interface IconsInterface {
153
154
  fullscreen: string;
154
155
  add_reaction: string;
155
156
  spotlight: string;
156
- 'people-assigned': string;
157
- 'double-up-arrow': string;
158
- 'move-up': string;
159
- 'close-room': string;
160
- 'open-room': string;
161
- announcement: string;
162
- 'settings-outlined': string;
163
- 'breakout-room': string;
164
157
  }
@@ -14,6 +14,7 @@ import {
14
14
  Modal,
15
15
  View,
16
16
  Image,
17
+ ScrollView,
17
18
  } from 'react-native';
18
19
  import {isWebInternal} from '../utils/common';
19
20
  import ThemeConfig from '../theme';
@@ -34,6 +35,8 @@ interface Props {
34
35
  defaultSelectedValues?: LanguageType[];
35
36
  isOpen: boolean;
36
37
  setIsOpen: React.Dispatch<React.SetStateAction<boolean>>;
38
+ maxAllowedSelection?: number;
39
+ protectedLanguages?: LanguageType[];
37
40
  }
38
41
 
39
42
  const DropdownMulti: FC<Props> = ({
@@ -45,6 +48,8 @@ const DropdownMulti: FC<Props> = ({
45
48
  icon,
46
49
  isOpen,
47
50
  setIsOpen,
51
+ maxAllowedSelection = 2,
52
+ protectedLanguages = [],
48
53
  }) => {
49
54
  const DropdownButton = useRef();
50
55
  const maxHeight = 170;
@@ -78,20 +83,20 @@ const DropdownMulti: FC<Props> = ({
78
83
  //setIsOpen(false);
79
84
 
80
85
  const isSelected = selectedValues.includes(item.value);
86
+ const isProtected = protectedLanguages.includes(item.value);
81
87
  let updatedValues = [...selectedValues];
82
88
 
83
89
  if (isSelected) {
84
- // Item is already selected, remove it if there are more than one selected languages
85
- if (selectedValues.length > 0) {
86
- updatedValues = selectedValues.filter((value) => value !== item.value);
90
+ // Item is already selected, remove it if it's not protected and there are more than one selected languages
91
+ if (selectedValues.length > 0 && !isProtected) {
92
+ updatedValues = selectedValues.filter(value => value !== item.value);
87
93
  }
88
94
  } else {
89
95
  // Item is not selected, add it
90
- if (selectedValues.length < 2) {
96
+ if (selectedValues.length < maxAllowedSelection) {
91
97
  updatedValues = [...selectedValues, item.value];
92
98
  } else {
93
- // Max selection limit reached, replace the second selected value
94
- // updatedValues = [selectedValues[1], item.value];
99
+ // Max selection limit reached, do nothing or implement replacement logic
95
100
  }
96
101
  }
97
102
 
@@ -102,13 +107,15 @@ const DropdownMulti: FC<Props> = ({
102
107
  // renders each lang checkbox row
103
108
  const renderItem = ({item}): ReactElement<any, any> => {
104
109
  const isSelected = selectedValues.includes(item.value);
110
+ const isProtected = protectedLanguages.includes(item.value);
105
111
  const isUSEngLangSelected = selectedValues.includes('en-US');
106
112
  const isINEngLangSelected = selectedValues.includes('en-IN');
107
113
 
108
114
  const isDisabled =
109
- (!isSelected && selectedValues.length === 2) ||
115
+ (!isSelected && selectedValues.length === maxAllowedSelection) ||
110
116
  (item.value === 'en-US' && isINEngLangSelected) ||
111
- (item.value === 'en-IN' && isUSEngLangSelected);
117
+ (item.value === 'en-IN' && isUSEngLangSelected) ||
118
+ (isSelected && isProtected);
112
119
 
113
120
  setError(isDisabled || selectedValues.length === 0);
114
121
 
@@ -119,8 +126,12 @@ const DropdownMulti: FC<Props> = ({
119
126
  <Checkbox
120
127
  disabled={isDisabled}
121
128
  checked={isSelected}
122
- label={item.label}
123
- labelStye={styles.itemText}
129
+ label={item.label + (isProtected ? ' (Selected already)' : '')}
130
+ labelStye={
131
+ isProtected
132
+ ? {...styles.itemText, ...styles.protectedItemText}
133
+ : styles.itemText
134
+ }
124
135
  onChange={() => onItemPress(item)}
125
136
  />
126
137
  </View>
@@ -144,28 +155,39 @@ const DropdownMulti: FC<Props> = ({
144
155
  );
145
156
  };
146
157
 
147
- const selectedLabels = selectedValues.map((value) => {
148
- const selectedLanguage = data.find((item) => item.value === value);
158
+ const selectedLabels = selectedValues.map(value => {
159
+ const selectedLanguage = data.find(item => item.value === value);
160
+ const isProtected = protectedLanguages.includes(value);
149
161
  return selectedLanguage ? (
150
- <View style={styles.selectedLang}>
162
+ <View style={[styles.selectedLang, isProtected && styles.protectedPill]}>
163
+ <Text
164
+ style={[
165
+ styles.dropdownOptionText,
166
+ isProtected && styles.protectedPillText,
167
+ ]}>
168
+ {selectedLanguage.label}
169
+ </Text>
151
170
  <TouchableOpacity
171
+ disabled={isProtected}
152
172
  onPress={() => {
153
- const updatedValues = selectedValues.filter(
154
- (value) => value !== selectedLanguage.value,
155
- );
156
- setSelectedValues(updatedValues);
173
+ if (!isProtected) {
174
+ const updatedValues = selectedValues.filter(
175
+ value => value !== selectedLanguage.value,
176
+ );
177
+ setSelectedValues(updatedValues);
178
+ }
157
179
  }}>
158
180
  <ImageIcon
159
181
  iconType="plain"
160
182
  name={'close'}
161
183
  iconSize={20}
162
- tintColor={$config.CARD_LAYER_5_COLOR}
184
+ tintColor={
185
+ isProtected
186
+ ? $config.FONT_COLOR + hexadecimalTransparency['40%']
187
+ : $config.CARD_LAYER_5_COLOR
188
+ }
163
189
  />
164
190
  </TouchableOpacity>
165
-
166
- <Text numberOfLines={1} style={styles.dropdownOptionText}>
167
- {selectedLanguage.label}
168
- </Text>
169
191
  </View>
170
192
  ) : (
171
193
  <></>
@@ -210,13 +232,20 @@ const DropdownMulti: FC<Props> = ({
210
232
  <></>
211
233
  )}
212
234
  {/* Dropdown Text */}
213
- <View
235
+ <ScrollView
236
+ horizontal
237
+ showsHorizontalScrollIndicator={true}
238
+ contentContainerStyle={styles.scrollContainer}
214
239
  style={[
215
240
  styles.dropdownOptionTextContainer,
216
- selectedValues.length === 2 && {flex: 0.9},
241
+ selectedValues.length === maxAllowedSelection && {flex: 1},
217
242
  ]}>
218
- {formattedSelectedLanguages}
219
- </View>
243
+ {selectedValues.length === 0 ? (
244
+ <Text style={styles.placeholderText}>Select languages</Text>
245
+ ) : (
246
+ formattedSelectedLanguages
247
+ )}
248
+ </ScrollView>
220
249
  </View>
221
250
  {/* Dropdown end Icon */}
222
251
  <View style={styles.dropdownIconContainer}>
@@ -274,14 +303,25 @@ const styles = StyleSheet.create({
274
303
  alignSelf: 'center',
275
304
  flexDirection: 'row',
276
305
  },
306
+ scrollContainer: {
307
+ alignItems: 'center',
308
+ flexDirection: 'row',
309
+ },
277
310
  dropdownOptionText: {
278
311
  textAlign: 'left',
279
312
  fontFamily: ThemeConfig.FontFamily.sansPro,
280
313
  fontWeight: '400',
281
314
  fontSize: ThemeConfig.FontSize.normal,
282
315
  color: $config.FONT_COLOR,
283
- marginLeft: 4,
284
- flex: 1,
316
+ marginRight: 4,
317
+ },
318
+ placeholderText: {
319
+ textAlign: 'left',
320
+ fontFamily: ThemeConfig.FontFamily.sansPro,
321
+ fontWeight: '400',
322
+ fontSize: ThemeConfig.FontSize.normal,
323
+ color: $config.FONT_COLOR + hexadecimalTransparency['70%'],
324
+ paddingLeft: 8,
285
325
  },
286
326
  dropdownIconContainer: {
287
327
  alignSelf: 'center',
@@ -311,7 +351,7 @@ const styles = StyleSheet.create({
311
351
  paddingLeft: 8,
312
352
  backgroundColor: $config.CARD_LAYER_4_COLOR,
313
353
  borderRadius: 6,
314
- flex: 1,
354
+ maxWidth: 140,
315
355
  justifyContent: 'flex-start',
316
356
  alignItems: 'center',
317
357
  flexDirection: 'row',
@@ -344,6 +384,17 @@ const styles = StyleSheet.create({
344
384
  justifyContent: 'center',
345
385
  alignItems: 'center',
346
386
  },
387
+ protectedItemText: {
388
+ paddingVertical: 12,
389
+ opacity: 0.6,
390
+ fontStyle: 'italic',
391
+ },
392
+ protectedPill: {
393
+ backgroundColor: $config.CARD_LAYER_2_COLOR,
394
+ },
395
+ protectedPillText: {
396
+ color: $config.FONT_COLOR + ThemeConfig.EmphasisPlus.low,
397
+ },
347
398
  });
348
399
 
349
400
  export default DropdownMulti;
@@ -14,8 +14,6 @@ import {
14
14
  Modal,
15
15
  View,
16
16
  Image,
17
- StyleProp,
18
- ViewStyle,
19
17
  } from 'react-native';
20
18
  import {isWebInternal} from '../utils/common';
21
19
  import ThemeConfig from '../theme';
@@ -30,7 +28,6 @@ interface Props {
30
28
  onSelect: (item: {label: string; value: string}) => void;
31
29
  enabled: boolean;
32
30
  selectedValue: string;
33
- containerStyle?: StyleProp<ViewStyle>;
34
31
  }
35
32
 
36
33
  const Dropdown: FC<Props> = ({
@@ -40,7 +37,6 @@ const Dropdown: FC<Props> = ({
40
37
  enabled,
41
38
  selectedValue,
42
39
  icon,
43
- containerStyle = {},
44
40
  }) => {
45
41
  const DropdownButton = useRef();
46
42
  const [visible, setVisible] = useState(false);
@@ -152,7 +148,6 @@ const Dropdown: FC<Props> = ({
152
148
  ref={DropdownButton}
153
149
  style={[
154
150
  styles.dropdownOptionContainer,
155
- containerStyle,
156
151
  !enabled || !data || !data.length
157
152
  ? {opacity: ThemeConfig.EmphasisOpacity.disabled}
158
153
  : {},
@@ -60,7 +60,7 @@ const styles = StyleSheet.create({
60
60
  // height: 60, //causes text cut off in android
61
61
  width: '100%',
62
62
  borderWidth: 1,
63
- paddingVertical: 21,
63
+ paddingVertical: 12,
64
64
  paddingHorizontal: 16,
65
65
  borderColor: $config.INPUT_FIELD_BORDER_COLOR,
66
66
  color: $config.FONT_COLOR,
@@ -71,6 +71,7 @@ const styles = StyleSheet.create({
71
71
  ...Platform.select({
72
72
  web: {
73
73
  outlineStyle: 'none',
74
+ lineHeight: '26px',
74
75
  },
75
76
  }),
76
77
  },
@@ -120,6 +120,6 @@ const styles = StyleSheet.create({
120
120
  cursor: 'default',
121
121
  },
122
122
  disabledText: {
123
- color: $config.FONT_COLOR + ThemeConfig.EmphasisPlus.low,
123
+ color: $config.SEMANTIC_NEUTRAL,
124
124
  },
125
125
  });
@@ -10,7 +10,7 @@ function getInitials(name: string) {
10
10
  return 'U';
11
11
  }
12
12
 
13
- const UserAvatar = ({name, containerStyle = {}, textStyle = {}}) => {
13
+ const UserAvatar = ({name, containerStyle, textStyle}) => {
14
14
  return (
15
15
  <View
16
16
  style={[
@@ -9,9 +9,8 @@
9
9
  information visit https://appbuilder.agora.io.
10
10
  *********************************************
11
11
  */
12
- import {type RTMClient} from 'agora-react-native-rtm';
13
- import {UidType, ContentInterface} from '../../agora-rn-uikit';
14
- import {RTMUserPreferences} from '../rtm/RTMGlobalStateProvider';
12
+ import RtmEngine from 'agora-react-native-rtm';
13
+ import {UidType} from '../../agora-rn-uikit';
15
14
  import {createContext, SetStateAction} from 'react';
16
15
 
17
16
  import {ChatMessageType, Reaction} from './chat-messages/useChatMessages';
@@ -90,10 +89,9 @@ export interface RtmContextInterface {
90
89
  isInitialQueueCompleted: boolean;
91
90
  hasUserJoinedRTM: boolean;
92
91
  rtmInitTimstamp: number;
93
- engine: RTMClient;
92
+ engine: RtmEngine;
94
93
  localUid: UidType;
95
94
  onlineUsersCount: number;
96
- syncUserState: (uid: number, data: Partial<ContentInterface>) => void;
97
95
  }
98
96
 
99
97
  export enum controlMessageEnum {