agora-appbuilder-core 3.0.9 → 3.0.10
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/Readme.md +6 -0
- package/package.json +2 -2
- package/template/_package-lock.json +5871 -4728
- package/template/agora-rn-uikit/src/Contexts/LocalUserContext.tsx +4 -0
- package/template/agora-rn-uikit/src/Contexts/PropsContext.tsx +18 -0
- package/template/agora-rn-uikit/src/Contexts/RtcContext.tsx +2 -0
- package/template/agora-rn-uikit/src/Controls/BtnTemplate.tsx +30 -26
- package/template/agora-rn-uikit/src/Controls/Icons.ts +30 -83
- package/template/agora-rn-uikit/src/Controls/ImageIcon.tsx +6 -6
- package/template/agora-rn-uikit/src/Reducer/ActiveSpeakerDetected.ts +11 -0
- package/template/agora-rn-uikit/src/Reducer/LocalMuteAudio.ts +1 -0
- package/template/agora-rn-uikit/src/Reducer/LocalMuteVideo.ts +1 -0
- package/template/agora-rn-uikit/src/Reducer/LocalPermissionState.ts +24 -0
- package/template/agora-rn-uikit/src/Reducer/RemoteAudioStateChanged.ts +1 -0
- package/template/agora-rn-uikit/src/Reducer/RemoteVideoStateChanged.ts +1 -0
- package/template/agora-rn-uikit/src/Reducer/UpdateDualStreamMode.ts +1 -0
- package/template/agora-rn-uikit/src/Reducer/UserJoined.ts +2 -0
- package/template/agora-rn-uikit/src/Reducer/UserMuteRemoteAudio.ts +1 -0
- package/template/agora-rn-uikit/src/Reducer/UserMuteRemoteVideo.ts +1 -0
- package/template/agora-rn-uikit/src/Reducer/UserOffline.ts +1 -0
- package/template/agora-rn-uikit/src/Reducer/UserPin.ts +11 -0
- package/template/agora-rn-uikit/src/Reducer/index.ts +3 -0
- package/template/agora-rn-uikit/src/Rtc/Create.tsx +89 -1
- package/template/agora-rn-uikit/src/RtcConfigure.tsx +39 -2
- package/template/agora-rn-uikit/src/Views/MaxVideoView.native.tsx +15 -5
- package/template/agora-rn-uikit/src/Views/MaxVideoView.tsx +15 -9
- package/template/agora-rn-uikit/src/index.ts +3 -1
- package/template/android/app/build.gradle +1 -0
- package/template/android/app/src/main/AndroidManifest.xml +22 -15
- package/template/android/app/src/main/assets/fonts/SourceSansPro-Regular.ttf +0 -0
- package/template/android/app/src/main/assets/fonts/icomoon.ttf +0 -0
- package/template/android/app/src/main/java/com/helloworld/MainActivity.java +50 -0
- package/template/android/app/src/main/res/values/colors.xml +7 -0
- package/template/android/build.gradle +3 -3
- package/template/babel.config.js +1 -0
- package/template/bridge/rtc/webNg/RtcEngine.ts +110 -17
- package/template/customization-api/sub-components.ts +1 -1
- package/template/customization-api/typeDefinition.ts +2 -1
- package/template/electron/index.html +27 -27
- package/template/electron/renderer/index.js +1 -0
- package/template/global.d.ts +25 -4
- package/template/index.rsdk.tsx +1 -0
- package/template/index.web.js +2 -1
- package/template/index.wsdk.tsx +1 -1
- package/template/ios/HelloWorld/Info.plist +14 -1
- package/template/ios/HelloWorld.xcodeproj/project.pbxproj +17 -0
- package/template/metro.config.js +1 -1
- package/template/package.json +18 -7
- package/template/react-native-toast-message/index.d.ts +43 -43
- package/template/react-native-toast-message/src/colors/index.js +3 -2
- package/template/react-native-toast-message/src/components/base/index.js +46 -59
- package/template/react-native-toast-message/src/components/base/styles.js +16 -32
- package/template/react-native-toast-message/src/components/checkbox.js +178 -0
- package/template/react-native-toast-message/src/components/error.js +3 -2
- package/template/react-native-toast-message/src/components/info.js +3 -2
- package/template/react-native-toast-message/src/components/success.js +3 -2
- package/template/react-native-toast-message/src/index.js +122 -31
- package/template/react-native-toast-message/src/index.sdk.tsx +125 -35
- package/template/react-native-toast-message/src/styles.js +3 -4
- package/template/react-native-toast-message/src/styles.sdk.ts +3 -4
- package/template/react-native.config.js +7 -0
- package/template/src/App.tsx +6 -0
- package/template/src/AppWrapper.tsx +63 -28
- package/template/src/assets/font-styles.css +329 -0
- package/template/src/assets/fonts/SourceSansPro-Regular.ttf +0 -0
- package/template/src/assets/fonts/icomoon.ttf +0 -0
- package/template/src/assets/permission.png +0 -0
- package/template/src/assets/selection.json +1 -0
- package/template/src/atoms/ActionMenu.tsx +236 -0
- package/template/src/atoms/AnimatedActiveSpeaker.native.tsx +71 -0
- package/template/src/atoms/AnimatedActiveSpeaker.tsx +84 -0
- package/template/src/atoms/AnimatedRings.native.tsx +68 -0
- package/template/src/atoms/AnimatedRings.tsx +70 -0
- package/template/src/atoms/Card.tsx +61 -0
- package/template/src/atoms/CircularProgress.native.tsx +121 -0
- package/template/src/atoms/CircularProgress.tsx +102 -0
- package/template/src/atoms/CustomIcon.tsx +88 -0
- package/template/src/atoms/CustomSwitch.tsx +287 -0
- package/template/src/atoms/Dropdown.tsx +306 -0
- package/template/src/atoms/HorizontalRule.tsx +3 -1
- package/template/src/atoms/IconButton.tsx +162 -0
- package/template/src/atoms/ImageIcon.tsx +98 -0
- package/template/src/atoms/InfoBubble.tsx +291 -0
- package/template/src/atoms/Input.tsx +87 -0
- package/template/src/atoms/InviteInfo.tsx +166 -0
- package/template/src/atoms/LinkButton.tsx +28 -0
- package/template/src/atoms/OutlineButton.tsx +61 -0
- package/template/src/atoms/ParticipantsCount.tsx +73 -0
- package/template/src/atoms/Popup.tsx +147 -0
- package/template/src/atoms/PrimaryButton.tsx +51 -26
- package/template/src/atoms/RecordingInfo.tsx +49 -0
- package/template/src/atoms/SecondaryButton.tsx +8 -5
- package/template/src/atoms/Spacer.tsx +22 -0
- package/template/src/atoms/TertiaryButton.tsx +78 -0
- package/template/src/atoms/TextInput.tsx +12 -14
- package/template/src/atoms/Toggle.tsx +47 -0
- package/template/src/atoms/Tooltip.native.tsx +65 -0
- package/template/src/atoms/Tooltip.tsx +94 -0
- package/template/src/atoms/UserAvatar.tsx +60 -0
- package/template/src/components/Chat.tsx +86 -214
- package/template/src/components/ChatContext.ts +8 -1
- package/template/src/components/ColorConfigure.tsx +1 -1
- package/template/src/components/ColorContext.ts +1 -1
- package/template/src/components/CommonStyles.ts +44 -0
- package/template/src/components/Controls.tsx +342 -42
- package/template/src/components/{Controls.native.tsx → Controls1.native.tsx} +6 -4
- package/template/src/components/DeviceConfigure.tsx +461 -101
- package/template/src/components/DeviceContext.tsx +8 -4
- package/template/src/components/EventsConfigure.tsx +144 -7
- package/template/src/components/GraphQLProvider.tsx +1 -1
- package/template/src/components/GridVideo.tsx +59 -44
- package/template/src/components/HostControlView.tsx +114 -35
- package/template/src/components/Navbar.tsx +216 -398
- package/template/src/components/NetworkQualityContext.tsx +20 -20
- package/template/src/components/ParticipantsView.tsx +177 -154
- package/template/src/components/PinnedVideo.tsx +207 -120
- package/template/src/components/Precall.native.tsx +358 -119
- package/template/src/components/Precall.tsx +269 -135
- package/template/src/components/RTMConfigure.tsx +27 -4
- package/template/src/components/Router.electron.ts +1 -0
- package/template/src/components/Router.native.ts +1 -0
- package/template/src/components/Router.sdk.ts +1 -0
- package/template/src/components/Router.ts +1 -0
- package/template/src/components/Settings.tsx +26 -95
- package/template/src/components/SettingsView.tsx +251 -56
- package/template/src/components/Share.tsx +302 -273
- package/template/src/components/StorageContext.tsx +30 -3
- package/template/src/components/ToastComponent.tsx +8 -0
- package/template/src/components/chat-messages/useChatMessages.tsx +69 -23
- package/template/src/components/chat-ui/useChatUIControl.tsx +7 -0
- package/template/src/components/common/Error.tsx +20 -6
- package/template/src/components/common/Logo.tsx +16 -15
- package/template/src/components/contexts/LiveStreamDataContext.tsx +10 -5
- package/template/src/components/contexts/VideoMeetingDataContext.tsx +37 -7
- package/template/src/components/livestream/LiveStreamContext.tsx +270 -36
- package/template/src/components/livestream/Types.ts +39 -14
- package/template/src/components/livestream/index.ts +1 -0
- package/template/src/components/livestream/views/LiveStreamControls.tsx +12 -4
- package/template/src/components/participants/AllAudienceParticipants.tsx +101 -30
- package/template/src/components/participants/AllHostParticipants.tsx +103 -34
- package/template/src/components/participants/Participant.tsx +302 -0
- package/template/src/components/participants/ParticipantName.tsx +13 -7
- package/template/src/components/participants/ParticipantSectionTitle.tsx +35 -10
- package/template/src/components/participants/ScreenshareParticipants.tsx +144 -12
- package/template/src/components/participants/UserActionMenuOptions.tsx +398 -0
- package/template/src/components/popups/InvitePopup.tsx +115 -0
- package/template/src/components/popups/StopRecordingPopup.tsx +114 -0
- package/template/src/components/precall/LocalMute.tsx +84 -14
- package/template/src/components/precall/{LocalMute.native.tsx → LocalMute1.native.tsx} +21 -5
- package/template/src/components/precall/PermissionHelper.native.tsx +5 -0
- package/template/src/components/precall/PermissionHelper.tsx +126 -0
- package/template/src/components/precall/PreCallSettings.tsx +52 -0
- package/template/src/components/precall/VideoPreview.native.tsx +48 -3
- package/template/src/components/precall/VideoPreview.tsx +163 -7
- package/template/src/components/precall/joinCallBtn.tsx +15 -2
- package/template/src/components/precall/meetingTitle.tsx +15 -12
- package/template/src/components/precall/selectDevice.tsx +1 -21
- package/template/src/components/precall/textInput.tsx +32 -4
- package/template/src/components/precall/usePreCall.tsx +16 -0
- package/template/src/components/styles.ts +42 -21
- package/template/src/components/useShareLink.tsx +12 -14
- package/template/src/components/useToast.tsx +41 -0
- package/template/src/components/useVideoCall.tsx +65 -0
- package/template/src/language/default-labels/precallScreenLabels.ts +3 -3
- package/template/src/pages/Authenticate.tsx +5 -15
- package/template/src/pages/Create.tsx +293 -165
- package/template/src/pages/Endcall.tsx +148 -0
- package/template/src/pages/Join.tsx +93 -67
- package/template/src/pages/VideoCall.tsx +89 -64
- package/template/src/pages/video-call/ActionSheet.native.tsx +215 -0
- package/template/src/pages/video-call/ActionSheet.tsx +226 -0
- package/template/src/pages/video-call/ActionSheetContent.tsx +479 -0
- package/template/src/pages/video-call/ActionSheetHandle.tsx +38 -0
- package/template/src/pages/video-call/ActionSheetStyles.css +138 -0
- package/template/src/pages/video-call/DefaultLayouts.ts +4 -4
- package/template/src/pages/video-call/NameWithMicIcon.tsx +120 -44
- package/template/src/pages/video-call/RenderComponent.tsx +3 -2
- package/template/src/pages/video-call/SidePanelHeader.tsx +190 -0
- package/template/src/pages/video-call/VideoCallMobileView.tsx +139 -0
- package/template/src/pages/video-call/VideoCallScreen.native.tsx +37 -0
- package/template/src/pages/video-call/VideoCallScreen.tsx +45 -9
- package/template/src/pages/video-call/VideoComponent.tsx +18 -3
- package/template/src/pages/video-call/VideoRenderer.tsx +218 -60
- package/template/src/rtm-events/constants.ts +2 -0
- package/template/src/subComponents/ChatBubble.tsx +123 -83
- package/template/src/subComponents/ChatContainer.tsx +257 -84
- package/template/src/subComponents/ChatInput.ios.tsx +237 -0
- package/template/src/subComponents/ChatInput.tsx +61 -46
- package/template/src/subComponents/Checkbox.native.tsx +16 -5
- package/template/src/subComponents/Checkbox.tsx +2 -2
- package/template/src/subComponents/CopyJoinInfo.tsx +36 -58
- package/template/src/subComponents/EndcallPopup.tsx +107 -0
- package/template/src/subComponents/FallbackLogo.tsx +122 -40
- package/template/src/subComponents/LanguageSelector.tsx +1 -1
- package/template/src/subComponents/LayoutIconButton.tsx +201 -0
- package/template/src/subComponents/LayoutIconDropdown.tsx +131 -134
- package/template/src/subComponents/{LayoutIconDropdown.native.tsx → LayoutIconDropdown1.native.tsx} +4 -18
- package/template/src/subComponents/LocalAudioMute.tsx +119 -27
- package/template/src/subComponents/LocalEndCall.tsx +71 -33
- package/template/src/subComponents/LocalSwitchCamera.tsx +17 -30
- package/template/src/subComponents/LocalVideoMute.tsx +117 -27
- package/template/src/subComponents/Logo.tsx +3 -4
- package/template/src/subComponents/LogoutButton.tsx +1 -1
- package/template/src/subComponents/NetworkQualityPill.tsx +60 -63
- package/template/src/subComponents/OpenInNativeButton.tsx +3 -3
- package/template/src/subComponents/Recording.tsx +28 -29
- package/template/src/subComponents/RemoteAudioMute.tsx +83 -29
- package/template/src/subComponents/RemoteEndCall.tsx +8 -5
- package/template/src/subComponents/RemoteMutePopup.tsx +193 -0
- package/template/src/subComponents/RemoteVideoMute.tsx +74 -21
- package/template/src/subComponents/RemoveMeetingPopup.tsx +109 -0
- package/template/src/subComponents/RemoveScreensharePopup.tsx +109 -0
- package/template/src/subComponents/ScreenShareNotice.tsx +83 -8
- package/template/src/subComponents/SelectDevice.tsx +404 -61
- package/template/src/subComponents/SelectDeviceSettings.backup.tsx +207 -0
- package/template/src/subComponents/SelectOAuth.tsx +9 -8
- package/template/src/subComponents/SidePanelHeader.tsx +112 -0
- package/template/src/subComponents/ToastConfig.tsx +150 -10
- package/template/src/subComponents/chat/ChatParticipants.tsx +187 -78
- package/template/src/subComponents/livestream/CurrentLiveStreamRequestsView.tsx +95 -32
- package/template/src/subComponents/livestream/controls/LocalRaiseHand.tsx +29 -33
- package/template/src/subComponents/livestream/controls/RemoteLiveStreamApprovedRequestRecall.tsx +6 -6
- package/template/src/subComponents/livestream/controls/RemoteLiveStreamRequestApprove.tsx +24 -11
- package/template/src/subComponents/livestream/controls/RemoteLiveStreamRequestReject.tsx +17 -10
- package/template/src/subComponents/recording/useRecording.tsx +79 -27
- package/template/src/subComponents/screenshare/ScreenshareButton.tsx +52 -70
- package/template/src/subComponents/screenshare/ScreenshareConfigure.native.tsx +11 -2
- package/template/src/subComponents/screenshare/ScreenshareConfigure.tsx +26 -4
- package/template/src/theme/index.ts +46 -0
- package/template/src/utils/PlatformWrapper.tsx +21 -0
- package/template/src/utils/common.tsx +155 -1
- package/template/src/utils/hexadecimalTransparency.ts +108 -0
- package/template/src/utils/index.tsx +19 -0
- package/template/src/utils/isMobileOrTablet.ts +7 -2
- package/template/src/utils/pendingStateUpdateHelper.ts +19 -0
- package/template/src/utils/useButtonTemplate.tsx +1 -0
- package/template/src/utils/useFocus.tsx +46 -0
- package/template/src/utils/useIsActiveSpeaker.ts +27 -0
- package/template/src/utils/useIsHandRaised.ts +13 -0
- package/template/src/utils/useMuteToggleLocal.ts +54 -3
- package/template/src/utils/useRemoteEndScreenshare.ts +26 -0
- package/template/src/utils/useRemoteRequest.ts +84 -0
- package/template/web/index.html +5 -0
- package/template/webpack.commons.js +13 -8
- package/template/webpack.web.config.js +1 -0
- package/template/src/assets/icons.ts +0 -102
- package/template/src/components/participants/MeParticipant.tsx +0 -38
- package/template/src/components/participants/RemoteParticipants.tsx +0 -71
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import React, {createContext, useContext, useState, useRef} from 'react';
|
|
2
|
+
import {StyleSheet} from 'react-native';
|
|
2
3
|
import ChatContext, {controlMessageEnum} from '../ChatContext';
|
|
3
4
|
import Toast from '../../../react-native-toast-message';
|
|
4
5
|
import {
|
|
@@ -16,7 +17,10 @@ import {useMeetingInfo} from '../meeting-info/useMeetingInfo';
|
|
|
16
17
|
import {useScreenshare} from '../../subComponents/screenshare/useScreenshare';
|
|
17
18
|
import events, {EventPersistLevel} from '../../rtm-events-api';
|
|
18
19
|
import {EventNames} from '../../rtm-events';
|
|
19
|
-
import {useRender} from 'customization-api';
|
|
20
|
+
import {SidePanelType, useRender, useSidePanel} from 'customization-api';
|
|
21
|
+
import TertiaryButton from '../../atoms/TertiaryButton';
|
|
22
|
+
import PrimaryButton from '../../atoms/PrimaryButton';
|
|
23
|
+
import {trimText} from '../../utils/common';
|
|
20
24
|
|
|
21
25
|
const LiveStreamContext = createContext(null as unknown as liveStreamContext);
|
|
22
26
|
|
|
@@ -39,6 +43,18 @@ export const LiveStreamContextProvider: React.FC<liveStreamPropsInterface> = (
|
|
|
39
43
|
const raiseHandListRef = useRef<any>();
|
|
40
44
|
raiseHandListRef.current = raiseHandList;
|
|
41
45
|
|
|
46
|
+
const [coHostUids, setCoHostUids] = useState<UidType[]>([]);
|
|
47
|
+
const coHostUidsRef = useRef<any>();
|
|
48
|
+
coHostUidsRef.current = coHostUids;
|
|
49
|
+
|
|
50
|
+
const {sidePanel} = useSidePanel();
|
|
51
|
+
const sidePanelRef = useRef<any>();
|
|
52
|
+
sidePanelRef.current = sidePanel;
|
|
53
|
+
|
|
54
|
+
React.useEffect(() => {
|
|
55
|
+
sidePanelRef.current = sidePanel;
|
|
56
|
+
}, [sidePanel]);
|
|
57
|
+
|
|
42
58
|
React.useEffect(() => {
|
|
43
59
|
renderListRef.current = renderList;
|
|
44
60
|
}, [renderList]);
|
|
@@ -47,11 +63,41 @@ export const LiveStreamContextProvider: React.FC<liveStreamPropsInterface> = (
|
|
|
47
63
|
raiseHandListRef.current = raiseHandList;
|
|
48
64
|
}, [raiseHandList]);
|
|
49
65
|
|
|
66
|
+
React.useEffect(() => {
|
|
67
|
+
coHostUidsRef.current = coHostUids;
|
|
68
|
+
}, [coHostUids]);
|
|
69
|
+
|
|
70
|
+
React.useEffect(() => {
|
|
71
|
+
/**
|
|
72
|
+
* when user rejoin the meeting. its showing previosly raised livesteaming request.
|
|
73
|
+
* so deleting raise hand data once the user is offline
|
|
74
|
+
* */
|
|
75
|
+
let newRaiseHandList = raiseHandList;
|
|
76
|
+
const data = Object.keys(
|
|
77
|
+
filterObject(
|
|
78
|
+
renderList,
|
|
79
|
+
([k, v]) => v?.type === 'rtc' && v.offline === true,
|
|
80
|
+
),
|
|
81
|
+
);
|
|
82
|
+
let isRaiseHandListChanged = false;
|
|
83
|
+
data &&
|
|
84
|
+
data.length &&
|
|
85
|
+
data.forEach((uid, index) => {
|
|
86
|
+
if (newRaiseHandList[uid]) {
|
|
87
|
+
isRaiseHandListChanged = true;
|
|
88
|
+
delete newRaiseHandList[uid];
|
|
89
|
+
}
|
|
90
|
+
if (data.length - 1 === index && isRaiseHandListChanged) {
|
|
91
|
+
setRaiseHandList(newRaiseHandList);
|
|
92
|
+
}
|
|
93
|
+
});
|
|
94
|
+
}, [renderList]);
|
|
95
|
+
|
|
50
96
|
const localUid = useLocalUid();
|
|
51
97
|
const localUidRef = useRef<any>();
|
|
52
98
|
localUidRef.current = localUid;
|
|
53
99
|
|
|
54
|
-
const {hasUserJoinedRTM} = useContext(ChatContext);
|
|
100
|
+
const {hasUserJoinedRTM, rtmInitTimstamp} = useContext(ChatContext);
|
|
55
101
|
|
|
56
102
|
const {setRtcProps, rtcProps, callActive} = props?.value;
|
|
57
103
|
const {
|
|
@@ -66,11 +112,48 @@ export const LiveStreamContextProvider: React.FC<liveStreamPropsInterface> = (
|
|
|
66
112
|
|
|
67
113
|
const [isPendingRequestToReview, setPendingRequestToReview] = useState(false);
|
|
68
114
|
|
|
69
|
-
const showToast = (
|
|
115
|
+
const showToast = (
|
|
116
|
+
text: string,
|
|
117
|
+
text2: string,
|
|
118
|
+
uid?: UidType,
|
|
119
|
+
toastId?: number,
|
|
120
|
+
) => {
|
|
121
|
+
let btns: any = {};
|
|
122
|
+
if (uid) {
|
|
123
|
+
//toastId used to hide this particular notification
|
|
124
|
+
btns.toastId = toastId;
|
|
125
|
+
btns.primaryBtn = (
|
|
126
|
+
<PrimaryButton
|
|
127
|
+
containerStyle={style.primaryBtn}
|
|
128
|
+
textStyle={style.primaryBtnText}
|
|
129
|
+
text="ALLOW TO BE A PRESENTER"
|
|
130
|
+
onPress={() => {
|
|
131
|
+
hostApprovesRequestOfUID(uid);
|
|
132
|
+
Toast.hide();
|
|
133
|
+
}}
|
|
134
|
+
/>
|
|
135
|
+
);
|
|
136
|
+
btns.secondaryBtn = (
|
|
137
|
+
<TertiaryButton
|
|
138
|
+
containerStyle={style.secondaryBtn}
|
|
139
|
+
text="DENY"
|
|
140
|
+
onPress={() => {
|
|
141
|
+
hostRejectsRequestOfUID(uid);
|
|
142
|
+
Toast.hide();
|
|
143
|
+
}}
|
|
144
|
+
/>
|
|
145
|
+
);
|
|
146
|
+
} else {
|
|
147
|
+
btns.primaryBtn = null;
|
|
148
|
+
btns.secondaryBtn = null;
|
|
149
|
+
}
|
|
150
|
+
|
|
70
151
|
Toast.show({
|
|
71
|
-
type: '
|
|
152
|
+
type: 'info',
|
|
72
153
|
text1: text,
|
|
73
|
-
|
|
154
|
+
text2: text2 ? text2 : null,
|
|
155
|
+
visibilityTime: 3000,
|
|
156
|
+
...btns,
|
|
74
157
|
});
|
|
75
158
|
};
|
|
76
159
|
|
|
@@ -101,6 +184,7 @@ export const LiveStreamContextProvider: React.FC<liveStreamPropsInterface> = (
|
|
|
101
184
|
[userId]: {
|
|
102
185
|
raised: payload?.raised || RaiseHandValue.FALSE,
|
|
103
186
|
ts: payload?.ts || Date.now(),
|
|
187
|
+
isProcessed: payload?.isProcessed || false,
|
|
104
188
|
role:
|
|
105
189
|
payload?.role ||
|
|
106
190
|
oldRaisedHandList[userId]?.role ||
|
|
@@ -128,9 +212,23 @@ export const LiveStreamContextProvider: React.FC<liveStreamPropsInterface> = (
|
|
|
128
212
|
JSON.stringify({
|
|
129
213
|
action: LiveStreamControlMessageEnum.notifyHostsInChannel,
|
|
130
214
|
value: RaiseHandValue.FALSE,
|
|
215
|
+
ts: new Date().getTime(),
|
|
216
|
+
isProcessed: true,
|
|
131
217
|
}),
|
|
132
218
|
EventPersistLevel.LEVEL2,
|
|
133
219
|
);
|
|
220
|
+
//update local cohost state
|
|
221
|
+
setCoHostUids((prevState) => {
|
|
222
|
+
return [
|
|
223
|
+
...prevState.filter((i) => i !== parseInt(localUidRef.current)),
|
|
224
|
+
];
|
|
225
|
+
});
|
|
226
|
+
// Audience notfies all users that co-host permission removed
|
|
227
|
+
events.send(
|
|
228
|
+
LiveStreamControlMessageEnum.coHostRemoved,
|
|
229
|
+
JSON.stringify({uid: localUidRef.current}),
|
|
230
|
+
EventPersistLevel.LEVEL2,
|
|
231
|
+
);
|
|
134
232
|
break;
|
|
135
233
|
case ClientRole.Broadcaster:
|
|
136
234
|
// Update local state
|
|
@@ -145,9 +243,21 @@ export const LiveStreamContextProvider: React.FC<liveStreamPropsInterface> = (
|
|
|
145
243
|
JSON.stringify({
|
|
146
244
|
action: LiveStreamControlMessageEnum.notifyHostsInChannel,
|
|
147
245
|
value: RaiseHandValue.TRUE,
|
|
246
|
+
ts: new Date().getTime(),
|
|
247
|
+
isProcessed: true,
|
|
148
248
|
}),
|
|
149
249
|
EventPersistLevel.LEVEL2,
|
|
150
250
|
);
|
|
251
|
+
//update local cohost state
|
|
252
|
+
setCoHostUids((prevState) => {
|
|
253
|
+
return [...prevState, localUidRef.current];
|
|
254
|
+
});
|
|
255
|
+
// Audience notfies all users that co-host has joined
|
|
256
|
+
events.send(
|
|
257
|
+
LiveStreamControlMessageEnum.coHostJoined,
|
|
258
|
+
JSON.stringify({uid: localUidRef.current}),
|
|
259
|
+
EventPersistLevel.LEVEL2,
|
|
260
|
+
);
|
|
151
261
|
default:
|
|
152
262
|
break;
|
|
153
263
|
}
|
|
@@ -237,6 +347,7 @@ export const LiveStreamContextProvider: React.FC<liveStreamPropsInterface> = (
|
|
|
237
347
|
const payload = JSON.parse(data.payload);
|
|
238
348
|
const action = payload.action;
|
|
239
349
|
const value = payload.value;
|
|
350
|
+
const isProcessed = payload?.isProcessed || false;
|
|
240
351
|
|
|
241
352
|
switch (action) {
|
|
242
353
|
// 1. Host can receive raise hand request with true or false value
|
|
@@ -244,30 +355,46 @@ export const LiveStreamContextProvider: React.FC<liveStreamPropsInterface> = (
|
|
|
244
355
|
switch (value) {
|
|
245
356
|
case RaiseHandValue.TRUE:
|
|
246
357
|
// Step 1: Show notifications
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
358
|
+
if (
|
|
359
|
+
payload.ts > rtmInitTimstamp &&
|
|
360
|
+
sidePanelRef.current !== SidePanelType.Participants
|
|
361
|
+
) {
|
|
362
|
+
showToast(
|
|
363
|
+
`${trimText(getAttendeeName(data.sender))} ${
|
|
364
|
+
LSNotificationObject.RAISE_HAND_RECEIVED.text1
|
|
365
|
+
}`,
|
|
366
|
+
LSNotificationObject.RAISE_HAND_RECEIVED.text2,
|
|
367
|
+
data.sender,
|
|
368
|
+
data.ts,
|
|
369
|
+
);
|
|
370
|
+
}
|
|
252
371
|
// 2. All Hosts in channel update their raised state to "true" when attendee raise their hand
|
|
253
372
|
addOrUpdateLiveStreamRequest(data.sender, {
|
|
254
373
|
ts: data.ts,
|
|
255
374
|
raised: RaiseHandValue.TRUE,
|
|
256
375
|
role: ClientRole.Audience,
|
|
376
|
+
isProcessed: isProcessed,
|
|
257
377
|
});
|
|
258
378
|
break;
|
|
259
379
|
case RaiseHandValue.FALSE:
|
|
260
380
|
// Step 1: Show notifications
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
381
|
+
if (
|
|
382
|
+
payload.ts > rtmInitTimstamp &&
|
|
383
|
+
sidePanelRef.current !== SidePanelType.Participants
|
|
384
|
+
) {
|
|
385
|
+
showToast(
|
|
386
|
+
`${trimText(getAttendeeName(data.sender))} ${
|
|
387
|
+
LSNotificationObject.RAISE_HAND_REQUEST_RECALL.text1
|
|
388
|
+
}`,
|
|
389
|
+
LSNotificationObject.RAISE_HAND_REQUEST_RECALL.text2,
|
|
390
|
+
);
|
|
391
|
+
}
|
|
266
392
|
// 2. All Hosts in channel update raised state to "false" when attendee recalls their request
|
|
267
393
|
addOrUpdateLiveStreamRequest(data.sender, {
|
|
268
394
|
ts: data.ts,
|
|
269
395
|
raised: RaiseHandValue.FALSE,
|
|
270
396
|
role: ClientRole.Audience,
|
|
397
|
+
isProcessed: isProcessed,
|
|
271
398
|
});
|
|
272
399
|
default:
|
|
273
400
|
break;
|
|
@@ -282,6 +409,7 @@ export const LiveStreamContextProvider: React.FC<liveStreamPropsInterface> = (
|
|
|
282
409
|
ts: data.ts,
|
|
283
410
|
raised: RaiseHandValue.TRUE,
|
|
284
411
|
role: ClientRole.Broadcaster,
|
|
412
|
+
isProcessed: isProcessed,
|
|
285
413
|
});
|
|
286
414
|
break;
|
|
287
415
|
case RaiseHandValue.FALSE:
|
|
@@ -289,6 +417,7 @@ export const LiveStreamContextProvider: React.FC<liveStreamPropsInterface> = (
|
|
|
289
417
|
ts: data.ts,
|
|
290
418
|
raised: RaiseHandValue.FALSE,
|
|
291
419
|
role: ClientRole.Audience,
|
|
420
|
+
isProcessed: isProcessed,
|
|
292
421
|
});
|
|
293
422
|
break;
|
|
294
423
|
default:
|
|
@@ -306,7 +435,10 @@ export const LiveStreamContextProvider: React.FC<liveStreamPropsInterface> = (
|
|
|
306
435
|
events.on(LiveStreamControlMessageEnum.raiseHandRequestAccepted, (data) => {
|
|
307
436
|
if (raiseHandList[localUidRef.current]?.raised === RaiseHandValue.FALSE)
|
|
308
437
|
return;
|
|
309
|
-
showToast(
|
|
438
|
+
showToast(
|
|
439
|
+
LSNotificationObject.RAISE_HAND_ACCEPTED.text1,
|
|
440
|
+
LSNotificationObject.RAISE_HAND_ACCEPTED.text2,
|
|
441
|
+
);
|
|
310
442
|
// Promote user's privileges to host
|
|
311
443
|
changeClientRoleTo(ClientRole.Broadcaster);
|
|
312
444
|
// Audience updates its local attributes and notfies all host when request is approved
|
|
@@ -322,13 +454,19 @@ export const LiveStreamContextProvider: React.FC<liveStreamPropsInterface> = (
|
|
|
322
454
|
raiseHandListRef.current[localUidRef.current].role ==
|
|
323
455
|
ClientRole.Audience
|
|
324
456
|
) {
|
|
325
|
-
showToast(
|
|
457
|
+
showToast(
|
|
458
|
+
LSNotificationObject.RAISE_HAND_REJECTED.text1,
|
|
459
|
+
LSNotificationObject.RAISE_HAND_REJECTED.text2,
|
|
460
|
+
);
|
|
326
461
|
} else if (
|
|
327
462
|
raiseHandListRef.current[localUidRef.current].role ==
|
|
328
463
|
ClientRole.Broadcaster
|
|
329
464
|
) {
|
|
330
465
|
/** 2.b */
|
|
331
|
-
showToast(
|
|
466
|
+
showToast(
|
|
467
|
+
LSNotificationObject.RAISE_HAND_APPROVED_REQUEST_RECALL.text1,
|
|
468
|
+
LSNotificationObject.RAISE_HAND_APPROVED_REQUEST_RECALL.text2,
|
|
469
|
+
);
|
|
332
470
|
screenshareContextInstanceRef?.current?.stopUserScreenShare(); // This will not exist on ios
|
|
333
471
|
|
|
334
472
|
// Demote user's privileges to audience
|
|
@@ -342,6 +480,39 @@ export const LiveStreamContextProvider: React.FC<liveStreamPropsInterface> = (
|
|
|
342
480
|
// Audience updates its local attributes and notfies all host when they(audience) are kicked out
|
|
343
481
|
UpdtLocStateAndBCastAttr(ClientRole.Audience, data.ts);
|
|
344
482
|
});
|
|
483
|
+
// 4. Host promote audience as co-host
|
|
484
|
+
events.on(LiveStreamControlMessageEnum.promoteAsCoHost, (data) => {
|
|
485
|
+
showToast(
|
|
486
|
+
LSNotificationObject.PROMOTE_AS_CO_HOST.text1,
|
|
487
|
+
LSNotificationObject.PROMOTE_AS_CO_HOST.text2,
|
|
488
|
+
);
|
|
489
|
+
// Promote user's privileges to host
|
|
490
|
+
changeClientRoleTo(ClientRole.Broadcaster);
|
|
491
|
+
// Audience updates its local attributes and notfies all host when request is approved
|
|
492
|
+
UpdtLocStateAndBCastAttr(ClientRole.Broadcaster, data.ts);
|
|
493
|
+
});
|
|
494
|
+
// 4. New co-host has joined
|
|
495
|
+
events.on(LiveStreamControlMessageEnum.coHostJoined, ({payload}) => {
|
|
496
|
+
try {
|
|
497
|
+
const data = JSON.parse(payload);
|
|
498
|
+
if (data?.uid) {
|
|
499
|
+
setCoHostUids((prevState) => {
|
|
500
|
+
return [...prevState, parseInt(data.uid)];
|
|
501
|
+
});
|
|
502
|
+
}
|
|
503
|
+
} catch (error) {}
|
|
504
|
+
});
|
|
505
|
+
// 5. Co-host removed
|
|
506
|
+
events.on(LiveStreamControlMessageEnum.coHostRemoved, ({payload}) => {
|
|
507
|
+
try {
|
|
508
|
+
const data = JSON.parse(payload);
|
|
509
|
+
if (data?.uid) {
|
|
510
|
+
setCoHostUids((prevState) => {
|
|
511
|
+
return [...prevState.filter((i) => i !== parseInt(data.uid))];
|
|
512
|
+
});
|
|
513
|
+
}
|
|
514
|
+
} catch (error) {}
|
|
515
|
+
});
|
|
345
516
|
/** ********************** AUDIENCE EVENTS SECTION ENDS ********************** */
|
|
346
517
|
}, []);
|
|
347
518
|
|
|
@@ -354,25 +525,51 @@ export const LiveStreamContextProvider: React.FC<liveStreamPropsInterface> = (
|
|
|
354
525
|
*/
|
|
355
526
|
|
|
356
527
|
const hostApprovesRequestOfUID = (uid: UidType) => {
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
528
|
+
if (!raiseHandListRef.current[uid]?.isProcessed) {
|
|
529
|
+
addOrUpdateLiveStreamRequest(uid, {
|
|
530
|
+
raised: RaiseHandValue.TRUE,
|
|
531
|
+
ts: new Date().getTime(),
|
|
532
|
+
isProcessed: true,
|
|
533
|
+
});
|
|
534
|
+
events.send(
|
|
535
|
+
LiveStreamControlMessageEnum.raiseHandRequestAccepted,
|
|
536
|
+
'',
|
|
537
|
+
EventPersistLevel.LEVEL1,
|
|
538
|
+
uid,
|
|
539
|
+
);
|
|
540
|
+
} else {
|
|
541
|
+
Toast.hide();
|
|
542
|
+
setTimeout(() => {
|
|
543
|
+
showToast('Request already processed.', null);
|
|
544
|
+
});
|
|
545
|
+
}
|
|
367
546
|
};
|
|
368
547
|
|
|
369
548
|
const hostRejectsRequestOfUID = (uid: UidType) => {
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
549
|
+
if (!raiseHandListRef.current[uid]?.isProcessed) {
|
|
550
|
+
addOrUpdateLiveStreamRequest(uid, {
|
|
551
|
+
raised: RaiseHandValue.FALSE,
|
|
552
|
+
ts: new Date().getTime(),
|
|
553
|
+
isProcessed: true,
|
|
554
|
+
});
|
|
555
|
+
events.send(
|
|
556
|
+
LiveStreamControlMessageEnum.raiseHandRequestRejected,
|
|
557
|
+
'',
|
|
558
|
+
EventPersistLevel.LEVEL1,
|
|
559
|
+
uid,
|
|
560
|
+
);
|
|
561
|
+
} else {
|
|
562
|
+
Toast.hide();
|
|
563
|
+
setTimeout(() => {
|
|
564
|
+
showToast('Request already processed.', null);
|
|
565
|
+
});
|
|
566
|
+
}
|
|
567
|
+
};
|
|
568
|
+
|
|
569
|
+
// promote audience as co-host
|
|
570
|
+
const promoteAudienceAsCoHost = async (uid: UidType): Promise<void> => {
|
|
374
571
|
events.send(
|
|
375
|
-
LiveStreamControlMessageEnum.
|
|
572
|
+
LiveStreamControlMessageEnum.promoteAsCoHost,
|
|
376
573
|
'',
|
|
377
574
|
EventPersistLevel.LEVEL1,
|
|
378
575
|
uid,
|
|
@@ -392,14 +589,19 @@ export const LiveStreamContextProvider: React.FC<liveStreamPropsInterface> = (
|
|
|
392
589
|
// If hand is already raised, skip the call
|
|
393
590
|
if (raiseHandList[localUidRef.current]?.raised === RaiseHandValue.TRUE)
|
|
394
591
|
return;
|
|
395
|
-
showToast(
|
|
592
|
+
showToast(
|
|
593
|
+
LSNotificationObject.RAISE_HAND_REQUEST.text1,
|
|
594
|
+
LSNotificationObject.RAISE_HAND_REQUEST.text2,
|
|
595
|
+
);
|
|
396
596
|
events.send(
|
|
397
597
|
EventNames.RAISED_ATTRIBUTE,
|
|
398
598
|
JSON.stringify({
|
|
399
599
|
action: LiveStreamControlMessageEnum.raiseHandRequest,
|
|
400
600
|
value: RaiseHandValue.TRUE,
|
|
601
|
+
ts: new Date().getTime(),
|
|
602
|
+
isProcessed: false,
|
|
401
603
|
}),
|
|
402
|
-
EventPersistLevel.
|
|
604
|
+
EventPersistLevel.LEVEL2,
|
|
403
605
|
);
|
|
404
606
|
// Update local state
|
|
405
607
|
addOrUpdateLiveStreamRequest(localUidRef.current, {
|
|
@@ -424,8 +626,22 @@ export const LiveStreamContextProvider: React.FC<liveStreamPropsInterface> = (
|
|
|
424
626
|
// Change role
|
|
425
627
|
changeClientRoleTo(ClientRole.Audience);
|
|
426
628
|
}
|
|
629
|
+
//notify host users
|
|
630
|
+
events.send(
|
|
631
|
+
EventNames.RAISED_ATTRIBUTE,
|
|
632
|
+
JSON.stringify({
|
|
633
|
+
action: LiveStreamControlMessageEnum.raiseHandRequest,
|
|
634
|
+
value: RaiseHandValue.FALSE,
|
|
635
|
+
ts: new Date().getTime(),
|
|
636
|
+
isProcessed: true,
|
|
637
|
+
}),
|
|
638
|
+
EventPersistLevel.LEVEL2,
|
|
639
|
+
);
|
|
427
640
|
UpdtLocStateAndBCastAttr(ClientRole.Audience, new Date().getTime());
|
|
428
|
-
showToast(
|
|
641
|
+
showToast(
|
|
642
|
+
LSNotificationObject.RAISE_HAND_REQUEST_RECALL_LOCAL.text1,
|
|
643
|
+
LSNotificationObject.RAISE_HAND_REQUEST_RECALL_LOCAL.text2,
|
|
644
|
+
);
|
|
429
645
|
};
|
|
430
646
|
|
|
431
647
|
/** ******* AUDIENCE CONTROLS SECTION ENDS ******* */
|
|
@@ -433,6 +649,7 @@ export const LiveStreamContextProvider: React.FC<liveStreamPropsInterface> = (
|
|
|
433
649
|
return (
|
|
434
650
|
<LiveStreamContext.Provider
|
|
435
651
|
value={{
|
|
652
|
+
coHostUids: coHostUids,
|
|
436
653
|
setLastCheckedRequestTimestamp,
|
|
437
654
|
isPendingRequestToReview,
|
|
438
655
|
raiseHandList,
|
|
@@ -440,6 +657,7 @@ export const LiveStreamContextProvider: React.FC<liveStreamPropsInterface> = (
|
|
|
440
657
|
hostRejectsRequestOfUID,
|
|
441
658
|
audienceSendsRequest,
|
|
442
659
|
audienceRecallsRequest,
|
|
660
|
+
promoteAudienceAsCoHost,
|
|
443
661
|
}}>
|
|
444
662
|
{props.children}
|
|
445
663
|
</LiveStreamContext.Provider>
|
|
@@ -447,3 +665,19 @@ export const LiveStreamContextProvider: React.FC<liveStreamPropsInterface> = (
|
|
|
447
665
|
};
|
|
448
666
|
|
|
449
667
|
export default LiveStreamContext;
|
|
668
|
+
|
|
669
|
+
const style = StyleSheet.create({
|
|
670
|
+
secondaryBtn: {marginLeft: 16, height: 40, paddingVertical: 5},
|
|
671
|
+
primaryBtn: {
|
|
672
|
+
minWidth: 'auto',
|
|
673
|
+
paddingHorizontal: 12,
|
|
674
|
+
height: 40,
|
|
675
|
+
borderRadius: 4,
|
|
676
|
+
paddingVertical: 5,
|
|
677
|
+
},
|
|
678
|
+
primaryBtnText: {
|
|
679
|
+
fontWeight: '600',
|
|
680
|
+
fontSize: 16,
|
|
681
|
+
paddingLeft: 0,
|
|
682
|
+
},
|
|
683
|
+
});
|
|
@@ -16,6 +16,7 @@ export interface raiseHandItemInterface {
|
|
|
16
16
|
role: ClientRole;
|
|
17
17
|
raised: RaiseHandValue;
|
|
18
18
|
ts: number;
|
|
19
|
+
isProcessed: boolean;
|
|
19
20
|
}
|
|
20
21
|
|
|
21
22
|
import {UidType} from '../../../agora-rn-uikit';
|
|
@@ -42,23 +43,45 @@ export enum LiveStreamControlMessageEnum {
|
|
|
42
43
|
notifyAllRequestApproved = 'NOTIFY_REQUEST_APPROVED',
|
|
43
44
|
notifyAllRequestRejected = 'NOTIFY_REQUEST_REJECTED',
|
|
44
45
|
notifyHostsInChannel = 'NOTIFY_HOSTS_IN_CHANNEL',
|
|
46
|
+
promoteAsCoHost = 'PROMOTE_AS_CO_HOST',
|
|
47
|
+
coHostJoined = 'CO_HOST_JOINED',
|
|
48
|
+
coHostRemoved = 'CO_HOST_REMOVED',
|
|
45
49
|
}
|
|
46
50
|
|
|
47
51
|
export const LSNotificationObject = {
|
|
48
|
-
[LiveStreamControlMessageEnum.raiseHandRequest]:
|
|
49
|
-
'You
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
[LiveStreamControlMessageEnum.
|
|
53
|
-
'
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
'You
|
|
60
|
-
|
|
61
|
-
|
|
52
|
+
[LiveStreamControlMessageEnum.raiseHandRequest]: {
|
|
53
|
+
text1: 'You’ve raised your hand.',
|
|
54
|
+
text2: 'Waiting for host to approve the request',
|
|
55
|
+
},
|
|
56
|
+
[LiveStreamControlMessageEnum.raiseHandRequestReceived]: {
|
|
57
|
+
text1: 'has raised their hand to be a Presenter',
|
|
58
|
+
text2:
|
|
59
|
+
'Once approved they will be able to speak, share their video and present during this call.',
|
|
60
|
+
},
|
|
61
|
+
[LiveStreamControlMessageEnum.raiseHandRequestAccepted]: {
|
|
62
|
+
text1: 'Host has approved your request.',
|
|
63
|
+
text2: 'You are now a Presenter',
|
|
64
|
+
},
|
|
65
|
+
[LiveStreamControlMessageEnum.raiseHandRequestRejected]: {
|
|
66
|
+
text1: 'Your request was rejected by the host',
|
|
67
|
+
text2: null,
|
|
68
|
+
},
|
|
69
|
+
[LiveStreamControlMessageEnum.raiseHandRequestRecall]: {
|
|
70
|
+
text1: 'has lowered their hand',
|
|
71
|
+
text2: null,
|
|
72
|
+
},
|
|
73
|
+
[LiveStreamControlMessageEnum.raiseHandRequestRecallLocal]: {
|
|
74
|
+
text1: 'You’ve lowered your hand.',
|
|
75
|
+
text2: null,
|
|
76
|
+
},
|
|
77
|
+
[LiveStreamControlMessageEnum.raiseHandApprovedRequestRecall]: {
|
|
78
|
+
text1: 'Host has revoked streaming permissions.',
|
|
79
|
+
text2: null,
|
|
80
|
+
},
|
|
81
|
+
[LiveStreamControlMessageEnum.promoteAsCoHost]: {
|
|
82
|
+
text1: 'Host promoted you as a Presenter',
|
|
83
|
+
text2: null,
|
|
84
|
+
},
|
|
62
85
|
};
|
|
63
86
|
|
|
64
87
|
export interface liveStreamPropsInterface {
|
|
@@ -74,6 +97,8 @@ export interface liveStreamContext {
|
|
|
74
97
|
hostRejectsRequestOfUID: (uid: number) => void;
|
|
75
98
|
audienceSendsRequest: () => void;
|
|
76
99
|
audienceRecallsRequest: () => void;
|
|
100
|
+
promoteAudienceAsCoHost: (uid: UidType) => void;
|
|
101
|
+
coHostUids: UidType[];
|
|
77
102
|
}
|
|
78
103
|
|
|
79
104
|
export interface requestInterface {
|
|
@@ -15,16 +15,24 @@ import {LocalRaiseHand} from '../../../subComponents/livestream';
|
|
|
15
15
|
|
|
16
16
|
export interface LiveStreamControlsProps {
|
|
17
17
|
showControls: boolean;
|
|
18
|
+
isDesktop: boolean;
|
|
19
|
+
showLabel?: boolean;
|
|
18
20
|
}
|
|
19
21
|
|
|
20
22
|
const LiveStreamControls = (props: LiveStreamControlsProps) => {
|
|
21
|
-
const {showControls} = props;
|
|
23
|
+
const {showControls, isDesktop, showLabel = $config.ICON_TEXT} = props;
|
|
22
24
|
if (!$config.RAISE_HAND) return <></>;
|
|
23
25
|
if (!showControls) return <></>;
|
|
24
26
|
return (
|
|
25
|
-
|
|
26
|
-
<
|
|
27
|
-
|
|
27
|
+
<>
|
|
28
|
+
<View
|
|
29
|
+
style={{
|
|
30
|
+
alignSelf: 'center',
|
|
31
|
+
marginHorizontal: 10,
|
|
32
|
+
}}>
|
|
33
|
+
<LocalRaiseHand showLabel={showLabel} />
|
|
34
|
+
</View>
|
|
35
|
+
</>
|
|
28
36
|
);
|
|
29
37
|
};
|
|
30
38
|
|