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
|
@@ -35,12 +35,12 @@ import events, {PersistanceLevel} from '../../rtm-events-api';
|
|
|
35
35
|
import VideoCallMobileView from './VideoCallMobileView';
|
|
36
36
|
import CaptionContainer from '../../subComponents/caption/CaptionContainer';
|
|
37
37
|
import Transcript from '../../subComponents/caption/Transcript';
|
|
38
|
-
|
|
39
38
|
import Spacer from '../../atoms/Spacer';
|
|
40
39
|
import Leftbar, {LeftbarProps} from '../../components/Leftbar';
|
|
41
40
|
import Rightbar, {RightbarProps} from '../../components/Rightbar';
|
|
42
41
|
import useFindActiveSpeaker from '../../utils/useFindActiveSpeaker';
|
|
43
42
|
import VBPanel from '../../components/virtual-background/VBPanel';
|
|
43
|
+
import {useIsRecordingBot} from '../../subComponents/recording/useIsRecordingBot';
|
|
44
44
|
|
|
45
45
|
const VideoCallScreen = () => {
|
|
46
46
|
useFindActiveSpeaker();
|
|
@@ -231,6 +231,8 @@ const VideoCallScreen = () => {
|
|
|
231
231
|
const isDesktop = useIsDesktop();
|
|
232
232
|
const isSmall = useIsSmall();
|
|
233
233
|
|
|
234
|
+
const {isRecordingBot, recordingBotUIConfig} = useIsRecordingBot();
|
|
235
|
+
|
|
234
236
|
return VideocallComponent ? (
|
|
235
237
|
<VideocallComponent />
|
|
236
238
|
) : // ) : !isDesktop ? (
|
|
@@ -255,16 +257,23 @@ const VideoCallScreen = () => {
|
|
|
255
257
|
)}
|
|
256
258
|
</ToolbarProvider>
|
|
257
259
|
<View style={style.full}>
|
|
258
|
-
<
|
|
259
|
-
{
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
260
|
+
<View
|
|
261
|
+
style={
|
|
262
|
+
isRecordingBot &&
|
|
263
|
+
!recordingBotUIConfig.topBar &&
|
|
264
|
+
style.zeroHeight
|
|
265
|
+
}>
|
|
266
|
+
<ToolbarProvider value={{position: ToolbarPosition.top}}>
|
|
267
|
+
{TopbarProps?.length ? (
|
|
268
|
+
<TopbarComponent
|
|
269
|
+
customItems={TopbarProps}
|
|
270
|
+
includeDefaultItems={false}
|
|
271
|
+
/>
|
|
272
|
+
) : (
|
|
273
|
+
<TopbarComponent />
|
|
274
|
+
)}
|
|
275
|
+
</ToolbarProvider>
|
|
276
|
+
</View>
|
|
268
277
|
<View
|
|
269
278
|
style={[
|
|
270
279
|
style.videoView,
|
|
@@ -316,7 +325,14 @@ const VideoCallScreen = () => {
|
|
|
316
325
|
<>
|
|
317
326
|
<CaptionContainer />
|
|
318
327
|
<Spacer size={10} />
|
|
319
|
-
<
|
|
328
|
+
<View
|
|
329
|
+
style={
|
|
330
|
+
isRecordingBot &&
|
|
331
|
+
!recordingBotUIConfig.bottomBar &&
|
|
332
|
+
style.zeroHeight
|
|
333
|
+
}>
|
|
334
|
+
<BottombarComponent />
|
|
335
|
+
</View>
|
|
320
336
|
</>
|
|
321
337
|
)}
|
|
322
338
|
</ToolbarProvider>
|
|
@@ -362,4 +378,8 @@ const style = StyleSheet.create({
|
|
|
362
378
|
flex: 12,
|
|
363
379
|
flexDirection: 'row',
|
|
364
380
|
},
|
|
381
|
+
zeroHeight: {
|
|
382
|
+
height: 0,
|
|
383
|
+
visibility: 'hidden',
|
|
384
|
+
},
|
|
365
385
|
});
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import React, {useContext, useEffect} from 'react';
|
|
2
|
+
import {PropsContext} from '../../../agora-rn-uikit';
|
|
3
|
+
import VideoCallScreen from '../video-call/VideoCallScreen';
|
|
4
|
+
import {isWebInternal} from '../../utils/common';
|
|
5
|
+
import {useLocation} from '../../components/Router';
|
|
6
|
+
import {getParamFromURL} from '../../utils/common';
|
|
7
|
+
import {useUserPreference} from '../../components/useUserPreference';
|
|
8
|
+
import WhiteboardConfigure from '../../components/whiteboard/WhiteboardConfigure';
|
|
9
|
+
|
|
10
|
+
const VideoCallScreenWithRecordingBot: React.FC = () => {
|
|
11
|
+
const location = useLocation();
|
|
12
|
+
const {setDisplayName} = useUserPreference();
|
|
13
|
+
|
|
14
|
+
const recordingBotName = getParamFromURL(location?.search, 'user_name');
|
|
15
|
+
|
|
16
|
+
useEffect(() => {
|
|
17
|
+
setDisplayName(recordingBotName);
|
|
18
|
+
}, []);
|
|
19
|
+
return <VideoCallScreen />;
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
const VideoCallScreenWrapper: React.FC = () => {
|
|
23
|
+
const {rtcProps} = useContext(PropsContext);
|
|
24
|
+
|
|
25
|
+
if ($config.ENABLE_WHITEBOARD) {
|
|
26
|
+
return (
|
|
27
|
+
<WhiteboardConfigure>
|
|
28
|
+
{rtcProps?.recordingBot ? (
|
|
29
|
+
<VideoCallScreenWithRecordingBot />
|
|
30
|
+
) : (
|
|
31
|
+
<VideoCallScreen />
|
|
32
|
+
)}
|
|
33
|
+
</WhiteboardConfigure>
|
|
34
|
+
);
|
|
35
|
+
} else if (rtcProps?.recordingBot) {
|
|
36
|
+
return <VideoCallScreenWithRecordingBot />;
|
|
37
|
+
}
|
|
38
|
+
return <VideoCallScreen />;
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
export default VideoCallScreenWrapper;
|
|
@@ -2,7 +2,7 @@ import React, {useContext, useEffect, useRef, useState} from 'react';
|
|
|
2
2
|
import {View} from 'react-native';
|
|
3
3
|
import useLayoutsData from './useLayoutsData';
|
|
4
4
|
import {isArray, useIsDesktop, isValidReactComponent} from '../../utils/common';
|
|
5
|
-
import {PropsContext,
|
|
5
|
+
import {PropsContext, ClientRoleType} from '../../../agora-rn-uikit';
|
|
6
6
|
import {useLayout} from '../../utils/useLayout';
|
|
7
7
|
import {useContent} from 'customization-api';
|
|
8
8
|
import {getGridLayoutName} from './DefaultLayouts';
|
|
@@ -53,7 +53,10 @@ const VideoComponent = () => {
|
|
|
53
53
|
}, [currentLayout]);
|
|
54
54
|
|
|
55
55
|
const showInviteTile = () => {
|
|
56
|
-
if (
|
|
56
|
+
if (
|
|
57
|
+
$config.EVENT_MODE &&
|
|
58
|
+
rtcProps.role == ClientRoleType.ClientRoleAudience
|
|
59
|
+
) {
|
|
57
60
|
return false;
|
|
58
61
|
}
|
|
59
62
|
if (activeUids.length == 1) return true;
|
|
@@ -68,7 +68,12 @@ const VideoRenderer: React.FC<VideoRendererProps> = ({
|
|
|
68
68
|
const videoMoreMenuRef = useRef(null);
|
|
69
69
|
const [actionMenuVisible, setActionMenuVisible] = React.useState(false);
|
|
70
70
|
const {setVideoTileInViewPortState} = useVideoCall();
|
|
71
|
-
const {
|
|
71
|
+
const {
|
|
72
|
+
getWhiteboardUid = () => 0,
|
|
73
|
+
isWhiteboardOnFullScreen,
|
|
74
|
+
setWhiteboardOnFullScreen,
|
|
75
|
+
whiteboardActive,
|
|
76
|
+
} = useWhiteboard();
|
|
72
77
|
const [landscapeMode, setLandscapeMode] = useState(
|
|
73
78
|
isAndroid() || isIOS() ? true : false,
|
|
74
79
|
);
|
|
@@ -90,22 +95,19 @@ const VideoRenderer: React.FC<VideoRendererProps> = ({
|
|
|
90
95
|
//if screenshare is on fullscreen then get the width/height to set landscape mode
|
|
91
96
|
if (isScreenShareOnFullView) {
|
|
92
97
|
if (isAndroid() || isIOS()) {
|
|
93
|
-
const cb =
|
|
98
|
+
const cb = (connection, stats) => {
|
|
94
99
|
if (
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
100
|
+
stats?.uid == user.uid &&
|
|
101
|
+
stats?.width &&
|
|
102
|
+
stats?.height &&
|
|
103
|
+
stats.height > stats.width
|
|
99
104
|
) {
|
|
100
105
|
landscapeModeRef.current.landscapeMode && setLandscapeMode(false);
|
|
101
106
|
}
|
|
102
107
|
};
|
|
103
|
-
|
|
104
|
-
'RemoteVideoStats',
|
|
105
|
-
cb,
|
|
106
|
-
);
|
|
108
|
+
RtcEngineUnsafe.addListener('onRemoteVideoStats', cb);
|
|
107
109
|
setTimeout(() => {
|
|
108
|
-
|
|
110
|
+
RtcEngineUnsafe.removeAllListeners('onRemoteVideoStats');
|
|
109
111
|
}, 5000);
|
|
110
112
|
} else {
|
|
111
113
|
if (screenShareData && screenShareData?.[user.uid] && isMobileUA()) {
|
|
@@ -125,8 +127,13 @@ const VideoRenderer: React.FC<VideoRendererProps> = ({
|
|
|
125
127
|
}, [screenShareData, isScreenShareOnFullView]);
|
|
126
128
|
|
|
127
129
|
const isNativeScreenShareActive =
|
|
128
|
-
(isAndroid() || isIOS()) &&
|
|
129
|
-
|
|
130
|
+
(isAndroid() || isIOS() || isMobileUA()) && user?.type === 'screenshare';
|
|
131
|
+
|
|
132
|
+
const isNativeWhiteboardActive =
|
|
133
|
+
(isAndroid() || isIOS() || isMobileUA()) && whiteboardActive;
|
|
134
|
+
|
|
135
|
+
const enableExpandButton =
|
|
136
|
+
isNativeScreenShareActive || isNativeWhiteboardActive ? true : false;
|
|
130
137
|
|
|
131
138
|
const {enablePinForMe} = useVideoCall();
|
|
132
139
|
|
|
@@ -191,13 +198,15 @@ const VideoRenderer: React.FC<VideoRendererProps> = ({
|
|
|
191
198
|
) : (
|
|
192
199
|
<></>
|
|
193
200
|
)}
|
|
194
|
-
{enableExpandButton &&
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
201
|
+
{(enableExpandButton &&
|
|
202
|
+
screenShareData &&
|
|
203
|
+
screenShareData?.[user.uid] &&
|
|
204
|
+
isMobileUA()) ||
|
|
205
|
+
(isMobileUA() && enableExpandButton && user?.type == 'whiteboard') ? (
|
|
198
206
|
<IconButton
|
|
199
207
|
containerStyle={
|
|
200
|
-
isScreenShareOnFullView &&
|
|
208
|
+
(isScreenShareOnFullView || isWhiteboardOnFullScreen) &&
|
|
209
|
+
landscapeMode
|
|
201
210
|
? {
|
|
202
211
|
position: 'absolute',
|
|
203
212
|
top: 8,
|
|
@@ -206,6 +215,14 @@ const VideoRenderer: React.FC<VideoRendererProps> = ({
|
|
|
206
215
|
zIndex: 999,
|
|
207
216
|
elevation: 999,
|
|
208
217
|
}
|
|
218
|
+
: user?.type == 'whiteboard'
|
|
219
|
+
? {
|
|
220
|
+
position: 'absolute',
|
|
221
|
+
top: 8,
|
|
222
|
+
left: 8,
|
|
223
|
+
zIndex: 999,
|
|
224
|
+
elevation: 999,
|
|
225
|
+
}
|
|
209
226
|
: {
|
|
210
227
|
position: 'absolute',
|
|
211
228
|
top: 8,
|
|
@@ -220,18 +237,22 @@ const VideoRenderer: React.FC<VideoRendererProps> = ({
|
|
|
220
237
|
}
|
|
221
238
|
}
|
|
222
239
|
onPress={() => {
|
|
223
|
-
|
|
224
|
-
!
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
240
|
+
if (user?.type == 'whiteboard') {
|
|
241
|
+
setWhiteboardOnFullScreen(!isWhiteboardOnFullScreen);
|
|
242
|
+
} else {
|
|
243
|
+
setScreenShareOnFullView(
|
|
244
|
+
!screenShareData[user.uid]?.isExpanded,
|
|
245
|
+
);
|
|
246
|
+
setScreenShareData(prevState => {
|
|
247
|
+
return {
|
|
248
|
+
...prevState,
|
|
249
|
+
[user.uid]: {
|
|
250
|
+
...prevState[user.uid],
|
|
251
|
+
isExpanded: !prevState[user.uid]?.isExpanded,
|
|
252
|
+
},
|
|
253
|
+
};
|
|
254
|
+
});
|
|
255
|
+
}
|
|
235
256
|
}}
|
|
236
257
|
iconProps={{
|
|
237
258
|
iconContainerStyle: {
|
|
@@ -241,6 +262,7 @@ const VideoRenderer: React.FC<VideoRendererProps> = ({
|
|
|
241
262
|
transform: [{rotate: '-45deg'}],
|
|
242
263
|
},
|
|
243
264
|
name:
|
|
265
|
+
isWhiteboardOnFullScreen ||
|
|
244
266
|
screenShareData?.[user?.uid]?.isExpanded === true
|
|
245
267
|
? 'collapse'
|
|
246
268
|
: 'expand',
|
|
@@ -284,7 +306,7 @@ const VideoRenderer: React.FC<VideoRendererProps> = ({
|
|
|
284
306
|
avatarSize,
|
|
285
307
|
);
|
|
286
308
|
}}
|
|
287
|
-
user={
|
|
309
|
+
user={user}
|
|
288
310
|
containerStyle={{
|
|
289
311
|
width:
|
|
290
312
|
landscapeMode && isScreenShareOnFullView
|
|
@@ -292,8 +314,6 @@ const VideoRenderer: React.FC<VideoRendererProps> = ({
|
|
|
292
314
|
: '100%',
|
|
293
315
|
height:
|
|
294
316
|
landscapeMode && isScreenShareOnFullView ? width : '100%',
|
|
295
|
-
// width: '100%',
|
|
296
|
-
// height: '100%',
|
|
297
317
|
borderRadius: 4,
|
|
298
318
|
overflow: 'hidden',
|
|
299
319
|
}}
|
|
@@ -307,6 +327,7 @@ const VideoRenderer: React.FC<VideoRendererProps> = ({
|
|
|
307
327
|
</ZoomableWrapper>
|
|
308
328
|
{(!isScreenShareOnFullView && !CustomChild) ||
|
|
309
329
|
(CustomChild &&
|
|
330
|
+
!isWhiteboardOnFullScreen &&
|
|
310
331
|
(pinnedUid !== getWhiteboardUid() || currentLayout === 'grid')) ? (
|
|
311
332
|
<VideoContainerProvider value={{videoTileWidth}}>
|
|
312
333
|
<NameWithMicIcon
|
|
@@ -325,7 +346,7 @@ const VideoRenderer: React.FC<VideoRendererProps> = ({
|
|
|
325
346
|
) : (
|
|
326
347
|
<></>
|
|
327
348
|
)}
|
|
328
|
-
{!isScreenShareOnFullView &&
|
|
349
|
+
{!(isScreenShareOnFullView || isWhiteboardOnFullScreen) &&
|
|
329
350
|
// user.uid !== rtcProps?.screenShareUid &&
|
|
330
351
|
(isHovered || actionMenuVisible || isMobileUA()) ? (
|
|
331
352
|
<MoreMenu
|
|
@@ -2,7 +2,6 @@
|
|
|
2
2
|
// 1. RECORDING
|
|
3
3
|
const RECORDING_STARTED = 'RECORDING_STARTED';
|
|
4
4
|
const RECORDING_STOPPED = 'RECORDING_STOPPED';
|
|
5
|
-
const RECORDING_STOP_REQUEST = 'RECORDING_STOP_REQUEST';
|
|
6
5
|
// 2. SCREENSHARE
|
|
7
6
|
const SCREENSHARE_STARTED = 'SCREENSHARE_STARTED';
|
|
8
7
|
const SCREENSHARE_STOPPED = 'SCREENSHARE_STOPPED';
|
|
@@ -10,7 +9,6 @@ const SCREENSHARE_STOPPED = 'SCREENSHARE_STOPPED';
|
|
|
10
9
|
const EventActions = {
|
|
11
10
|
RECORDING_STARTED,
|
|
12
11
|
RECORDING_STOPPED,
|
|
13
|
-
RECORDING_STOP_REQUEST,
|
|
14
12
|
SCREENSHARE_STARTED,
|
|
15
13
|
SCREENSHARE_STOPPED,
|
|
16
14
|
};
|
|
@@ -170,6 +170,7 @@ const style = StyleSheet.create({
|
|
|
170
170
|
borderBottomRightRadius: 8,
|
|
171
171
|
borderTopLeftRadius: 0,
|
|
172
172
|
borderTopRightRadius: 8,
|
|
173
|
+
maxWidth: '88%',
|
|
173
174
|
},
|
|
174
175
|
chatBubbleRemoteViewLayer2: {
|
|
175
176
|
backgroundColor: 'transparent',
|
|
@@ -204,6 +205,7 @@ const style = StyleSheet.create({
|
|
|
204
205
|
borderBottomRightRadius: 8,
|
|
205
206
|
borderTopLeftRadius: 8,
|
|
206
207
|
borderTopRightRadius: 0,
|
|
208
|
+
maxWidth: '88%',
|
|
207
209
|
},
|
|
208
210
|
messageStyle: {
|
|
209
211
|
fontFamily: ThemeConfig.FontFamily.sansPro,
|
|
@@ -14,7 +14,7 @@ import {
|
|
|
14
14
|
ToggleState,
|
|
15
15
|
PermissionState,
|
|
16
16
|
ImageIcon as UIKitImageIcon,
|
|
17
|
-
|
|
17
|
+
ClientRoleType,
|
|
18
18
|
PropsContext,
|
|
19
19
|
useLocalUid,
|
|
20
20
|
DispatchContext,
|
|
@@ -140,8 +140,9 @@ function LocalAudioMute(props: LocalAudioMuteProps) {
|
|
|
140
140
|
// justifyContent: 'center',
|
|
141
141
|
// alignItems: 'center',
|
|
142
142
|
// };
|
|
143
|
-
const isAudience = rtcProps?.role ==
|
|
144
|
-
const isBroadCasting =
|
|
143
|
+
const isAudience = rtcProps?.role == ClientRoleType.ClientRoleAudience;
|
|
144
|
+
const isBroadCasting =
|
|
145
|
+
rtcProps?.role == ClientRoleType.ClientRoleBroadcaster;
|
|
145
146
|
|
|
146
147
|
iconButtonProps.disabled =
|
|
147
148
|
permissionDenied || ($config.EVENT_MODE && isAudience && !isBroadCasting)
|
|
@@ -178,7 +179,7 @@ function LocalAudioMute(props: LocalAudioMuteProps) {
|
|
|
178
179
|
}
|
|
179
180
|
|
|
180
181
|
if (
|
|
181
|
-
rtcProps.role ==
|
|
182
|
+
rtcProps.role == ClientRoleType.ClientRoleAudience &&
|
|
182
183
|
$config.EVENT_MODE &&
|
|
183
184
|
!$config.RAISE_HAND
|
|
184
185
|
) {
|
|
@@ -186,7 +187,7 @@ function LocalAudioMute(props: LocalAudioMuteProps) {
|
|
|
186
187
|
}
|
|
187
188
|
|
|
188
189
|
if (
|
|
189
|
-
(rtcProps.role ==
|
|
190
|
+
(rtcProps.role == ClientRoleType.ClientRoleAudience &&
|
|
190
191
|
$config.EVENT_MODE &&
|
|
191
192
|
$config.RAISE_HAND &&
|
|
192
193
|
!isHost) ||
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import React, {useContext} from 'react';
|
|
2
2
|
import {Text, ViewStyle} from 'react-native';
|
|
3
3
|
import {useString} from '../utils/useString';
|
|
4
|
-
import {
|
|
4
|
+
import {ClientRoleType, PropsContext, ToggleState} from '../../agora-rn-uikit';
|
|
5
5
|
import Styles from '../components/styles';
|
|
6
6
|
import {isAndroid, isIOS, useLocalUserInfo, useRtc} from 'customization-api';
|
|
7
7
|
import IconButton, {IconButtonProps} from '../atoms/IconButton';
|
|
@@ -37,8 +37,8 @@ function LocalSwitchCamera(props: LocalSwitchCameraProps) {
|
|
|
37
37
|
|
|
38
38
|
const {rtcProps} = useContext(PropsContext);
|
|
39
39
|
const isLiveStream = $config.EVENT_MODE;
|
|
40
|
-
const isAudience = rtcProps?.role ==
|
|
41
|
-
const isBroadCasting = rtcProps?.role ==
|
|
40
|
+
const isAudience = rtcProps?.role == ClientRoleType.ClientRoleAudience;
|
|
41
|
+
const isBroadCasting = rtcProps?.role == ClientRoleType.ClientRoleBroadcaster;
|
|
42
42
|
const showTitle = showText ? showLabel : false;
|
|
43
43
|
const onPress = () => {
|
|
44
44
|
RtcEngineUnsafe.switchCamera();
|
|
@@ -14,7 +14,7 @@ import {
|
|
|
14
14
|
ToggleState,
|
|
15
15
|
PermissionState,
|
|
16
16
|
ImageIcon as UIKitImageIcon,
|
|
17
|
-
|
|
17
|
+
ClientRoleType,
|
|
18
18
|
PropsContext,
|
|
19
19
|
RtcContext,
|
|
20
20
|
DispatchContext,
|
|
@@ -154,8 +154,9 @@ function LocalVideoMute(props: LocalVideoMuteProps) {
|
|
|
154
154
|
// justifyContent: 'center',
|
|
155
155
|
// alignItems: 'center',
|
|
156
156
|
// };
|
|
157
|
-
const isAudience = rtcProps?.role ==
|
|
158
|
-
const isBroadCasting =
|
|
157
|
+
const isAudience = rtcProps?.role == ClientRoleType.ClientRoleAudience;
|
|
158
|
+
const isBroadCasting =
|
|
159
|
+
rtcProps?.role == ClientRoleType.ClientRoleBroadcaster;
|
|
159
160
|
|
|
160
161
|
iconButtonProps.disabled =
|
|
161
162
|
permissionDenied || ($config.EVENT_MODE && isAudience && !isBroadCasting)
|
|
@@ -191,7 +192,7 @@ function LocalVideoMute(props: LocalVideoMuteProps) {
|
|
|
191
192
|
}
|
|
192
193
|
|
|
193
194
|
if (
|
|
194
|
-
rtcProps.role ==
|
|
195
|
+
rtcProps.role == ClientRoleType.ClientRoleAudience &&
|
|
195
196
|
$config.EVENT_MODE &&
|
|
196
197
|
!$config.RAISE_HAND
|
|
197
198
|
) {
|
|
@@ -199,7 +200,7 @@ function LocalVideoMute(props: LocalVideoMuteProps) {
|
|
|
199
200
|
}
|
|
200
201
|
|
|
201
202
|
if (
|
|
202
|
-
(rtcProps.role ==
|
|
203
|
+
(rtcProps.role == ClientRoleType.ClientRoleAudience &&
|
|
203
204
|
$config.EVENT_MODE &&
|
|
204
205
|
$config.RAISE_HAND &&
|
|
205
206
|
!isHost) ||
|
|
@@ -13,7 +13,7 @@ import React, {useContext, useEffect, useState, useMemo} from 'react';
|
|
|
13
13
|
import {StyleSheet, View, Text} from 'react-native';
|
|
14
14
|
import {
|
|
15
15
|
PropsContext,
|
|
16
|
-
|
|
16
|
+
ClientRoleType,
|
|
17
17
|
LocalContext,
|
|
18
18
|
PermissionState,
|
|
19
19
|
LocalUserContext,
|
|
@@ -68,7 +68,10 @@ const useSelectDevice = (): [boolean, string] => {
|
|
|
68
68
|
const [isPickerDisabled, setPickerDisabled] = React.useState<boolean>(false);
|
|
69
69
|
|
|
70
70
|
React.useEffect(() => {
|
|
71
|
-
if (
|
|
71
|
+
if (
|
|
72
|
+
$config.EVENT_MODE &&
|
|
73
|
+
rtcProps.role === ClientRoleType.ClientRoleAudience
|
|
74
|
+
) {
|
|
72
75
|
setPickerDisabled(true);
|
|
73
76
|
setBtnTheme('rgba(16, 16, 16, 0.3)');
|
|
74
77
|
} else {
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
*/
|
|
12
12
|
import React, {useContext, useEffect} from 'react';
|
|
13
13
|
import {StyleSheet, View, Text} from 'react-native';
|
|
14
|
-
import {PropsContext,
|
|
14
|
+
import {PropsContext, ClientRoleType} from '../../agora-rn-uikit';
|
|
15
15
|
import DeviceContext from '../components/DeviceContext';
|
|
16
16
|
import ColorContext from '../components/ColorContext';
|
|
17
17
|
import {useString} from '../utils/useString';
|
|
@@ -30,7 +30,10 @@ const useSelectDevice = (): [boolean, string] => {
|
|
|
30
30
|
const [btnTheme, setBtnTheme] = React.useState<string>(primaryColor);
|
|
31
31
|
const [isPickerDisabled, setPickerDisabled] = React.useState<boolean>(false);
|
|
32
32
|
React.useEffect(() => {
|
|
33
|
-
if (
|
|
33
|
+
if (
|
|
34
|
+
$config.EVENT_MODE &&
|
|
35
|
+
rtcProps.role === ClientRoleType.ClientRoleAudience
|
|
36
|
+
) {
|
|
34
37
|
setPickerDisabled(true);
|
|
35
38
|
setBtnTheme('rgba(16, 16, 16, 0.3)');
|
|
36
39
|
} else {
|
|
@@ -60,7 +63,7 @@ const SelectVideoDevice = (props: SelectVideoDeviceProps) => {
|
|
|
60
63
|
return true;
|
|
61
64
|
}
|
|
62
65
|
})
|
|
63
|
-
?.map(
|
|
66
|
+
?.map(device => {
|
|
64
67
|
return {
|
|
65
68
|
label: device.label,
|
|
66
69
|
value: device.deviceId,
|
|
@@ -102,7 +105,7 @@ const SelectAudioDevice = (props: SelectAudioDeviceProps) => {
|
|
|
102
105
|
const [isFocussed, setIsFocussed] = React.useState(false);
|
|
103
106
|
|
|
104
107
|
const data = deviceList
|
|
105
|
-
.filter(
|
|
108
|
+
.filter(device => {
|
|
106
109
|
if (device.kind === 'audioinput') {
|
|
107
110
|
return true;
|
|
108
111
|
}
|
|
@@ -140,12 +143,12 @@ const SelectDeviceSettings = () => {
|
|
|
140
143
|
const {deviceList} = useContext(DeviceContext);
|
|
141
144
|
const {setCameraAvailable, setMicAvailable} = usePreCall();
|
|
142
145
|
|
|
143
|
-
const audioDevices = deviceList.filter(
|
|
146
|
+
const audioDevices = deviceList.filter(device => {
|
|
144
147
|
if (device.kind === 'audioinput') {
|
|
145
148
|
return true;
|
|
146
149
|
}
|
|
147
150
|
});
|
|
148
|
-
const videoDevices = deviceList.filter(
|
|
151
|
+
const videoDevices = deviceList.filter(device => {
|
|
149
152
|
if (device.kind === 'videoinput') {
|
|
150
153
|
return true;
|
|
151
154
|
}
|
|
@@ -6,11 +6,14 @@ import CaptionText from './CaptionText';
|
|
|
6
6
|
import Loading from '../Loading';
|
|
7
7
|
import {isWebInternal} from '../../utils/common';
|
|
8
8
|
import useStreamMessageUtils from './useStreamMessageUtils';
|
|
9
|
-
import {StreamMessageCallback} from 'react-native-agora/lib/typescript/common/RtcEvents';
|
|
10
9
|
import hexadecimalTransparency from '../../utils/hexadecimalTransparency';
|
|
11
10
|
import {useString} from '../../utils/useString';
|
|
12
11
|
import {sttSettingSpokenLanguageText} from '../../language/default-labels/videoCallScreenLabels';
|
|
13
12
|
|
|
13
|
+
type WebStreamMessageArgs = [number, Uint8Array];
|
|
14
|
+
type NativeStreamMessageArgs = [{}, number, number, Uint8Array, number, number];
|
|
15
|
+
type StreamMessageArgs = WebStreamMessageArgs | NativeStreamMessageArgs;
|
|
16
|
+
|
|
14
17
|
const Caption: React.FC = () => {
|
|
15
18
|
const {RtcEngineUnsafe} = useRtc();
|
|
16
19
|
const {
|
|
@@ -28,25 +31,24 @@ const Caption: React.FC = () => {
|
|
|
28
31
|
const [activelinesAvailable, setActiveLinesAvailable] = React.useState(0);
|
|
29
32
|
const [inActiveLinesAvailable, setInActiveLinesAvaialble] = React.useState(0);
|
|
30
33
|
|
|
31
|
-
const handleStreamMessageCallback = (
|
|
32
|
-
...args: [number, Uint8Array] | [number, string, Uint8Array]
|
|
33
|
-
) => {
|
|
34
|
+
const handleStreamMessageCallback = (...args: StreamMessageArgs) => {
|
|
34
35
|
setIsSTTListenerAdded(true);
|
|
35
36
|
if (isWebInternal()) {
|
|
36
|
-
|
|
37
|
+
const [uid, data] = args as WebStreamMessageArgs;
|
|
38
|
+
streamMessageCallback([uid, data]);
|
|
37
39
|
} else {
|
|
38
|
-
const [uid, , data] = args;
|
|
39
|
-
|
|
40
|
-
streamMessageCallback([uid, new Uint8Array(streamBuffer)]);
|
|
40
|
+
const [, uid, , data] = args as NativeStreamMessageArgs;
|
|
41
|
+
streamMessageCallback([uid, data]);
|
|
41
42
|
}
|
|
42
43
|
};
|
|
43
44
|
|
|
44
45
|
React.useEffect(() => {
|
|
45
46
|
!isSTTListenerAdded &&
|
|
46
47
|
RtcEngineUnsafe.addListener(
|
|
47
|
-
'
|
|
48
|
-
handleStreamMessageCallback
|
|
48
|
+
'onStreamMessage',
|
|
49
|
+
handleStreamMessageCallback,
|
|
49
50
|
);
|
|
51
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
50
52
|
}, []);
|
|
51
53
|
|
|
52
54
|
if (isLangChangeInProgress)
|
|
@@ -31,7 +31,6 @@ import ImageIcon from '../../atoms/ImageIcon';
|
|
|
31
31
|
import hexadecimalTransparency from '../../../src/utils/hexadecimalTransparency';
|
|
32
32
|
import Spacer from '../../atoms/Spacer';
|
|
33
33
|
import useStreamMessageUtils from './useStreamMessageUtils';
|
|
34
|
-
import {StreamMessageCallback} from 'react-native-agora/lib/typescript/common/RtcEvents';
|
|
35
34
|
import useCaptionWidth from './useCaptionWidth';
|
|
36
35
|
import DownloadTranscriptBtn from './DownloadTranscriptBtn';
|
|
37
36
|
import {useString} from '../../../src/utils/useString';
|
|
@@ -45,6 +44,11 @@ import {
|
|
|
45
44
|
interface TranscriptProps {
|
|
46
45
|
showHeader?: boolean;
|
|
47
46
|
}
|
|
47
|
+
|
|
48
|
+
type WebStreamMessageArgs = [number, Uint8Array];
|
|
49
|
+
type NativeStreamMessageArgs = [{}, number, number, Uint8Array, number, number];
|
|
50
|
+
type StreamMessageArgs = WebStreamMessageArgs | NativeStreamMessageArgs;
|
|
51
|
+
|
|
48
52
|
const Transcript = (props: TranscriptProps) => {
|
|
49
53
|
const settingSpokenLanguageLabel = useString(sttSettingSpokenLanguageText)();
|
|
50
54
|
const searchText = useString(sttTranscriptPanelSearchText)();
|
|
@@ -175,26 +179,25 @@ const Transcript = (props: TranscriptProps) => {
|
|
|
175
179
|
return <Text style={styles.emptyMsg}>{noresults}</Text>;
|
|
176
180
|
};
|
|
177
181
|
|
|
178
|
-
const handleStreamMessageCallback = (
|
|
179
|
-
...args: [number, Uint8Array] | [number, string, Uint8Array]
|
|
180
|
-
) => {
|
|
182
|
+
const handleStreamMessageCallback = (...args: StreamMessageArgs) => {
|
|
181
183
|
setIsSTTListenerAdded(true);
|
|
182
184
|
if (isWebInternal()) {
|
|
183
|
-
|
|
185
|
+
const [uid, data] = args as WebStreamMessageArgs;
|
|
186
|
+
streamMessageCallback([uid, data]);
|
|
184
187
|
} else {
|
|
185
|
-
const [uid, , data] = args;
|
|
186
|
-
|
|
187
|
-
streamMessageCallback([uid, new Uint8Array(streamBuffer)]);
|
|
188
|
+
const [, uid, , data] = args as NativeStreamMessageArgs;
|
|
189
|
+
streamMessageCallback([uid, data]);
|
|
188
190
|
}
|
|
189
191
|
};
|
|
190
192
|
|
|
191
193
|
React.useEffect(() => {
|
|
192
194
|
if (!isSTTListenerAdded) {
|
|
193
195
|
RtcEngineUnsafe.addListener(
|
|
194
|
-
'
|
|
195
|
-
handleStreamMessageCallback
|
|
196
|
+
'onStreamMessage',
|
|
197
|
+
handleStreamMessageCallback,
|
|
196
198
|
);
|
|
197
199
|
}
|
|
200
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
198
201
|
}, []);
|
|
199
202
|
|
|
200
203
|
return (
|
|
@@ -33,22 +33,17 @@ const useTranscriptDownload = (): {
|
|
|
33
33
|
.writeFile(filePath, finalContent, 'utf8')
|
|
34
34
|
.then(() => {
|
|
35
35
|
console.warn('Content downloaded successfully on native.');
|
|
36
|
-
//
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
.
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
.catch(error => {
|
|
48
|
-
console.error('Error sharing file:', error);
|
|
49
|
-
reject(error);
|
|
50
|
-
});
|
|
51
|
-
}
|
|
36
|
+
// need to show the preview of downloaded file
|
|
37
|
+
Share.open({url: `file://${filePath}`, type: 'text/plain'})
|
|
38
|
+
.then(res => {
|
|
39
|
+
// console.warn('File shared successfully:', res);
|
|
40
|
+
resolve(filePath);
|
|
41
|
+
})
|
|
42
|
+
.catch(error => {
|
|
43
|
+
// console.error('Error sharing file:', error);
|
|
44
|
+
reject(error);
|
|
45
|
+
});
|
|
46
|
+
|
|
52
47
|
resolve(filePath);
|
|
53
48
|
})
|
|
54
49
|
.catch(error => {
|