@100mslive/roomkit-react 0.1.6-alpha.0 → 0.1.6-alpha.2
Sign up to get free protection for your applications and to get access to all the features.
- package/dist/{HLSView-PY2FKWX3.js → HLSView-QMU5JK7U.js} +208 -118
- package/dist/HLSView-QMU5JK7U.js.map +7 -0
- package/dist/Prebuilt/AppContext.d.ts +1 -1
- package/dist/Prebuilt/components/Chat/ChatFooter.d.ts +7 -0
- package/dist/Prebuilt/components/Connection/ConnectionIndicator.d.ts +6 -0
- package/dist/Prebuilt/components/Connection/TileConnection.d.ts +10 -0
- package/dist/Prebuilt/components/Footer/ChatToggle.d.ts +2 -0
- package/dist/Prebuilt/components/Footer/RoleAccordion.d.ts +14 -0
- package/dist/Prebuilt/components/Footer/RoleOptions.d.ts +6 -0
- package/dist/Prebuilt/components/Header/StreamActions.d.ts +11 -0
- package/dist/Prebuilt/components/Leave/DesktopLeaveRoom.d.ts +4 -3
- package/dist/Prebuilt/components/Leave/EndSessionContent.d.ts +4 -3
- package/dist/Prebuilt/components/Leave/LeaveCard.d.ts +1 -2
- package/dist/Prebuilt/components/Leave/LeaveSessionContent.d.ts +3 -1
- package/dist/Prebuilt/components/Leave/MwebLeaveRoom.d.ts +4 -3
- package/dist/Prebuilt/components/MoreSettings/SplitComponents/MwebOptions.d.ts +6 -0
- package/dist/Prebuilt/components/Preview/PreviewContainer.d.ts +3 -0
- package/dist/Prebuilt/components/Preview/PreviewJoin.d.ts +16 -0
- package/dist/Prebuilt/components/RoleChangeRequestModal.d.ts +2 -0
- package/dist/Prebuilt/components/SecondaryTiles.d.ts +1 -1
- package/dist/Prebuilt/components/SidePaneTabs.d.ts +7 -0
- package/dist/Prebuilt/components/VideoLayouts/EqualProminence.d.ts +1 -1
- package/dist/Prebuilt/components/VideoLayouts/Grid.d.ts +1 -0
- package/dist/Prebuilt/components/VideoLayouts/GridLayout.d.ts +5 -3
- package/dist/Prebuilt/components/VideoLayouts/ProminenceLayout.d.ts +6 -3
- package/dist/Prebuilt/components/VideoLayouts/RoleProminence.d.ts +1 -1
- package/dist/Prebuilt/components/VideoLayouts/ScreenshareLayout.d.ts +1 -1
- package/dist/Prebuilt/components/VideoLayouts/interface.d.ts +1 -0
- package/dist/Prebuilt/components/hooks/useAutoStartStreaming.d.ts +1 -0
- package/dist/Prebuilt/components/hooks/useRedirectToLeave.d.ts +3 -0
- package/dist/Prebuilt/components/hooks/useTileLayout.d.ts +2 -1
- package/dist/Prebuilt/components/hooks/useVideoTileLayout.d.ts +2 -0
- package/dist/Prebuilt/layouts/SidePane.d.ts +4 -1
- package/dist/Prebuilt/layouts/VideoStreamingSection.d.ts +2 -1
- package/dist/{VirtualBackground-AYDHYLIZ.js → VirtualBackground-37FXUPYO.js} +6 -6
- package/dist/VirtualBackground-37FXUPYO.js.map +7 -0
- package/dist/{chunk-GQD2AGWW.js → chunk-KBVIZGYW.js} +12 -2
- package/dist/{chunk-GQD2AGWW.js.map → chunk-KBVIZGYW.js.map} +2 -2
- package/dist/{chunk-RXTHJUMZ.js → chunk-WVGGQZK4.js} +986 -436
- package/dist/chunk-WVGGQZK4.js.map +7 -0
- package/dist/{chunk-E2M2ZSOL.js → chunk-ZKE2N5LH.js} +2 -2
- package/dist/{conference-V2XZGTKU.js → conference-FJJQ4TXX.js} +1136 -1301
- package/dist/conference-FJJQ4TXX.js.map +7 -0
- package/dist/index.cjs.js +3565 -3092
- package/dist/index.cjs.js.map +4 -4
- package/dist/index.js +2 -2
- package/dist/meta.cjs.json +773 -525
- package/dist/meta.esbuild.json +833 -579
- package/package.json +8 -7
- package/src/Prebuilt/App.tsx +10 -21
- package/src/Prebuilt/AppContext.tsx +1 -1
- package/src/Prebuilt/IconButton.jsx +10 -0
- package/src/Prebuilt/common/PeersSorter.ts +1 -1
- package/src/Prebuilt/common/constants.js +1 -2
- package/src/Prebuilt/common/utils.js +1 -1
- package/src/Prebuilt/components/AppData/AppData.jsx +8 -2
- package/src/Prebuilt/components/AppData/useUISettings.js +6 -6
- package/src/Prebuilt/components/AudioVideoToggle.jsx +8 -6
- package/src/Prebuilt/components/Chat/Chat.jsx +24 -11
- package/src/Prebuilt/components/Chat/ChatBody.jsx +20 -21
- package/src/Prebuilt/components/Chat/{ChatFooter.jsx → ChatFooter.tsx} +38 -13
- package/src/Prebuilt/components/Chat/useEmojiPickerStyles.js +5 -4
- package/src/Prebuilt/components/Connection/{ConnectionIndicator.jsx → ConnectionIndicator.tsx} +12 -4
- package/src/Prebuilt/components/Connection/{TileConnection.jsx → TileConnection.tsx} +20 -6
- package/src/Prebuilt/components/EmojiReaction.jsx +2 -6
- package/src/Prebuilt/components/Footer/{ChatToggle.jsx → ChatToggle.tsx} +4 -1
- package/src/Prebuilt/components/Footer/Footer.tsx +30 -5
- package/src/Prebuilt/components/Footer/ParticipantList.jsx +15 -49
- package/src/Prebuilt/components/Footer/{RoleAccordion.jsx → RoleAccordion.tsx} +33 -17
- package/src/Prebuilt/components/Footer/RoleOptions.tsx +155 -0
- package/src/Prebuilt/components/FullPageProgress.jsx +3 -3
- package/src/Prebuilt/components/HMSVideo/Controls.jsx +1 -0
- package/src/Prebuilt/components/HMSVideo/HLSQualitySelector.jsx +39 -17
- package/src/Prebuilt/components/HMSVideo/HMSVideo.jsx +2 -2
- package/src/Prebuilt/components/HMSVideo/VideoProgress.jsx +5 -6
- package/src/Prebuilt/components/HMSVideo/VolumeControl.jsx +1 -1
- package/src/Prebuilt/components/Header/HeaderComponents.jsx +8 -1
- package/src/Prebuilt/components/Header/{StreamActions.jsx → StreamActions.tsx} +23 -9
- package/src/Prebuilt/components/Header/common.jsx +5 -2
- package/src/Prebuilt/components/IconButtonWithOptions/IconButtonWithOptions.jsx +6 -1
- package/src/Prebuilt/components/InsetTile.tsx +15 -8
- package/src/Prebuilt/components/Leave/DesktopLeaveRoom.tsx +21 -11
- package/src/Prebuilt/components/Leave/EndSessionContent.tsx +2 -5
- package/src/Prebuilt/components/Leave/LeaveCard.tsx +1 -3
- package/src/Prebuilt/components/Leave/LeaveRoom.tsx +28 -25
- package/src/Prebuilt/components/Leave/LeaveSessionContent.tsx +8 -2
- package/src/Prebuilt/components/Leave/MwebLeaveRoom.tsx +8 -8
- package/src/Prebuilt/components/MoreSettings/ChangeNameContent.jsx +4 -0
- package/src/Prebuilt/components/MoreSettings/MoreSettings.tsx +1 -1
- package/src/Prebuilt/components/MoreSettings/SplitComponents/DesktopOptions.tsx +9 -23
- package/src/Prebuilt/components/MoreSettings/SplitComponents/{MwebOptions.jsx → MwebOptions.tsx} +89 -28
- package/src/Prebuilt/components/Notifications/Notifications.jsx +44 -28
- package/src/Prebuilt/components/Notifications/ReconnectNotifications.jsx +5 -11
- package/src/Prebuilt/components/Pagination.tsx +14 -12
- package/src/Prebuilt/components/Preview/{PreviewContainer.jsx → PreviewContainer.tsx} +11 -2
- package/src/Prebuilt/components/Preview/PreviewForm.tsx +6 -8
- package/src/Prebuilt/components/Preview/{PreviewJoin.jsx → PreviewJoin.tsx} +44 -21
- package/src/Prebuilt/components/{RoleChangeRequestModal.jsx → RoleChangeRequestModal.tsx} +36 -17
- package/src/Prebuilt/components/ScreenshareTile.jsx +6 -7
- package/src/Prebuilt/components/SecondaryTiles.tsx +12 -10
- package/src/Prebuilt/components/SidePaneTabs.tsx +120 -0
- package/src/Prebuilt/components/TileMenu/TileMenu.jsx +1 -1
- package/src/Prebuilt/components/TileMenu/TileMenuContent.jsx +14 -10
- package/src/Prebuilt/components/Toast/ToastConfig.jsx +5 -4
- package/src/Prebuilt/components/VideoLayouts/EqualProminence.tsx +13 -10
- package/src/Prebuilt/components/VideoLayouts/Grid.tsx +36 -34
- package/src/Prebuilt/components/VideoLayouts/GridLayout.tsx +33 -15
- package/src/Prebuilt/components/VideoLayouts/ProminenceLayout.tsx +45 -31
- package/src/Prebuilt/components/VideoLayouts/RoleProminence.tsx +12 -9
- package/src/Prebuilt/components/VideoLayouts/ScreenshareLayout.tsx +25 -9
- package/src/Prebuilt/components/VideoLayouts/interface.ts +1 -0
- package/src/Prebuilt/components/VideoTile.jsx +45 -53
- package/src/Prebuilt/components/conference.jsx +71 -74
- package/src/Prebuilt/components/hooks/useAutoStartStreaming.tsx +57 -0
- package/src/Prebuilt/components/hooks/useMetadata.jsx +19 -28
- package/src/Prebuilt/components/hooks/useRedirectToLeave.tsx +34 -0
- package/src/Prebuilt/components/hooks/useRoleProminencePeers.tsx +1 -1
- package/src/Prebuilt/components/hooks/useTileLayout.tsx +24 -18
- package/src/Prebuilt/components/hooks/useVideoTileLayout.ts +4 -0
- package/src/Prebuilt/layouts/EmbedView.jsx +1 -11
- package/src/Prebuilt/layouts/HLSView.jsx +152 -82
- package/src/Prebuilt/layouts/SidePane.tsx +25 -11
- package/src/Prebuilt/layouts/VideoStreamingSection.tsx +11 -47
- package/src/Prebuilt/plugins/FlyingEmoji.jsx +14 -2
- package/src/Prebuilt/plugins/VirtualBackground/VirtualBackground.jsx +3 -3
- package/src/Prebuilt/provider/roomLayoutProvider/hooks/useFetchRoomLayout.ts +2 -2
- package/src/Prebuilt/services/FeatureFlags.jsx +0 -1
- package/src/VideoTile/StyledVideoTile.tsx +1 -0
- package/dist/HLSView-PY2FKWX3.js.map +0 -7
- package/dist/VirtualBackground-AYDHYLIZ.js.map +0 -7
- package/dist/chunk-RXTHJUMZ.js.map +0 -7
- package/dist/conference-V2XZGTKU.js.map +0 -7
- package/src/Prebuilt/components/AudioLevel/BeamSpeakerLabelsLogging.jsx +0 -16
- package/src/Prebuilt/components/Chat/ChatParticipantHeader.jsx +0 -73
- package/src/Prebuilt/components/VideoList.jsx +0 -73
- /package/dist/{chunk-E2M2ZSOL.js.map → chunk-ZKE2N5LH.js.map} +0 -0
@@ -10,7 +10,6 @@ import {
|
|
10
10
|
import { config as cssConfig } from '../../../Theme';
|
11
11
|
|
12
12
|
const aspectRatioConfig = { default: [1 / 1, 4 / 3, 16 / 9], mobile: [1 / 1, 3 / 4, 9 / 16] };
|
13
|
-
const gap = 8; // gap between flex items
|
14
13
|
|
15
14
|
export const usePagesWithTiles = ({ peers, maxTileCount }: { peers: HMSPeer[]; maxTileCount: number }) => {
|
16
15
|
const vanillaStore = useHMSVanillaStore();
|
@@ -39,9 +38,11 @@ export const usePagesWithTiles = ({ peers, maxTileCount }: { peers: HMSPeer[]; m
|
|
39
38
|
export const useTileLayout = ({
|
40
39
|
pageList,
|
41
40
|
maxTileCount,
|
41
|
+
edgeToEdge = false,
|
42
42
|
}: {
|
43
43
|
pageList: TrackWithPeerAndDimensions[][];
|
44
44
|
maxTileCount: number;
|
45
|
+
edgeToEdge?: boolean;
|
45
46
|
}) => {
|
46
47
|
const vanillaStore = useHMSVanillaStore();
|
47
48
|
const [ref, { width, height }] = useMeasure<HTMLDivElement>();
|
@@ -76,6 +77,7 @@ export const useTileLayout = ({
|
|
76
77
|
return rowElements;
|
77
78
|
});
|
78
79
|
|
80
|
+
const gap = edgeToEdge && isMobile ? 0 : 8; // gap between flex items
|
79
81
|
const maxHeight = height - (maxRows - 1) * gap;
|
80
82
|
const maxRowHeight = maxHeight / matrix.length;
|
81
83
|
const aspectRatios =
|
@@ -86,25 +88,29 @@ export const useTileLayout = ({
|
|
86
88
|
for (const row of matrix) {
|
87
89
|
let tileWidth = (width - (row.length - 1) * gap) / row.length;
|
88
90
|
let tileHeight = 0;
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
91
|
+
if (edgeToEdge) {
|
92
|
+
tileHeight = maxRowHeight;
|
93
|
+
} else {
|
94
|
+
const calcHeights = aspectRatios.map(aR => tileWidth / aR);
|
95
|
+
for (const h of calcHeights) {
|
96
|
+
if (h < maxRowHeight) {
|
97
|
+
if (tileHeight < h) {
|
98
|
+
tileHeight = h;
|
99
|
+
}
|
94
100
|
}
|
95
101
|
}
|
96
|
-
}
|
97
102
|
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
103
|
+
// tileHeight is not calculated as it could be exceeding the max possible height
|
104
|
+
// find the max possible width instead
|
105
|
+
if (tileHeight === 0) {
|
106
|
+
tileHeight = maxRowHeight;
|
107
|
+
const calcWidths = aspectRatios.map(aR => tileHeight * aR);
|
108
|
+
tileWidth = 0;
|
109
|
+
for (const w of calcWidths) {
|
110
|
+
if (w < width) {
|
111
|
+
if (tileWidth < w) {
|
112
|
+
tileWidth = w;
|
113
|
+
}
|
108
114
|
}
|
109
115
|
}
|
110
116
|
}
|
@@ -116,6 +122,6 @@ export const useTileLayout = ({
|
|
116
122
|
}
|
117
123
|
}
|
118
124
|
setPagesWithTiles([...pageList]);
|
119
|
-
}, [width, height, maxTileCount, pageList, vanillaStore, isMobile]);
|
125
|
+
}, [width, height, maxTileCount, pageList, vanillaStore, isMobile, edgeToEdge]);
|
120
126
|
return { pagesWithTiles, ref };
|
121
127
|
};
|
@@ -5,7 +5,9 @@ type TileContextType = {
|
|
5
5
|
hideParticipantNameOnTile?: boolean;
|
6
6
|
roundedVideoTile?: boolean;
|
7
7
|
hideAudioMuteOnTile?: boolean;
|
8
|
+
hideAudioLevelOnTile?: boolean;
|
8
9
|
objectFit?: 'cover' | 'contain';
|
10
|
+
hideMetadataOnTile?: boolean;
|
9
11
|
};
|
10
12
|
|
11
13
|
export const VideoTileContext = React.createContext<TileContextType>({
|
@@ -13,7 +15,9 @@ export const VideoTileContext = React.createContext<TileContextType>({
|
|
13
15
|
hideParticipantNameOnTile: false,
|
14
16
|
roundedVideoTile: true,
|
15
17
|
hideAudioMuteOnTile: false,
|
18
|
+
hideAudioLevelOnTile: false,
|
16
19
|
objectFit: 'contain',
|
20
|
+
hideMetadataOnTile: false,
|
17
21
|
});
|
18
22
|
|
19
23
|
export const useVideoTileContext = () => {
|
@@ -1,7 +1,5 @@
|
|
1
1
|
import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
2
2
|
import {
|
3
|
-
selectLocalPeerID,
|
4
|
-
selectLocalPeerRoleName,
|
5
3
|
selectPeers,
|
6
4
|
selectPeerScreenSharing,
|
7
5
|
throwErrorHandler,
|
@@ -25,21 +23,13 @@ export const EmbedView = () => {
|
|
25
23
|
export const EmbebScreenShareView = ({ children }) => {
|
26
24
|
const peers = useHMSStore(selectPeers);
|
27
25
|
|
28
|
-
const localPeerID = useHMSStore(selectLocalPeerID);
|
29
|
-
const localPeerRole = useHMSStore(selectLocalPeerRoleName);
|
30
26
|
const peerPresenting = useHMSStore(selectPeerScreenSharing);
|
31
|
-
const isPresenterFromMyRole = peerPresenting?.roleName?.toLowerCase() === localPeerRole?.toLowerCase();
|
32
|
-
const amIPresenting = localPeerID === peerPresenting?.id;
|
33
|
-
const showPresenterInSmallTile = amIPresenting || isPresenterFromMyRole;
|
34
27
|
const [, setActiveScreenSharePeer] = useSetAppDataByKey(APP_DATA.activeScreensharePeerId);
|
35
28
|
|
36
29
|
const smallTilePeers = useMemo(() => {
|
37
30
|
const smallTilePeers = peers.filter(peer => peer.id !== peerPresenting?.id);
|
38
|
-
if (showPresenterInSmallTile && peerPresenting) {
|
39
|
-
smallTilePeers.unshift(peerPresenting); // put presenter on first page
|
40
|
-
}
|
41
31
|
return smallTilePeers;
|
42
|
-
}, [peers, peerPresenting
|
32
|
+
}, [peers, peerPresenting]);
|
43
33
|
|
44
34
|
useEffect(() => {
|
45
35
|
setActiveScreenSharePeer(peerPresenting?.id);
|
@@ -1,9 +1,9 @@
|
|
1
1
|
import React, { useCallback, useEffect, useRef, useState } from 'react';
|
2
|
-
import { useFullscreen, useToggle } from 'react-use';
|
2
|
+
import { useFullscreen, useMedia, useToggle } from 'react-use';
|
3
3
|
import { HLSPlaybackState, HMSHLSPlayer, HMSHLSPlayerEvents } from '@100mslive/hls-player';
|
4
4
|
import screenfull from 'screenfull';
|
5
5
|
import { selectAppData, selectHLSState, useHMSActions, useHMSStore } from '@100mslive/react-sdk';
|
6
|
-
import { ExpandIcon, RadioIcon, ShrinkIcon } from '@100mslive/react-icons';
|
6
|
+
import { ColoredHandIcon, ExpandIcon, RadioIcon, ShrinkIcon } from '@100mslive/react-icons';
|
7
7
|
import { HlsStatsOverlay } from '../components/HlsStatsOverlay';
|
8
8
|
import { HMSVideoPlayer } from '../components/HMSVideo';
|
9
9
|
import { FullScreenButton } from '../components/HMSVideo/FullscreenButton';
|
@@ -14,7 +14,7 @@ import { IconButton } from '../../IconButton';
|
|
14
14
|
import { Box, Flex } from '../../Layout';
|
15
15
|
import { Loading } from '../../Loading';
|
16
16
|
import { Text } from '../../Text';
|
17
|
-
import { useTheme } from '../../Theme';
|
17
|
+
import { config, useTheme } from '../../Theme';
|
18
18
|
import { Tooltip } from '../../Tooltip';
|
19
19
|
import { APP_DATA, EMOJI_REACTION_TYPE } from '../common/constants';
|
20
20
|
|
@@ -26,7 +26,8 @@ const HLSView = () => {
|
|
26
26
|
const hlsState = useHMSStore(selectHLSState);
|
27
27
|
const enablHlsStats = useHMSStore(selectAppData(APP_DATA.hlsStats));
|
28
28
|
const hmsActions = useHMSActions();
|
29
|
-
const { themeType } = useTheme();
|
29
|
+
const { themeType, theme } = useTheme();
|
30
|
+
const [streamEnded, setStreamEnded] = useState(false);
|
30
31
|
let [hlsStatsState, setHlsStatsState] = useState(null);
|
31
32
|
const hlsUrl = hlsState.variants[0]?.url;
|
32
33
|
const [availableLayers, setAvailableLayers] = useState([]);
|
@@ -37,6 +38,12 @@ const HLSView = () => {
|
|
37
38
|
const [isPaused, setIsPaused] = useState(false);
|
38
39
|
const isFullScreenSupported = screenfull.isEnabled;
|
39
40
|
const [show, toggle] = useToggle(false);
|
41
|
+
const [controlsVisible, setControlsVisible] = useState(true);
|
42
|
+
const controlsRef = useRef();
|
43
|
+
const controlsTimerRef = useRef();
|
44
|
+
const [qualityDropDownOpen, setQualityDropDownOpen] = useState(false);
|
45
|
+
|
46
|
+
const isMobile = useMedia(config.media.md);
|
40
47
|
const isFullScreen = useFullscreen(hlsViewRef, show, {
|
41
48
|
onClose: () => toggle(false),
|
42
49
|
});
|
@@ -58,6 +65,19 @@ const HLSView = () => {
|
|
58
65
|
};
|
59
66
|
}, []);
|
60
67
|
|
68
|
+
useEffect(() => {
|
69
|
+
const videoElem = videoRef.current;
|
70
|
+
const setStreamEndedCallback = () => {
|
71
|
+
setStreamEnded(true);
|
72
|
+
// no point keeping the callback attached once the streaming is ended
|
73
|
+
videoElem?.removeEventListener('ended', setStreamEndedCallback);
|
74
|
+
};
|
75
|
+
videoElem?.addEventListener('ended', setStreamEndedCallback);
|
76
|
+
return () => {
|
77
|
+
videoElem?.removeEventListener('ended', setStreamEndedCallback);
|
78
|
+
};
|
79
|
+
}, [hlsUrl]);
|
80
|
+
|
61
81
|
/**
|
62
82
|
* initialize HMSHLSPlayer and add event listeners.
|
63
83
|
*/
|
@@ -82,7 +102,7 @@ const HLSView = () => {
|
|
82
102
|
const parsedPayload = parsePayload(payload);
|
83
103
|
switch (parsedPayload.type) {
|
84
104
|
case EMOJI_REACTION_TYPE:
|
85
|
-
window.showFlyingEmoji(parsedPayload?.emojiId, parsedPayload?.senderId);
|
105
|
+
window.showFlyingEmoji?.({ emojiId: parsedPayload?.emojiId, senderId: parsedPayload?.senderId });
|
86
106
|
break;
|
87
107
|
default: {
|
88
108
|
const toast = {
|
@@ -167,6 +187,43 @@ const HLSView = () => {
|
|
167
187
|
hmsActions.setAppData(APP_DATA.hlsStats, !enablHlsStats);
|
168
188
|
};
|
169
189
|
|
190
|
+
useEffect(() => {
|
191
|
+
if (controlsVisible && isFullScreen && !qualityDropDownOpen) {
|
192
|
+
if (controlsTimerRef.current) {
|
193
|
+
clearTimeout(controlsTimerRef.current);
|
194
|
+
}
|
195
|
+
controlsTimerRef.current = setTimeout(() => {
|
196
|
+
setControlsVisible(false);
|
197
|
+
}, 5000);
|
198
|
+
}
|
199
|
+
if (!isFullScreen && controlsTimerRef.current) {
|
200
|
+
clearTimeout(controlsTimerRef.current);
|
201
|
+
}
|
202
|
+
return () => {
|
203
|
+
if (controlsTimerRef.current) {
|
204
|
+
clearTimeout(controlsTimerRef.current);
|
205
|
+
}
|
206
|
+
};
|
207
|
+
}, [controlsVisible, isFullScreen, qualityDropDownOpen]);
|
208
|
+
|
209
|
+
const onHoverHandler = useCallback(
|
210
|
+
event => {
|
211
|
+
if (event.type === 'mouseenter' || qualityDropDownOpen) {
|
212
|
+
setControlsVisible(true);
|
213
|
+
return;
|
214
|
+
}
|
215
|
+
if (event.type === 'mouseleave') {
|
216
|
+
setControlsVisible(false);
|
217
|
+
} else if (isFullScreen && !controlsVisible && event.type === 'mousemove') {
|
218
|
+
setControlsVisible(true);
|
219
|
+
if (controlsTimerRef.current) {
|
220
|
+
clearTimeout(controlsTimerRef.current);
|
221
|
+
}
|
222
|
+
}
|
223
|
+
},
|
224
|
+
[controlsVisible, isFullScreen, qualityDropDownOpen],
|
225
|
+
);
|
226
|
+
|
170
227
|
return (
|
171
228
|
<Flex
|
172
229
|
key="hls-viewer"
|
@@ -179,7 +236,7 @@ const HLSView = () => {
|
|
179
236
|
{hlsStatsState?.url && enablHlsStats ? (
|
180
237
|
<HlsStatsOverlay hlsStatsState={hlsStatsState} onClose={sfnOverlayClose} />
|
181
238
|
) : null}
|
182
|
-
{hlsUrl &&
|
239
|
+
{hlsUrl && !streamEnded ? (
|
183
240
|
<Flex
|
184
241
|
id="hls-player-container"
|
185
242
|
align="center"
|
@@ -188,7 +245,6 @@ const HLSView = () => {
|
|
188
245
|
width: '100%',
|
189
246
|
margin: '0 auto',
|
190
247
|
height: '100%',
|
191
|
-
background: 'linear-gradient(180deg, rgba(0, 0, 0, 0.00) 0%, #000 100%)',
|
192
248
|
}}
|
193
249
|
>
|
194
250
|
<HLSAutoplayBlockedPrompt open={isHlsAutoplayBlocked} unblockAutoPlay={unblockAutoPlay} />
|
@@ -203,100 +259,114 @@ const HLSView = () => {
|
|
203
259
|
<Loading width={72} height={72} />
|
204
260
|
</Flex>
|
205
261
|
)}
|
206
|
-
<HMSVideoPlayer.Root
|
262
|
+
<HMSVideoPlayer.Root
|
263
|
+
ref={videoRef}
|
264
|
+
onMouseEnter={onHoverHandler}
|
265
|
+
onMouseMove={onHoverHandler}
|
266
|
+
onMouseLeave={onHoverHandler}
|
267
|
+
>
|
207
268
|
<Flex
|
269
|
+
ref={controlsRef}
|
208
270
|
direction="column"
|
209
271
|
justify="flex-end"
|
210
272
|
align="flex-start"
|
211
273
|
css={{
|
212
|
-
|
274
|
+
position: 'absolute',
|
275
|
+
bottom: '0',
|
276
|
+
left: '0',
|
277
|
+
background: `linear-gradient(180deg, ${theme.colors.background_dim.value}00 29.46%, ${theme.colors.background_dim.value}A3 100%);`,
|
278
|
+
width: '100%',
|
279
|
+
pt: '$8',
|
280
|
+
flexShrink: 0,
|
281
|
+
transition: 'visibility 0s 0.5s, opacity 0.5s linear',
|
282
|
+
visibility: controlsVisible ? `` : `hidden`,
|
283
|
+
opacity: controlsVisible ? `1` : '0',
|
213
284
|
}}
|
214
285
|
>
|
215
|
-
{
|
216
|
-
<HMSVideoPlayer.
|
217
|
-
|
218
|
-
|
286
|
+
{!isMobile && (
|
287
|
+
<HMSVideoPlayer.Controls.Root
|
288
|
+
css={{
|
289
|
+
p: '$4 $8',
|
219
290
|
}}
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
onClick={async () => {
|
228
|
-
isPaused ? await hlsPlayer?.play() : hlsPlayer?.pause();
|
229
|
-
}}
|
230
|
-
isPaused={isPaused}
|
231
|
-
/>
|
232
|
-
<HMSVideoPlayer.Duration hlsPlayer={hlsPlayer} />
|
233
|
-
<HMSVideoPlayer.Volume hlsPlayer={hlsPlayer} />
|
234
|
-
<IconButton
|
235
|
-
variant="standard"
|
236
|
-
css={{ px: '$2' }}
|
237
|
-
onClick={async () => {
|
238
|
-
await hlsPlayer.seekToLivePosition();
|
239
|
-
setIsVideoLive(true);
|
240
|
-
}}
|
241
|
-
key="jump-to-live_btn"
|
242
|
-
data-testid="jump-to-live_btn"
|
243
|
-
>
|
244
|
-
<Tooltip title="Go to Live" side="top">
|
245
|
-
<Flex justify="center" gap={2} align="center">
|
246
|
-
<Box
|
247
|
-
css={{
|
248
|
-
height: '$4',
|
249
|
-
width: '$4',
|
250
|
-
background: isVideoLive ? '$alert_error_default' : '$on_primary_medium',
|
251
|
-
r: '$1',
|
252
|
-
}}
|
253
|
-
/>
|
254
|
-
<Text
|
255
|
-
variant={{
|
256
|
-
'@sm': 'xs',
|
257
|
-
}}
|
258
|
-
css={{
|
259
|
-
c: isVideoLive ? '$on_primary_high' : '$on_primary_medium',
|
260
|
-
}}
|
261
|
-
>
|
262
|
-
{isVideoLive ? 'LIVE' : 'GO LIVE'}
|
263
|
-
</Text>
|
264
|
-
</Flex>
|
265
|
-
</Tooltip>
|
266
|
-
</IconButton>
|
267
|
-
</HMSVideoPlayer.Controls.Left>
|
268
|
-
|
269
|
-
<HMSVideoPlayer.Controls.Right>
|
270
|
-
{availableLayers.length > 0 ? (
|
271
|
-
<HLSQualitySelector
|
272
|
-
layers={availableLayers}
|
273
|
-
selection={currentSelectedQuality}
|
274
|
-
onQualityChange={handleQuality}
|
275
|
-
isAuto={isUserSelectedAuto}
|
291
|
+
>
|
292
|
+
<HMSVideoPlayer.Controls.Left>
|
293
|
+
<HMSVideoPlayer.PlayButton
|
294
|
+
onClick={async () => {
|
295
|
+
isPaused ? await hlsPlayer?.play() : hlsPlayer?.pause();
|
296
|
+
}}
|
297
|
+
isPaused={isPaused}
|
276
298
|
/>
|
277
|
-
|
278
|
-
|
279
|
-
<
|
280
|
-
|
281
|
-
|
282
|
-
|
283
|
-
|
284
|
-
|
285
|
-
|
286
|
-
|
299
|
+
<HMSVideoPlayer.Duration hlsPlayer={hlsPlayer} />
|
300
|
+
<HMSVideoPlayer.Volume hlsPlayer={hlsPlayer} />
|
301
|
+
<IconButton
|
302
|
+
variant="standard"
|
303
|
+
css={{ px: '$2' }}
|
304
|
+
onClick={async () => {
|
305
|
+
await hlsPlayer.seekToLivePosition();
|
306
|
+
setIsVideoLive(true);
|
307
|
+
}}
|
308
|
+
key="jump-to-live_btn"
|
309
|
+
data-testid="jump-to-live_btn"
|
310
|
+
>
|
311
|
+
<Tooltip title="Go to Live" side="top">
|
312
|
+
<Flex justify="center" gap={2} align="center">
|
313
|
+
<Box
|
314
|
+
css={{
|
315
|
+
height: '$4',
|
316
|
+
width: '$4',
|
317
|
+
background: isVideoLive ? '$alert_error_default' : '$on_primary_medium',
|
318
|
+
r: '$1',
|
319
|
+
}}
|
320
|
+
/>
|
321
|
+
<Text
|
322
|
+
variant={{
|
323
|
+
'@sm': 'xs',
|
324
|
+
}}
|
325
|
+
css={{
|
326
|
+
c: isVideoLive ? '$on_surface_high' : '$on_surface_medium',
|
327
|
+
}}
|
328
|
+
>
|
329
|
+
{isVideoLive ? 'LIVE' : 'GO LIVE'}
|
330
|
+
</Text>
|
331
|
+
</Flex>
|
332
|
+
</Tooltip>
|
333
|
+
</IconButton>
|
334
|
+
</HMSVideoPlayer.Controls.Left>
|
335
|
+
|
336
|
+
<HMSVideoPlayer.Controls.Right>
|
337
|
+
{availableLayers.length > 0 ? (
|
338
|
+
<HLSQualitySelector
|
339
|
+
layers={availableLayers}
|
340
|
+
onOpen={setQualityDropDownOpen}
|
341
|
+
open={qualityDropDownOpen}
|
342
|
+
selection={currentSelectedQuality}
|
343
|
+
onQualityChange={handleQuality}
|
344
|
+
isAuto={isUserSelectedAuto}
|
345
|
+
/>
|
346
|
+
) : null}
|
347
|
+
{isFullScreenSupported ? (
|
348
|
+
<FullScreenButton
|
349
|
+
isFullScreen={isFullScreen}
|
350
|
+
onToggle={toggle}
|
351
|
+
icon={isFullScreen ? <ShrinkIcon /> : <ExpandIcon />}
|
352
|
+
/>
|
353
|
+
) : null}
|
354
|
+
</HMSVideoPlayer.Controls.Right>
|
355
|
+
</HMSVideoPlayer.Controls.Root>
|
356
|
+
)}
|
287
357
|
</Flex>
|
288
358
|
</HMSVideoPlayer.Root>
|
289
359
|
</Flex>
|
290
360
|
) : (
|
291
361
|
<Flex align="center" justify="center" direction="column" css={{ size: '100%', px: '$10' }}>
|
292
362
|
<Flex css={{ c: '$on_surface_high', r: '$round', bg: '$surface_default', p: '$2' }}>
|
293
|
-
<RadioIcon height={56} width={56} />
|
363
|
+
{streamEnded ? <ColoredHandIcon height={56} width={56} /> : <RadioIcon height={56} width={56} />}
|
294
364
|
</Flex>
|
295
365
|
<Text variant="h5" css={{ c: '$on_surface_high', mt: '$10', mb: 0, textAlign: 'center' }}>
|
296
|
-
Stream yet to start
|
366
|
+
{streamEnded ? 'Stream has ended' : 'Stream yet to start'}
|
297
367
|
</Text>
|
298
368
|
<Text variant="md" css={{ textAlign: 'center', mt: '$4', c: '$on_surface_medium' }}>
|
299
|
-
Sit back and relax
|
369
|
+
{streamEnded ? 'Have a nice day!' : 'Sit back and relax'}
|
300
370
|
</Text>
|
301
371
|
</Flex>
|
302
372
|
)}
|
@@ -2,29 +2,35 @@ import React from 'react';
|
|
2
2
|
import { useMedia } from 'react-use';
|
3
3
|
import { ConferencingScreen } from '@100mslive/types-prebuilt';
|
4
4
|
import { selectAppData, selectVideoTrackByPeerID, useHMSStore } from '@100mslive/react-sdk';
|
5
|
-
|
6
|
-
import { Chat } from '../components/Chat/Chat';
|
7
|
-
// @ts-ignore: No implicit Any
|
8
|
-
import { ParticipantList } from '../components/Footer/ParticipantList';
|
5
|
+
import { SidePaneTabs } from '../components/SidePaneTabs';
|
9
6
|
// @ts-ignore: No implicit Any
|
10
7
|
import { StreamingLanding } from '../components/Streaming/StreamingLanding';
|
8
|
+
import { TileCustomisationProps } from '../components/VideoLayouts/GridLayout';
|
11
9
|
// @ts-ignore: No implicit Any
|
12
10
|
import VideoTile from '../components/VideoTile';
|
13
11
|
import { Box, Flex } from '../../Layout';
|
14
12
|
import { config as cssConfig } from '../../Theme';
|
13
|
+
import { useRoomLayoutConferencingScreen } from '../provider/roomLayoutProvider/hooks/useRoomLayoutScreen';
|
15
14
|
// @ts-ignore: No implicit Any
|
16
15
|
import { APP_DATA, SIDE_PANE_OPTIONS } from '../common/constants';
|
17
16
|
|
18
|
-
const SidePane = ({
|
17
|
+
const SidePane = ({
|
18
|
+
screenType,
|
19
|
+
tileProps,
|
20
|
+
hideControls = false,
|
21
|
+
}: {
|
22
|
+
screenType: keyof ConferencingScreen;
|
23
|
+
tileProps: TileCustomisationProps;
|
24
|
+
hideControls: boolean;
|
25
|
+
}) => {
|
19
26
|
const isMobile = useMedia(cssConfig.media.md);
|
20
27
|
const sidepane = useHMSStore(selectAppData(APP_DATA.sidePane));
|
21
28
|
const activeScreensharePeerId = useHMSStore(selectAppData(APP_DATA.activeScreensharePeerId));
|
22
29
|
const trackId = useHMSStore(selectVideoTrackByPeerID(activeScreensharePeerId))?.id;
|
30
|
+
const { elements } = useRoomLayoutConferencingScreen();
|
23
31
|
let ViewComponent;
|
24
|
-
if (sidepane === SIDE_PANE_OPTIONS.PARTICIPANTS) {
|
25
|
-
ViewComponent = <
|
26
|
-
} else if (sidepane === SIDE_PANE_OPTIONS.CHAT) {
|
27
|
-
ViewComponent = <Chat screenType={screenType} />;
|
32
|
+
if (sidepane === SIDE_PANE_OPTIONS.PARTICIPANTS || sidepane === SIDE_PANE_OPTIONS.CHAT) {
|
33
|
+
ViewComponent = <SidePaneTabs screenType={screenType} hideControls={hideControls} active={sidepane} />;
|
28
34
|
} else if (sidepane === SIDE_PANE_OPTIONS.STREAMING) {
|
29
35
|
ViewComponent = <StreamingLanding />;
|
30
36
|
}
|
@@ -32,7 +38,15 @@ const SidePane = ({ screenType }: { screenType: keyof ConferencingScreen }) => {
|
|
32
38
|
return null;
|
33
39
|
}
|
34
40
|
|
35
|
-
const
|
41
|
+
const tileLayout = {
|
42
|
+
hideParticipantNameOnTile: tileProps?.hide_participant_name_on_tile,
|
43
|
+
roundedVideoTile: tileProps?.rounded_video_tile,
|
44
|
+
hideAudioMuteOnTile: tileProps?.hide_audio_mute_on_tile,
|
45
|
+
hideMetadataOnTile: tileProps?.hide_metadata_on_tile,
|
46
|
+
objectFit: tileProps?.video_object_fit,
|
47
|
+
};
|
48
|
+
|
49
|
+
const mwebStreamingChat = isMobile && sidepane === SIDE_PANE_OPTIONS.CHAT && elements?.chat?.is_overlay;
|
36
50
|
|
37
51
|
return (
|
38
52
|
<Flex
|
@@ -53,7 +67,7 @@ const SidePane = ({ screenType }: { screenType: keyof ConferencingScreen }) => {
|
|
53
67
|
width="100%"
|
54
68
|
height={225}
|
55
69
|
rootCSS={{ p: 0, alignSelf: 'start', flexShrink: 0 }}
|
56
|
-
|
70
|
+
{...tileLayout}
|
57
71
|
/>
|
58
72
|
)}
|
59
73
|
{!!ViewComponent && (
|
@@ -1,43 +1,30 @@
|
|
1
|
-
import React, { Suspense,
|
2
|
-
import { HMSException } from '@100mslive/hms-video';
|
1
|
+
import React, { Suspense, useEffect } from 'react';
|
3
2
|
import {
|
4
3
|
ConferencingScreen,
|
5
4
|
DefaultConferencingScreen_Elements,
|
6
5
|
HLSLiveStreamingScreen_Elements,
|
7
6
|
} from '@100mslive/types-prebuilt';
|
8
|
-
import {
|
9
|
-
selectIsConnectedToRoom,
|
10
|
-
selectLocalPeerRoleName,
|
11
|
-
selectPermissions,
|
12
|
-
useHMSActions,
|
13
|
-
useHMSStore,
|
14
|
-
useRecordingStreaming,
|
15
|
-
} from '@100mslive/react-sdk';
|
7
|
+
import { selectIsConnectedToRoom, selectLocalPeerRoleName, useHMSActions, useHMSStore } from '@100mslive/react-sdk';
|
16
8
|
// @ts-ignore: No implicit Any
|
17
9
|
import FullPageProgress from '../components/FullPageProgress';
|
18
|
-
// @ts-ignore: No implicit Any
|
19
10
|
import { GridLayout } from '../components/VideoLayouts/GridLayout';
|
20
11
|
import { Flex } from '../../Layout';
|
21
12
|
// @ts-ignore: No implicit Any
|
22
13
|
import { EmbedView } from './EmbedView';
|
23
14
|
// @ts-ignore: No implicit Any
|
24
15
|
import { PDFView } from './PDFView';
|
25
|
-
// @ts-ignore: No implicit Any
|
26
16
|
import SidePane from './SidePane';
|
27
17
|
// @ts-ignore: No implicit Any
|
28
18
|
import { WaitingView } from './WaitingView';
|
29
19
|
// import { useWhiteboardMetadata } from '../plugins/whiteboard';
|
30
20
|
import {
|
31
21
|
usePDFAnnotator,
|
32
|
-
useSetAppDataByKey,
|
33
22
|
useUrlToEmbed,
|
34
23
|
useWaitingViewerRole,
|
35
24
|
// @ts-ignore: No implicit Any
|
36
25
|
} from '../components/AppData/useUISettings';
|
37
26
|
// @ts-ignore: No implicit Any
|
38
|
-
import {
|
39
|
-
// @ts-ignore: No implicit Any
|
40
|
-
import { APP_DATA, SESSION_STORE_KEY } from '../common/constants';
|
27
|
+
import { SESSION_STORE_KEY } from '../common/constants';
|
41
28
|
|
42
29
|
// const WhiteboardView = React.lazy(() => import("./WhiteboardView"));
|
43
30
|
// @ts-ignore: No implicit Any
|
@@ -46,9 +33,11 @@ const HLSView = React.lazy(() => import('./HLSView'));
|
|
46
33
|
export const VideoStreamingSection = ({
|
47
34
|
screenType,
|
48
35
|
elements,
|
36
|
+
hideControls = false,
|
49
37
|
}: {
|
50
38
|
screenType: keyof ConferencingScreen;
|
51
39
|
elements: DefaultConferencingScreen_Elements | HLSLiveStreamingScreen_Elements;
|
40
|
+
hideControls: boolean;
|
52
41
|
}) => {
|
53
42
|
const localPeerRole = useHMSStore(selectLocalPeerRoleName);
|
54
43
|
// const { whiteboardOwner: whiteboardShared } = useWhiteboardMetadata();
|
@@ -57,36 +46,6 @@ export const VideoStreamingSection = ({
|
|
57
46
|
const waitingViewerRole = useWaitingViewerRole();
|
58
47
|
const urlToIframe = useUrlToEmbed();
|
59
48
|
const pdfAnnotatorActive = usePDFAnnotator();
|
60
|
-
const { isHLSRunning } = useRecordingStreaming();
|
61
|
-
const [isHLSStarted, setHLSStarted] = useSetAppDataByKey(APP_DATA.hlsStarted);
|
62
|
-
const permissions = useHMSStore(selectPermissions);
|
63
|
-
const showStreamingUI = useShowStreamingUI();
|
64
|
-
|
65
|
-
const startHLS = useCallback(async () => {
|
66
|
-
try {
|
67
|
-
if (isHLSStarted) {
|
68
|
-
return;
|
69
|
-
}
|
70
|
-
setHLSStarted(true);
|
71
|
-
await hmsActions.startHLSStreaming();
|
72
|
-
} catch (error) {
|
73
|
-
if ((error as HMSException).message?.includes('beam already started')) {
|
74
|
-
return;
|
75
|
-
}
|
76
|
-
setHLSStarted(false);
|
77
|
-
}
|
78
|
-
}, [hmsActions, isHLSStarted, setHLSStarted]);
|
79
|
-
|
80
|
-
useEffect(() => {
|
81
|
-
if (!isConnected) {
|
82
|
-
return;
|
83
|
-
}
|
84
|
-
// Is a streaming kit and broadcaster joins
|
85
|
-
if (permissions?.hlsStreaming && !isHLSRunning && showStreamingUI) {
|
86
|
-
startHLS();
|
87
|
-
}
|
88
|
-
// eslint-disable-next-line react-hooks/exhaustive-deps
|
89
|
-
}, [isConnected]);
|
90
49
|
|
91
50
|
useEffect(() => {
|
92
51
|
if (!isConnected) {
|
@@ -125,7 +84,12 @@ export const VideoStreamingSection = ({
|
|
125
84
|
}}
|
126
85
|
>
|
127
86
|
{ViewComponent}
|
128
|
-
<SidePane
|
87
|
+
<SidePane
|
88
|
+
screenType={screenType}
|
89
|
+
// @ts-ignore
|
90
|
+
tileProps={(elements as DefaultConferencingScreen_Elements)?.video_tile_layout?.grid}
|
91
|
+
hideControls={hideControls}
|
92
|
+
/>
|
129
93
|
</Flex>
|
130
94
|
</Suspense>
|
131
95
|
);
|
@@ -1,9 +1,16 @@
|
|
1
1
|
import React, { useCallback, useEffect, useMemo, useState } from 'react';
|
2
2
|
import { useMedia } from 'react-use';
|
3
|
-
import {
|
3
|
+
import {
|
4
|
+
selectLocalPeerID,
|
5
|
+
selectPeerNameByID,
|
6
|
+
useCustomEvent,
|
7
|
+
useHMSStore,
|
8
|
+
useHMSVanillaStore,
|
9
|
+
} from '@100mslive/react-sdk';
|
4
10
|
import { Box, Flex } from '../../Layout';
|
5
11
|
import { Text } from '../../Text';
|
6
12
|
import { config as cssConfig, keyframes } from '../../Theme';
|
13
|
+
import { EMOJI_REACTION_TYPE } from '../common/constants';
|
7
14
|
|
8
15
|
let emojiCount = 1;
|
9
16
|
|
@@ -42,7 +49,7 @@ export function FlyingEmoji() {
|
|
42
49
|
const startingPoints = useMemo(() => getStartingPoints(isMobile), [isMobile]);
|
43
50
|
|
44
51
|
const showFlyingEmoji = useCallback(
|
45
|
-
(emojiId, senderId) => {
|
52
|
+
({ emojiId, senderId }) => {
|
46
53
|
if (!emojiId || !senderId || document.hidden) {
|
47
54
|
return;
|
48
55
|
}
|
@@ -67,6 +74,11 @@ export function FlyingEmoji() {
|
|
67
74
|
[localPeerId, vanillaStore, startingPoints],
|
68
75
|
);
|
69
76
|
|
77
|
+
useCustomEvent({
|
78
|
+
type: EMOJI_REACTION_TYPE,
|
79
|
+
onEvent: showFlyingEmoji,
|
80
|
+
});
|
81
|
+
|
70
82
|
useEffect(() => {
|
71
83
|
window.showFlyingEmoji = showFlyingEmoji;
|
72
84
|
}, [showFlyingEmoji]);
|