@100mslive/roomkit-react 0.2.8-alpha.1 → 0.2.8-alpha.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/HLSView-FBEGJ3L7.js +1396 -0
- package/dist/HLSView-FBEGJ3L7.js.map +7 -0
- package/dist/Prebuilt/common/hooks.d.ts +3 -0
- package/dist/Prebuilt/components/Chat/MwebChatOption.d.ts +1 -1
- package/dist/Prebuilt/components/HMSVideo/FullscreenButton.d.ts +5 -0
- package/dist/Prebuilt/components/HMSVideo/HLSAutoplayBlockedPrompt.d.ts +5 -0
- package/dist/Prebuilt/components/HMSVideo/HLSCaptionSelector.d.ts +1 -2
- package/dist/Prebuilt/components/HMSVideo/HLSQualitySelector.d.ts +13 -0
- package/dist/Prebuilt/components/HMSVideo/MwebHLSViewTitle.d.ts +2 -0
- package/dist/Prebuilt/components/HMSVideo/PlayButton.d.ts +6 -0
- package/dist/Prebuilt/components/HMSVideo/PlayPauseButton.d.ts +6 -0
- package/dist/Prebuilt/components/HMSVideo/PlayerContext.d.ts +8 -0
- package/dist/Prebuilt/components/HMSVideo/SeekControls.d.ts +7 -0
- package/dist/Prebuilt/components/HMSVideo/VideoProgress.d.ts +5 -0
- package/dist/Prebuilt/components/HMSVideo/VideoTime.d.ts +2 -0
- package/dist/Prebuilt/components/HMSVideo/VolumeControl.d.ts +2 -0
- package/dist/Prebuilt/components/HMSVideo/index.d.ts +26 -0
- package/dist/Prebuilt/components/HMSVideo/utils.d.ts +8 -0
- package/dist/Prebuilt/components/Leave/DesktopLeaveRoom.d.ts +2 -1
- package/dist/Prebuilt/components/Leave/LeaveRoom.d.ts +2 -1
- package/dist/Prebuilt/components/Leave/MwebLeaveRoom.d.ts +2 -3
- package/dist/Prebuilt/components/MwebLandscapePrompt.d.ts +1 -1
- package/dist/Prebuilt/components/RaiseHand.d.ts +5 -0
- package/dist/Prebuilt/components/SidePaneTabs.d.ts +1 -1
- package/dist/Sheet/Sheet.d.ts +1 -0
- package/dist/{chunk-ERIM35YN.js → chunk-R2JJJQR3.js} +1539 -1173
- package/dist/chunk-R2JJJQR3.js.map +7 -0
- package/dist/index.cjs.js +2709 -1898
- package/dist/index.cjs.js.map +4 -4
- package/dist/index.js +1 -1
- package/dist/meta.cjs.json +777 -290
- package/dist/meta.esbuild.json +796 -298
- package/package.json +7 -6
- package/src/Button/Button.tsx +4 -4
- package/src/Fieldset/Fieldset.tsx +1 -1
- package/src/Input/PasswordInput.stories.tsx +1 -1
- package/src/Pagination/StyledPagination.stories.tsx +2 -2
- package/src/Prebuilt/IconButton.tsx +1 -1
- package/src/Prebuilt/common/hooks.ts +21 -0
- package/src/Prebuilt/components/AppData/useSidepane.js +34 -7
- package/src/Prebuilt/components/AuthToken.jsx +1 -1
- package/src/Prebuilt/components/Chat/Chat.tsx +41 -1
- package/src/Prebuilt/components/Chat/ChatFooter.tsx +33 -13
- package/src/Prebuilt/components/Chat/MwebChatOption.tsx +1 -1
- package/src/Prebuilt/components/ConferenceScreen.tsx +48 -7
- package/src/Prebuilt/components/EmojiReaction.jsx +33 -23
- package/src/Prebuilt/components/Footer/Footer.tsx +0 -1
- package/src/Prebuilt/components/Footer/RoleOptions.tsx +138 -125
- package/src/Prebuilt/components/HMSVideo/Controls.jsx +1 -1
- package/src/Prebuilt/components/HMSVideo/FullscreenButton.tsx +13 -0
- package/src/Prebuilt/components/HMSVideo/HLSAutoplayBlockedPrompt.tsx +72 -0
- package/src/Prebuilt/components/HMSVideo/HLSCaptionSelector.tsx +4 -2
- package/src/Prebuilt/components/HMSVideo/HLSQualitySelector.tsx +248 -0
- package/src/Prebuilt/components/HMSVideo/HMSVideo.jsx +17 -7
- package/src/Prebuilt/components/HMSVideo/MwebHLSViewTitle.tsx +84 -0
- package/src/Prebuilt/components/HMSVideo/PlayButton.tsx +27 -0
- package/src/Prebuilt/components/HMSVideo/PlayPauseButton.tsx +27 -0
- package/src/Prebuilt/components/HMSVideo/PlayerContext.tsx +15 -0
- package/src/Prebuilt/components/HMSVideo/SeekControls.tsx +22 -0
- package/src/Prebuilt/components/HMSVideo/VideoProgress.tsx +95 -0
- package/src/Prebuilt/components/HMSVideo/VideoTime.tsx +43 -0
- package/src/Prebuilt/components/HMSVideo/{VolumeControl.jsx → VolumeControl.tsx} +6 -4
- package/src/Prebuilt/components/HMSVideo/{index.js → index.ts} +6 -2
- package/src/Prebuilt/components/HMSVideo/{HMSVIdeoUtils.js → utils.ts} +5 -5
- package/src/Prebuilt/components/Header/StreamActions.tsx +1 -1
- package/src/Prebuilt/components/IconButtonWithOptions/IconButtonWithOptions.tsx +1 -1
- package/src/Prebuilt/components/Leave/DesktopLeaveRoom.tsx +50 -46
- package/src/Prebuilt/components/Leave/LeaveRoom.tsx +15 -4
- package/src/Prebuilt/components/Leave/MwebLeaveRoom.tsx +46 -27
- package/src/Prebuilt/components/MoreSettings/MoreSettings.tsx +3 -1
- package/src/Prebuilt/components/MoreSettings/SplitComponents/DesktopOptions.tsx +37 -31
- package/src/Prebuilt/components/MoreSettings/SplitComponents/MwebOptions.tsx +12 -8
- package/src/Prebuilt/components/MwebLandscapePrompt.tsx +14 -3
- package/src/Prebuilt/components/Notifications/HandRaisedNotifications.tsx +5 -2
- package/src/Prebuilt/components/Notifications/PeerNotifications.tsx +1 -1
- package/src/Prebuilt/components/Polls/Voting/QuestionCard.jsx +19 -8
- package/src/Prebuilt/components/Polls/Voting/Voting.tsx +3 -2
- package/src/Prebuilt/components/Polls/common/OptionInputWithDelete.tsx +1 -1
- package/src/Prebuilt/components/Polls/common/utils.ts +2 -2
- package/src/Prebuilt/components/RaiseHand.tsx +24 -0
- package/src/Prebuilt/components/RoomDetails/RoomDetailsPane.tsx +41 -14
- package/src/Prebuilt/components/SidePaneTabs.tsx +56 -48
- package/src/Prebuilt/components/StatsForNerds.jsx +14 -6
- package/src/Prebuilt/components/Streaming/Common.jsx +1 -1
- package/src/Prebuilt/components/TileMenu/TileMenuContent.tsx +2 -2
- package/src/Prebuilt/components/Toast/ToastBatcher.js +8 -1
- package/src/Prebuilt/components/Toast/ToastConfig.jsx +17 -0
- package/src/Prebuilt/components/pdfAnnotator/shareScreenOptions.jsx +2 -2
- package/src/Prebuilt/components/pdfAnnotator/uploadedFile.jsx +1 -1
- package/src/Prebuilt/layouts/HLSView.jsx +359 -178
- package/src/Prebuilt/layouts/SidePane.tsx +145 -59
- package/src/Prebuilt/layouts/VideoStreamingSection.tsx +22 -2
- package/src/Prebuilt/primitives/DialogContent.jsx +1 -1
- package/src/Prebuilt/provider/roomLayoutProvider/index.tsx +1 -1
- package/src/Sheet/Sheet.tsx +7 -3
- package/dist/HLSView-SJCF34GE.js +0 -987
- package/dist/HLSView-SJCF34GE.js.map +0 -7
- package/dist/chunk-ERIM35YN.js.map +0 -7
- package/src/Prebuilt/components/HMSVideo/FullscreenButton.jsx +0 -18
- package/src/Prebuilt/components/HMSVideo/HLSAutoplayBlockedPrompt.jsx +0 -35
- package/src/Prebuilt/components/HMSVideo/HLSQualitySelector.jsx +0 -127
- package/src/Prebuilt/components/HMSVideo/PlayButton.jsx +0 -13
- package/src/Prebuilt/components/HMSVideo/VideoProgress.jsx +0 -76
- package/src/Prebuilt/components/HMSVideo/VideoTime.jsx +0 -33
- package/src/Prebuilt/components/RaiseHand.jsx +0 -17
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import React, { forwardRef } from 'react';
|
|
2
|
-
import { Flex } from '../../../';
|
|
2
|
+
import { Flex } from '../../../Layout';
|
|
3
3
|
|
|
4
4
|
export const HMSVideo = forwardRef(({ children, ...props }, videoRef) => {
|
|
5
5
|
return (
|
|
@@ -8,18 +8,25 @@ export const HMSVideo = forwardRef(({ children, ...props }, videoRef) => {
|
|
|
8
8
|
css={{
|
|
9
9
|
size: '100%',
|
|
10
10
|
position: 'relative',
|
|
11
|
+
justifyContent: 'center',
|
|
12
|
+
'@md': {
|
|
13
|
+
height: 'auto',
|
|
14
|
+
'& video': {
|
|
15
|
+
height: '$60 !important',
|
|
16
|
+
},
|
|
17
|
+
},
|
|
11
18
|
'& video::cue': {
|
|
12
19
|
color: 'white',
|
|
13
|
-
// textShadow: '0px 0px 4px #000',
|
|
14
20
|
whiteSpace: 'pre-line',
|
|
15
|
-
fontSize: '$
|
|
21
|
+
fontSize: '$sm',
|
|
16
22
|
fontStyle: 'normal',
|
|
17
|
-
fontWeight: '$
|
|
23
|
+
fontWeight: '$regular',
|
|
18
24
|
lineHeight: '$sm',
|
|
19
|
-
letterSpacing: '0.
|
|
25
|
+
letterSpacing: '0.25px',
|
|
20
26
|
},
|
|
21
27
|
'& video::-webkit-media-text-track-display': {
|
|
22
28
|
padding: '0 $4',
|
|
29
|
+
boxShadow: '0px 1px 3px 0px #000000A3',
|
|
23
30
|
},
|
|
24
31
|
'& video::-webkit-media-text-track-container': {
|
|
25
32
|
fontSize: '$space$10 !important',
|
|
@@ -30,9 +37,12 @@ export const HMSVideo = forwardRef(({ children, ...props }, videoRef) => {
|
|
|
30
37
|
>
|
|
31
38
|
<video
|
|
32
39
|
style={{
|
|
33
|
-
flex: '1 1 0',
|
|
34
40
|
margin: '0 auto',
|
|
35
|
-
|
|
41
|
+
objectFit: 'contain',
|
|
42
|
+
width: 'auto',
|
|
43
|
+
height: 'auto',
|
|
44
|
+
maxWidth: '100%',
|
|
45
|
+
maxHeight: '100%',
|
|
36
46
|
}}
|
|
37
47
|
ref={videoRef}
|
|
38
48
|
playsInline
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { ChevronDownIcon } from '@100mslive/react-icons';
|
|
3
|
+
import { Flex } from '../../../Layout';
|
|
4
|
+
import { Text } from '../../../Text';
|
|
5
|
+
// @ts-ignore: No implicit any
|
|
6
|
+
import { Logo } from '../Header/HeaderComponents';
|
|
7
|
+
import { RoomDetailsRow } from '../RoomDetails/RoomDetailsRow';
|
|
8
|
+
import { useRoomLayoutHeader } from '../../provider/roomLayoutProvider/hooks/useRoomLayoutScreen';
|
|
9
|
+
// @ts-ignore
|
|
10
|
+
import { useIsSidepaneTypeOpen, useSidepaneToggle } from '../AppData/useSidepane';
|
|
11
|
+
import { SIDE_PANE_OPTIONS } from '../../common/constants';
|
|
12
|
+
|
|
13
|
+
/*
|
|
14
|
+
player handler --> left -> go live with timer or live, right -> expand icon
|
|
15
|
+
inbetween -> play pause icon, double tap to go back/forward
|
|
16
|
+
seekbar
|
|
17
|
+
half page will have chat or participant view
|
|
18
|
+
*/
|
|
19
|
+
export const HLSViewTitle = () => {
|
|
20
|
+
const { title, details } = useRoomLayoutHeader();
|
|
21
|
+
const toggleDetailsPane = useSidepaneToggle(SIDE_PANE_OPTIONS.ROOM_DETAILS);
|
|
22
|
+
const isDetailSidepaneOpen = useIsSidepaneTypeOpen(SIDE_PANE_OPTIONS.ROOM_DETAILS);
|
|
23
|
+
|
|
24
|
+
if (isDetailSidepaneOpen) {
|
|
25
|
+
return (
|
|
26
|
+
<Flex
|
|
27
|
+
gap="4"
|
|
28
|
+
align="center"
|
|
29
|
+
justify="between"
|
|
30
|
+
css={{
|
|
31
|
+
position: 'relative',
|
|
32
|
+
h: 'fit-content',
|
|
33
|
+
w: '100%',
|
|
34
|
+
borderBottom: '1px solid $border_bright',
|
|
35
|
+
p: '$8',
|
|
36
|
+
backgroundColor: '$surface_dim',
|
|
37
|
+
}}
|
|
38
|
+
>
|
|
39
|
+
<Text variant="sub2" css={{ fontWeight: '$semiBold' }}>
|
|
40
|
+
About Session
|
|
41
|
+
</Text>
|
|
42
|
+
<Flex
|
|
43
|
+
onClick={toggleDetailsPane}
|
|
44
|
+
css={{
|
|
45
|
+
color: '$on_surface_high',
|
|
46
|
+
cursor: 'pointer',
|
|
47
|
+
'&:hover': { opacity: '0.8' },
|
|
48
|
+
}}
|
|
49
|
+
>
|
|
50
|
+
<ChevronDownIcon />
|
|
51
|
+
</Flex>
|
|
52
|
+
</Flex>
|
|
53
|
+
);
|
|
54
|
+
}
|
|
55
|
+
return (
|
|
56
|
+
<Flex
|
|
57
|
+
gap="4"
|
|
58
|
+
align="center"
|
|
59
|
+
css={{
|
|
60
|
+
position: 'relative',
|
|
61
|
+
h: 'fit-content',
|
|
62
|
+
w: '100%',
|
|
63
|
+
borderBottom: '1px solid $border_bright',
|
|
64
|
+
p: '$8',
|
|
65
|
+
backgroundColor: '$surface_dim',
|
|
66
|
+
}}
|
|
67
|
+
>
|
|
68
|
+
<Logo />
|
|
69
|
+
<Flex direction="column">
|
|
70
|
+
{title ? (
|
|
71
|
+
<Text variant="sub2" css={{ fontWeight: '$semiBold' }}>
|
|
72
|
+
{title}
|
|
73
|
+
</Text>
|
|
74
|
+
) : null}
|
|
75
|
+
<Flex>
|
|
76
|
+
<RoomDetailsRow details={details} />
|
|
77
|
+
<Text variant="caption" css={{ color: '$on_surface_medium' }} onClick={toggleDetailsPane}>
|
|
78
|
+
...more
|
|
79
|
+
</Text>
|
|
80
|
+
</Flex>
|
|
81
|
+
</Flex>
|
|
82
|
+
</Flex>
|
|
83
|
+
);
|
|
84
|
+
};
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import React, { MouseEvent } from 'react';
|
|
2
|
+
import { PauseIcon, PlayIcon } from '@100mslive/react-icons';
|
|
3
|
+
import { IconButton, Tooltip } from '../../..';
|
|
4
|
+
import { useHMSPlayerContext } from './PlayerContext';
|
|
5
|
+
|
|
6
|
+
export const PlayButton = ({
|
|
7
|
+
isPaused,
|
|
8
|
+
width = 20,
|
|
9
|
+
height = 20,
|
|
10
|
+
}: {
|
|
11
|
+
isPaused: boolean;
|
|
12
|
+
width: number;
|
|
13
|
+
height: number;
|
|
14
|
+
}) => {
|
|
15
|
+
const { hlsPlayer } = useHMSPlayerContext();
|
|
16
|
+
const onClick = async (event: MouseEvent) => {
|
|
17
|
+
event?.stopPropagation();
|
|
18
|
+
isPaused ? await hlsPlayer?.play() : hlsPlayer?.pause();
|
|
19
|
+
};
|
|
20
|
+
return (
|
|
21
|
+
<Tooltip title={isPaused ? 'Play' : 'Pause'} side="top">
|
|
22
|
+
<IconButton onClick={onClick} data-testid="play_pause_btn">
|
|
23
|
+
{isPaused ? <PlayIcon width={width} height={height} /> : <PauseIcon width={width} height={height} />}
|
|
24
|
+
</IconButton>
|
|
25
|
+
</Tooltip>
|
|
26
|
+
);
|
|
27
|
+
};
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import React, { MouseEvent } from 'react';
|
|
2
|
+
import { PauseIcon, PlayIcon } from '@100mslive/react-icons';
|
|
3
|
+
import { IconButton, Tooltip } from '../../..';
|
|
4
|
+
import { useHMSPlayerContext } from './PlayerContext';
|
|
5
|
+
|
|
6
|
+
export const PlayPauseButton = ({
|
|
7
|
+
isPaused,
|
|
8
|
+
width = 20,
|
|
9
|
+
height = 20,
|
|
10
|
+
}: {
|
|
11
|
+
isPaused: boolean;
|
|
12
|
+
width: number;
|
|
13
|
+
height: number;
|
|
14
|
+
}) => {
|
|
15
|
+
const { hlsPlayer } = useHMSPlayerContext();
|
|
16
|
+
const onClick = async (event: MouseEvent) => {
|
|
17
|
+
event?.stopPropagation();
|
|
18
|
+
isPaused ? await hlsPlayer?.play() : hlsPlayer?.pause();
|
|
19
|
+
};
|
|
20
|
+
return (
|
|
21
|
+
<Tooltip title={isPaused ? 'Play' : 'Pause'} side="top">
|
|
22
|
+
<IconButton onClick={onClick} data-testid="play_pause_btn">
|
|
23
|
+
{isPaused ? <PlayIcon width={width} height={height} /> : <PauseIcon width={width} height={height} />}
|
|
24
|
+
</IconButton>
|
|
25
|
+
</Tooltip>
|
|
26
|
+
);
|
|
27
|
+
};
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import React, { useContext } from 'react';
|
|
2
|
+
import { HMSHLSPlayer } from '@100mslive/hls-player';
|
|
3
|
+
|
|
4
|
+
type IHMSPlayerContext = {
|
|
5
|
+
hlsPlayer?: HMSHLSPlayer;
|
|
6
|
+
};
|
|
7
|
+
|
|
8
|
+
export const HMSPlayerContext = React.createContext<IHMSPlayerContext>({
|
|
9
|
+
hlsPlayer: undefined,
|
|
10
|
+
});
|
|
11
|
+
|
|
12
|
+
export const useHMSPlayerContext = () => {
|
|
13
|
+
const context = useContext(HMSPlayerContext);
|
|
14
|
+
return context;
|
|
15
|
+
};
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import React, { MouseEventHandler } from 'react';
|
|
2
|
+
import { IconButton, Tooltip } from '../../..';
|
|
3
|
+
|
|
4
|
+
export const SeekControls = ({
|
|
5
|
+
title,
|
|
6
|
+
onClick,
|
|
7
|
+
children,
|
|
8
|
+
css,
|
|
9
|
+
}: {
|
|
10
|
+
title: string;
|
|
11
|
+
onClick?: MouseEventHandler<HTMLButtonElement>;
|
|
12
|
+
css: any;
|
|
13
|
+
children: React.ReactNode;
|
|
14
|
+
}) => {
|
|
15
|
+
return (
|
|
16
|
+
<Tooltip title={title} side="top">
|
|
17
|
+
<IconButton onClick={onClick} data-testid="backward_forward_arrow_btn" css={css}>
|
|
18
|
+
{children}
|
|
19
|
+
</IconButton>
|
|
20
|
+
</Tooltip>
|
|
21
|
+
);
|
|
22
|
+
};
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import React, { useCallback, useEffect, useState } from 'react';
|
|
2
|
+
import { Box, Flex, Slider } from '../../..';
|
|
3
|
+
import { useHMSPlayerContext } from './PlayerContext';
|
|
4
|
+
import { getPercentage } from './utils';
|
|
5
|
+
|
|
6
|
+
export const VideoProgress = ({
|
|
7
|
+
seekProgress,
|
|
8
|
+
setSeekProgress,
|
|
9
|
+
}: {
|
|
10
|
+
seekProgress: boolean;
|
|
11
|
+
setSeekProgress: (value: boolean) => void;
|
|
12
|
+
}) => {
|
|
13
|
+
const { hlsPlayer } = useHMSPlayerContext();
|
|
14
|
+
const [videoProgress, setVideoProgress] = useState<number>(0);
|
|
15
|
+
const [bufferProgress, setBufferProgress] = useState(0);
|
|
16
|
+
const videoEl = hlsPlayer?.getVideoElement();
|
|
17
|
+
|
|
18
|
+
const setProgress = useCallback(() => {
|
|
19
|
+
if (!videoEl) {
|
|
20
|
+
return;
|
|
21
|
+
}
|
|
22
|
+
const duration = isFinite(videoEl.duration) ? videoEl.duration : videoEl.seekable?.end(0) || 0;
|
|
23
|
+
const videoProgress = Math.floor(getPercentage(videoEl.currentTime, duration));
|
|
24
|
+
let bufferProgress = 0;
|
|
25
|
+
if (videoEl.buffered.length > 0) {
|
|
26
|
+
bufferProgress = Math.floor(getPercentage(videoEl.buffered?.end(0), duration));
|
|
27
|
+
}
|
|
28
|
+
setVideoProgress(isNaN(videoProgress) ? 0 : videoProgress);
|
|
29
|
+
setBufferProgress(isNaN(bufferProgress) ? 0 : bufferProgress);
|
|
30
|
+
}, [videoEl]);
|
|
31
|
+
const timeupdateHandler = useCallback(() => {
|
|
32
|
+
if (!videoEl || seekProgress) {
|
|
33
|
+
return;
|
|
34
|
+
}
|
|
35
|
+
setProgress();
|
|
36
|
+
}, [seekProgress, setProgress, videoEl]);
|
|
37
|
+
useEffect(() => {
|
|
38
|
+
if (!videoEl) {
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
videoEl.addEventListener('timeupdate', timeupdateHandler);
|
|
42
|
+
return function cleanup() {
|
|
43
|
+
videoEl?.removeEventListener('timeupdate', timeupdateHandler);
|
|
44
|
+
};
|
|
45
|
+
}, [timeupdateHandler, videoEl]);
|
|
46
|
+
|
|
47
|
+
const onProgress = (progress: number[]) => {
|
|
48
|
+
const progress1 = Math.floor(getPercentage(progress[0], 100));
|
|
49
|
+
const videoEl = hlsPlayer?.getVideoElement();
|
|
50
|
+
if (!videoEl) {
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
const duration = isFinite(videoEl.duration) ? videoEl.duration : videoEl.seekable?.end(0) || 0;
|
|
54
|
+
const currentTime = (progress1 * duration) / 100;
|
|
55
|
+
hlsPlayer?.seekTo(currentTime);
|
|
56
|
+
setProgress();
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
if (!videoEl) {
|
|
60
|
+
return null;
|
|
61
|
+
}
|
|
62
|
+
return (
|
|
63
|
+
<Flex align="center" css={{ cursor: 'pointer', h: '$2', alignSelf: 'stretch' }}>
|
|
64
|
+
<Slider
|
|
65
|
+
id="video-actual-rest"
|
|
66
|
+
css={{
|
|
67
|
+
cursor: 'pointer',
|
|
68
|
+
h: '$2',
|
|
69
|
+
zIndex: 1,
|
|
70
|
+
transition: `all .2s ease .5s`,
|
|
71
|
+
}}
|
|
72
|
+
min={0}
|
|
73
|
+
max={100}
|
|
74
|
+
step={1}
|
|
75
|
+
value={[videoProgress]}
|
|
76
|
+
showTooltip={false}
|
|
77
|
+
onValueChange={onProgress}
|
|
78
|
+
onPointerDown={() => setSeekProgress(true)}
|
|
79
|
+
onPointerUp={() => setSeekProgress(false)}
|
|
80
|
+
thumbStyles={{ w: '$6', h: '$6' }}
|
|
81
|
+
/>
|
|
82
|
+
<Box
|
|
83
|
+
id="video-buffer"
|
|
84
|
+
css={{
|
|
85
|
+
h: '$2',
|
|
86
|
+
width: `${bufferProgress - videoProgress}%`,
|
|
87
|
+
background: '$on_surface_high',
|
|
88
|
+
position: 'absolute',
|
|
89
|
+
left: `${videoProgress}%`,
|
|
90
|
+
opacity: '25%',
|
|
91
|
+
}}
|
|
92
|
+
/>
|
|
93
|
+
</Flex>
|
|
94
|
+
);
|
|
95
|
+
};
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import React, { useEffect, useState } from 'react';
|
|
2
|
+
import { HMSHLSPlayerEvents } from '@100mslive/hls-player';
|
|
3
|
+
import { Text } from '../../../Text';
|
|
4
|
+
import { useHMSPlayerContext } from './PlayerContext';
|
|
5
|
+
import { getDurationFromSeconds } from './utils';
|
|
6
|
+
|
|
7
|
+
export const VideoTime = () => {
|
|
8
|
+
const { hlsPlayer } = useHMSPlayerContext();
|
|
9
|
+
const [videoTime, setVideoTime] = useState('');
|
|
10
|
+
|
|
11
|
+
useEffect(() => {
|
|
12
|
+
const timeupdateHandler = (currentTime: number) => {
|
|
13
|
+
const videoEl = hlsPlayer?.getVideoElement();
|
|
14
|
+
if (videoEl) {
|
|
15
|
+
const duration = isFinite(videoEl.duration) ? videoEl.duration : videoEl.seekable.end(0) || 0;
|
|
16
|
+
setVideoTime(getDurationFromSeconds(duration - currentTime));
|
|
17
|
+
} else {
|
|
18
|
+
setVideoTime(getDurationFromSeconds(currentTime));
|
|
19
|
+
}
|
|
20
|
+
};
|
|
21
|
+
if (hlsPlayer) {
|
|
22
|
+
hlsPlayer.on(HMSHLSPlayerEvents.CURRENT_TIME, timeupdateHandler);
|
|
23
|
+
}
|
|
24
|
+
return function cleanup() {
|
|
25
|
+
hlsPlayer?.off(HMSHLSPlayerEvents.CURRENT_TIME, timeupdateHandler);
|
|
26
|
+
};
|
|
27
|
+
}, [hlsPlayer]);
|
|
28
|
+
|
|
29
|
+
return hlsPlayer ? (
|
|
30
|
+
<Text
|
|
31
|
+
variant="body1"
|
|
32
|
+
css={{
|
|
33
|
+
minWidth: '$16',
|
|
34
|
+
c: '$on_surface_medium',
|
|
35
|
+
display: 'flex',
|
|
36
|
+
justifyContent: 'center',
|
|
37
|
+
fontWeight: '$regular',
|
|
38
|
+
}}
|
|
39
|
+
>
|
|
40
|
+
-{videoTime}
|
|
41
|
+
</Text>
|
|
42
|
+
) : null;
|
|
43
|
+
};
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import React, { useState } from 'react';
|
|
2
2
|
import { VolumeOneIcon, VolumeTwoIcon, VolumeZeroIcon } from '@100mslive/react-icons';
|
|
3
|
-
import { Flex, Slider } from '
|
|
3
|
+
import { Flex, Slider } from '../../..';
|
|
4
|
+
import { useHMSPlayerContext } from './PlayerContext';
|
|
4
5
|
|
|
5
|
-
export const VolumeControl = (
|
|
6
|
+
export const VolumeControl = () => {
|
|
7
|
+
const { hlsPlayer } = useHMSPlayerContext();
|
|
6
8
|
const [volume, setVolume] = useState(hlsPlayer?.volume ?? 100);
|
|
7
9
|
const [showSlider, setShowSlider] = useState(false);
|
|
8
10
|
|
|
@@ -47,7 +49,7 @@ export const VolumeControl = ({ hlsPlayer }) => {
|
|
|
47
49
|
step={1}
|
|
48
50
|
value={[volume]}
|
|
49
51
|
onValueChange={volume => {
|
|
50
|
-
hlsPlayer
|
|
52
|
+
hlsPlayer?.setVolume(volume[0]);
|
|
51
53
|
setVolume(volume[0]);
|
|
52
54
|
}}
|
|
53
55
|
thumbStyles={{ w: '$6', h: '$6' }}
|
|
@@ -56,7 +58,7 @@ export const VolumeControl = ({ hlsPlayer }) => {
|
|
|
56
58
|
);
|
|
57
59
|
};
|
|
58
60
|
|
|
59
|
-
const VolumeIcon = ({ volume, onClick }) => {
|
|
61
|
+
const VolumeIcon = ({ volume, onClick }: { volume: number; onClick: () => void }) => {
|
|
60
62
|
if (volume === 0) {
|
|
61
63
|
return <VolumeZeroIcon style={{ cursor: 'pointer', transition: 'color 0.3s' }} onClick={onClick} />;
|
|
62
64
|
}
|
|
@@ -1,13 +1,16 @@
|
|
|
1
|
+
// @ts-ignore
|
|
1
2
|
import { LeftControls, RightControls, VideoControls } from './Controls';
|
|
3
|
+
// @ts-ignore
|
|
2
4
|
import { HMSVideo } from './HMSVideo';
|
|
3
|
-
import {
|
|
5
|
+
import { PlayPauseButton } from './PlayPauseButton';
|
|
6
|
+
import { SeekControls } from './SeekControls';
|
|
4
7
|
import { VideoProgress } from './VideoProgress';
|
|
5
8
|
import { VideoTime } from './VideoTime';
|
|
6
9
|
import { VolumeControl } from './VolumeControl';
|
|
7
10
|
|
|
8
11
|
export const HMSVideoPlayer = {
|
|
9
12
|
Root: HMSVideo,
|
|
10
|
-
|
|
13
|
+
PlayPauseButton: PlayPauseButton,
|
|
11
14
|
Progress: VideoProgress,
|
|
12
15
|
Duration: VideoTime,
|
|
13
16
|
Volume: VolumeControl,
|
|
@@ -16,4 +19,5 @@ export const HMSVideoPlayer = {
|
|
|
16
19
|
Left: LeftControls,
|
|
17
20
|
Right: RightControls,
|
|
18
21
|
},
|
|
22
|
+
Seeker: SeekControls,
|
|
19
23
|
};
|
|
@@ -1,14 +1,14 @@
|
|
|
1
|
-
export function getPercentage(a, b) {
|
|
1
|
+
export function getPercentage(a: number, b: number) {
|
|
2
2
|
return (a / b) * 100;
|
|
3
3
|
}
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
|
+
* Take a time in seconds and return its equivalent time in hh:mm:ss format
|
|
7
|
+
* @param {number} timeInSeconds if given as floating point value, it is floored.
|
|
6
8
|
*
|
|
7
|
-
* @
|
|
8
|
-
* @returns a string representing timeInSeconds in HH:MM:SS format.
|
|
9
|
-
* (e.g) getDurationFromSeconds(3910) returns "1:05:10"
|
|
9
|
+
* @returns a string representing timeInSeconds in HH:MM:SS format.
|
|
10
10
|
*/
|
|
11
|
-
export function getDurationFromSeconds(timeInSeconds) {
|
|
11
|
+
export function getDurationFromSeconds(timeInSeconds: number) {
|
|
12
12
|
let time = Math.floor(timeInSeconds);
|
|
13
13
|
const hours = Math.floor(time / 3600);
|
|
14
14
|
time = time - hours * 3600;
|
|
@@ -42,7 +42,7 @@ export const LiveStatus = () => {
|
|
|
42
42
|
setLiveTime(Date.now() - timeStamp.getTime());
|
|
43
43
|
}
|
|
44
44
|
}, 1000);
|
|
45
|
-
}, [hlsState?.running, hlsState?.variants]);
|
|
45
|
+
}, [hlsState?.running, hlsState?.variants, screenType]);
|
|
46
46
|
|
|
47
47
|
useEffect(() => {
|
|
48
48
|
if (hlsState?.running) {
|
|
@@ -17,10 +17,12 @@ export const DesktopLeaveRoom = ({
|
|
|
17
17
|
leaveRoom,
|
|
18
18
|
screenType,
|
|
19
19
|
endRoom,
|
|
20
|
+
container,
|
|
20
21
|
}: {
|
|
21
22
|
leaveRoom: (options?: { endStream?: boolean }) => Promise<void>;
|
|
22
23
|
screenType: keyof ConferencingScreen;
|
|
23
24
|
endRoom: () => Promise<void>;
|
|
25
|
+
container?: HTMLElement;
|
|
24
26
|
}) => {
|
|
25
27
|
const [open, setOpen] = useState(false);
|
|
26
28
|
const [showLeaveRoomAlert, setShowLeaveRoomAlert] = useState(false);
|
|
@@ -69,54 +71,56 @@ export const DesktopLeaveRoom = ({
|
|
|
69
71
|
<VerticalMenuIcon />
|
|
70
72
|
</MenuTriggerButton>
|
|
71
73
|
</Dropdown.Trigger>
|
|
72
|
-
<Dropdown.
|
|
73
|
-
<Dropdown.
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
74
|
+
<Dropdown.Portal container={container}>
|
|
75
|
+
<Dropdown.Content css={{ p: 0, w: '$100' }} alignOffset={-50} sideOffset={10}>
|
|
76
|
+
<Dropdown.Item
|
|
77
|
+
css={{
|
|
78
|
+
bg: '$surface_dim',
|
|
79
|
+
color: '$on_surface_medium',
|
|
80
|
+
'&:hover': { bg: '$surface_default', color: '$on_surface_high' },
|
|
81
|
+
p: '0',
|
|
82
|
+
}}
|
|
83
|
+
data-testid="just_leave_btn"
|
|
84
|
+
>
|
|
85
|
+
<LeaveCard
|
|
86
|
+
title={showStream ? 'Leave Stream' : 'Leave Session'}
|
|
87
|
+
subtitle={`Others will continue after you leave. You can join the ${
|
|
88
|
+
showStream ? 'stream' : 'session'
|
|
89
|
+
} again.`}
|
|
90
|
+
bg=""
|
|
91
|
+
titleColor="$on_surface_high"
|
|
92
|
+
icon={<ExitIcon height={24} width={24} style={{ transform: 'rotate(180deg)' }} />}
|
|
93
|
+
onClick={async () => await leaveRoom()}
|
|
94
|
+
css={{ p: '$8 $4' }}
|
|
95
|
+
/>
|
|
96
|
+
</Dropdown.Item>
|
|
94
97
|
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
}}
|
|
102
|
-
data-testid="end_room_btn"
|
|
103
|
-
>
|
|
104
|
-
<LeaveCard
|
|
105
|
-
title={showStream ? 'End Stream' : 'End Session'}
|
|
106
|
-
subtitle={`The ${
|
|
107
|
-
showStream ? 'stream' : 'session'
|
|
108
|
-
} will end for everyone. You can't undo this action.`}
|
|
109
|
-
bg=""
|
|
110
|
-
titleColor="$alert_error_brighter"
|
|
111
|
-
icon={<StopIcon height={24} width={24} />}
|
|
112
|
-
onClick={() => {
|
|
113
|
-
setOpen(false);
|
|
114
|
-
setShowEndStreamAlert(true);
|
|
98
|
+
<Dropdown.Item
|
|
99
|
+
css={{
|
|
100
|
+
bg: '$alert_error_dim',
|
|
101
|
+
color: '$alert_error_bright',
|
|
102
|
+
'&:hover': { bg: '$alert_error_dim', color: '$alert_error_brighter' },
|
|
103
|
+
p: '0',
|
|
115
104
|
}}
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
105
|
+
data-testid="end_room_btn"
|
|
106
|
+
>
|
|
107
|
+
<LeaveCard
|
|
108
|
+
title={showStream ? 'End Stream' : 'End Session'}
|
|
109
|
+
subtitle={`The ${
|
|
110
|
+
showStream ? 'stream' : 'session'
|
|
111
|
+
} will end for everyone. You can't undo this action.`}
|
|
112
|
+
bg=""
|
|
113
|
+
titleColor="$alert_error_brighter"
|
|
114
|
+
icon={<StopIcon height={24} width={24} />}
|
|
115
|
+
onClick={() => {
|
|
116
|
+
setOpen(false);
|
|
117
|
+
setShowEndStreamAlert(true);
|
|
118
|
+
}}
|
|
119
|
+
css={{ p: '$8 $4' }}
|
|
120
|
+
/>
|
|
121
|
+
</Dropdown.Item>
|
|
122
|
+
</Dropdown.Content>
|
|
123
|
+
</Dropdown.Portal>
|
|
120
124
|
</Dropdown.Root>
|
|
121
125
|
</Flex>
|
|
122
126
|
) : (
|
|
@@ -14,12 +14,18 @@ import {
|
|
|
14
14
|
} from '@100mslive/react-sdk';
|
|
15
15
|
import { config as cssConfig } from '../../../Theme';
|
|
16
16
|
// @ts-ignore: No implicit Any
|
|
17
|
-
// @ts-ignore: No implicit Any
|
|
18
17
|
import { ToastManager } from '../Toast/ToastManager';
|
|
19
18
|
import { DesktopLeaveRoom } from './DesktopLeaveRoom';
|
|
20
19
|
import { MwebLeaveRoom } from './MwebLeaveRoom';
|
|
20
|
+
import { useLandscapeHLSStream, useMobileHLSStream } from '../../common/hooks';
|
|
21
21
|
|
|
22
|
-
export const LeaveRoom = ({
|
|
22
|
+
export const LeaveRoom = ({
|
|
23
|
+
screenType,
|
|
24
|
+
container,
|
|
25
|
+
}: {
|
|
26
|
+
screenType: keyof ConferencingScreen;
|
|
27
|
+
container?: HTMLElement;
|
|
28
|
+
}) => {
|
|
23
29
|
const isConnected = useHMSStore(selectIsConnectedToRoom);
|
|
24
30
|
const permissions = useHMSStore(selectPermissions);
|
|
25
31
|
const isMobile = useMedia(cssConfig.media.md);
|
|
@@ -33,6 +39,8 @@ export const LeaveRoom = ({ screenType }: { screenType: keyof ConferencingScreen
|
|
|
33
39
|
);
|
|
34
40
|
const hlsState = useHMSStore(selectHLSState);
|
|
35
41
|
const hmsActions = useHMSActions();
|
|
42
|
+
const isMobileHLSStream = useMobileHLSStream();
|
|
43
|
+
const isLandscapeHLSStream = useLandscapeHLSStream();
|
|
36
44
|
|
|
37
45
|
const stopStream = async () => {
|
|
38
46
|
try {
|
|
@@ -61,9 +69,12 @@ export const LeaveRoom = ({ screenType }: { screenType: keyof ConferencingScreen
|
|
|
61
69
|
if (!permissions || !isConnected) {
|
|
62
70
|
return null;
|
|
63
71
|
}
|
|
72
|
+
if (isMobileHLSStream || isLandscapeHLSStream) {
|
|
73
|
+
return <MwebLeaveRoom leaveRoom={leaveRoom} endRoom={endRoom} container={container} />;
|
|
74
|
+
}
|
|
64
75
|
return isMobile ? (
|
|
65
|
-
<MwebLeaveRoom leaveRoom={leaveRoom}
|
|
76
|
+
<MwebLeaveRoom leaveRoom={leaveRoom} endRoom={endRoom} container={container} />
|
|
66
77
|
) : (
|
|
67
|
-
<DesktopLeaveRoom leaveRoom={leaveRoom} screenType={screenType} endRoom={endRoom} />
|
|
78
|
+
<DesktopLeaveRoom leaveRoom={leaveRoom} screenType={screenType} endRoom={endRoom} container={container} />
|
|
68
79
|
);
|
|
69
80
|
};
|