@100mslive/roomkit-react 0.2.8-alpha.0 → 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-72B32WVR.js → chunk-R2JJJQR3.js} +1684 -1316
- package/dist/chunk-R2JJJQR3.js.map +7 -0
- package/dist/index.cjs.js +2866 -2053
- package/dist/index.cjs.js.map +4 -4
- package/dist/index.js +1 -1
- package/dist/meta.cjs.json +786 -299
- package/dist/meta.esbuild.json +805 -307
- 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/AudioVideoToggle.tsx +2 -1
- 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/VideoLayouts/RoleProminence.tsx +1 -1
- package/src/Prebuilt/components/hooks/useRoleProminencePeers.tsx +2 -1
- 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-37B2YVTC.js +0 -987
- package/dist/HLSView-37B2YVTC.js.map +0 -7
- package/dist/chunk-72B32WVR.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
|
@@ -38,9 +38,9 @@ export const Voting = ({ id, toggleVoting }: { id: string; toggleVoting: () => v
|
|
|
38
38
|
<Flex
|
|
39
39
|
align="center"
|
|
40
40
|
css={{
|
|
41
|
-
gap: '$
|
|
41
|
+
gap: '$4',
|
|
42
42
|
py: '$6',
|
|
43
|
-
px: '$
|
|
43
|
+
px: '$8',
|
|
44
44
|
my: '$4',
|
|
45
45
|
w: '100%',
|
|
46
46
|
color: '$on_surface_high',
|
|
@@ -60,6 +60,7 @@ export const Voting = ({ id, toggleVoting }: { id: string; toggleVoting: () => v
|
|
|
60
60
|
marginLeft: 'auto',
|
|
61
61
|
cursor: 'pointer',
|
|
62
62
|
'&:hover': { opacity: '0.8' },
|
|
63
|
+
height: 'fit-content',
|
|
63
64
|
}}
|
|
64
65
|
>
|
|
65
66
|
<CrossIcon onClick={toggleVoting} />
|
|
@@ -29,7 +29,7 @@ export const OptionInputWithDelete = ({
|
|
|
29
29
|
key={index}
|
|
30
30
|
onChange={event => handleOptionTextChange(index, event.target.value)}
|
|
31
31
|
/>
|
|
32
|
-
<IconButton onClick={() => removeOption(index)} css={{ bg: '
|
|
32
|
+
<IconButton onClick={() => removeOption(index)} css={{ bg: 'transparent', border: 'none' }}>
|
|
33
33
|
<TrashIcon />
|
|
34
34
|
</IconButton>
|
|
35
35
|
</>
|
|
@@ -4,7 +4,7 @@ export const getFormattedTime = (milliseconds: number | undefined, precise = tru
|
|
|
4
4
|
const totalSeconds = milliseconds / 1000;
|
|
5
5
|
const hours = Math.floor(totalSeconds / 3600);
|
|
6
6
|
const minutes = Math.floor((totalSeconds % 3600) / 60);
|
|
7
|
-
const seconds =
|
|
7
|
+
const seconds = totalSeconds % 60;
|
|
8
8
|
|
|
9
9
|
let formattedTime = '';
|
|
10
10
|
if (hours) {
|
|
@@ -16,7 +16,7 @@ export const getFormattedTime = (milliseconds: number | undefined, precise = tru
|
|
|
16
16
|
if (!precise && (hours || minutes)) {
|
|
17
17
|
return formattedTime;
|
|
18
18
|
}
|
|
19
|
-
formattedTime += `${seconds}s`;
|
|
19
|
+
formattedTime += `${precise ? seconds.toFixed(3) : Math.floor(seconds)}s`;
|
|
20
20
|
|
|
21
21
|
return formattedTime;
|
|
22
22
|
};
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { HandIcon, HandRaiseSlashedIcon } from '@100mslive/react-icons';
|
|
3
|
+
import { CSS } from '../../Theme';
|
|
4
|
+
import { Tooltip } from '../../Tooltip';
|
|
5
|
+
// @ts-ignore: No implicit Any
|
|
6
|
+
import IconButton from '../IconButton';
|
|
7
|
+
// @ts-ignore: No implicit Any
|
|
8
|
+
import { useMyMetadata } from './hooks/useMetadata';
|
|
9
|
+
|
|
10
|
+
export const RaiseHand = ({ css }: { css?: CSS }) => {
|
|
11
|
+
const { isHandRaised, toggleHandRaise } = useMyMetadata();
|
|
12
|
+
return (
|
|
13
|
+
<Tooltip title={isHandRaised ? 'Lower hand' : 'Raise hand'}>
|
|
14
|
+
<IconButton
|
|
15
|
+
data-testid="hand_raise_btn"
|
|
16
|
+
css={css}
|
|
17
|
+
active={!isHandRaised}
|
|
18
|
+
onClick={async () => await toggleHandRaise()}
|
|
19
|
+
>
|
|
20
|
+
{isHandRaised ? <HandRaiseSlashedIcon /> : <HandIcon />}
|
|
21
|
+
</IconButton>
|
|
22
|
+
</Tooltip>
|
|
23
|
+
);
|
|
24
|
+
};
|
|
@@ -2,31 +2,32 @@ import React from 'react';
|
|
|
2
2
|
import { CrossIcon } from '@100mslive/react-icons';
|
|
3
3
|
import { Box, Flex } from '../../../Layout';
|
|
4
4
|
import { Text } from '../../../Text';
|
|
5
|
+
// @ts-ignore: No implicit any
|
|
6
|
+
import { Logo } from '../Header/HeaderComponents';
|
|
5
7
|
import { RoomDetailsRow } from './RoomDetailsRow';
|
|
6
8
|
import { useRoomLayoutHeader } from '../../provider/roomLayoutProvider/hooks/useRoomLayoutScreen';
|
|
7
9
|
// @ts-ignore
|
|
8
10
|
import { useSidepaneToggle } from '../AppData/useSidepane';
|
|
11
|
+
import { useMobileHLSStream } from '../../common/hooks';
|
|
9
12
|
import { SIDE_PANE_OPTIONS } from '../../common/constants';
|
|
10
13
|
|
|
11
14
|
export const RoomDetailsPane = () => {
|
|
12
|
-
const {
|
|
13
|
-
const
|
|
15
|
+
const { description } = useRoomLayoutHeader();
|
|
16
|
+
const isMwebHLSStream = useMobileHLSStream();
|
|
14
17
|
return (
|
|
15
18
|
<Box css={{ flex: '1 1 0' }}>
|
|
16
|
-
|
|
17
|
-
<
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
css={{ color: '$on_surface_high', cursor: 'pointer', '&:hover': { opacity: '0.8' } }}
|
|
21
|
-
>
|
|
22
|
-
<CrossIcon />
|
|
19
|
+
{isMwebHLSStream ? (
|
|
20
|
+
<Flex direction="row" align="center" gap="2">
|
|
21
|
+
<Logo />
|
|
22
|
+
<ShowRoomDetailHeader />
|
|
23
23
|
</Flex>
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
24
|
+
) : (
|
|
25
|
+
<ShowRoomDetailHeader />
|
|
26
|
+
)}
|
|
28
27
|
<Box css={{ mt: '$10' }}>
|
|
29
|
-
<Text css={{ color: '$on_surface_high', fontWeight: '$semiBold' }}>
|
|
28
|
+
<Text css={{ color: '$on_surface_high', fontWeight: '$semiBold', display: isMwebHLSStream ? 'none' : '' }}>
|
|
29
|
+
Description
|
|
30
|
+
</Text>
|
|
30
31
|
<Text variant="sm" css={{ c: '$on_surface_medium' }}>
|
|
31
32
|
{description}
|
|
32
33
|
</Text>
|
|
@@ -34,3 +35,29 @@ export const RoomDetailsPane = () => {
|
|
|
34
35
|
</Box>
|
|
35
36
|
);
|
|
36
37
|
};
|
|
38
|
+
|
|
39
|
+
const ShowRoomDetailHeader = () => {
|
|
40
|
+
const { title, details } = useRoomLayoutHeader();
|
|
41
|
+
const toggleDetailsPane = useSidepaneToggle(SIDE_PANE_OPTIONS.ROOM_DETAILS);
|
|
42
|
+
const isMwebHLSStream = useMobileHLSStream();
|
|
43
|
+
return (
|
|
44
|
+
<Flex direction="column">
|
|
45
|
+
<Flex justify="between" align="center" css={{ w: '100%' }}>
|
|
46
|
+
<Text variant="h6">{title}</Text>
|
|
47
|
+
{!isMwebHLSStream && (
|
|
48
|
+
<Flex
|
|
49
|
+
onClick={toggleDetailsPane}
|
|
50
|
+
css={{
|
|
51
|
+
color: '$on_surface_high',
|
|
52
|
+
cursor: 'pointer',
|
|
53
|
+
'&:hover': { opacity: '0.8' },
|
|
54
|
+
}}
|
|
55
|
+
>
|
|
56
|
+
<CrossIcon />
|
|
57
|
+
</Flex>
|
|
58
|
+
)}
|
|
59
|
+
</Flex>
|
|
60
|
+
<RoomDetailsRow details={details} />
|
|
61
|
+
</Flex>
|
|
62
|
+
);
|
|
63
|
+
};
|
|
@@ -1,16 +1,15 @@
|
|
|
1
1
|
import React, { useEffect, useState } from 'react';
|
|
2
2
|
import { useMedia } from 'react-use';
|
|
3
3
|
import { DefaultConferencingScreen_Elements } from '@100mslive/types-prebuilt';
|
|
4
|
+
import { match } from 'ts-pattern';
|
|
4
5
|
import { selectPeerCount, useHMSStore } from '@100mslive/react-sdk';
|
|
5
6
|
import { CrossIcon } from '@100mslive/react-icons';
|
|
6
|
-
// @ts-ignore: No implicit Any
|
|
7
7
|
import { Chat } from './Chat/Chat';
|
|
8
8
|
import { PaginatedParticipants } from './Footer/PaginatedParticipants';
|
|
9
9
|
import { ParticipantList } from './Footer/ParticipantList';
|
|
10
10
|
import { Box, config as cssConfig, Flex, IconButton, Tabs, Text } from '../..';
|
|
11
11
|
import { Tooltip } from '../../Tooltip';
|
|
12
12
|
import { ChatSettings } from './ChatSettings';
|
|
13
|
-
// @ts-ignore: No implicit Any
|
|
14
13
|
import { useRoomLayoutConferencingScreen } from '../provider/roomLayoutProvider/hooks/useRoomLayoutScreen';
|
|
15
14
|
// @ts-ignore: No implicit Any
|
|
16
15
|
import { useIsSidepaneTypeOpen, useSidepaneReset, useSidepaneToggle } from './AppData/useSidepane';
|
|
@@ -19,12 +18,15 @@ import { getFormattedCount } from '../common/utils';
|
|
|
19
18
|
import { SIDE_PANE_OPTIONS } from '../common/constants';
|
|
20
19
|
|
|
21
20
|
const tabTriggerCSS = {
|
|
22
|
-
color: '$
|
|
21
|
+
color: '$on_surface_low',
|
|
23
22
|
p: '$4',
|
|
24
23
|
fontWeight: '$semiBold',
|
|
25
24
|
fontSize: '$sm',
|
|
26
25
|
w: '100%',
|
|
27
26
|
justifyContent: 'center',
|
|
27
|
+
'&[data-state="active"]': {
|
|
28
|
+
color: '$on_surface_high',
|
|
29
|
+
},
|
|
28
30
|
};
|
|
29
31
|
|
|
30
32
|
const ParticipantCount = ({ count }: { count: number }) => {
|
|
@@ -39,19 +41,19 @@ const ParticipantCount = ({ count }: { count: number }) => {
|
|
|
39
41
|
|
|
40
42
|
export const SidePaneTabs = React.memo<{
|
|
41
43
|
active: 'Participants | Chat';
|
|
42
|
-
|
|
43
|
-
}>(({ active = SIDE_PANE_OPTIONS.CHAT,
|
|
44
|
+
hideTab?: boolean;
|
|
45
|
+
}>(({ active = SIDE_PANE_OPTIONS.CHAT, hideTab = false }) => {
|
|
44
46
|
const toggleChat = useSidepaneToggle(SIDE_PANE_OPTIONS.CHAT);
|
|
45
47
|
const toggleParticipants = useSidepaneToggle(SIDE_PANE_OPTIONS.PARTICIPANTS);
|
|
46
48
|
const resetSidePane = useSidepaneReset();
|
|
47
49
|
const [activeTab, setActiveTab] = useState(active);
|
|
48
50
|
const [activeRole, setActiveRole] = useState('');
|
|
49
51
|
const peerCount = useHMSStore(selectPeerCount);
|
|
50
|
-
const { elements } = useRoomLayoutConferencingScreen();
|
|
52
|
+
const { elements, screenType } = useRoomLayoutConferencingScreen();
|
|
51
53
|
const chat_title = elements?.chat?.chat_title || 'Chat';
|
|
52
54
|
const showChat = !!elements?.chat;
|
|
53
55
|
const showParticipants = !!elements?.participant_list;
|
|
54
|
-
const hideTabs = !(showChat && showParticipants);
|
|
56
|
+
const hideTabs = !(showChat && showParticipants) || hideTab;
|
|
55
57
|
const isMobile = useMedia(cssConfig.media.md);
|
|
56
58
|
const isOverlayChat = !!elements?.chat?.is_overlay && isMobile;
|
|
57
59
|
const { off_stage_roles = [] } = (elements as DefaultConferencingScreen_Elements)?.on_stage_exp || {};
|
|
@@ -59,13 +61,16 @@ export const SidePaneTabs = React.memo<{
|
|
|
59
61
|
const showChatSettings = showChat && isChatOpen && (!isMobile || !isOverlayChat);
|
|
60
62
|
|
|
61
63
|
useEffect(() => {
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
64
|
+
match({ activeTab, showChat, showParticipants })
|
|
65
|
+
.with({ activeTab: SIDE_PANE_OPTIONS.CHAT, showChat: false, showParticipants: true }, () => {
|
|
66
|
+
setActiveTab(SIDE_PANE_OPTIONS.PARTICIPANTS);
|
|
67
|
+
})
|
|
68
|
+
.with({ activeTab: SIDE_PANE_OPTIONS.PARTICIPANTS, showChat: true, showParticipants: false }, () => {
|
|
69
|
+
setActiveTab(SIDE_PANE_OPTIONS.CHAT);
|
|
70
|
+
})
|
|
71
|
+
.with({ showChat: false, showParticipants: false }, () => {
|
|
72
|
+
resetSidePane();
|
|
73
|
+
});
|
|
69
74
|
}, [showChat, activeTab, showParticipants, resetSidePane]);
|
|
70
75
|
|
|
71
76
|
useEffect(() => {
|
|
@@ -79,7 +84,6 @@ export const SidePaneTabs = React.memo<{
|
|
|
79
84
|
css={{
|
|
80
85
|
color: '$on_primary_high',
|
|
81
86
|
h: '100%',
|
|
82
|
-
marginTop: hideControls && isOverlayChat ? '$17' : '0',
|
|
83
87
|
transition: 'margin 0.3s ease-in-out',
|
|
84
88
|
position: 'relative',
|
|
85
89
|
}}
|
|
@@ -97,20 +101,27 @@ export const SidePaneTabs = React.memo<{
|
|
|
97
101
|
css={{
|
|
98
102
|
color: '$on_primary_high',
|
|
99
103
|
h: '100%',
|
|
100
|
-
marginTop: hideControls && isOverlayChat ? '$17' : '0',
|
|
101
104
|
transition: 'margin 0.3s ease-in-out',
|
|
102
105
|
}}
|
|
103
106
|
>
|
|
104
|
-
{isOverlayChat
|
|
105
|
-
<Chat />
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
{hideTabs ? (
|
|
107
|
+
{match({ isOverlayChat, isChatOpen, showChat, hideTabs })
|
|
108
|
+
.with({ isOverlayChat: true, isChatOpen: true, showChat: true }, () => <Chat />)
|
|
109
|
+
.with({ hideTabs: true }, () => {
|
|
110
|
+
return (
|
|
109
111
|
<>
|
|
110
|
-
<Flex justify="between" css={{ w: '100%' }}>
|
|
111
|
-
<Text
|
|
112
|
-
|
|
113
|
-
|
|
112
|
+
<Flex justify="between" css={{ w: '100%', '&:empty': { display: 'none' } }}>
|
|
113
|
+
<Text
|
|
114
|
+
variant="sm"
|
|
115
|
+
css={{
|
|
116
|
+
fontWeight: '$semiBold',
|
|
117
|
+
p: '$4',
|
|
118
|
+
c: '$on_surface_high',
|
|
119
|
+
pr: '$12',
|
|
120
|
+
'&:empty': { display: 'none' },
|
|
121
|
+
}}
|
|
122
|
+
>
|
|
123
|
+
{activeTab === SIDE_PANE_OPTIONS.CHAT ? (
|
|
124
|
+
screenType !== 'hls_live_streaming' && chat_title
|
|
114
125
|
) : (
|
|
115
126
|
<span>
|
|
116
127
|
Participants
|
|
@@ -122,7 +133,12 @@ export const SidePaneTabs = React.memo<{
|
|
|
122
133
|
{showChatSettings ? <ChatSettings /> : null}
|
|
123
134
|
{isOverlayChat && isChatOpen ? null : (
|
|
124
135
|
<IconButton
|
|
125
|
-
css={{
|
|
136
|
+
css={{
|
|
137
|
+
my: '$1',
|
|
138
|
+
color: '$on_surface_medium',
|
|
139
|
+
'&:hover': { color: '$on_surface_high' },
|
|
140
|
+
'&:empty': { display: 'none' },
|
|
141
|
+
}}
|
|
126
142
|
onClick={e => {
|
|
127
143
|
e.stopPropagation();
|
|
128
144
|
if (activeTab === SIDE_PANE_OPTIONS.CHAT) {
|
|
@@ -133,14 +149,21 @@ export const SidePaneTabs = React.memo<{
|
|
|
133
149
|
}}
|
|
134
150
|
data-testid="close_chat"
|
|
135
151
|
>
|
|
136
|
-
<CrossIcon />
|
|
152
|
+
{screenType === 'hls_live_streaming' && isChatOpen ? null : <CrossIcon />}
|
|
137
153
|
</IconButton>
|
|
138
154
|
)}
|
|
139
155
|
</Flex>
|
|
140
156
|
</Flex>
|
|
141
|
-
{
|
|
157
|
+
{activeTab === SIDE_PANE_OPTIONS.CHAT ? (
|
|
158
|
+
<Chat />
|
|
159
|
+
) : (
|
|
160
|
+
<ParticipantList offStageRoles={off_stage_roles} onActive={setActiveRole} />
|
|
161
|
+
)}
|
|
142
162
|
</>
|
|
143
|
-
)
|
|
163
|
+
);
|
|
164
|
+
})
|
|
165
|
+
.otherwise(() => {
|
|
166
|
+
return (
|
|
144
167
|
<Tabs.Root
|
|
145
168
|
value={activeTab}
|
|
146
169
|
onValueChange={setActiveTab}
|
|
@@ -151,24 +174,10 @@ export const SidePaneTabs = React.memo<{
|
|
|
151
174
|
>
|
|
152
175
|
<Flex css={{ w: '100%' }}>
|
|
153
176
|
<Tabs.List css={{ flexGrow: 1, borderRadius: '$2', bg: '$surface_default' }}>
|
|
154
|
-
<Tabs.Trigger
|
|
155
|
-
value={SIDE_PANE_OPTIONS.CHAT}
|
|
156
|
-
onClick={toggleChat}
|
|
157
|
-
css={{
|
|
158
|
-
...tabTriggerCSS,
|
|
159
|
-
color: activeTab !== SIDE_PANE_OPTIONS.CHAT ? '$on_surface_low' : '$on_surface_high',
|
|
160
|
-
}}
|
|
161
|
-
>
|
|
177
|
+
<Tabs.Trigger value={SIDE_PANE_OPTIONS.CHAT} onClick={toggleChat} css={tabTriggerCSS}>
|
|
162
178
|
{chat_title}
|
|
163
179
|
</Tabs.Trigger>
|
|
164
|
-
<Tabs.Trigger
|
|
165
|
-
value={SIDE_PANE_OPTIONS.PARTICIPANTS}
|
|
166
|
-
onClick={toggleParticipants}
|
|
167
|
-
css={{
|
|
168
|
-
...tabTriggerCSS,
|
|
169
|
-
color: activeTab !== SIDE_PANE_OPTIONS.PARTICIPANTS ? '$on_surface_low' : '$on_surface_high',
|
|
170
|
-
}}
|
|
171
|
-
>
|
|
180
|
+
<Tabs.Trigger value={SIDE_PANE_OPTIONS.PARTICIPANTS} onClick={toggleParticipants} css={tabTriggerCSS}>
|
|
172
181
|
Participants
|
|
173
182
|
<ParticipantCount count={peerCount} />
|
|
174
183
|
</Tabs.Trigger>
|
|
@@ -198,9 +207,8 @@ export const SidePaneTabs = React.memo<{
|
|
|
198
207
|
<Chat />
|
|
199
208
|
</Tabs.Content>
|
|
200
209
|
</Tabs.Root>
|
|
201
|
-
)
|
|
202
|
-
|
|
203
|
-
)}
|
|
210
|
+
);
|
|
211
|
+
})}
|
|
204
212
|
</Flex>
|
|
205
213
|
);
|
|
206
214
|
});
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import React, { useEffect, useMemo, useRef, useState } from 'react';
|
|
2
|
+
import { match, P } from 'ts-pattern';
|
|
2
3
|
import {
|
|
3
4
|
selectHMSStats,
|
|
4
5
|
selectLocalPeerID,
|
|
@@ -188,11 +189,15 @@ const LocalPeerStats = () => {
|
|
|
188
189
|
};
|
|
189
190
|
|
|
190
191
|
const TrackStats = ({ trackID, layer, local }) => {
|
|
191
|
-
const selector = layer
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
192
|
+
const selector = match({ trackID, layer, local })
|
|
193
|
+
.with(
|
|
194
|
+
{
|
|
195
|
+
layer: P.when(layer => !!layer),
|
|
196
|
+
},
|
|
197
|
+
() => selectHMSStats.localVideoTrackStatsByLayer(layer)(trackID),
|
|
198
|
+
)
|
|
199
|
+
.with({ local: P.when(local => !!local) }, () => selectHMSStats.localAudioTrackStatsByID(trackID))
|
|
200
|
+
.otherwise(() => selectHMSStats.trackStatsByID(trackID));
|
|
196
201
|
const stats = useHMSStatsStore(selector);
|
|
197
202
|
if (!stats) {
|
|
198
203
|
return null;
|
|
@@ -215,7 +220,10 @@ const TrackStats = ({ trackID, layer, local }) => {
|
|
|
215
220
|
{!inbound && <StatsRow label="Quality Limitation Reason" value={stats.qualityLimitationReason} />}
|
|
216
221
|
</>
|
|
217
222
|
)}
|
|
218
|
-
<StatsRow
|
|
223
|
+
<StatsRow
|
|
224
|
+
label="Round Trip Time"
|
|
225
|
+
value={stats.roundTripTime ? `${(stats.roundTripTime * 1000).toFixed(3)} ms` : '-'}
|
|
226
|
+
/>
|
|
219
227
|
</Flex>
|
|
220
228
|
);
|
|
221
229
|
};
|
|
@@ -20,7 +20,7 @@ export const StreamCard = ({ title, subtitle, Icon, imgSrc = '', css = {}, onCli
|
|
|
20
20
|
onClick={onClick}
|
|
21
21
|
>
|
|
22
22
|
<Text css={{ alignSelf: 'center', p: '$4' }}>
|
|
23
|
-
{imgSrc ? <img src={imgSrc} height={40} width={40} /> : <Icon width={40} height={40} />}
|
|
23
|
+
{imgSrc ? <img src={imgSrc} height={40} width={40} alt="Streaming" /> : <Icon width={40} height={40} />}
|
|
24
24
|
</Text>
|
|
25
25
|
<Box css={{ flex: '1 1 0', mx: '$8' }}>
|
|
26
26
|
<Text variant="h6" css={{ mb: '$4' }}>
|
|
@@ -289,7 +289,7 @@ export const TileMenuContent = ({
|
|
|
289
289
|
data-testid={isVideoEnabled ? 'mute_video_participant_btn' : 'unmute_video_participant_btn'}
|
|
290
290
|
>
|
|
291
291
|
{isVideoEnabled ? <VideoOnIcon height={20} width={20} /> : <VideoOffIcon height={20} width={20} />}
|
|
292
|
-
<span>{isVideoEnabled ? 'Mute' : 'Request Unmute'}</span>
|
|
292
|
+
<span>{isVideoEnabled ? 'Mute Video' : 'Request to Unmute Video'}</span>
|
|
293
293
|
</StyledMenuTile.ItemButton>
|
|
294
294
|
) : null}
|
|
295
295
|
|
|
@@ -304,7 +304,7 @@ export const TileMenuContent = ({
|
|
|
304
304
|
data-testid={isAudioEnabled ? 'mute_audio_participant_btn' : 'unmute_audio_participant_btn'}
|
|
305
305
|
>
|
|
306
306
|
{isAudioEnabled ? <MicOnIcon height={20} width={20} /> : <MicOffIcon height={20} width={20} />}
|
|
307
|
-
<span>{isAudioEnabled ? 'Mute' : 'Request Unmute'}</span>
|
|
307
|
+
<span>{isAudioEnabled ? 'Mute Audio' : 'Request to Unmute Audio'}</span>
|
|
308
308
|
</StyledMenuTile.ItemButton>
|
|
309
309
|
) : null}
|
|
310
310
|
|
|
@@ -3,6 +3,7 @@ import { ToastManager } from './ToastManager';
|
|
|
3
3
|
|
|
4
4
|
export const ToastBatcher = {
|
|
5
5
|
toastsType: new Map(),
|
|
6
|
+
toastCache: {},
|
|
6
7
|
showToastInternal({ notification, duration, type }) {
|
|
7
8
|
let notificationType = type;
|
|
8
9
|
if (!type) {
|
|
@@ -40,7 +41,13 @@ export const ToastBatcher = {
|
|
|
40
41
|
},
|
|
41
42
|
showToast({ notification, duration = 3000, type }) {
|
|
42
43
|
try {
|
|
43
|
-
this.
|
|
44
|
+
if (!this.toastCache[notification.id]) {
|
|
45
|
+
this.showToastInternal({ notification, duration, type });
|
|
46
|
+
}
|
|
47
|
+
this.toastCache[notification.id] = true;
|
|
48
|
+
if (Object.keys(this.toastCache).length > 100) {
|
|
49
|
+
this.toastCache = {};
|
|
50
|
+
}
|
|
44
51
|
} catch (err) {
|
|
45
52
|
console.debug('Notifications', err);
|
|
46
53
|
}
|
|
@@ -123,6 +123,23 @@ export const ToastConfig = {
|
|
|
123
123
|
},
|
|
124
124
|
},
|
|
125
125
|
RAISE_HAND: {
|
|
126
|
+
single: notification => {
|
|
127
|
+
return {
|
|
128
|
+
title: `${notification.data?.name} raised hand`,
|
|
129
|
+
icon: <HandIcon />,
|
|
130
|
+
};
|
|
131
|
+
},
|
|
132
|
+
multiple: notifications => {
|
|
133
|
+
const count = new Set(notifications.map(notification => notification.data?.id)).size;
|
|
134
|
+
return {
|
|
135
|
+
title: `${notifications[notifications.length - 1].data?.name} ${
|
|
136
|
+
count > 1 ? `${count} and others` : ''
|
|
137
|
+
} raised hand`,
|
|
138
|
+
icon: <HandIcon />,
|
|
139
|
+
};
|
|
140
|
+
},
|
|
141
|
+
},
|
|
142
|
+
RAISE_HAND_HLS: {
|
|
126
143
|
single: notification => {
|
|
127
144
|
return {
|
|
128
145
|
title: `${notification.data?.name} raised hand`,
|
|
@@ -67,7 +67,7 @@ export function RoleProminence({
|
|
|
67
67
|
edgeToEdge={edgeToEdge}
|
|
68
68
|
hasSidebar={layoutMode === LayoutMode.SIDEBAR}
|
|
69
69
|
/>
|
|
70
|
-
{isInsetEnabled && localPeer && !prominentPeers.includes(localPeer) && <InsetTile />}
|
|
70
|
+
{isInsetEnabled && localPeer && prominentPeers.length > 0 && !prominentPeers.includes(localPeer) && <InsetTile />}
|
|
71
71
|
</ProminenceLayout.Root>
|
|
72
72
|
);
|
|
73
73
|
}
|
|
@@ -17,7 +17,7 @@ export const useRoleProminencePeers = (prominentRoles: string[], peers: HMSPeer[
|
|
|
17
17
|
}
|
|
18
18
|
return acc;
|
|
19
19
|
}
|
|
20
|
-
if (peer.isLocal && isInsetEnabled) {
|
|
20
|
+
if (peer.isLocal && isInsetEnabled && !prominentRoles?.includes(peer.roleName || '')) {
|
|
21
21
|
return acc;
|
|
22
22
|
}
|
|
23
23
|
if (prominentRoles?.includes(peer.roleName || '')) {
|
|
@@ -25,6 +25,7 @@ export const useRoleProminencePeers = (prominentRoles: string[], peers: HMSPeer[
|
|
|
25
25
|
} else {
|
|
26
26
|
acc[1].push(peer);
|
|
27
27
|
}
|
|
28
|
+
|
|
28
29
|
return acc;
|
|
29
30
|
},
|
|
30
31
|
[[], []],
|
|
@@ -61,7 +61,7 @@ export function ShareScreenOptions() {
|
|
|
61
61
|
pt: '$10',
|
|
62
62
|
pb: '$6',
|
|
63
63
|
'&:hover': {
|
|
64
|
-
bg: '
|
|
64
|
+
bg: 'transparent',
|
|
65
65
|
cursor: 'default',
|
|
66
66
|
},
|
|
67
67
|
}}
|
|
@@ -78,7 +78,7 @@ export function ShareScreenOptions() {
|
|
|
78
78
|
pt: '$6',
|
|
79
79
|
pb: '$10',
|
|
80
80
|
'&:hover': {
|
|
81
|
-
bg: '
|
|
81
|
+
bg: 'transparent',
|
|
82
82
|
cursor: 'default',
|
|
83
83
|
},
|
|
84
84
|
}}
|