agora-appbuilder-core 4.1.9-beta.3 → 4.1.10-beta.1
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/Gulpfile.js +0 -16
- package/template/agora-rn-uikit/src/Contexts/PropsContext.tsx +1 -3
- package/template/agora-rn-uikit/src/Contexts/RtcContext.tsx +1 -2
- package/template/agora-rn-uikit/src/Reducer/index.ts +0 -2
- package/template/agora-rn-uikit/src/Rtc/Join.tsx +11 -25
- package/template/agora-rn-uikit/src/RtcConfigure.tsx +1 -14
- package/template/bridge/rtc/webNg/RtcEngine.ts +2 -2
- package/template/bridge/rtm/web/index.ts +30 -0
- package/template/customization-api/typeDefinition.ts +1 -0
- package/template/defaultConfig.js +3 -2
- package/template/global.d.ts +1 -0
- package/template/package.json +0 -2
- package/template/src/AppRoutes.tsx +3 -3
- package/template/src/ai-agent/components/ControlButtons.tsx +1 -1
- package/template/src/assets/font-styles.css +36 -0
- package/template/src/assets/fonts/icomoon.ttf +0 -0
- package/template/src/assets/selection.json +1 -1
- package/template/src/atoms/CustomIcon.tsx +8 -0
- package/template/src/atoms/Dropdown.tsx +5 -0
- package/template/src/atoms/TertiaryButton.tsx +1 -1
- package/template/src/atoms/UserAvatar.tsx +1 -1
- package/template/src/components/ChatContext.ts +5 -3
- package/template/src/components/Controls.tsx +68 -22
- package/template/src/components/DeviceConfigure.tsx +1 -1
- package/template/src/components/EventsConfigure.tsx +22 -17
- package/template/src/components/Navbar.tsx +14 -11
- package/template/src/components/RTMConfigure.tsx +31 -1036
- package/template/src/components/UserGlobalPreferenceProvider.tsx +227 -0
- package/template/src/components/beauty-effect/useBeautyEffects.tsx +50 -13
- package/template/src/components/breakout-room/BreakoutRoomPanel.tsx +58 -0
- package/template/src/components/breakout-room/context/BreakoutRoomContext.tsx +2508 -0
- package/template/src/components/breakout-room/events/BreakoutRoomEventsConfigure.tsx +272 -0
- package/template/src/components/breakout-room/events/constants.ts +17 -0
- package/template/src/components/breakout-room/hoc/BreakoutRoomNameRenderer.tsx +68 -0
- package/template/src/components/breakout-room/hooks/useBreakoutRoomExit.ts +49 -0
- package/template/src/components/breakout-room/state/reducer.ts +522 -0
- package/template/src/components/breakout-room/state/types.ts +54 -0
- package/template/src/components/breakout-room/ui/BreakoutMeetingTitle.tsx +60 -0
- package/template/src/components/breakout-room/ui/BreakoutRoomActionMenu.tsx +136 -0
- package/template/src/components/breakout-room/ui/BreakoutRoomAnnouncementModal.tsx +135 -0
- package/template/src/components/breakout-room/ui/BreakoutRoomGroupSettings.tsx +588 -0
- package/template/src/components/breakout-room/ui/BreakoutRoomMainRoomUsers.tsx +142 -0
- package/template/src/components/breakout-room/ui/BreakoutRoomMemberActionMenu.tsx +122 -0
- package/template/src/components/breakout-room/ui/BreakoutRoomParticipants.tsx +124 -0
- package/template/src/components/breakout-room/ui/BreakoutRoomRaiseHand.tsx +65 -0
- package/template/src/components/breakout-room/ui/BreakoutRoomRenameModal.tsx +227 -0
- package/template/src/components/breakout-room/ui/BreakoutRoomSettings.tsx +140 -0
- package/template/src/components/breakout-room/ui/BreakoutRoomTransition.tsx +52 -0
- package/template/src/components/breakout-room/ui/BreakoutRoomView.tsx +193 -0
- package/template/src/components/breakout-room/ui/ExitBreakoutRoomIconButton.tsx +79 -0
- package/template/src/components/breakout-room/ui/ParticipantManualAssignmentModal.tsx +638 -0
- package/template/src/components/breakout-room/ui/SelectParticipantAssignmentStrategy.tsx +57 -0
- package/template/src/components/chat/chatConfigure.tsx +7 -1
- package/template/src/components/chat-messages/useChatMessages.tsx +43 -11
- package/template/src/components/common/Dividers.tsx +53 -0
- package/template/src/components/controls/toolbar-items/ExitBreakoutRoomToolbarItem.tsx +13 -0
- package/template/src/components/controls/useControlPermissionMatrix.tsx +32 -4
- package/template/src/components/participants/AllHostParticipants.tsx +10 -2
- package/template/src/components/participants/Participant.tsx +7 -1
- package/template/src/components/participants/UserActionMenuOptions.tsx +12 -2
- package/template/src/components/precall/joinWaitingRoomBtn.native.tsx +12 -8
- package/template/src/components/precall/joinWaitingRoomBtn.tsx +14 -10
- package/template/src/components/raise-hand/RaiseHandButton.tsx +50 -0
- package/template/src/components/raise-hand/RaiseHandProvider.tsx +308 -0
- package/template/src/components/raise-hand/index.ts +14 -0
- package/template/src/components/recordings/RecordingsDateTable.tsx +3 -2
- package/template/src/components/room-info/useCurrentRoomInfo.tsx +42 -0
- package/template/src/components/room-info/useSetBreakoutRoomInfo.tsx +64 -0
- package/template/src/components/useUserPreference.tsx +39 -12
- package/template/src/components/virtual-background/useVB.tsx +18 -0
- package/template/src/components/whiteboard/WhiteboardConfigure.tsx +27 -0
- package/template/src/language/default-labels/videoCallScreenLabels.ts +7 -0
- package/template/src/logger/AppBuilderLogger.tsx +11 -3
- package/template/src/pages/VideoCall.tsx +171 -518
- package/template/src/pages/video-call/BreakoutVideoCall.tsx +213 -0
- package/template/src/pages/video-call/SidePanelHeader.tsx +17 -0
- package/template/src/pages/video-call/VideoCallContent.tsx +211 -0
- package/template/src/pages/video-call/VideoCallScreen.tsx +18 -0
- package/template/src/pages/video-call/VideoCallScreenWrapper.tsx +0 -1
- package/template/src/pages/video-call/VideoCallStateWrapper.tsx +495 -0
- package/template/src/rtm/RTMConfigureBreakoutRoomProvider.tsx +882 -0
- package/template/src/rtm/RTMConfigureMainRoomProvider.tsx +757 -0
- package/template/src/rtm/RTMCoreProvider.tsx +419 -0
- package/template/src/rtm/RTMEngine.ts +188 -60
- package/template/src/rtm/RTMGlobalStateProvider.tsx +706 -0
- package/template/src/rtm/RTMStatusBanner.tsx +99 -0
- package/template/src/rtm/constants.ts +12 -0
- package/template/src/rtm/hooks/useMainRoomUserDisplayName.ts +45 -0
- package/template/src/rtm/rtm-presence-utils.ts +344 -0
- package/template/src/rtm/utils.ts +68 -1
- package/template/src/rtm-events/constants.ts +40 -1
- package/template/src/rtm-events-api/Events.ts +62 -19
- package/template/src/subComponents/ChatBubble.tsx +3 -3
- package/template/src/subComponents/ChatContainer.tsx +19 -9
- package/template/src/subComponents/LocalAudioMute.tsx +2 -2
- package/template/src/subComponents/LocalVideoMute.tsx +2 -2
- package/template/src/subComponents/SidePanelEnum.tsx +1 -0
- package/template/src/subComponents/caption/useCaption.tsx +1 -1
- package/template/src/subComponents/chat/ChatAnnouncementView.tsx +65 -0
- package/template/src/subComponents/chat/ChatSendButton.tsx +1 -0
- package/template/src/subComponents/screenshare/ScreenshareButton.tsx +16 -0
- package/template/src/subComponents/screenshare/ScreenshareConfigure.native.tsx +1 -1
- package/template/src/subComponents/waiting-rooms/WaitingRoomControls.tsx +7 -4
- package/template/src/utils/useDebouncedCallback.tsx +20 -0
- package/template/src/utils/useEndCall.ts +0 -2
- package/template/src/utils/useMuteToggleLocal.ts +14 -10
- package/template/agora-rn-uikit/src/Reducer/Spotlight.ts +0 -11
- package/template/agora-rn-uikit/src/Reducer/UserBanned.ts +0 -11
|
@@ -7,6 +7,7 @@ import {useLocalUid} from '../../../agora-rn-uikit';
|
|
|
7
7
|
import {UidType, useContent} from 'customization-api';
|
|
8
8
|
import {
|
|
9
9
|
ChatMessageType,
|
|
10
|
+
ChatNotificationType,
|
|
10
11
|
ChatOption,
|
|
11
12
|
SDKChatType,
|
|
12
13
|
useChatMessages,
|
|
@@ -255,7 +256,7 @@ const ChatConfigure = ({children}) => {
|
|
|
255
256
|
);
|
|
256
257
|
}
|
|
257
258
|
},
|
|
258
|
-
//
|
|
259
|
+
// Text message is recieved, update receiver side ui
|
|
259
260
|
onTextMessage: message => {
|
|
260
261
|
if (message?.ext?.channel !== data?.channel) {
|
|
261
262
|
return;
|
|
@@ -272,11 +273,14 @@ const ChatConfigure = ({children}) => {
|
|
|
272
273
|
|
|
273
274
|
if (message.chatType === SDKChatType.GROUP_CHAT) {
|
|
274
275
|
// show to notifcation- group msg received
|
|
276
|
+
|
|
275
277
|
showMessageNotification(
|
|
276
278
|
message.msg,
|
|
277
279
|
fromUser,
|
|
278
280
|
false,
|
|
279
281
|
message.type,
|
|
282
|
+
false,
|
|
283
|
+
message.ext?.announcement,
|
|
280
284
|
);
|
|
281
285
|
addMessageToStore(Number(fromUser), {
|
|
282
286
|
msg: message.msg.replace(/^(\n)+|(\n)+$/g, ''),
|
|
@@ -285,6 +289,7 @@ const ChatConfigure = ({children}) => {
|
|
|
285
289
|
isDeleted: false,
|
|
286
290
|
type: ChatMessageType.TXT,
|
|
287
291
|
replyToMsgId: message.ext?.replyToMsgId,
|
|
292
|
+
announcement: message.ext?.announcement,
|
|
288
293
|
});
|
|
289
294
|
}
|
|
290
295
|
|
|
@@ -418,6 +423,7 @@ const ChatConfigure = ({children}) => {
|
|
|
418
423
|
ext: option?.ext?.file_ext,
|
|
419
424
|
fileName: option?.ext?.file_name,
|
|
420
425
|
replyToMsgId: option?.ext?.replyToMsgId,
|
|
426
|
+
announcement: option?.ext?.announcement,
|
|
421
427
|
};
|
|
422
428
|
|
|
423
429
|
// update local user message store
|
|
@@ -46,6 +46,11 @@ interface ChatMessagesProviderProps {
|
|
|
46
46
|
children: React.ReactNode;
|
|
47
47
|
callActive: boolean;
|
|
48
48
|
}
|
|
49
|
+
|
|
50
|
+
export enum ChatNotificationType {
|
|
51
|
+
ANNOUNCEMENT = 'ANNOUNCEMENT',
|
|
52
|
+
}
|
|
53
|
+
|
|
49
54
|
export enum ChatMessageType {
|
|
50
55
|
/**
|
|
51
56
|
* Text message.
|
|
@@ -85,6 +90,10 @@ export enum ChatMessageType {
|
|
|
85
90
|
COMBINE = 'combine',
|
|
86
91
|
}
|
|
87
92
|
|
|
93
|
+
export interface AnnouncementMessage {
|
|
94
|
+
sender: string;
|
|
95
|
+
heading: string;
|
|
96
|
+
}
|
|
88
97
|
export interface messageInterface {
|
|
89
98
|
createdTimestamp: number;
|
|
90
99
|
updatedTimestamp?: number;
|
|
@@ -99,6 +108,7 @@ export interface messageInterface {
|
|
|
99
108
|
reactions?: Reaction[];
|
|
100
109
|
replyToMsgId?: string;
|
|
101
110
|
hide?: boolean;
|
|
111
|
+
announcement?: AnnouncementMessage;
|
|
102
112
|
}
|
|
103
113
|
|
|
104
114
|
export enum SDKChatType {
|
|
@@ -122,6 +132,7 @@ export interface ChatOption {
|
|
|
122
132
|
channel?: string;
|
|
123
133
|
msg?: string;
|
|
124
134
|
replyToMsgId?: string;
|
|
135
|
+
announcement?: AnnouncementMessage;
|
|
125
136
|
};
|
|
126
137
|
url?: string;
|
|
127
138
|
}
|
|
@@ -178,6 +189,8 @@ interface ChatMessagesInterface {
|
|
|
178
189
|
uid: string,
|
|
179
190
|
isPrivateMessage?: boolean,
|
|
180
191
|
msgType?: ChatMessageType,
|
|
192
|
+
forceStop?: boolean,
|
|
193
|
+
notificationType?: ChatNotificationType,
|
|
181
194
|
) => void;
|
|
182
195
|
openPrivateChat: (toUid: UidType) => void;
|
|
183
196
|
removeMessageFromStore: (msgId: string, isMsgRecalled: boolean) => void;
|
|
@@ -277,11 +290,20 @@ const ChatMessagesProvider = (props: ChatMessagesProviderProps) => {
|
|
|
277
290
|
|
|
278
291
|
//commented for v1 release
|
|
279
292
|
//const fromText = useString('messageSenderNotificationLabel');
|
|
280
|
-
const fromText = (
|
|
293
|
+
const fromText = (
|
|
294
|
+
name: string,
|
|
295
|
+
msgType: ChatMessageType,
|
|
296
|
+
announcement?: AnnouncementText,
|
|
297
|
+
) => {
|
|
281
298
|
let text = '';
|
|
282
299
|
switch (msgType) {
|
|
283
300
|
case ChatMessageType.TXT:
|
|
284
|
-
|
|
301
|
+
if (announcement?.text) {
|
|
302
|
+
text = `${announcement.sender}: made an announcement in public chat`;
|
|
303
|
+
} else {
|
|
304
|
+
text = txtToastHeading?.current(name);
|
|
305
|
+
}
|
|
306
|
+
|
|
285
307
|
break;
|
|
286
308
|
case ChatMessageType.IMAGE:
|
|
287
309
|
text = imgToastHeading?.current(name);
|
|
@@ -329,12 +351,15 @@ const ChatMessagesProvider = (props: ChatMessagesProviderProps) => {
|
|
|
329
351
|
|
|
330
352
|
//TODO: check why need
|
|
331
353
|
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
354
|
+
// If this is needed use syncUserState
|
|
355
|
+
//
|
|
356
|
+
// const updateRenderListState = (
|
|
357
|
+
// uid: number,
|
|
358
|
+
// data: Partial<ContentInterface>,
|
|
359
|
+
// ) => {
|
|
360
|
+
// dispatch({type: 'UpdateRenderList', value: [uid, data]});
|
|
361
|
+
// };
|
|
362
|
+
//
|
|
338
363
|
|
|
339
364
|
const addMessageToStore = (uid: UidType, body: messageInterface) => {
|
|
340
365
|
setMessageStore((m: messageStoreInterface[]) => {
|
|
@@ -353,6 +378,7 @@ const ChatMessagesProvider = (props: ChatMessagesProviderProps) => {
|
|
|
353
378
|
fileName: body?.fileName,
|
|
354
379
|
replyToMsgId: body?.replyToMsgId,
|
|
355
380
|
hide: false,
|
|
381
|
+
announcement: body?.announcement,
|
|
356
382
|
},
|
|
357
383
|
];
|
|
358
384
|
});
|
|
@@ -520,6 +546,7 @@ const ChatMessagesProvider = (props: ChatMessagesProviderProps) => {
|
|
|
520
546
|
isPrivateMessage: boolean = false,
|
|
521
547
|
msgType: ChatMessageType,
|
|
522
548
|
forceStop: boolean = false,
|
|
549
|
+
announcement: AnnouncementMessage,
|
|
523
550
|
) => {
|
|
524
551
|
if (isUserBanedRef.current.isUserBaned) {
|
|
525
552
|
return;
|
|
@@ -684,17 +711,22 @@ const ChatMessagesProvider = (props: ChatMessagesProviderProps) => {
|
|
|
684
711
|
primaryBtn: null,
|
|
685
712
|
secondaryBtn: null,
|
|
686
713
|
type: 'info',
|
|
687
|
-
leadingIconName: 'chat-nav',
|
|
688
|
-
text1:
|
|
714
|
+
leadingIconName: announcement ? 'announcement' : 'chat-nav',
|
|
715
|
+
text1: announcement
|
|
716
|
+
? announcement.heading
|
|
717
|
+
: isPrivateMessage
|
|
689
718
|
? privateMessageLabel?.current()
|
|
690
719
|
: //@ts-ignore
|
|
691
|
-
|
|
720
|
+
announcement?.sender
|
|
721
|
+
? announcement.sender
|
|
722
|
+
: defaultContentRef.current.defaultContent[uidAsNumber]?.name
|
|
692
723
|
? fromText(
|
|
693
724
|
trimText(
|
|
694
725
|
//@ts-ignore
|
|
695
726
|
defaultContentRef.current.defaultContent[uidAsNumber]?.name,
|
|
696
727
|
),
|
|
697
728
|
msgType,
|
|
729
|
+
announcement,
|
|
698
730
|
)
|
|
699
731
|
: '',
|
|
700
732
|
text2: isPrivateMessage
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import {View, StyleSheet} from 'react-native';
|
|
3
|
+
import ThemeConfig from '../../theme';
|
|
4
|
+
|
|
5
|
+
interface DividerProps {
|
|
6
|
+
orientation?: 'horizontal' | 'vertical';
|
|
7
|
+
marginTop?: number;
|
|
8
|
+
marginBottom?: number;
|
|
9
|
+
marginLeft?: number;
|
|
10
|
+
marginRight?: number;
|
|
11
|
+
thickness?: number;
|
|
12
|
+
color?: string;
|
|
13
|
+
length?: number | string; // only for vertical dividers
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
const Divider: React.FC<DividerProps> = ({
|
|
17
|
+
orientation = 'horizontal',
|
|
18
|
+
marginTop = 8,
|
|
19
|
+
marginBottom = 8,
|
|
20
|
+
marginLeft = 0,
|
|
21
|
+
marginRight = 0,
|
|
22
|
+
thickness = 1,
|
|
23
|
+
color = $config.CARD_LAYER_4_COLOR,
|
|
24
|
+
length = '100%',
|
|
25
|
+
}) => {
|
|
26
|
+
const isHorizontal = orientation === 'horizontal';
|
|
27
|
+
|
|
28
|
+
const style = isHorizontal
|
|
29
|
+
? {
|
|
30
|
+
height: thickness,
|
|
31
|
+
width: '100%',
|
|
32
|
+
backgroundColor: color,
|
|
33
|
+
marginTop,
|
|
34
|
+
marginBottom,
|
|
35
|
+
}
|
|
36
|
+
: {
|
|
37
|
+
width: thickness,
|
|
38
|
+
height: length,
|
|
39
|
+
backgroundColor: color,
|
|
40
|
+
marginLeft,
|
|
41
|
+
marginRight,
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
return <View style={[styles.base, style]} />;
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
const styles = StyleSheet.create({
|
|
48
|
+
base: {
|
|
49
|
+
backgroundColor: $config.CARD_LAYER_4_COLOR,
|
|
50
|
+
},
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
export default Divider;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import ToolbarItem, {ToolbarItemProps} from '../../../atoms/ToolbarItem';
|
|
3
|
+
import ExitBreakoutRoomIconButton from '../../breakout-room/ui/ExitBreakoutRoomIconButton';
|
|
4
|
+
|
|
5
|
+
export interface Props extends ToolbarItemProps {}
|
|
6
|
+
|
|
7
|
+
export const ExitBreakoutRoomToolbarItem = (props: Props) => {
|
|
8
|
+
return (
|
|
9
|
+
<ToolbarItem testID="exit-breakout-room-btn" toolbarProps={props}>
|
|
10
|
+
<ExitBreakoutRoomIconButton />
|
|
11
|
+
</ToolbarItem>
|
|
12
|
+
);
|
|
13
|
+
};
|
|
@@ -3,7 +3,9 @@ import {useContext} from 'react';
|
|
|
3
3
|
import {ClientRoleType, PropsContext} from '../../../agora-rn-uikit/src';
|
|
4
4
|
import {useRoomInfo} from '../room-info/useRoomInfo';
|
|
5
5
|
import {joinRoomPreference} from '../../utils/useJoinRoom';
|
|
6
|
-
import {isWeb} from '../../utils/common';
|
|
6
|
+
import {isWeb, isWebInternal} from '../../utils/common';
|
|
7
|
+
import {ENABLE_AUTH} from '../../auth/config';
|
|
8
|
+
import {useBreakoutRoomInfo} from '../room-info/useSetBreakoutRoomInfo';
|
|
7
9
|
|
|
8
10
|
/**
|
|
9
11
|
* ControlPermissionKey represents the different keys
|
|
@@ -15,7 +17,12 @@ export type ControlPermissionKey =
|
|
|
15
17
|
| 'participantControl'
|
|
16
18
|
| 'screenshareControl'
|
|
17
19
|
| 'settingsControl'
|
|
18
|
-
| '
|
|
20
|
+
| 'viewAllTextTracksControl'
|
|
21
|
+
| 'breakoutRoomControl'
|
|
22
|
+
| 'whiteboardControl'
|
|
23
|
+
| 'recordingControl'
|
|
24
|
+
| 'captionsControl'
|
|
25
|
+
| 'transcriptsControl';
|
|
19
26
|
|
|
20
27
|
/**
|
|
21
28
|
* ControlPermissionRule defines the properties used to evaluate permission rules.
|
|
@@ -24,6 +31,7 @@ export type ControlPermissionRule = {
|
|
|
24
31
|
isHost: boolean;
|
|
25
32
|
role: ClientRoleType;
|
|
26
33
|
preference: joinRoomPreference;
|
|
34
|
+
isInBreakoutRoom: boolean;
|
|
27
35
|
};
|
|
28
36
|
|
|
29
37
|
export const controlPermissionMatrix: Record<
|
|
@@ -36,12 +44,30 @@ export const controlPermissionMatrix: Record<
|
|
|
36
44
|
settingsControl: ({preference}) => !preference.disableSettings,
|
|
37
45
|
screenshareControl: ({preference}) =>
|
|
38
46
|
$config.SCREEN_SHARING && !preference.disableScreenShare,
|
|
39
|
-
|
|
47
|
+
|
|
48
|
+
viewAllTextTracksControl: ({isHost, isInBreakoutRoom}) =>
|
|
40
49
|
isHost &&
|
|
41
50
|
$config.ENABLE_STT &&
|
|
42
51
|
$config.ENABLE_MEETING_TRANSCRIPT &&
|
|
43
52
|
$config.ENABLE_TEXT_TRACKS &&
|
|
44
|
-
isWeb()
|
|
53
|
+
isWeb() &&
|
|
54
|
+
!isInBreakoutRoom,
|
|
55
|
+
whiteboardControl: ({isHost, isInBreakoutRoom}) =>
|
|
56
|
+
isHost && $config.ENABLE_WHITEBOARD && isWebInternal() && !isInBreakoutRoom,
|
|
57
|
+
recordingControl: ({isHost, isInBreakoutRoom}) =>
|
|
58
|
+
isHost && $config.CLOUD_RECORDING && !isInBreakoutRoom,
|
|
59
|
+
captionsControl: ({isInBreakoutRoom}) =>
|
|
60
|
+
$config.ENABLE_STT && $config.ENABLE_CAPTION && !isInBreakoutRoom,
|
|
61
|
+
transcriptsControl: ({isInBreakoutRoom}) =>
|
|
62
|
+
$config.ENABLE_MEETING_TRANSCRIPT && !isInBreakoutRoom,
|
|
63
|
+
breakoutRoomControl: () =>
|
|
64
|
+
isWeb() &&
|
|
65
|
+
$config.ENABLE_BREAKOUT_ROOM &&
|
|
66
|
+
ENABLE_AUTH &&
|
|
67
|
+
!$config.ENABLE_CONVERSATIONAL_AI &&
|
|
68
|
+
!$config.EVENT_MODE &&
|
|
69
|
+
!$config.RAISE_HAND &&
|
|
70
|
+
!$config.ENABLE_WAITING_ROOM,
|
|
45
71
|
};
|
|
46
72
|
|
|
47
73
|
export const useControlPermissionMatrix = (
|
|
@@ -49,12 +75,14 @@ export const useControlPermissionMatrix = (
|
|
|
49
75
|
): boolean => {
|
|
50
76
|
const {data: roomData, roomPreference} = useRoomInfo();
|
|
51
77
|
const {rtcProps} = useContext(PropsContext);
|
|
78
|
+
const {breakoutRoomChannelData} = useBreakoutRoomInfo();
|
|
52
79
|
|
|
53
80
|
// Build the permission rule context for the current user.
|
|
54
81
|
const rule: ControlPermissionRule = {
|
|
55
82
|
isHost: roomData?.isHost || false,
|
|
56
83
|
role: rtcProps.role,
|
|
57
84
|
preference: {...roomPreference},
|
|
85
|
+
isInBreakoutRoom: breakoutRoomChannelData?.isBreakoutMode || false,
|
|
58
86
|
};
|
|
59
87
|
// Retrieve the permission function for the given key and evaluate it.
|
|
60
88
|
const permissionFn = controlPermissionMatrix[key];
|
|
@@ -73,12 +73,14 @@ export default function AllHostParticipants(props: any) {
|
|
|
73
73
|
isAudienceUser={false}
|
|
74
74
|
name={getParticipantName(localUid)}
|
|
75
75
|
user={defaultContent[localUid]}
|
|
76
|
-
showControls={true}
|
|
76
|
+
showControls={props?.hideControls ? false : true}
|
|
77
77
|
isHostUser={hostUids.indexOf(localUid) !== -1}
|
|
78
78
|
key={localUid}
|
|
79
79
|
isMobile={isMobile}
|
|
80
80
|
handleClose={handleClose}
|
|
81
81
|
updateActionSheet={updateActionSheet}
|
|
82
|
+
showBreakoutRoomMenu={props?.showBreakoutRoomMenu}
|
|
83
|
+
from={props?.from}
|
|
82
84
|
/>
|
|
83
85
|
{renderScreenShare(defaultContent[localUid])}
|
|
84
86
|
</>
|
|
@@ -104,12 +106,18 @@ export default function AllHostParticipants(props: any) {
|
|
|
104
106
|
isAudienceUser={false}
|
|
105
107
|
name={getParticipantName(uid)}
|
|
106
108
|
user={defaultContent[uid]}
|
|
107
|
-
showControls={
|
|
109
|
+
showControls={
|
|
110
|
+
defaultContent[uid]?.type === 'rtc' &&
|
|
111
|
+
isHost &&
|
|
112
|
+
(props?.hideControls ? false : true)
|
|
113
|
+
}
|
|
108
114
|
isHostUser={hostUids.indexOf(uid) !== -1}
|
|
109
115
|
key={uid}
|
|
110
116
|
isMobile={isMobile}
|
|
111
117
|
handleClose={handleClose}
|
|
112
118
|
updateActionSheet={updateActionSheet}
|
|
119
|
+
showBreakoutRoomMenu={props?.showBreakoutRoomMenu}
|
|
120
|
+
from={props?.from}
|
|
113
121
|
/>
|
|
114
122
|
{renderScreenShare(defaultContent[uid])}
|
|
115
123
|
</>
|
|
@@ -66,6 +66,12 @@ interface ParticipantInterface {
|
|
|
66
66
|
updateActionSheet: (screenName: 'chat' | 'participants' | 'settings') => {};
|
|
67
67
|
uid?: UidType;
|
|
68
68
|
screenUid?: UidType;
|
|
69
|
+
showBreakoutRoomMenu?: boolean;
|
|
70
|
+
from?:
|
|
71
|
+
| 'breakout-room'
|
|
72
|
+
| 'partcipant'
|
|
73
|
+
| 'screenshare-participant'
|
|
74
|
+
| 'video-tile';
|
|
69
75
|
}
|
|
70
76
|
|
|
71
77
|
const Participant = (props: ParticipantInterface) => {
|
|
@@ -106,7 +112,7 @@ const Participant = (props: ParticipantInterface) => {
|
|
|
106
112
|
setActionMenuVisible={setActionMenuVisible}
|
|
107
113
|
user={props.user}
|
|
108
114
|
btnRef={moreIconRef}
|
|
109
|
-
from={'partcipant'}
|
|
115
|
+
from={props?.from || 'partcipant'}
|
|
110
116
|
spotlightUid={spotlightUid}
|
|
111
117
|
setSpotlightUid={setSpotlightUid}
|
|
112
118
|
/>
|
|
@@ -77,13 +77,21 @@ import {
|
|
|
77
77
|
DEFAULT_ACTION_KEYS,
|
|
78
78
|
UserActionMenuItemsConfig,
|
|
79
79
|
} from '../../atoms/UserActionMenuPreset';
|
|
80
|
+
import {
|
|
81
|
+
MemberDropdownOption,
|
|
82
|
+
useBreakoutRoom,
|
|
83
|
+
} from '../breakout-room/context/BreakoutRoomContext';
|
|
80
84
|
|
|
81
85
|
interface UserActionMenuOptionsOptionsProps {
|
|
82
86
|
user: ContentInterface;
|
|
83
87
|
actionMenuVisible: boolean;
|
|
84
88
|
setActionMenuVisible: (actionMenuVisible: boolean) => void;
|
|
85
89
|
btnRef: any;
|
|
86
|
-
from:
|
|
90
|
+
from:
|
|
91
|
+
| 'partcipant'
|
|
92
|
+
| 'screenshare-participant'
|
|
93
|
+
| 'video-tile'
|
|
94
|
+
| 'breakout-room';
|
|
87
95
|
spotlightUid?: UidType;
|
|
88
96
|
setSpotlightUid?: (uid: UidType) => void;
|
|
89
97
|
items?: UserActionMenuItemsConfig;
|
|
@@ -102,7 +110,8 @@ export default function UserActionMenuOptionsOptions(
|
|
|
102
110
|
useState(false);
|
|
103
111
|
const [actionMenuitems, setActionMenuitems] = useState<ActionMenuItem[]>([]);
|
|
104
112
|
const {setSidePanel} = useSidePanel();
|
|
105
|
-
const {user, actionMenuVisible, setActionMenuVisible, spotlightUid} =
|
|
113
|
+
const {user, actionMenuVisible, setActionMenuVisible, spotlightUid, from} =
|
|
114
|
+
props;
|
|
106
115
|
const {currentLayout} = useLayout();
|
|
107
116
|
const {pinnedUid, activeUids, customContent, secondaryPinnedUid} =
|
|
108
117
|
useContent();
|
|
@@ -729,6 +738,7 @@ export default function UserActionMenuOptionsOptions(
|
|
|
729
738
|
secondaryPinnedUid,
|
|
730
739
|
currentLayout,
|
|
731
740
|
spotlightUid,
|
|
741
|
+
from,
|
|
732
742
|
]);
|
|
733
743
|
|
|
734
744
|
const {width: globalWidth, height: globalHeight} = useWindowDimensions();
|
|
@@ -39,6 +39,7 @@ import {
|
|
|
39
39
|
waitingRoomHostNotJoined,
|
|
40
40
|
waitingRoomUsersInCall,
|
|
41
41
|
} from '../../language/default-labels/videoCallScreenLabels';
|
|
42
|
+
import ChatContext from '../ChatContext';
|
|
42
43
|
|
|
43
44
|
export interface PreCallJoinWaitingRoomBtnProps {
|
|
44
45
|
render?: (
|
|
@@ -58,6 +59,7 @@ const JoinWaitingRoomBtn = (props: PreCallJoinWaitingRoomBtnProps) => {
|
|
|
58
59
|
const waitingRoomUsersInCallText = useString(waitingRoomUsersInCall);
|
|
59
60
|
let pollingTimeout = React.useRef(null);
|
|
60
61
|
const {rtcProps} = useContext(PropsContext);
|
|
62
|
+
const {syncUserState} = useContext(ChatContext);
|
|
61
63
|
const {setCallActive, callActive} = usePreCall();
|
|
62
64
|
const username = useGetName();
|
|
63
65
|
const {isJoinDataFetched, isInWaitingRoom} = useRoomInfo();
|
|
@@ -139,10 +141,11 @@ const JoinWaitingRoomBtn = (props: PreCallJoinWaitingRoomBtnProps) => {
|
|
|
139
141
|
if (callActive) return;
|
|
140
142
|
// on approve/reject response from host, waiting room permission is reset
|
|
141
143
|
// update waitinng room status on uid
|
|
142
|
-
dispatch({
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
});
|
|
144
|
+
// dispatch({
|
|
145
|
+
// type: 'UpdateRenderList',
|
|
146
|
+
// value: [localUid, {isInWaitingRoom: false}],
|
|
147
|
+
// });
|
|
148
|
+
syncUserState(localUid, {isInWaitingRoom: false});
|
|
146
149
|
|
|
147
150
|
if (approved) {
|
|
148
151
|
setRoomInfo(prev => {
|
|
@@ -219,10 +222,11 @@ const JoinWaitingRoomBtn = (props: PreCallJoinWaitingRoomBtnProps) => {
|
|
|
219
222
|
});
|
|
220
223
|
|
|
221
224
|
// add the waitingRoomStatus to the uid
|
|
222
|
-
dispatch({
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
});
|
|
225
|
+
// dispatch({
|
|
226
|
+
// type: 'UpdateRenderList',
|
|
227
|
+
// value: [localUid, {isInWaitingRoom: true}],
|
|
228
|
+
// });
|
|
229
|
+
syncUserState(localUid, {isInWaitingRoom: true});
|
|
226
230
|
|
|
227
231
|
// join request API to server, server will send RTM message to all hosts regarding request from this user,
|
|
228
232
|
requestServerToJoinRoom();
|
|
@@ -45,6 +45,7 @@ import {
|
|
|
45
45
|
waitingRoomHostNotJoined,
|
|
46
46
|
waitingRoomUsersInCall,
|
|
47
47
|
} from '../../language/default-labels/videoCallScreenLabels';
|
|
48
|
+
import ChatContext from '../ChatContext';
|
|
48
49
|
|
|
49
50
|
const audio = new Audio(
|
|
50
51
|
'https://dl.dropboxusercontent.com/s/1cdwpm3gca9mlo0/kick.mp3',
|
|
@@ -84,7 +85,7 @@ const JoinWaitingRoomBtn = (props: PreCallJoinWaitingRoomBtnProps) => {
|
|
|
84
85
|
|
|
85
86
|
const localUid = useLocalUid();
|
|
86
87
|
const {dispatch} = useContext(DispatchContext);
|
|
87
|
-
|
|
88
|
+
const {syncUserState} = useContext(ChatContext);
|
|
88
89
|
const [buttonText, setButtonText] = React.useState(
|
|
89
90
|
waitingRoomButton({
|
|
90
91
|
ready: isInWaitingRoom,
|
|
@@ -144,10 +145,11 @@ const JoinWaitingRoomBtn = (props: PreCallJoinWaitingRoomBtnProps) => {
|
|
|
144
145
|
if (callActive) return;
|
|
145
146
|
// on approve/reject response from host, waiting room permission is reset
|
|
146
147
|
// update waitinng room status on uid
|
|
147
|
-
dispatch({
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
});
|
|
148
|
+
// dispatch({
|
|
149
|
+
// type: 'UpdateRenderList',
|
|
150
|
+
// value: [localUid, {isInWaitingRoom: false}],
|
|
151
|
+
// });
|
|
152
|
+
syncUserState(localUid, {isInWaitingRoom: false});
|
|
151
153
|
|
|
152
154
|
if (approved) {
|
|
153
155
|
setRoomInfo(prev => {
|
|
@@ -241,10 +243,12 @@ const JoinWaitingRoomBtn = (props: PreCallJoinWaitingRoomBtnProps) => {
|
|
|
241
243
|
//setCallActive(true);
|
|
242
244
|
|
|
243
245
|
// add the waitingRoomStatus to the uid
|
|
244
|
-
dispatch({
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
});
|
|
246
|
+
// dispatch({
|
|
247
|
+
// type: 'UpdateRenderList',
|
|
248
|
+
// value: [localUid, {isInWaitingRoom: true}],
|
|
249
|
+
// });
|
|
250
|
+
syncUserState(localUid, {isInWaitingRoom: true});
|
|
251
|
+
|
|
248
252
|
// Enter waiting rooom;
|
|
249
253
|
setRoomInfo(prev => {
|
|
250
254
|
return {...prev, isInWaitingRoom: true};
|
|
@@ -281,7 +285,7 @@ const JoinWaitingRoomBtn = (props: PreCallJoinWaitingRoomBtnProps) => {
|
|
|
281
285
|
const title = buttonText;
|
|
282
286
|
const onPress = () => onSubmit();
|
|
283
287
|
const disabled = $config.ENABLE_WAITING_ROOM_AUTO_REQUEST
|
|
284
|
-
? !hasHostJoined || isInWaitingRoom ||
|
|
288
|
+
? !hasHostJoined || isInWaitingRoom || username?.trim() === ''
|
|
285
289
|
: isInWaitingRoom || username?.trim() === '';
|
|
286
290
|
return props?.render ? (
|
|
287
291
|
props.render(onPress, title, disabled)
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/*
|
|
2
|
+
********************************************
|
|
3
|
+
Copyright © 2021 Agora Lab, Inc., all rights reserved.
|
|
4
|
+
AppBuilder and all associated components, source code, APIs, services, and documentation
|
|
5
|
+
(the "Materials") are owned by Agora Lab, Inc. and its licensors. The Materials may not be
|
|
6
|
+
accessed, used, modified, or distributed for any purpose without a license from Agora Lab, Inc.
|
|
7
|
+
Use without a license or in violation of any license terms and conditions (including use for
|
|
8
|
+
any purpose competitive to Agora Lab, Inc.'s business) is strictly prohibited. For more
|
|
9
|
+
information visit https://appbuilder.agora.io.
|
|
10
|
+
*********************************************
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
import React from 'react';
|
|
14
|
+
import {useRaiseHand} from './RaiseHandProvider';
|
|
15
|
+
import {StyleSheet} from 'react-native';
|
|
16
|
+
import ThemeConfig from '../../theme';
|
|
17
|
+
import TertiaryButton from '../../atoms/TertiaryButton';
|
|
18
|
+
|
|
19
|
+
const RaiseHandButton: React.FC = () => {
|
|
20
|
+
const {isHandRaised, toggleHand} = useRaiseHand();
|
|
21
|
+
|
|
22
|
+
return (
|
|
23
|
+
<TertiaryButton
|
|
24
|
+
containerStyle={style.raiseHandBtn}
|
|
25
|
+
textStyle={style.raiseHandBtnText}
|
|
26
|
+
text={isHandRaised ? 'Lower Hand' : 'Raise Hand'}
|
|
27
|
+
iconName={isHandRaised ? 'lower-hand' : 'raise-hand'}
|
|
28
|
+
iconColor={$config.SEMANTIC_WARNING}
|
|
29
|
+
iconSize={15}
|
|
30
|
+
onPress={toggleHand}
|
|
31
|
+
/>
|
|
32
|
+
);
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
export default RaiseHandButton;
|
|
36
|
+
|
|
37
|
+
const style = StyleSheet.create({
|
|
38
|
+
raiseHandBtn: {
|
|
39
|
+
width: '100%',
|
|
40
|
+
borderRadius: 4,
|
|
41
|
+
borderColor: $config.SECONDARY_ACTION_COLOR,
|
|
42
|
+
backgroundColor: 'transparent',
|
|
43
|
+
},
|
|
44
|
+
raiseHandBtnText: {
|
|
45
|
+
textAlign: 'center',
|
|
46
|
+
color: $config.SECONDARY_ACTION_COLOR,
|
|
47
|
+
fontSize: ThemeConfig.FontSize.small,
|
|
48
|
+
lineHeight: 16,
|
|
49
|
+
},
|
|
50
|
+
});
|