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.
- package/package.json +2 -2
- package/template/agora-rn-uikit/src/Utils/isBotUser.ts +1 -1
- package/template/android/app/build.gradle +0 -7
- package/template/bridge/rtc/webNg/RtcEngine.ts +2 -2
- package/template/bridge/rtm/web/Types.ts +0 -183
- package/template/bridge/rtm/web/index.ts +488 -450
- package/template/customization-api/typeDefinition.ts +0 -1
- package/template/defaultConfig.js +3 -4
- package/template/global.d.ts +0 -1
- package/template/ios/Podfile +0 -41
- package/template/package.json +5 -5
- package/template/src/AppRoutes.tsx +3 -3
- package/template/src/ai-agent/components/ControlButtons.tsx +1 -1
- package/template/src/assets/font-styles.css +1 -33
- package/template/src/assets/fonts/icomoon.ttf +0 -0
- package/template/src/assets/selection.json +1 -1
- package/template/src/atoms/ActionMenu.tsx +93 -13
- package/template/src/atoms/CustomIcon.tsx +1 -8
- package/template/src/atoms/DropDownMulti.tsx +80 -29
- package/template/src/atoms/Dropdown.tsx +0 -5
- package/template/src/atoms/Input.tsx +2 -1
- package/template/src/atoms/TertiaryButton.tsx +1 -1
- package/template/src/atoms/UserAvatar.tsx +1 -1
- package/template/src/components/ChatContext.ts +3 -5
- package/template/src/components/Controls.tsx +167 -208
- package/template/src/components/DeviceConfigure.tsx +1 -1
- package/template/src/components/EventsConfigure.tsx +168 -118
- package/template/src/components/Navbar.tsx +11 -14
- package/template/src/components/RTMConfigure.tsx +819 -32
- package/template/src/components/beauty-effect/useBeautyEffects.tsx +13 -50
- package/template/src/components/chat/chatConfigure.tsx +1 -7
- package/template/src/components/chat-messages/useChatMessages.tsx +11 -43
- package/template/src/components/controls/useControlPermissionMatrix.tsx +4 -32
- package/template/src/components/participants/AllHostParticipants.tsx +2 -10
- package/template/src/components/participants/Participant.tsx +1 -7
- package/template/src/components/participants/UserActionMenuOptions.tsx +2 -12
- package/template/src/components/precall/joinCallBtn.native.tsx +7 -2
- package/template/src/components/precall/joinCallBtn.tsx +7 -2
- package/template/src/components/precall/joinWaitingRoomBtn.native.tsx +16 -15
- package/template/src/components/precall/joinWaitingRoomBtn.tsx +31 -17
- package/template/src/components/precall/textInput.tsx +45 -22
- package/template/src/components/precall/usePreCall.tsx +7 -0
- package/template/src/components/recordings/RecordingsDateTable.tsx +2 -3
- package/template/src/components/room-info/useRoomInfo.tsx +5 -0
- package/template/src/components/useUserPreference.tsx +12 -39
- package/template/src/components/virtual-background/useVB.tsx +0 -18
- package/template/src/components/whiteboard/WhiteboardConfigure.tsx +0 -27
- package/template/src/language/default-labels/videoCallScreenLabels.ts +27 -11
- package/template/src/logger/AppBuilderLogger.tsx +3 -11
- package/template/src/pages/VideoCall.tsx +518 -171
- package/template/src/pages/video-call/ActionSheetContent.tsx +77 -77
- package/template/src/pages/video-call/SidePanelHeader.tsx +81 -53
- package/template/src/pages/video-call/VideoCallScreen.tsx +0 -18
- package/template/src/pages/video-call/VideoCallScreenWrapper.tsx +1 -0
- package/template/src/rtm/RTMEngine.ts +37 -262
- package/template/src/rtm/utils.ts +1 -68
- package/template/src/rtm-events/constants.ts +7 -40
- package/template/src/rtm-events-api/Events.ts +39 -158
- package/template/src/subComponents/ChatBubble.tsx +3 -3
- package/template/src/subComponents/ChatContainer.tsx +9 -19
- package/template/src/subComponents/LocalAudioMute.tsx +2 -2
- package/template/src/subComponents/LocalVideoMute.tsx +2 -2
- package/template/src/subComponents/SidePanelEnum.tsx +0 -1
- package/template/src/subComponents/caption/Caption.tsx +48 -7
- package/template/src/subComponents/caption/CaptionContainer.tsx +324 -51
- package/template/src/subComponents/caption/CaptionIcon.tsx +35 -34
- package/template/src/subComponents/caption/CaptionText.tsx +103 -2
- package/template/src/subComponents/caption/LanguageSelectorPopup.tsx +179 -69
- package/template/src/subComponents/caption/Transcript.tsx +46 -11
- package/template/src/subComponents/caption/TranscriptIcon.tsx +27 -35
- package/template/src/subComponents/caption/TranscriptText.tsx +78 -3
- package/template/src/subComponents/caption/proto/ptoto.js +38 -4
- package/template/src/subComponents/caption/proto/test.proto +34 -19
- package/template/src/subComponents/caption/useCaption.tsx +754 -11
- package/template/src/subComponents/caption/useSTTAPI.tsx +118 -205
- package/template/src/subComponents/caption/useStreamMessageUtils.native.ts +152 -33
- package/template/src/subComponents/caption/useStreamMessageUtils.ts +165 -34
- package/template/src/subComponents/caption/utils.ts +171 -3
- package/template/src/subComponents/chat/ChatSendButton.tsx +0 -1
- package/template/src/subComponents/screenshare/ScreenshareButton.tsx +0 -16
- package/template/src/subComponents/screenshare/ScreenshareConfigure.native.tsx +1 -1
- package/template/src/subComponents/waiting-rooms/WaitingRoomControls.tsx +4 -7
- package/template/src/utils/SdkEvents.ts +3 -0
- package/template/src/utils/useEndCall.ts +4 -4
- package/template/src/utils/useMuteToggleLocal.ts +10 -14
- package/template/src/utils/useSpeechToText.ts +31 -20
- package/template/bridge/rtm/web/index-legacy.ts +0 -540
- package/template/src/components/RTMConfigure-legacy.tsx +0 -848
- package/template/src/components/UserGlobalPreferenceProvider.tsx +0 -227
- package/template/src/components/breakout-room/BreakoutRoomPanel.tsx +0 -58
- package/template/src/components/breakout-room/context/BreakoutRoomContext.tsx +0 -2508
- package/template/src/components/breakout-room/events/BreakoutRoomEventsConfigure.tsx +0 -272
- package/template/src/components/breakout-room/events/constants.ts +0 -17
- package/template/src/components/breakout-room/hoc/BreakoutRoomNameRenderer.tsx +0 -68
- package/template/src/components/breakout-room/hooks/useBreakoutRoomExit.ts +0 -49
- package/template/src/components/breakout-room/state/reducer.ts +0 -522
- package/template/src/components/breakout-room/state/types.ts +0 -54
- package/template/src/components/breakout-room/ui/BreakoutMeetingTitle.tsx +0 -60
- package/template/src/components/breakout-room/ui/BreakoutRoomActionMenu.tsx +0 -136
- package/template/src/components/breakout-room/ui/BreakoutRoomAnnouncementModal.tsx +0 -135
- package/template/src/components/breakout-room/ui/BreakoutRoomGroupSettings.tsx +0 -588
- package/template/src/components/breakout-room/ui/BreakoutRoomMainRoomUsers.tsx +0 -142
- package/template/src/components/breakout-room/ui/BreakoutRoomMemberActionMenu.tsx +0 -122
- package/template/src/components/breakout-room/ui/BreakoutRoomParticipants.tsx +0 -124
- package/template/src/components/breakout-room/ui/BreakoutRoomRaiseHand.tsx +0 -65
- package/template/src/components/breakout-room/ui/BreakoutRoomRenameModal.tsx +0 -227
- package/template/src/components/breakout-room/ui/BreakoutRoomSettings.tsx +0 -140
- package/template/src/components/breakout-room/ui/BreakoutRoomTransition.tsx +0 -52
- package/template/src/components/breakout-room/ui/BreakoutRoomView.tsx +0 -193
- package/template/src/components/breakout-room/ui/ExitBreakoutRoomIconButton.tsx +0 -79
- package/template/src/components/breakout-room/ui/ParticipantManualAssignmentModal.tsx +0 -638
- package/template/src/components/breakout-room/ui/SelectParticipantAssignmentStrategy.tsx +0 -57
- package/template/src/components/common/Dividers.tsx +0 -53
- package/template/src/components/controls/toolbar-items/ExitBreakoutRoomToolbarItem.tsx +0 -13
- package/template/src/components/raise-hand/RaiseHandButton.tsx +0 -50
- package/template/src/components/raise-hand/RaiseHandProvider.tsx +0 -308
- package/template/src/components/raise-hand/index.ts +0 -14
- package/template/src/components/room-info/useCurrentRoomInfo.tsx +0 -42
- package/template/src/components/room-info/useSetBreakoutRoomInfo.tsx +0 -64
- package/template/src/pages/video-call/BreakoutVideoCall.tsx +0 -213
- package/template/src/pages/video-call/VideoCallContent.tsx +0 -211
- package/template/src/pages/video-call/VideoCallStateWrapper.tsx +0 -495
- package/template/src/rtm/RTMConfigureBreakoutRoomProvider.tsx +0 -882
- package/template/src/rtm/RTMConfigureMainRoomProvider.tsx +0 -757
- package/template/src/rtm/RTMCoreProvider.tsx +0 -419
- package/template/src/rtm/RTMGlobalStateProvider.tsx +0 -706
- package/template/src/rtm/RTMStatusBanner.tsx +0 -99
- package/template/src/rtm/constants.ts +0 -12
- package/template/src/rtm/hooks/useMainRoomUserDisplayName.ts +0 -45
- package/template/src/rtm/rtm-presence-utils.ts +0 -344
- package/template/src/subComponents/chat/ChatAnnouncementView.tsx +0 -65
- 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
|
|
108
|
-
|
|
109
|
-
|
|
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={
|
|
142
|
+
base64TintColor={color}
|
|
114
143
|
iconType="plain"
|
|
115
|
-
iconSize={
|
|
144
|
+
iconSize={size}
|
|
116
145
|
icon={externalIconString}
|
|
117
|
-
tintColor={
|
|
146
|
+
tintColor={color}
|
|
118
147
|
/>
|
|
119
148
|
) : (
|
|
120
149
|
<ImageIcon
|
|
121
150
|
base64={isBase64Icon}
|
|
122
|
-
base64TintColor={
|
|
151
|
+
base64TintColor={color}
|
|
123
152
|
iconType="plain"
|
|
124
|
-
iconSize={
|
|
125
|
-
name={
|
|
126
|
-
tintColor={
|
|
153
|
+
iconSize={size}
|
|
154
|
+
name={iconName}
|
|
155
|
+
tintColor={color}
|
|
127
156
|
/>
|
|
128
157
|
)}
|
|
129
158
|
</View>
|
|
130
|
-
|
|
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
|
-
{
|
|
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
|
-
{
|
|
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(
|
|
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 <
|
|
96
|
+
if (selectedValues.length < maxAllowedSelection) {
|
|
91
97
|
updatedValues = [...selectedValues, item.value];
|
|
92
98
|
} else {
|
|
93
|
-
// Max selection limit reached,
|
|
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 ===
|
|
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={
|
|
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(
|
|
148
|
-
const selectedLanguage = data.find(
|
|
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
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
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={
|
|
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
|
-
<
|
|
235
|
+
<ScrollView
|
|
236
|
+
horizontal
|
|
237
|
+
showsHorizontalScrollIndicator={true}
|
|
238
|
+
contentContainerStyle={styles.scrollContainer}
|
|
214
239
|
style={[
|
|
215
240
|
styles.dropdownOptionTextContainer,
|
|
216
|
-
selectedValues.length ===
|
|
241
|
+
selectedValues.length === maxAllowedSelection && {flex: 1},
|
|
217
242
|
]}>
|
|
218
|
-
{
|
|
219
|
-
|
|
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
|
-
|
|
284
|
-
|
|
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
|
-
|
|
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:
|
|
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
|
},
|
|
@@ -9,9 +9,8 @@
|
|
|
9
9
|
information visit https://appbuilder.agora.io.
|
|
10
10
|
*********************************************
|
|
11
11
|
*/
|
|
12
|
-
import
|
|
13
|
-
import {UidType
|
|
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:
|
|
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 {
|