agora-appbuilder-core 4.0.26 → 4.0.27
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 +1 -1
- package/template/agora-rn-uikit/package-lock.json +25024 -0
- package/template/bridge/rtc/webNg/RtcSurfaceView.tsx +0 -2
- package/template/customization-api/utils.ts +1 -0
- package/template/defaultConfig.js +2 -2
- package/template/package-lock.json +57743 -0
- package/template/react-native-toast-message/package-lock.json +10553 -0
- package/template/src/assets/font-styles.css +4 -0
- package/template/src/assets/fonts/icomoon.ttf +0 -0
- package/template/src/assets/selection.json +1 -1
- package/template/src/atoms/CustomIcon.tsx +1 -0
- package/template/src/components/GridVideo.tsx +14 -10
- package/template/src/components/PinnedVideo.tsx +33 -6
- package/template/src/components/participants/UserActionMenuOptions.tsx +27 -26
- package/template/src/logger/AppBuilderLogger.tsx +2 -1
- package/template/src/pages/video-call/ActionSheetContent.tsx +0 -4
- package/template/src/pages/video-call/VideoCallMobileView.tsx +25 -1
- package/template/src/pages/video-call/VideoRenderer.tsx +24 -13
- package/template/src/utils/useFullScreen.ts +161 -0
- package/template/web/index.html +43 -40
|
@@ -77,17 +77,21 @@ const GridVideo: LayoutComponent = ({renderData}) => {
|
|
|
77
77
|
disabled={renderData.length === 1}
|
|
78
78
|
onPress={() => {
|
|
79
79
|
//if (!(ridx === 0 && cidx === 0)) {
|
|
80
|
-
const currentUid = renderData[ridx * dims.c + cidx];
|
|
81
|
-
if (
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
) {
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
}
|
|
80
|
+
//const currentUid = renderData[ridx * dims.c + cidx];
|
|
81
|
+
// if (
|
|
82
|
+
// currentUid !== pinnedUid &&
|
|
83
|
+
// currentUid !== secondaryPinnedUid
|
|
84
|
+
// ) {
|
|
85
|
+
// dispatch({
|
|
86
|
+
// type: 'ActiveSpeaker',
|
|
87
|
+
// value: [renderData[ridx * dims.c + cidx]],
|
|
88
|
+
// });
|
|
89
|
+
// }
|
|
90
90
|
//}
|
|
91
|
+
dispatch({
|
|
92
|
+
type: 'UserPin',
|
|
93
|
+
value: [renderData[ridx * dims.c + cidx]],
|
|
94
|
+
});
|
|
91
95
|
setPinnedLayout();
|
|
92
96
|
}}
|
|
93
97
|
style={{
|
|
@@ -20,7 +20,7 @@ import {
|
|
|
20
20
|
Text,
|
|
21
21
|
} from 'react-native';
|
|
22
22
|
import {layoutProps} from '../../theme.json';
|
|
23
|
-
import {useContent} from 'customization-api';
|
|
23
|
+
import {useContent, useLocalUserInfo} 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';
|
|
@@ -36,9 +36,12 @@ import {
|
|
|
36
36
|
moreBtnRemoveFromLarge,
|
|
37
37
|
videoRoomGoToActiveSpeakerText,
|
|
38
38
|
} from '../language/default-labels/videoCallScreenLabels';
|
|
39
|
+
import {useFullScreen} from '..//utils/useFullScreen';
|
|
39
40
|
const {topPinned} = layoutProps;
|
|
40
41
|
|
|
41
42
|
const PinnedVideo = ({renderData}) => {
|
|
43
|
+
const {screenUid} = useLocalUserInfo();
|
|
44
|
+
const {requestFullscreen} = useFullScreen();
|
|
42
45
|
const removeFromLargeText = useString(moreBtnRemoveFromLarge)();
|
|
43
46
|
const goToASText = useString(videoRoomGoToActiveSpeakerText)();
|
|
44
47
|
const [isOnTop, setIsOnTop] = useState(true);
|
|
@@ -52,6 +55,7 @@ const PinnedVideo = ({renderData}) => {
|
|
|
52
55
|
const {dispatch} = useContext(DispatchContext);
|
|
53
56
|
const {videoTileInViewPortState} = useVideoCall();
|
|
54
57
|
const {getWhiteboardUid = () => 0} = useWhiteboard();
|
|
58
|
+
const {defaultContent, customContent} = useContent();
|
|
55
59
|
useEffect(() => {
|
|
56
60
|
if (activeSpeaker && !videoTileInViewPortState[activeSpeaker] && isOnTop) {
|
|
57
61
|
dispatch({
|
|
@@ -80,6 +84,14 @@ const PinnedVideo = ({renderData}) => {
|
|
|
80
84
|
!isOnTop && setIsOnTop(true);
|
|
81
85
|
}
|
|
82
86
|
};
|
|
87
|
+
|
|
88
|
+
const isWhiteboard = customContent && customContent[pinnedUid || maxUid];
|
|
89
|
+
const isRemoteScreenshare =
|
|
90
|
+
(pinnedUid || maxUid) != screenUid &&
|
|
91
|
+
defaultContent &&
|
|
92
|
+
defaultContent[pinnedUid || maxUid]?.video &&
|
|
93
|
+
defaultContent[pinnedUid || maxUid]?.type === 'screenshare';
|
|
94
|
+
|
|
83
95
|
return (
|
|
84
96
|
<View
|
|
85
97
|
style={{
|
|
@@ -248,7 +260,7 @@ const PinnedVideo = ({renderData}) => {
|
|
|
248
260
|
: style.flex8
|
|
249
261
|
}>
|
|
250
262
|
<View style={style.flex1} key={'maxVideo' + (pinnedUid || maxUid)}>
|
|
251
|
-
{isSidePinnedlayout && (
|
|
263
|
+
{isSidePinnedlayout && (isWhiteboard || isRemoteScreenshare) ? (
|
|
252
264
|
<IconButton
|
|
253
265
|
containerStyle={{
|
|
254
266
|
position: 'absolute',
|
|
@@ -257,7 +269,16 @@ const PinnedVideo = ({renderData}) => {
|
|
|
257
269
|
zIndex: 999,
|
|
258
270
|
elevation: 999,
|
|
259
271
|
}}
|
|
260
|
-
onPress={() =>
|
|
272
|
+
onPress={() => {
|
|
273
|
+
if (
|
|
274
|
+
defaultContent &&
|
|
275
|
+
defaultContent[pinnedUid || maxUid]?.video
|
|
276
|
+
) {
|
|
277
|
+
requestFullscreen(pinnedUid || maxUid);
|
|
278
|
+
} else if (customContent[pinnedUid || maxUid]) {
|
|
279
|
+
setCollapse(!collapse);
|
|
280
|
+
}
|
|
281
|
+
}}
|
|
261
282
|
iconProps={{
|
|
262
283
|
iconContainerStyle: {
|
|
263
284
|
padding: 8,
|
|
@@ -265,13 +286,19 @@ const PinnedVideo = ({renderData}) => {
|
|
|
265
286
|
$config.CARD_LAYER_5_COLOR +
|
|
266
287
|
hexadecimalTransparency['10%'],
|
|
267
288
|
},
|
|
268
|
-
name:
|
|
289
|
+
name: isRemoteScreenshare
|
|
290
|
+
? 'fullscreen'
|
|
291
|
+
: isWhiteboard && collapse
|
|
292
|
+
? 'collapse'
|
|
293
|
+
: 'expand',
|
|
269
294
|
tintColor: $config.SECONDARY_ACTION_COLOR,
|
|
270
295
|
iconSize: 24,
|
|
271
296
|
}}
|
|
272
297
|
/>
|
|
298
|
+
) : (
|
|
299
|
+
<></>
|
|
273
300
|
)}
|
|
274
|
-
{pinnedUid && pinnedUid !== getWhiteboardUid() ? (
|
|
301
|
+
{/* {pinnedUid && pinnedUid !== getWhiteboardUid() ? (
|
|
275
302
|
<IconButton
|
|
276
303
|
containerStyle={{
|
|
277
304
|
paddingHorizontal: 8,
|
|
@@ -310,7 +337,7 @@ const PinnedVideo = ({renderData}) => {
|
|
|
310
337
|
/>
|
|
311
338
|
) : (
|
|
312
339
|
<></>
|
|
313
|
-
)}
|
|
340
|
+
)} */}
|
|
314
341
|
{/** Render the maximized view */}
|
|
315
342
|
<RenderComponent uid={pinnedUid || maxUid} isMax={true} />
|
|
316
343
|
</View>
|
|
@@ -39,7 +39,7 @@ import {useScreenshare} from '../../subComponents/screenshare/useScreenshare';
|
|
|
39
39
|
import {useFocus} from '../../utils/useFocus';
|
|
40
40
|
import Toast from '../../../react-native-toast-message';
|
|
41
41
|
import RemoteMutePopup from '../../subComponents/RemoteMutePopup';
|
|
42
|
-
import {calculatePosition, trimText} from '../../utils/common';
|
|
42
|
+
import {calculatePosition, isMobileUA, trimText} from '../../utils/common';
|
|
43
43
|
import {useVideoCall} from '../useVideoCall';
|
|
44
44
|
import {customEvents} from 'customization-api';
|
|
45
45
|
import {useDisableChat} from '../disable-chat/useDisableChat';
|
|
@@ -63,6 +63,7 @@ import {
|
|
|
63
63
|
moreBtnViewWhiteboard,
|
|
64
64
|
userRemovedFromTheRoomToastHeading,
|
|
65
65
|
} from '../../language/default-labels/videoCallScreenLabels';
|
|
66
|
+
import {isAndroid, isIOS} from '../../utils/common';
|
|
66
67
|
|
|
67
68
|
interface UserActionMenuOptionsOptionsProps {
|
|
68
69
|
user: ContentInterface;
|
|
@@ -154,32 +155,33 @@ export default function UserActionMenuOptionsOptions(
|
|
|
154
155
|
)
|
|
155
156
|
) {
|
|
156
157
|
if (enablePinForMe) {
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
158
|
+
if (pinnedUid !== user.uid) {
|
|
159
|
+
items.push({
|
|
160
|
+
//disabled: activeUids?.filter(i => !customContent[i])?.length === 1,
|
|
161
|
+
disabled: activeUids?.length === 1,
|
|
162
|
+
icon: pinnedUid ? 'unpin-outlined' : 'pin-outlined',
|
|
163
|
+
onHoverIcon: pinnedUid ? 'unpin-outlined' : 'pin-filled',
|
|
164
|
+
iconColor: $config.SECONDARY_ACTION_COLOR,
|
|
165
|
+
textColor: $config.SECONDARY_ACTION_COLOR,
|
|
166
|
+
title: pinnedUid
|
|
167
|
+
? user.uid === pinnedUid
|
|
168
|
+
? removeFromLargeLabel
|
|
169
|
+
: user.uid === getWhiteboardUid()
|
|
170
|
+
? viewWhiteboardLabel
|
|
171
|
+
: viewInLargeLabel
|
|
168
172
|
: user.uid === getWhiteboardUid()
|
|
169
173
|
? viewWhiteboardLabel
|
|
170
|
-
: viewInLargeLabel
|
|
171
|
-
:
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
},
|
|
182
|
-
});
|
|
174
|
+
: viewInLargeLabel,
|
|
175
|
+
callback: () => {
|
|
176
|
+
setActionMenuVisible(false);
|
|
177
|
+
dispatch({
|
|
178
|
+
type: 'UserPin',
|
|
179
|
+
value: [pinnedUid && user.uid === pinnedUid ? 0 : user.uid],
|
|
180
|
+
});
|
|
181
|
+
setLayout(getPinnedLayoutName());
|
|
182
|
+
},
|
|
183
|
+
});
|
|
184
|
+
}
|
|
183
185
|
if (currentLayout === DefaultLayouts[1].name) {
|
|
184
186
|
items.push({
|
|
185
187
|
// disabled:
|
|
@@ -207,7 +209,6 @@ export default function UserActionMenuOptionsOptions(
|
|
|
207
209
|
},
|
|
208
210
|
});
|
|
209
211
|
}
|
|
210
|
-
//}
|
|
211
212
|
}
|
|
212
213
|
}
|
|
213
214
|
|
|
@@ -473,12 +473,8 @@ const ActionSheetContent = props => {
|
|
|
473
473
|
([_, v]) => !isHidden(v?.hide) && v?.component,
|
|
474
474
|
);
|
|
475
475
|
|
|
476
|
-
console.log('debugging displayItems', displayItems);
|
|
477
|
-
|
|
478
476
|
const displayItemsOrdered = CustomToolbarSorting(displayItems);
|
|
479
477
|
|
|
480
|
-
console.log('debugging displayItemsOrdered', displayItemsOrdered);
|
|
481
|
-
|
|
482
478
|
if (displayCustomBottomSheetContent) {
|
|
483
479
|
return <View>{customBottomSheetContent}</View>;
|
|
484
480
|
}
|
|
@@ -42,7 +42,12 @@ import WhiteboardView from '../../components/whiteboard/WhiteboardView';
|
|
|
42
42
|
const VideoCallMobileView = props => {
|
|
43
43
|
const {native = true} = props;
|
|
44
44
|
const {customContent} = useContent();
|
|
45
|
-
const {
|
|
45
|
+
const {
|
|
46
|
+
isScreenShareOnFullView,
|
|
47
|
+
screenShareData,
|
|
48
|
+
setScreenShareData,
|
|
49
|
+
setScreenShareOnFullView,
|
|
50
|
+
} = useScreenContext();
|
|
46
51
|
const {getWhiteboardUid, isWhiteboardOnFullScreen} = useWhiteboard();
|
|
47
52
|
|
|
48
53
|
const {RtcEngineUnsafe} = useContext(RtcContext);
|
|
@@ -66,6 +71,25 @@ const VideoCallMobileView = props => {
|
|
|
66
71
|
const isVBAvaialble =
|
|
67
72
|
$config.ENABLE_VIRTUAL_BACKGROUND && !$config.AUDIO_ROOM && isVBActive;
|
|
68
73
|
|
|
74
|
+
useEffect(() => {
|
|
75
|
+
if (
|
|
76
|
+
isScreenShareOnFullView &&
|
|
77
|
+
defaultContent &&
|
|
78
|
+
!defaultContent[maxScreenShareUid]?.video
|
|
79
|
+
) {
|
|
80
|
+
setScreenShareOnFullView(false);
|
|
81
|
+
setScreenShareData(prevState => {
|
|
82
|
+
return {
|
|
83
|
+
...prevState,
|
|
84
|
+
[maxScreenShareUid]: {
|
|
85
|
+
...prevState[maxScreenShareUid],
|
|
86
|
+
isExpanded: !prevState[maxScreenShareUid]?.isExpanded,
|
|
87
|
+
},
|
|
88
|
+
};
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
}, [defaultContent, maxScreenShareUid, isScreenShareOnFullView]);
|
|
92
|
+
|
|
69
93
|
useEffect(() => {
|
|
70
94
|
// console.log(`Video State ${local.video} in Mode ${appStateVisible}`);
|
|
71
95
|
//native screenshare use local uid to publish the screenshare stream
|
|
@@ -38,6 +38,7 @@ import {
|
|
|
38
38
|
moreBtnViewWhiteboard,
|
|
39
39
|
} from '../../language/default-labels/videoCallScreenLabels';
|
|
40
40
|
import {LogSource, logger} from '../../logger/AppBuilderLogger';
|
|
41
|
+
import {useFullScreen} from '../../utils/useFullScreen';
|
|
41
42
|
export interface VideoRendererProps {
|
|
42
43
|
user: ContentInterface;
|
|
43
44
|
isMax?: boolean;
|
|
@@ -49,6 +50,7 @@ const VideoRenderer: React.FC<VideoRendererProps> = ({
|
|
|
49
50
|
CustomChild,
|
|
50
51
|
}) => {
|
|
51
52
|
const {height, width} = useWindowDimensions();
|
|
53
|
+
const {requestFullscreen} = useFullScreen();
|
|
52
54
|
const {dispatch} = useContext(DispatchContext);
|
|
53
55
|
const {RtcEngineUnsafe} = useRtc();
|
|
54
56
|
const {pinnedUid, secondaryPinnedUid} = useContent();
|
|
@@ -141,6 +143,19 @@ const VideoRenderer: React.FC<VideoRendererProps> = ({
|
|
|
141
143
|
const viewinlargeLabel = useString(moreBtnViewInLarge)();
|
|
142
144
|
const viewwhiteboardlabel = useString(moreBtnViewWhiteboard)();
|
|
143
145
|
|
|
146
|
+
const setScreenShareFullScreen = () => {
|
|
147
|
+
setScreenShareOnFullView(!screenShareData[user.uid]?.isExpanded);
|
|
148
|
+
setScreenShareData(prevState => {
|
|
149
|
+
return {
|
|
150
|
+
...prevState,
|
|
151
|
+
[user.uid]: {
|
|
152
|
+
...prevState[user.uid],
|
|
153
|
+
isExpanded: !prevState[user.uid]?.isExpanded,
|
|
154
|
+
},
|
|
155
|
+
};
|
|
156
|
+
});
|
|
157
|
+
};
|
|
158
|
+
|
|
144
159
|
return (
|
|
145
160
|
<>
|
|
146
161
|
<UserActionMenuOptionsOptions
|
|
@@ -231,7 +246,8 @@ const VideoRenderer: React.FC<VideoRendererProps> = ({
|
|
|
231
246
|
pinnedUid &&
|
|
232
247
|
pinnedUid == user.uid &&
|
|
233
248
|
!isScreenShareOnFullView
|
|
234
|
-
? 160 + (isAndroid() ? 15 : 0)
|
|
249
|
+
? //160 + (isAndroid() ? 15 : 0)
|
|
250
|
+
8
|
|
235
251
|
: 8,
|
|
236
252
|
zIndex: 999,
|
|
237
253
|
elevation: 999,
|
|
@@ -241,18 +257,13 @@ const VideoRenderer: React.FC<VideoRendererProps> = ({
|
|
|
241
257
|
if (user?.type == 'whiteboard') {
|
|
242
258
|
setWhiteboardOnFullScreen(!isWhiteboardOnFullScreen);
|
|
243
259
|
} else {
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
...prevState[user.uid],
|
|
252
|
-
isExpanded: !prevState[user.uid]?.isExpanded,
|
|
253
|
-
},
|
|
254
|
-
};
|
|
255
|
-
});
|
|
260
|
+
if (isMobileUA() && !(isAndroid() || isIOS())) {
|
|
261
|
+
requestFullscreen(user.uid).catch(() => {
|
|
262
|
+
setScreenShareFullScreen();
|
|
263
|
+
});
|
|
264
|
+
} else {
|
|
265
|
+
setScreenShareFullScreen();
|
|
266
|
+
}
|
|
256
267
|
}
|
|
257
268
|
}}
|
|
258
269
|
iconProps={{
|
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
import {useEffect, useRef} from 'react';
|
|
2
|
+
import {useContent, useLocalUserInfo} from 'customization-api';
|
|
3
|
+
import {UidType} from '../../agora-rn-uikit';
|
|
4
|
+
import {isWebInternal} from '../utils/common';
|
|
5
|
+
import {logger, LogSource} from '../logger/AppBuilderLogger';
|
|
6
|
+
|
|
7
|
+
export const useFullScreen = () => {
|
|
8
|
+
const {uid: localUid, screenUid: localScreenUid} = useLocalUserInfo();
|
|
9
|
+
const {defaultContent} = useContent();
|
|
10
|
+
const defaultContentRef = useRef(defaultContent);
|
|
11
|
+
|
|
12
|
+
useEffect(() => {
|
|
13
|
+
defaultContentRef.current = defaultContent;
|
|
14
|
+
}, [defaultContent]);
|
|
15
|
+
|
|
16
|
+
const onFullScreenChange = () => {
|
|
17
|
+
setTimeout(() => {
|
|
18
|
+
try {
|
|
19
|
+
if (
|
|
20
|
+
document.fullscreenElement &&
|
|
21
|
+
screen?.orientation?.type?.startsWith('portrait')
|
|
22
|
+
) {
|
|
23
|
+
//@ts-ignore
|
|
24
|
+
screen?.orientation?.lock &&
|
|
25
|
+
//@ts-ignore
|
|
26
|
+
screen?.orientation?.lock('landscape')?.catch(e => {
|
|
27
|
+
console.error('debugging error on lock', e);
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
} catch (error) {
|
|
31
|
+
console.error('debugging error on onFullScreenChange', error);
|
|
32
|
+
}
|
|
33
|
+
}, 500);
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
useEffect(() => {
|
|
37
|
+
try {
|
|
38
|
+
document?.addEventListener('fullscreenchange', onFullScreenChange);
|
|
39
|
+
} catch (error) {}
|
|
40
|
+
|
|
41
|
+
return () => {
|
|
42
|
+
document?.removeEventListener('fullscreenchange', onFullScreenChange);
|
|
43
|
+
};
|
|
44
|
+
}, []);
|
|
45
|
+
|
|
46
|
+
const requestFullscreen = async (uid: UidType) => {
|
|
47
|
+
if (!document?.fullscreenEnabled) {
|
|
48
|
+
console.error('Full screen API - Not supported');
|
|
49
|
+
return Promise.reject(false);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
if (!isWebInternal()) {
|
|
53
|
+
console.error('Full screen API - only available web platform');
|
|
54
|
+
return Promise.reject(false);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
if (!uid) {
|
|
58
|
+
console.error("Full screen API - Uid can't be empty");
|
|
59
|
+
return Promise.reject(false);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
let isVideoEnabled = defaultContentRef?.current[uid]?.video;
|
|
63
|
+
|
|
64
|
+
if (!isVideoEnabled) {
|
|
65
|
+
console.error(
|
|
66
|
+
`Full screen API - please enable video for uid - ${uid} before calling full screen api`,
|
|
67
|
+
);
|
|
68
|
+
return Promise.reject(false);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
let fullScreenUid = uid === localUid ? 0 : uid === localScreenUid ? 1 : uid;
|
|
72
|
+
|
|
73
|
+
try {
|
|
74
|
+
/**
|
|
75
|
+
* Agora assign user uid in the video tag container element
|
|
76
|
+
* 0 - local user
|
|
77
|
+
* 1 - local screen
|
|
78
|
+
* actual user uid - for rest of remote stream
|
|
79
|
+
*
|
|
80
|
+
* agora assign uid to parent div of video element
|
|
81
|
+
* so that's reason we are access children element to get the video element
|
|
82
|
+
*
|
|
83
|
+
* we can requestFullScreen for parent div
|
|
84
|
+
* but it won't have auto rotate as soon fullscreen enabled and timer/exit full screen buttons
|
|
85
|
+
*
|
|
86
|
+
* Sample structure
|
|
87
|
+
* <div id="0" >
|
|
88
|
+
* <div>
|
|
89
|
+
* <video />
|
|
90
|
+
* </div>
|
|
91
|
+
* </div>
|
|
92
|
+
* */
|
|
93
|
+
const videoTag = document.getElementById(fullScreenUid?.toString())
|
|
94
|
+
?.children[0]?.children[0];
|
|
95
|
+
|
|
96
|
+
if (!document?.fullscreenElement && videoTag?.requestFullscreen) {
|
|
97
|
+
videoTag
|
|
98
|
+
?.requestFullscreen()
|
|
99
|
+
.then(() => {
|
|
100
|
+
logger.log(
|
|
101
|
+
LogSource.Internals,
|
|
102
|
+
'FULL_SCREEN',
|
|
103
|
+
'requestFullscreen success',
|
|
104
|
+
);
|
|
105
|
+
return Promise.resolve(true);
|
|
106
|
+
})
|
|
107
|
+
.catch(error => {
|
|
108
|
+
logger.error(
|
|
109
|
+
LogSource.Internals,
|
|
110
|
+
'FULL_SCREEN',
|
|
111
|
+
'requestFullscreen - error',
|
|
112
|
+
error,
|
|
113
|
+
);
|
|
114
|
+
return Promise.reject(false);
|
|
115
|
+
});
|
|
116
|
+
} else {
|
|
117
|
+
logger.error(
|
|
118
|
+
LogSource.Internals,
|
|
119
|
+
'FULL_SCREEN',
|
|
120
|
+
'requestFullscreen - error',
|
|
121
|
+
);
|
|
122
|
+
return Promise.reject(false);
|
|
123
|
+
}
|
|
124
|
+
} catch (error) {
|
|
125
|
+
logger.log(
|
|
126
|
+
LogSource.Internals,
|
|
127
|
+
'FULL_SCREEN',
|
|
128
|
+
'requestFullscreen error',
|
|
129
|
+
error,
|
|
130
|
+
);
|
|
131
|
+
return Promise.reject(false);
|
|
132
|
+
}
|
|
133
|
+
};
|
|
134
|
+
|
|
135
|
+
const exitFullScreen = () => {
|
|
136
|
+
try {
|
|
137
|
+
if (document?.fullscreenElement) {
|
|
138
|
+
document?.exitFullscreen();
|
|
139
|
+
logger.log(
|
|
140
|
+
LogSource.Internals,
|
|
141
|
+
'FULL_SCREEN',
|
|
142
|
+
'exitFullscreen success',
|
|
143
|
+
);
|
|
144
|
+
return true;
|
|
145
|
+
} else {
|
|
146
|
+
console.error('Full screen AI - there is no fullscreen element');
|
|
147
|
+
return false;
|
|
148
|
+
}
|
|
149
|
+
} catch (error) {
|
|
150
|
+
logger.error(
|
|
151
|
+
LogSource.Internals,
|
|
152
|
+
'FULL_SCREEN',
|
|
153
|
+
'exitFullscreen error',
|
|
154
|
+
error,
|
|
155
|
+
);
|
|
156
|
+
return false;
|
|
157
|
+
}
|
|
158
|
+
};
|
|
159
|
+
|
|
160
|
+
return {requestFullscreen, exitFullScreen};
|
|
161
|
+
};
|
package/template/web/index.html
CHANGED
|
@@ -1,20 +1,19 @@
|
|
|
1
1
|
<!DOCTYPE html>
|
|
2
2
|
<html lang="en">
|
|
3
|
-
<head>
|
|
4
|
-
<meta charset="UTF-8"
|
|
5
|
-
<meta name="viewport" content="width=device-width, initial-scale=1.0"
|
|
6
|
-
<link rel="preconnect" href="https://fonts.googleapis.com"
|
|
7
|
-
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8" />
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
6
|
+
<link rel="preconnect" href="https://fonts.googleapis.com" />
|
|
7
|
+
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
|
|
8
8
|
<!-- moved to template/src/assets/font-styles.css as it was not available for sdks-->
|
|
9
9
|
<!-- <link href="https://fonts.googleapis.com/css2?family=Source+Sans+Pro:wght@400;600;700&display=swap" rel="stylesheet"> -->
|
|
10
10
|
|
|
11
|
-
<base href="/"
|
|
11
|
+
<base href="/" />
|
|
12
12
|
<title><%= htmlWebpackPlugin.options.title %></title>
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
<body>
|
|
13
|
+
</head>
|
|
14
|
+
<body>
|
|
16
15
|
<style>
|
|
17
|
-
|
|
16
|
+
/* .video-container > *{
|
|
18
17
|
background-color: #000 !important;
|
|
19
18
|
|
|
20
19
|
}
|
|
@@ -24,36 +23,40 @@
|
|
|
24
23
|
.video-container{
|
|
25
24
|
background-color: #000;
|
|
26
25
|
} */
|
|
27
|
-
|
|
26
|
+
/* *:active {
|
|
28
27
|
outline: none;
|
|
29
28
|
} */
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
29
|
+
/* Webkit (Chrome, Safari) */
|
|
30
|
+
::-webkit-scrollbar {
|
|
31
|
+
width: 4px;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
::-webkit-scrollbar-track {
|
|
35
|
+
background-color: transparent;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
::-webkit-scrollbar-thumb {
|
|
39
|
+
background-color: #777;
|
|
40
|
+
border-radius: 2px;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/** to hide screenshare fullscreen play/pause button */
|
|
44
|
+
video::-webkit-media-controls-play-button {
|
|
45
|
+
display: none !important;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/* Firefox */
|
|
49
|
+
html {
|
|
50
|
+
scrollbar-width: thin;
|
|
51
|
+
scrollbar-color: transparent #777;
|
|
52
|
+
}
|
|
50
53
|
</style>
|
|
51
|
-
<div
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
</body>
|
|
59
|
-
</html>
|
|
54
|
+
<div
|
|
55
|
+
id="react-app"
|
|
56
|
+
style="
|
|
57
|
+
height: 100vh;
|
|
58
|
+
max-height: -webkit-fill-available;
|
|
59
|
+
display: flex;
|
|
60
|
+
"></div>
|
|
61
|
+
</body>
|
|
62
|
+
</html>
|