@100mslive/roomkit-react 0.2.8-alpha.0 → 0.2.8-alpha.10
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
}}
|