agora-appbuilder-core 4.1.10-beta.1 → 4.1.11-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 +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
|
@@ -1,53 +0,0 @@
|
|
|
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;
|
|
@@ -1,13 +0,0 @@
|
|
|
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
|
-
};
|
|
@@ -1,50 +0,0 @@
|
|
|
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
|
-
});
|
|
@@ -1,308 +0,0 @@
|
|
|
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, {
|
|
14
|
-
createContext,
|
|
15
|
-
useContext,
|
|
16
|
-
useState,
|
|
17
|
-
useEffect,
|
|
18
|
-
useCallback,
|
|
19
|
-
} from 'react';
|
|
20
|
-
import {useCurrentRoomInfo} from '../room-info/useCurrentRoomInfo';
|
|
21
|
-
import {useLocalUid} from '../../../agora-rn-uikit';
|
|
22
|
-
import events, {PersistanceLevel} from '../../rtm-events-api';
|
|
23
|
-
import Toast from '../../../react-native-toast-message';
|
|
24
|
-
import {useMainRoomUserDisplayName} from '../../rtm/hooks/useMainRoomUserDisplayName';
|
|
25
|
-
import {EventNames} from '../../rtm-events';
|
|
26
|
-
import {useRoomInfo} from '../room-info/useRoomInfo';
|
|
27
|
-
import {useBreakoutRoomInfo} from '../room-info/useSetBreakoutRoomInfo';
|
|
28
|
-
|
|
29
|
-
interface RaiseHandData {
|
|
30
|
-
raised: boolean;
|
|
31
|
-
timestamp: number;
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
interface RaiseHandState {
|
|
35
|
-
// State
|
|
36
|
-
raisedHands: Record<number, RaiseHandData>;
|
|
37
|
-
isHandRaised: boolean;
|
|
38
|
-
isUserHandRaised: (uid: number) => boolean;
|
|
39
|
-
|
|
40
|
-
// Actions
|
|
41
|
-
raiseHand: () => void;
|
|
42
|
-
lowerHand: () => void;
|
|
43
|
-
toggleHand: () => void;
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
const RaiseHandContext = createContext<RaiseHandState>({
|
|
47
|
-
raisedHands: {},
|
|
48
|
-
isHandRaised: false,
|
|
49
|
-
isUserHandRaised: () => false,
|
|
50
|
-
raiseHand: () => {},
|
|
51
|
-
lowerHand: () => {},
|
|
52
|
-
toggleHand: () => {},
|
|
53
|
-
});
|
|
54
|
-
|
|
55
|
-
interface RaiseHandProviderProps {
|
|
56
|
-
children: React.ReactNode;
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
export const RaiseHandProvider: React.FC<RaiseHandProviderProps> = ({
|
|
60
|
-
children,
|
|
61
|
-
}) => {
|
|
62
|
-
const [raisedHands, setRaisedHands] = useState<Record<number, RaiseHandData>>(
|
|
63
|
-
{},
|
|
64
|
-
);
|
|
65
|
-
const localUid = useLocalUid();
|
|
66
|
-
const getDisplayName = useMainRoomUserDisplayName();
|
|
67
|
-
const {
|
|
68
|
-
data: {channel: mainChannelId},
|
|
69
|
-
} = useRoomInfo();
|
|
70
|
-
const {isInBreakoutRoute} = useCurrentRoomInfo();
|
|
71
|
-
const {breakoutRoomChannelData} = useBreakoutRoomInfo();
|
|
72
|
-
|
|
73
|
-
// Get current user's hand state
|
|
74
|
-
const isHandRaised = raisedHands[localUid]?.raised || false;
|
|
75
|
-
|
|
76
|
-
// Detect room changes and lower hand if raised
|
|
77
|
-
useEffect(() => {
|
|
78
|
-
// Send RTM event to reset attribute only if hand is raised
|
|
79
|
-
return () => {
|
|
80
|
-
if (isHandRaised) {
|
|
81
|
-
events.send(
|
|
82
|
-
EventNames.BREAKOUT_RAISE_HAND_ATTRIBUTE,
|
|
83
|
-
JSON.stringify({
|
|
84
|
-
uid: localUid,
|
|
85
|
-
raised: false,
|
|
86
|
-
timestamp: Date.now(),
|
|
87
|
-
}),
|
|
88
|
-
PersistanceLevel.Sender,
|
|
89
|
-
);
|
|
90
|
-
}
|
|
91
|
-
};
|
|
92
|
-
}, [localUid, isHandRaised]);
|
|
93
|
-
|
|
94
|
-
// Check if any user has hand raised
|
|
95
|
-
const isUserHandRaised = useCallback(
|
|
96
|
-
(uid: number): boolean => {
|
|
97
|
-
return raisedHands[uid]?.raised || false;
|
|
98
|
-
},
|
|
99
|
-
[raisedHands],
|
|
100
|
-
);
|
|
101
|
-
|
|
102
|
-
// Raise hand action
|
|
103
|
-
const raiseHand = useCallback(() => {
|
|
104
|
-
if (isHandRaised) {
|
|
105
|
-
return;
|
|
106
|
-
} // Already raised
|
|
107
|
-
|
|
108
|
-
const timestamp = Date.now();
|
|
109
|
-
const userName = getDisplayName(localUid) || `User ${localUid}`;
|
|
110
|
-
|
|
111
|
-
// Update local state immediately
|
|
112
|
-
setRaisedHands(prev => ({...prev, [localUid]: {raised: true, timestamp}}));
|
|
113
|
-
|
|
114
|
-
// 1. Send RTM attribute event (for current room UI)
|
|
115
|
-
events.send(
|
|
116
|
-
EventNames.BREAKOUT_RAISE_HAND_ATTRIBUTE,
|
|
117
|
-
JSON.stringify({
|
|
118
|
-
uid: localUid,
|
|
119
|
-
raised: true,
|
|
120
|
-
timestamp,
|
|
121
|
-
}),
|
|
122
|
-
PersistanceLevel.Sender,
|
|
123
|
-
);
|
|
124
|
-
|
|
125
|
-
// 2. Send cross-room notification to main room (if in breakout room)
|
|
126
|
-
if (isInBreakoutRoute) {
|
|
127
|
-
try {
|
|
128
|
-
// Get current active channel to restore later
|
|
129
|
-
events.send(
|
|
130
|
-
EventNames.CROSS_ROOM_RAISE_HAND_NOTIFICATION,
|
|
131
|
-
JSON.stringify({
|
|
132
|
-
type: 'raise_hand',
|
|
133
|
-
uid: localUid,
|
|
134
|
-
userName: userName,
|
|
135
|
-
roomName: breakoutRoomChannelData?.room_name || '',
|
|
136
|
-
timestamp,
|
|
137
|
-
}),
|
|
138
|
-
PersistanceLevel.None,
|
|
139
|
-
-1, // send in channel
|
|
140
|
-
mainChannelId, // send to main channel
|
|
141
|
-
);
|
|
142
|
-
} catch (error) {
|
|
143
|
-
console.error(
|
|
144
|
-
'Failed to send cross-room raise hand notification:',
|
|
145
|
-
error,
|
|
146
|
-
);
|
|
147
|
-
}
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
// Show toast notification
|
|
151
|
-
Toast.show({
|
|
152
|
-
type: 'success',
|
|
153
|
-
leadingIconName: 'raise-hand',
|
|
154
|
-
text1: 'Hand raised',
|
|
155
|
-
visibilityTime: 2000,
|
|
156
|
-
});
|
|
157
|
-
}, [
|
|
158
|
-
isHandRaised,
|
|
159
|
-
localUid,
|
|
160
|
-
getDisplayName,
|
|
161
|
-
isInBreakoutRoute,
|
|
162
|
-
mainChannelId,
|
|
163
|
-
breakoutRoomChannelData?.room_name,
|
|
164
|
-
]);
|
|
165
|
-
|
|
166
|
-
// Lower hand action
|
|
167
|
-
const lowerHand = useCallback(() => {
|
|
168
|
-
if (!isHandRaised) {
|
|
169
|
-
return;
|
|
170
|
-
} // Already lowered
|
|
171
|
-
|
|
172
|
-
// Update local state immediately (keep timestamp but set raised to false)
|
|
173
|
-
setRaisedHands(prev => ({
|
|
174
|
-
...prev,
|
|
175
|
-
[localUid]: {raised: false, timestamp: Date.now()},
|
|
176
|
-
}));
|
|
177
|
-
|
|
178
|
-
// Send RTM event
|
|
179
|
-
events.send(
|
|
180
|
-
EventNames.BREAKOUT_RAISE_HAND_ATTRIBUTE,
|
|
181
|
-
JSON.stringify({
|
|
182
|
-
uid: localUid,
|
|
183
|
-
raised: false,
|
|
184
|
-
timestamp: Date.now(),
|
|
185
|
-
}),
|
|
186
|
-
PersistanceLevel.Sender,
|
|
187
|
-
);
|
|
188
|
-
|
|
189
|
-
// // Show toast notification
|
|
190
|
-
// Toast.show({
|
|
191
|
-
// type: 'info',
|
|
192
|
-
// text1: 'Hand lowered',
|
|
193
|
-
// visibilityTime: 2000,
|
|
194
|
-
// });
|
|
195
|
-
}, [isHandRaised, localUid]);
|
|
196
|
-
|
|
197
|
-
// Toggle hand action
|
|
198
|
-
const toggleHand = useCallback(() => {
|
|
199
|
-
if (isHandRaised) {
|
|
200
|
-
lowerHand();
|
|
201
|
-
} else {
|
|
202
|
-
raiseHand();
|
|
203
|
-
}
|
|
204
|
-
}, [isHandRaised, raiseHand, lowerHand]);
|
|
205
|
-
|
|
206
|
-
// Listen for RTM events
|
|
207
|
-
useEffect(() => {
|
|
208
|
-
const handleRaiseHandEvent = (data: any) => {
|
|
209
|
-
try {
|
|
210
|
-
const {payload} = data;
|
|
211
|
-
const eventData = JSON.parse(payload);
|
|
212
|
-
const {uid, raised, timestamp} = eventData;
|
|
213
|
-
// Update raised hands state
|
|
214
|
-
setRaisedHands(prev => ({
|
|
215
|
-
...prev,
|
|
216
|
-
[uid]: {raised, timestamp},
|
|
217
|
-
}));
|
|
218
|
-
|
|
219
|
-
// Show toast for other users (not for self)
|
|
220
|
-
if (uid !== localUid) {
|
|
221
|
-
const userName = getDisplayName(uid) || `User ${uid}`;
|
|
222
|
-
Toast.show({
|
|
223
|
-
leadingIconName: raised ? 'raise-hand' : 'lower-hand',
|
|
224
|
-
type: 'info',
|
|
225
|
-
text1: raised
|
|
226
|
-
? `${userName} raised hand`
|
|
227
|
-
: `${userName} lowered hand`,
|
|
228
|
-
visibilityTime: 3000,
|
|
229
|
-
});
|
|
230
|
-
}
|
|
231
|
-
} catch (error) {
|
|
232
|
-
console.error('Failed to process raise hand event:', error);
|
|
233
|
-
}
|
|
234
|
-
};
|
|
235
|
-
|
|
236
|
-
const handleCrossRoomNotification = (data: any) => {
|
|
237
|
-
try {
|
|
238
|
-
const {payload} = data;
|
|
239
|
-
const eventData = JSON.parse(payload);
|
|
240
|
-
const {type, uid, userName, roomName} = eventData;
|
|
241
|
-
|
|
242
|
-
// Only show notifications for other users and only in main room
|
|
243
|
-
if (uid !== localUid && !isInBreakoutRoute) {
|
|
244
|
-
if (type === 'raise_hand') {
|
|
245
|
-
Toast.show({
|
|
246
|
-
type: 'info',
|
|
247
|
-
leadingIconName: 'raise-hand',
|
|
248
|
-
text1: `${userName} raised hand in ${roomName}`,
|
|
249
|
-
visibilityTime: 4000,
|
|
250
|
-
});
|
|
251
|
-
}
|
|
252
|
-
}
|
|
253
|
-
} catch (error) {
|
|
254
|
-
console.error('Failed to process cross-room notification:', error);
|
|
255
|
-
}
|
|
256
|
-
};
|
|
257
|
-
|
|
258
|
-
// Register event listeners
|
|
259
|
-
events.on(EventNames.BREAKOUT_RAISE_HAND_ATTRIBUTE, handleRaiseHandEvent);
|
|
260
|
-
events.on(
|
|
261
|
-
EventNames.CROSS_ROOM_RAISE_HAND_NOTIFICATION,
|
|
262
|
-
handleCrossRoomNotification,
|
|
263
|
-
);
|
|
264
|
-
|
|
265
|
-
return () => {
|
|
266
|
-
// Cleanup event listeners
|
|
267
|
-
events.off(
|
|
268
|
-
EventNames.BREAKOUT_RAISE_HAND_ATTRIBUTE,
|
|
269
|
-
handleRaiseHandEvent,
|
|
270
|
-
);
|
|
271
|
-
events.off(
|
|
272
|
-
EventNames.CROSS_ROOM_RAISE_HAND_NOTIFICATION,
|
|
273
|
-
handleCrossRoomNotification,
|
|
274
|
-
);
|
|
275
|
-
};
|
|
276
|
-
}, [localUid, getDisplayName, isInBreakoutRoute]);
|
|
277
|
-
|
|
278
|
-
// Clear raised hands when room changes (optional: could be handled by RTM attribute clearing)
|
|
279
|
-
useEffect(() => {
|
|
280
|
-
setRaisedHands({});
|
|
281
|
-
}, []);
|
|
282
|
-
|
|
283
|
-
const contextValue: RaiseHandState = {
|
|
284
|
-
raisedHands,
|
|
285
|
-
isHandRaised,
|
|
286
|
-
isUserHandRaised,
|
|
287
|
-
raiseHand,
|
|
288
|
-
lowerHand,
|
|
289
|
-
toggleHand,
|
|
290
|
-
};
|
|
291
|
-
|
|
292
|
-
return (
|
|
293
|
-
<RaiseHandContext.Provider value={contextValue}>
|
|
294
|
-
{children}
|
|
295
|
-
</RaiseHandContext.Provider>
|
|
296
|
-
);
|
|
297
|
-
};
|
|
298
|
-
|
|
299
|
-
// Hook to use raise hand functionality
|
|
300
|
-
export const useRaiseHand = (): RaiseHandState => {
|
|
301
|
-
const context = useContext(RaiseHandContext);
|
|
302
|
-
if (!context) {
|
|
303
|
-
throw new Error('useRaiseHand must be used within RaiseHandProvider');
|
|
304
|
-
}
|
|
305
|
-
return context;
|
|
306
|
-
};
|
|
307
|
-
|
|
308
|
-
export default RaiseHandProvider;
|
|
@@ -1,14 +0,0 @@
|
|
|
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
|
-
export {default as RaiseHandProvider, useRaiseHand} from './RaiseHandProvider';
|
|
14
|
-
export {default as RaiseHandButton} from './RaiseHandButton';
|
|
@@ -1,42 +0,0 @@
|
|
|
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 {useLocation} from '../Router';
|
|
14
|
-
import {useRoomInfo} from './useRoomInfo';
|
|
15
|
-
import {useBreakoutRoomInfo} from './useSetBreakoutRoomInfo';
|
|
16
|
-
|
|
17
|
-
export interface CurrentRoomInfoContextInterface {
|
|
18
|
-
isInBreakoutRoute: boolean;
|
|
19
|
-
channelId: string;
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
export const useCurrentRoomInfo = (): CurrentRoomInfoContextInterface => {
|
|
23
|
-
const mainRoomInfo = useRoomInfo(); // Always call - keeps public API intact
|
|
24
|
-
const {breakoutRoomChannelData} = useBreakoutRoomInfo(); // Always call - follows Rules of Hooks
|
|
25
|
-
const location = useLocation();
|
|
26
|
-
|
|
27
|
-
const isBreakoutMode =
|
|
28
|
-
new URLSearchParams(location.search).get('breakout') === 'true';
|
|
29
|
-
|
|
30
|
-
// Return overlapping data structure
|
|
31
|
-
if (isBreakoutMode && breakoutRoomChannelData) {
|
|
32
|
-
return {
|
|
33
|
-
isInBreakoutRoute: true,
|
|
34
|
-
channelId: breakoutRoomChannelData.channelId,
|
|
35
|
-
};
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
return {
|
|
39
|
-
isInBreakoutRoute: false,
|
|
40
|
-
channelId: mainRoomInfo.data.channel,
|
|
41
|
-
};
|
|
42
|
-
};
|
|
@@ -1,64 +0,0 @@
|
|
|
1
|
-
import React, {createContext, useContext, useState} from 'react';
|
|
2
|
-
import {BreakoutChannelJoinEventPayload} from '../breakout-room/state/types';
|
|
3
|
-
|
|
4
|
-
type BreakoutRoomData = BreakoutChannelJoinEventPayload['data']['data'] & {
|
|
5
|
-
isBreakoutMode: boolean;
|
|
6
|
-
};
|
|
7
|
-
|
|
8
|
-
interface BreakoutRoomInfoContextValue {
|
|
9
|
-
breakoutRoomChannelData: BreakoutRoomData | null;
|
|
10
|
-
setBreakoutRoomChannelData: React.Dispatch<
|
|
11
|
-
React.SetStateAction<BreakoutRoomData | null>
|
|
12
|
-
>;
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
const BreakoutRoomInfoContext = createContext<BreakoutRoomInfoContextValue>({
|
|
16
|
-
breakoutRoomChannelData: null,
|
|
17
|
-
setBreakoutRoomChannelData: () => {},
|
|
18
|
-
});
|
|
19
|
-
|
|
20
|
-
interface BreakoutRoomInfoProviderProps {
|
|
21
|
-
children: React.ReactNode;
|
|
22
|
-
initialData?: BreakoutRoomData | null;
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
export const BreakoutRoomInfoProvider: React.FC<
|
|
26
|
-
BreakoutRoomInfoProviderProps
|
|
27
|
-
> = ({children, initialData = null}) => {
|
|
28
|
-
const [breakoutRoomChannelData, setBreakoutRoomChannelData] =
|
|
29
|
-
useState<BreakoutRoomData | null>(initialData);
|
|
30
|
-
|
|
31
|
-
return (
|
|
32
|
-
<BreakoutRoomInfoContext.Provider
|
|
33
|
-
value={{breakoutRoomChannelData, setBreakoutRoomChannelData}}>
|
|
34
|
-
{children}
|
|
35
|
-
</BreakoutRoomInfoContext.Provider>
|
|
36
|
-
);
|
|
37
|
-
};
|
|
38
|
-
|
|
39
|
-
export const useBreakoutRoomInfo = () => {
|
|
40
|
-
return useContext(BreakoutRoomInfoContext);
|
|
41
|
-
};
|
|
42
|
-
|
|
43
|
-
export const useSetBreakoutRoomInfo = () => {
|
|
44
|
-
const {setBreakoutRoomChannelData} = useBreakoutRoomInfo();
|
|
45
|
-
|
|
46
|
-
const setBreakoutRoomChannelInfo = (
|
|
47
|
-
breakoutJoinChannelDetails: BreakoutRoomData,
|
|
48
|
-
) => {
|
|
49
|
-
const breakoutData: BreakoutRoomData = {
|
|
50
|
-
isBreakoutMode: true,
|
|
51
|
-
...breakoutJoinChannelDetails,
|
|
52
|
-
};
|
|
53
|
-
setBreakoutRoomChannelData(breakoutData);
|
|
54
|
-
};
|
|
55
|
-
|
|
56
|
-
const clearBreakoutRoomChannelInfo = () => {
|
|
57
|
-
setBreakoutRoomChannelData(null);
|
|
58
|
-
};
|
|
59
|
-
|
|
60
|
-
return {
|
|
61
|
-
setBreakoutRoomChannelInfo,
|
|
62
|
-
clearBreakoutRoomChannelInfo,
|
|
63
|
-
};
|
|
64
|
-
};
|