agora-appbuilder-core 4.0.0-api.8 → 4.0.0-api.9
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 +3 -3
- package/template/_package-lock.json +5911 -4861
- package/template/agora-rn-uikit/.eslintrc.js +5 -0
- package/template/agora-rn-uikit/package.json +14 -14
- package/template/agora-rn-uikit/src/Contexts/PropsContext.tsx +41 -22
- package/template/agora-rn-uikit/src/Contexts/RtcContext.tsx +2 -2
- package/template/agora-rn-uikit/src/Rtc/Create.tsx +90 -57
- package/template/agora-rn-uikit/src/Rtc/Join.tsx +20 -16
- package/template/agora-rn-uikit/src/RtcConfigure.tsx +10 -10
- package/template/agora-rn-uikit/src/Utils/isBotUser.ts +15 -0
- package/template/agora-rn-uikit/src/Utils/quality.tsx +8 -0
- package/template/agora-rn-uikit/src/Views/MaxVideoView.native.tsx +32 -16
- package/template/agora-rn-uikit/src/Views/MaxVideoView.tsx +25 -14
- package/template/agora-rn-uikit/src/Views/MinVideoView.tsx +15 -9
- package/template/agora-rn-uikit/src/index.ts +1 -1
- package/template/bridge/rtc/webNg/RtcEngine.ts +73 -58
- package/template/bridge/rtc/webNg/{SurfaceView.tsx → RtcSurfaceView.tsx} +20 -26
- package/template/bridge/rtc/webNg/Types.ts +20 -5
- package/template/bridge/rtc/webNg/index.ts +9 -13
- package/template/index.js +1 -0
- package/template/ios/HelloWorld/HelloWorldDebug.entitlements +10 -0
- package/template/ios/HelloWorld.xcodeproj/project.pbxproj +4 -0
- package/template/ios/Podfile +1 -1
- package/template/ios/Podfile.lock +72 -140
- package/template/package.json +5 -4
- package/template/src/App.tsx +58 -1
- package/template/src/AppRoutes.tsx +16 -3
- package/template/src/AppWrapper.tsx +21 -19
- package/template/src/components/Chat.tsx +17 -8
- package/template/src/components/Controls.tsx +5 -5
- package/template/src/components/Controls1.native.tsx +7 -3
- package/template/src/components/DeviceConfigure.native.tsx +2 -2
- package/template/src/components/DeviceConfigure.tsx +2 -2
- package/template/src/components/EventsConfigure.tsx +10 -4
- package/template/src/components/GraphQLProvider.tsx +47 -30
- package/template/src/components/GridVideo.tsx +6 -2
- package/template/src/components/NetworkQualityContext.tsx +11 -5
- package/template/src/components/ParticipantsView.tsx +3 -3
- package/template/src/components/PinnedVideo.tsx +2 -2
- package/template/src/components/Precall.native.tsx +9 -6
- package/template/src/components/Precall.tsx +9 -6
- package/template/src/components/StorageContext.tsx +5 -2
- package/template/src/components/ToastComponent.tsx +7 -1
- package/template/src/components/contexts/LiveStreamDataContext.tsx +3 -3
- package/template/src/components/livestream/LiveStreamContext.tsx +42 -33
- package/template/src/components/livestream/Types.ts +2 -2
- package/template/src/components/participants/Participant.tsx +1 -1
- package/template/src/components/participants/UserActionMenuOptions.tsx +7 -2
- package/template/src/components/recording-bot/RecordingBotRoute.tsx +42 -0
- package/template/src/components/virtual-background/useVB.native.tsx +16 -19
- package/template/src/components/virtual-background/useVB.tsx +1 -1
- package/template/src/components/whiteboard/WhiteboardConfigure.native.tsx +11 -0
- package/template/src/components/whiteboard/WhiteboardConfigure.tsx +5 -0
- package/template/src/components/whiteboard/WhiteboardView.native.tsx +91 -12
- package/template/src/components/whiteboard/WhiteboardWidget.tsx +15 -4
- package/template/src/language/default-labels/precallScreenLabels.ts +5 -3
- package/template/src/language/default-labels/videoCallScreenLabels.ts +93 -41
- package/template/src/pages/VideoCall.tsx +32 -18
- package/template/src/pages/video-call/ActionSheetContent.tsx +4 -3
- package/template/src/pages/video-call/NameWithMicIcon.tsx +2 -1
- package/template/src/pages/video-call/VideoCallMobileView.tsx +26 -2
- package/template/src/pages/video-call/VideoCallScreen.tsx +32 -12
- package/template/src/pages/video-call/VideoCallScreenWrapper.tsx +41 -0
- package/template/src/pages/video-call/VideoComponent.tsx +5 -2
- package/template/src/pages/video-call/VideoRenderer.tsx +55 -34
- package/template/src/rtm-events/constants.ts +0 -2
- package/template/src/subComponents/ChatBubble.tsx +2 -0
- package/template/src/subComponents/LocalAudioMute.tsx +6 -5
- package/template/src/subComponents/LocalSwitchCamera.tsx +3 -3
- package/template/src/subComponents/LocalVideoMute.tsx +6 -5
- package/template/src/subComponents/SelectDevice.tsx +5 -2
- package/template/src/subComponents/SelectDeviceSettings.backup.tsx +9 -6
- package/template/src/subComponents/caption/Caption.tsx +12 -10
- package/template/src/subComponents/caption/Transcript.tsx +13 -10
- package/template/src/subComponents/caption/useTranscriptDownload.native.ts +11 -16
- package/template/src/subComponents/caption/utils.ts +1 -0
- package/template/src/subComponents/livestream/ApprovedLiveStreamControlsView.tsx +2 -2
- package/template/src/subComponents/livestream/CurrentLiveStreamRequestsView.tsx +3 -2
- package/template/src/subComponents/livestream/controls/LocalRaiseHand.tsx +1 -1
- package/template/src/subComponents/recording/useIsRecordingBot.tsx +38 -0
- package/template/src/subComponents/recording/useRecording.tsx +176 -135
- package/template/src/subComponents/screenshare/ScreenshareButton.tsx +3 -3
- package/template/src/subComponents/screenshare/ScreenshareConfigure.tsx +1 -22
- package/template/src/utils/index.tsx +16 -5
- package/template/src/utils/useIsLocalUserSpeaking.ts +6 -1
- package/template/src/utils/useMuteToggleLocal.ts +10 -5
- package/template/src/utils/useSearchParams.tsx +18 -0
- package/template/src/wasms/agora-virtual-background.wasm +0 -0
- package/template/bridge/rtc/webNg/LocalView.tsx +0 -20
package/template/src/App.tsx
CHANGED
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
information visit https://appbuilder.agora.io.
|
|
10
10
|
*********************************************
|
|
11
11
|
*/
|
|
12
|
-
import React, {useState,
|
|
12
|
+
import React, {useState, useLayoutEffect} from 'react';
|
|
13
13
|
import {Platform} from 'react-native';
|
|
14
14
|
import KeyboardManager from 'react-native-keyboard-manager';
|
|
15
15
|
import AppWrapper from './AppWrapper';
|
|
@@ -21,6 +21,7 @@ import {
|
|
|
21
21
|
import {SetRoomInfoProvider} from './components/room-info/useSetRoomInfo';
|
|
22
22
|
import {ShareLinkProvider} from './components/useShareLink';
|
|
23
23
|
import AppRoutes from './AppRoutes';
|
|
24
|
+
import {isWebInternal} from './utils/common';
|
|
24
25
|
|
|
25
26
|
// hook can't be used in the outside react function calls. so directly checking the platform.
|
|
26
27
|
if (Platform.OS === 'ios') {
|
|
@@ -44,8 +45,64 @@ declare module 'agora-rn-uikit' {
|
|
|
44
45
|
// }
|
|
45
46
|
}
|
|
46
47
|
|
|
48
|
+
declare global {
|
|
49
|
+
interface Navigator {
|
|
50
|
+
notifyReady?: () => boolean;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
47
54
|
const App: React.FC = () => {
|
|
48
55
|
//commented for v1 release
|
|
56
|
+
//const CustomRoutes = useCustomization((data) => data?.customRoutes);
|
|
57
|
+
// const RenderCustomRoutes = () => {
|
|
58
|
+
// try {
|
|
59
|
+
// return (
|
|
60
|
+
// CustomRoutes &&
|
|
61
|
+
// Array.isArray(CustomRoutes) &&
|
|
62
|
+
// CustomRoutes.length &&
|
|
63
|
+
// CustomRoutes?.map((item: CustomRoutesInterface, i: number) => {
|
|
64
|
+
// let RouteComponent = item?.isPrivateRoute ? PrivateRoute : Route;
|
|
65
|
+
// return (
|
|
66
|
+
// <RouteComponent
|
|
67
|
+
// path={CUSTOM_ROUTES_PREFIX + item.path}
|
|
68
|
+
// exact={item.exact}
|
|
69
|
+
// key={i}
|
|
70
|
+
// failureRedirectTo={
|
|
71
|
+
// item.failureRedirectTo ? item.failureRedirectTo : '/'
|
|
72
|
+
// }
|
|
73
|
+
// {...item.routeProps}>
|
|
74
|
+
// <item.component {...item.componentProps} />
|
|
75
|
+
// </RouteComponent>
|
|
76
|
+
// );
|
|
77
|
+
// })
|
|
78
|
+
// );
|
|
79
|
+
// } catch (error) {
|
|
80
|
+
// console.error('Error on rendering the custom routes');
|
|
81
|
+
// return null;
|
|
82
|
+
// }
|
|
83
|
+
// };
|
|
84
|
+
|
|
85
|
+
const notifyReady = () => {
|
|
86
|
+
if (typeof window.navigator.notifyReady === 'function') {
|
|
87
|
+
console.log('recording-bot: notifyReady is available');
|
|
88
|
+
window.navigator.notifyReady();
|
|
89
|
+
} else {
|
|
90
|
+
console.log('recording-bot: notifyReady is un-available');
|
|
91
|
+
}
|
|
92
|
+
};
|
|
93
|
+
|
|
94
|
+
useLayoutEffect(() => {
|
|
95
|
+
if (isWebInternal()) {
|
|
96
|
+
// Register only on web
|
|
97
|
+
window.addEventListener('load', notifyReady);
|
|
98
|
+
}
|
|
99
|
+
return () => {
|
|
100
|
+
if (isWebInternal()) {
|
|
101
|
+
window.removeEventListener('load', notifyReady);
|
|
102
|
+
}
|
|
103
|
+
};
|
|
104
|
+
}, []);
|
|
105
|
+
|
|
49
106
|
const [roomInfo, setRoomInfo] =
|
|
50
107
|
useState<RoomInfoContextInterface>(RoomInfoDefaultValue);
|
|
51
108
|
|
|
@@ -20,6 +20,21 @@ import {Text} from 'react-native';
|
|
|
20
20
|
import {useCustomization} from 'customization-implementation';
|
|
21
21
|
import {CUSTOM_ROUTES_PREFIX, CustomRoutesInterface} from 'customization-api';
|
|
22
22
|
import PrivateRoute from './components/PrivateRoute';
|
|
23
|
+
import RecordingBotRoute from './components/recording-bot/RecordingBotRoute';
|
|
24
|
+
import {useIsRecordingBot} from './subComponents/recording/useIsRecordingBot';
|
|
25
|
+
|
|
26
|
+
function VideoCallWrapper(props) {
|
|
27
|
+
const {isRecordingBotRoute} = useIsRecordingBot();
|
|
28
|
+
return isRecordingBotRoute ? (
|
|
29
|
+
<RecordingBotRoute history={props.history}>
|
|
30
|
+
<VideoCall />
|
|
31
|
+
</RecordingBotRoute>
|
|
32
|
+
) : (
|
|
33
|
+
<AuthRoute>
|
|
34
|
+
<VideoCall />
|
|
35
|
+
</AuthRoute>
|
|
36
|
+
);
|
|
37
|
+
}
|
|
23
38
|
|
|
24
39
|
function AppRoutes() {
|
|
25
40
|
const CustomRoutes = useCustomization(data => data?.customRoutes);
|
|
@@ -65,9 +80,7 @@ function AppRoutes() {
|
|
|
65
80
|
<Create />
|
|
66
81
|
</AuthRoute>
|
|
67
82
|
{RenderCustomRoutes()}
|
|
68
|
-
<
|
|
69
|
-
<VideoCall />
|
|
70
|
-
</AuthRoute>
|
|
83
|
+
<Route exact path={'/:phrase'} component={VideoCallWrapper} />
|
|
71
84
|
<Route path="*">
|
|
72
85
|
<Text>Page not found</Text>
|
|
73
86
|
</Route>
|
|
@@ -87,22 +87,24 @@ const AppWrapper = (props: AppWrapperProps) => {
|
|
|
87
87
|
<StatusBar hidden={true} />
|
|
88
88
|
<StorageProvider>
|
|
89
89
|
<LanguageProvider>
|
|
90
|
-
<
|
|
91
|
-
<
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
90
|
+
<GraphQLProvider>
|
|
91
|
+
<Router
|
|
92
|
+
/*@ts-ignore Router will be memory Router in sdk*/
|
|
93
|
+
initialEntries={[
|
|
94
|
+
//@ts-ignore
|
|
95
|
+
isSDK && SdkJoinState.phrase
|
|
96
|
+
? //@ts-ignore
|
|
97
|
+
`/${SdkJoinState.phrase}`
|
|
98
|
+
: '',
|
|
99
|
+
]}>
|
|
100
|
+
<ToastProvider>
|
|
101
|
+
<ToastContext.Consumer>
|
|
102
|
+
{({isActionSheetVisible}) => {
|
|
103
|
+
return !isActionSheetVisible ? (
|
|
104
|
+
<ToastComponent />
|
|
105
|
+
) : null;
|
|
106
|
+
}}
|
|
107
|
+
</ToastContext.Consumer>
|
|
106
108
|
<AuthProvider>
|
|
107
109
|
<SessionProvider>
|
|
108
110
|
<ColorConfigure>
|
|
@@ -116,9 +118,9 @@ const AppWrapper = (props: AppWrapperProps) => {
|
|
|
116
118
|
</ColorConfigure>
|
|
117
119
|
</SessionProvider>
|
|
118
120
|
</AuthProvider>
|
|
119
|
-
</
|
|
120
|
-
</
|
|
121
|
-
</
|
|
121
|
+
</ToastProvider>
|
|
122
|
+
</Router>
|
|
123
|
+
</GraphQLProvider>
|
|
122
124
|
</LanguageProvider>
|
|
123
125
|
</StorageProvider>
|
|
124
126
|
</SafeAreaView>
|
|
@@ -39,6 +39,7 @@ import {useLayout} from '../utils/useLayout';
|
|
|
39
39
|
import {getGridLayoutName} from '../pages/video-call/DefaultLayouts';
|
|
40
40
|
import {ChatHeader} from '../pages/video-call/SidePanelHeader';
|
|
41
41
|
import useCaptionWidth from '../../src/subComponents/caption/useCaptionWidth';
|
|
42
|
+
import {useIsRecordingBot} from '../subComponents/recording/useIsRecordingBot';
|
|
42
43
|
|
|
43
44
|
export interface ChatProps {
|
|
44
45
|
chatBubble?: React.ComponentType<ChatBubbleProps>;
|
|
@@ -51,7 +52,7 @@ const Chat = (props?: ChatProps) => {
|
|
|
51
52
|
const isSmall = useIsSmall();
|
|
52
53
|
const {setSidePanel} = useSidePanel();
|
|
53
54
|
const {showHeader = true} = props;
|
|
54
|
-
|
|
55
|
+
const {isRecordingBot} = useIsRecordingBot();
|
|
55
56
|
const {chatType, setChatType, setPrivateChatUser} = useChatUIControls();
|
|
56
57
|
|
|
57
58
|
const {
|
|
@@ -170,9 +171,13 @@ const Chat = (props?: ChatProps) => {
|
|
|
170
171
|
{chatType === ChatType.Group ? (
|
|
171
172
|
<>
|
|
172
173
|
<ChatContainer {...props} />
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
174
|
+
{isRecordingBot ? (
|
|
175
|
+
<></>
|
|
176
|
+
) : (
|
|
177
|
+
<View style={style.chatInputContainer}>
|
|
178
|
+
<ChatInputComponent />
|
|
179
|
+
</View>
|
|
180
|
+
)}
|
|
176
181
|
</>
|
|
177
182
|
) : (
|
|
178
183
|
<></>
|
|
@@ -185,11 +190,15 @@ const Chat = (props?: ChatProps) => {
|
|
|
185
190
|
{chatType === ChatType.Private ? (
|
|
186
191
|
<>
|
|
187
192
|
<ChatContainer {...props} />
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
193
|
+
{isRecordingBot ? (
|
|
194
|
+
<></>
|
|
195
|
+
) : (
|
|
196
|
+
<View>
|
|
197
|
+
<View style={style.chatInputContainer}>
|
|
198
|
+
<ChatInputComponent />
|
|
199
|
+
</View>
|
|
191
200
|
</View>
|
|
192
|
-
|
|
201
|
+
)}
|
|
193
202
|
</>
|
|
194
203
|
) : (
|
|
195
204
|
<></>
|
|
@@ -29,7 +29,7 @@ import Recording from '../subComponents/Recording';
|
|
|
29
29
|
import LocalSwitchCamera from '../subComponents/LocalSwitchCamera';
|
|
30
30
|
import ScreenshareButton from '../subComponents/screenshare/ScreenshareButton';
|
|
31
31
|
import isMobileOrTablet from '../utils/isMobileOrTablet';
|
|
32
|
-
import {
|
|
32
|
+
import {ClientRoleType} from '../../agora-rn-uikit';
|
|
33
33
|
import LiveStreamControls from './livestream/views/LiveStreamControls';
|
|
34
34
|
import {
|
|
35
35
|
BREAKPOINTS,
|
|
@@ -525,14 +525,14 @@ const MoreButton = () => {
|
|
|
525
525
|
if ($config.SCREEN_SHARING) {
|
|
526
526
|
if (
|
|
527
527
|
!(
|
|
528
|
-
rtcProps.role ==
|
|
528
|
+
rtcProps.role == ClientRoleType.ClientRoleAudience &&
|
|
529
529
|
$config.EVENT_MODE &&
|
|
530
530
|
!$config.RAISE_HAND
|
|
531
531
|
)
|
|
532
532
|
) {
|
|
533
533
|
actionMenuitems.push({
|
|
534
534
|
disabled:
|
|
535
|
-
rtcProps.role ==
|
|
535
|
+
rtcProps.role == ClientRoleType.ClientRoleAudience &&
|
|
536
536
|
$config.EVENT_MODE &&
|
|
537
537
|
$config.RAISE_HAND &&
|
|
538
538
|
!isHost,
|
|
@@ -775,9 +775,9 @@ export const RaiseHandToolbarItem = () => {
|
|
|
775
775
|
data: {isHost},
|
|
776
776
|
} = useRoomInfo();
|
|
777
777
|
return $config.EVENT_MODE ? (
|
|
778
|
-
rtcProps.role ==
|
|
778
|
+
rtcProps.role == ClientRoleType.ClientRoleAudience ? (
|
|
779
779
|
<LiveStreamControls showControls={true} />
|
|
780
|
-
) : rtcProps?.role ==
|
|
780
|
+
) : rtcProps?.role == ClientRoleType.ClientRoleBroadcaster ? (
|
|
781
781
|
/**
|
|
782
782
|
* In event mode when raise hand feature is active
|
|
783
783
|
* and audience is promoted to host, the audience can also
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
*/
|
|
12
12
|
import React, {useContext} from 'react';
|
|
13
13
|
import {View, StyleSheet} from 'react-native';
|
|
14
|
-
import {PropsContext,
|
|
14
|
+
import {PropsContext, ClientRoleType} from '../../agora-rn-uikit';
|
|
15
15
|
import LocalAudioMute, {
|
|
16
16
|
LocalAudioMuteProps,
|
|
17
17
|
} from '../subComponents/LocalAudioMute';
|
|
@@ -40,7 +40,8 @@ const Controls = () => {
|
|
|
40
40
|
|
|
41
41
|
return (
|
|
42
42
|
<View style={style.bottomBar}>
|
|
43
|
-
{$config.EVENT_MODE &&
|
|
43
|
+
{$config.EVENT_MODE &&
|
|
44
|
+
rtcProps.role == ClientRoleType.ClientRoleAudience ? (
|
|
44
45
|
<LiveStreamControls showControls={true} />
|
|
45
46
|
) : (
|
|
46
47
|
<>
|
|
@@ -51,7 +52,10 @@ const Controls = () => {
|
|
|
51
52
|
*/}
|
|
52
53
|
{$config.EVENT_MODE && (
|
|
53
54
|
<LiveStreamControls
|
|
54
|
-
showControls={
|
|
55
|
+
showControls={
|
|
56
|
+
rtcProps?.role == ClientRoleType.ClientRoleBroadcaster &&
|
|
57
|
+
!isHost
|
|
58
|
+
}
|
|
55
59
|
/>
|
|
56
60
|
)}
|
|
57
61
|
<View style={{alignSelf: 'center'}}>
|
|
@@ -11,10 +11,10 @@
|
|
|
11
11
|
*/
|
|
12
12
|
import React from 'react';
|
|
13
13
|
import KeepAwake from 'react-native-keep-awake';
|
|
14
|
-
import {
|
|
14
|
+
import {ClientRoleType} from '../../agora-rn-uikit';
|
|
15
15
|
|
|
16
16
|
interface Props {
|
|
17
|
-
userRole:
|
|
17
|
+
userRole: ClientRoleType;
|
|
18
18
|
}
|
|
19
19
|
const DeviceConfigure: React.FC<Props> = (props: any) => {
|
|
20
20
|
return (
|
|
@@ -17,7 +17,7 @@ import React, {
|
|
|
17
17
|
useRef,
|
|
18
18
|
useContext,
|
|
19
19
|
} from 'react';
|
|
20
|
-
import {
|
|
20
|
+
import {ClientRoleType, RtcContext} from '../../agora-rn-uikit';
|
|
21
21
|
import DeviceContext from './DeviceContext';
|
|
22
22
|
import AgoraRTC, {DeviceInfo} from 'agora-rtc-sdk-ng';
|
|
23
23
|
import {useRtc} from 'customization-api';
|
|
@@ -49,7 +49,7 @@ const log = (...args: any[]) => {
|
|
|
49
49
|
type WebRtcEngineInstance = InstanceType<typeof RtcEngine>;
|
|
50
50
|
|
|
51
51
|
interface Props {
|
|
52
|
-
userRole:
|
|
52
|
+
userRole: ClientRoleType;
|
|
53
53
|
}
|
|
54
54
|
export type deviceInfo = MediaDeviceInfo;
|
|
55
55
|
export type deviceId = deviceInfo['deviceId'];
|
|
@@ -306,7 +306,7 @@ const EventsConfigure: React.FC<Props> = props => {
|
|
|
306
306
|
});
|
|
307
307
|
}
|
|
308
308
|
});
|
|
309
|
-
events.on(controlMessageEnum.muteAudio, ({sender}) => {
|
|
309
|
+
events.on(controlMessageEnum.muteAudio, async ({sender}) => {
|
|
310
310
|
Toast.show({
|
|
311
311
|
leadingIconName: 'mic-off',
|
|
312
312
|
type: 'info',
|
|
@@ -319,7 +319,10 @@ const EventsConfigure: React.FC<Props> = props => {
|
|
|
319
319
|
secondaryBtn: null,
|
|
320
320
|
leadingIcon: null,
|
|
321
321
|
});
|
|
322
|
-
|
|
322
|
+
isWebInternal()
|
|
323
|
+
? await RtcEngineUnsafe.muteLocalAudioStream(true)
|
|
324
|
+
: //@ts-ignore
|
|
325
|
+
await RtcEngineUnsafe.enableLocalAudio(false);
|
|
323
326
|
dispatch({
|
|
324
327
|
type: 'LocalMuteAudio',
|
|
325
328
|
value: [0],
|
|
@@ -364,8 +367,11 @@ const EventsConfigure: React.FC<Props> = props => {
|
|
|
364
367
|
containerStyle={style.primaryBtn}
|
|
365
368
|
textStyle={style.textStyle}
|
|
366
369
|
text={requestUserAudioPrimaryBtnRef.current}
|
|
367
|
-
onPress={() => {
|
|
368
|
-
|
|
370
|
+
onPress={async () => {
|
|
371
|
+
isWebInternal()
|
|
372
|
+
? await RtcEngineUnsafe.muteLocalAudioStream(false)
|
|
373
|
+
: //@ts-ignore
|
|
374
|
+
await RtcEngineUnsafe.enableLocalAudio(true);
|
|
369
375
|
dispatch({
|
|
370
376
|
type: 'LocalMuteAudio',
|
|
371
377
|
value: [1],
|
|
@@ -15,13 +15,11 @@ import {
|
|
|
15
15
|
InMemoryCache,
|
|
16
16
|
ApolloProvider,
|
|
17
17
|
NormalizedCacheObject,
|
|
18
|
+
ApolloLink,
|
|
18
19
|
// from,
|
|
19
20
|
} from '@apollo/client';
|
|
20
|
-
import {setContext} from '@apollo/client/link/context';
|
|
21
|
-
// import useMount from './useMount';
|
|
22
21
|
import React, {createContext, useContext, useEffect, useState} from 'react';
|
|
23
22
|
import StorageContext from './StorageContext';
|
|
24
|
-
import AsyncStorage from '@react-native-async-storage/async-storage';
|
|
25
23
|
|
|
26
24
|
export const GraphQLContext = createContext<{
|
|
27
25
|
client: ApolloClient<NormalizedCacheObject>;
|
|
@@ -35,38 +33,57 @@ const httpLink = createHttpLink({
|
|
|
35
33
|
credentials: 'include',
|
|
36
34
|
});
|
|
37
35
|
|
|
38
|
-
const
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
36
|
+
const cache = new InMemoryCache();
|
|
37
|
+
|
|
38
|
+
const DEFAULT_CLIENT = new ApolloClient({
|
|
39
|
+
link: httpLink,
|
|
40
|
+
cache: cache,
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
const authLink = (token: string) => {
|
|
44
|
+
/**
|
|
45
|
+
* Below we create a new link, whenever a token changes, set
|
|
46
|
+
* context with headers and forward the link so as to
|
|
47
|
+
* execute the next link in the chain
|
|
48
|
+
*/
|
|
49
|
+
return new ApolloLink((operation, forward) => {
|
|
50
|
+
if (token) {
|
|
51
|
+
operation.setContext(({headers = {}}) => ({
|
|
52
|
+
headers: {
|
|
53
|
+
...headers,
|
|
54
|
+
'X-Project-ID': $config.PROJECT_ID,
|
|
55
|
+
'X-Platform-ID': 'turnkey_web',
|
|
56
|
+
...(token && {
|
|
57
|
+
authorization: token ? `Bearer ${token}` : '',
|
|
58
|
+
}),
|
|
59
|
+
},
|
|
60
|
+
}));
|
|
61
|
+
}
|
|
62
|
+
return forward(operation);
|
|
52
63
|
});
|
|
64
|
+
};
|
|
53
65
|
|
|
54
66
|
const GraphQLProvider = (props: {children: React.ReactNode}) => {
|
|
55
67
|
const {store} = useContext(StorageContext);
|
|
56
|
-
const [client, setClient] = useState(
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
)
|
|
68
|
+
const [client, setClient] = useState(DEFAULT_CLIENT);
|
|
69
|
+
|
|
70
|
+
// useEffect(() => {
|
|
71
|
+
// setClient(
|
|
72
|
+
// new ApolloClient({
|
|
73
|
+
// link: authLink(store?.token).concat(httpLink),
|
|
74
|
+
// cache: new InMemoryCache(),
|
|
75
|
+
// }),
|
|
76
|
+
// );
|
|
77
|
+
// }, [store?.token]);
|
|
62
78
|
|
|
63
79
|
useEffect(() => {
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
80
|
+
if (!store?.token) {
|
|
81
|
+
return;
|
|
82
|
+
}
|
|
83
|
+
(async () => {
|
|
84
|
+
const link = authLink(store?.token).concat(httpLink);
|
|
85
|
+
setClient(new ApolloClient({link, cache}));
|
|
86
|
+
})();
|
|
70
87
|
}, [store?.token]);
|
|
71
88
|
|
|
72
89
|
// const errorLink = onError(
|
|
@@ -74,7 +91,7 @@ const GraphQLProvider = (props: {children: React.ReactNode}) => {
|
|
|
74
91
|
// // To retry on network errors, we recommend the RetryLink
|
|
75
92
|
// // instead of the onError link. This just logs the error.
|
|
76
93
|
// if (networkError) {
|
|
77
|
-
|
|
94
|
+
|
|
78
95
|
// // switch (err.extensions.code) {
|
|
79
96
|
// // // Apollo Server sets code to UNAUTHENTICATED
|
|
80
97
|
// // // when an AuthenticationError is thrown in a resolver
|
|
@@ -15,7 +15,11 @@ import {View, StyleSheet, Pressable, Text} from 'react-native';
|
|
|
15
15
|
import {isWebInternal, useIsDesktop} from '../utils/common';
|
|
16
16
|
import {useSetPinnedLayout} from '../pages/video-call/DefaultLayouts';
|
|
17
17
|
import RenderComponent from '../pages/video-call/RenderComponent';
|
|
18
|
-
import {
|
|
18
|
+
import {
|
|
19
|
+
ClientRoleType,
|
|
20
|
+
DispatchContext,
|
|
21
|
+
PropsContext,
|
|
22
|
+
} from '../../agora-rn-uikit';
|
|
19
23
|
import LiveStreamAttendeeLandingTile from './livestream/views/LiveStreamAttendeeLandingTile';
|
|
20
24
|
|
|
21
25
|
const layout = (len: number, isDesktop: boolean = true) => {
|
|
@@ -53,7 +57,7 @@ const GridVideo: LayoutComponent = ({renderData}) => {
|
|
|
53
57
|
//livestreaming audience will see this if no host joined the call
|
|
54
58
|
if (
|
|
55
59
|
$config.EVENT_MODE &&
|
|
56
|
-
rtcProps?.role ===
|
|
60
|
+
rtcProps?.role === ClientRoleType.ClientRoleAudience &&
|
|
57
61
|
activeUids.filter(i => !customContent[i]).length === 0
|
|
58
62
|
) {
|
|
59
63
|
return <LiveStreamAttendeeLandingTile />;
|
|
@@ -28,6 +28,12 @@ import {useRtc} from 'customization-api';
|
|
|
28
28
|
* 7 - Unsupported
|
|
29
29
|
* 8 - Loading
|
|
30
30
|
*/
|
|
31
|
+
|
|
32
|
+
interface RtcConnection {
|
|
33
|
+
channelId?: string;
|
|
34
|
+
localUid?: number;
|
|
35
|
+
}
|
|
36
|
+
|
|
31
37
|
export const networkIconsObject: {
|
|
32
38
|
[key: number]: {
|
|
33
39
|
icon: keyof IconsInterface;
|
|
@@ -106,13 +112,14 @@ export const NetworkQualityProvider: React.FC = (props: {
|
|
|
106
112
|
|
|
107
113
|
useMount(() => {
|
|
108
114
|
function handleNetworkQuality(
|
|
115
|
+
connection: RtcConnection,
|
|
109
116
|
uid: UidType,
|
|
110
|
-
downlinkQuality: number,
|
|
111
117
|
// Currently unused , potential use might be to take weighted average
|
|
112
118
|
// of this alongside the downlink quality.
|
|
113
|
-
uplinkQuality:
|
|
119
|
+
uplinkQuality: keyof typeof networkIconsObject,
|
|
120
|
+
downlinkQuality: keyof typeof networkIconsObject,
|
|
114
121
|
) {
|
|
115
|
-
setNetworkQualityStats(
|
|
122
|
+
setNetworkQualityStats(prevNetworkQualityStats => {
|
|
116
123
|
const updatedNetworkQualityStats = {...prevNetworkQualityStats};
|
|
117
124
|
if (uid === 0) {
|
|
118
125
|
const displayedNetworkQuality =
|
|
@@ -130,8 +137,7 @@ export const NetworkQualityProvider: React.FC = (props: {
|
|
|
130
137
|
return updatedNetworkQualityStats;
|
|
131
138
|
});
|
|
132
139
|
}
|
|
133
|
-
|
|
134
|
-
RtcEngineUnsafe.addListener('NetworkQuality', handleNetworkQuality);
|
|
140
|
+
RtcEngineUnsafe.addListener('onNetworkQuality', handleNetworkQuality);
|
|
135
141
|
});
|
|
136
142
|
|
|
137
143
|
return (
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
*/
|
|
12
12
|
import React, {useContext, useState} from 'react';
|
|
13
13
|
import {View, Text, StyleSheet, ScrollView} from 'react-native';
|
|
14
|
-
import {PropsContext,
|
|
14
|
+
import {PropsContext, ClientRoleType} from '../../agora-rn-uikit';
|
|
15
15
|
import CopyJoinInfo from '../subComponents/CopyJoinInfo';
|
|
16
16
|
import ParticipantSectionTitle from './participants/ParticipantSectionTitle';
|
|
17
17
|
import AllHostParticipants from './participants/AllHostParticipants';
|
|
@@ -109,7 +109,7 @@ const ParticipantView = props => {
|
|
|
109
109
|
{
|
|
110
110
|
/*Live streaming is true
|
|
111
111
|
Host and New host view */
|
|
112
|
-
rtcProps?.role ==
|
|
112
|
+
rtcProps?.role == ClientRoleType.ClientRoleBroadcaster &&
|
|
113
113
|
(isHost ? (
|
|
114
114
|
/**
|
|
115
115
|
* Original Host
|
|
@@ -177,7 +177,7 @@ const ParticipantView = props => {
|
|
|
177
177
|
/**
|
|
178
178
|
* Audience views all hosts without remote controls
|
|
179
179
|
*/
|
|
180
|
-
rtcProps?.role ==
|
|
180
|
+
rtcProps?.role == ClientRoleType.ClientRoleAudience && (
|
|
181
181
|
<>
|
|
182
182
|
<ParticipantSectionTitle
|
|
183
183
|
title={hostLabel}
|
|
@@ -24,7 +24,7 @@ import {useContent} from 'customization-api';
|
|
|
24
24
|
import RenderComponent from '../pages/video-call/RenderComponent';
|
|
25
25
|
import IconButton from '../atoms/IconButton';
|
|
26
26
|
import hexadecimalTransparency from '../utils/hexadecimalTransparency';
|
|
27
|
-
import {BREAKPOINTS, isMobileUA} from '../utils/common';
|
|
27
|
+
import {BREAKPOINTS, isMobileUA, isWebInternal} from '../utils/common';
|
|
28
28
|
import {DispatchContext} from '../../agora-rn-uikit';
|
|
29
29
|
import {useVideoCall} from '../components/useVideoCall';
|
|
30
30
|
import useActiveSpeaker from '../utils/useActiveSpeaker';
|
|
@@ -180,7 +180,7 @@ const PinnedVideo = ({renderData}) => {
|
|
|
180
180
|
);
|
|
181
181
|
})}
|
|
182
182
|
</ScrollView>
|
|
183
|
-
{$config.ACTIVE_SPEAKER && !isOnTop && (
|
|
183
|
+
{$config.ACTIVE_SPEAKER && !isOnTop && isWebInternal() && (
|
|
184
184
|
<View
|
|
185
185
|
style={
|
|
186
186
|
isSidePinnedlayout
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
*/
|
|
12
12
|
import React, {useState, useContext, useEffect} from 'react';
|
|
13
13
|
import {View, Text, StyleSheet, ScrollView} from 'react-native';
|
|
14
|
-
import {PropsContext,
|
|
14
|
+
import {PropsContext, ClientRoleType, ToggleState} from '../../agora-rn-uikit';
|
|
15
15
|
import {isValidReactComponent, isWebInternal, trimText} from '../utils/common';
|
|
16
16
|
import ColorContext from './ColorContext';
|
|
17
17
|
import {useRoomInfo} from './room-info/useRoomInfo';
|
|
@@ -96,7 +96,9 @@ const JoinRoomInputView = ({isDesktop}) => {
|
|
|
96
96
|
{/* <Text style={style.subTextStyle}>
|
|
97
97
|
Enter the name you would like to join the room as
|
|
98
98
|
</Text> */}
|
|
99
|
-
{rtcProps.role ==
|
|
99
|
+
{rtcProps.role == ClientRoleType.ClientRoleAudience && (
|
|
100
|
+
<Spacer size={20} />
|
|
101
|
+
)}
|
|
100
102
|
</>
|
|
101
103
|
) : (
|
|
102
104
|
<></>
|
|
@@ -104,7 +106,7 @@ const JoinRoomInputView = ({isDesktop}) => {
|
|
|
104
106
|
<View
|
|
105
107
|
style={
|
|
106
108
|
$config.EVENT_MODE &&
|
|
107
|
-
rtcProps.role ==
|
|
109
|
+
rtcProps.role == ClientRoleType.ClientRoleAudience && {
|
|
108
110
|
justifyContent: 'space-between',
|
|
109
111
|
flex: 1,
|
|
110
112
|
}
|
|
@@ -117,7 +119,7 @@ const JoinRoomInputView = ({isDesktop}) => {
|
|
|
117
119
|
: {width: '100%'}
|
|
118
120
|
}>
|
|
119
121
|
{$config.ENABLE_WAITING_ROOM &&
|
|
120
|
-
rtcProps.role ===
|
|
122
|
+
rtcProps.role === ClientRoleType.ClientRoleAudience ? (
|
|
121
123
|
<JoinWaitingRoomBtn />
|
|
122
124
|
) : (
|
|
123
125
|
<JoinButton />
|
|
@@ -203,7 +205,7 @@ const JoinRoomButton = () => {
|
|
|
203
205
|
return components;
|
|
204
206
|
});
|
|
205
207
|
return $config.ENABLE_WAITING_ROOM &&
|
|
206
|
-
rtcProps.role ===
|
|
208
|
+
rtcProps.role === ClientRoleType.ClientRoleAudience ? (
|
|
207
209
|
<JoinWaitingRoomBtn />
|
|
208
210
|
) : (
|
|
209
211
|
<JoinButton />
|
|
@@ -350,7 +352,8 @@ const Precall = (props: any) => {
|
|
|
350
352
|
contentContainerStyle={style.mainMobile}
|
|
351
353
|
testID="precall-screen">
|
|
352
354
|
{/* Precall screen only changes for audience in Live Stream event */}
|
|
353
|
-
{$config.EVENT_MODE &&
|
|
355
|
+
{$config.EVENT_MODE &&
|
|
356
|
+
rtcProps.role == ClientRoleType.ClientRoleAudience ? (
|
|
354
357
|
// Live (Audience)
|
|
355
358
|
<View style={{flex: 1}}>
|
|
356
359
|
<View
|