@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.
Files changed (136) hide show
  1. package/dist/{HLSView-PY2FKWX3.js → HLSView-QMU5JK7U.js} +208 -118
  2. package/dist/HLSView-QMU5JK7U.js.map +7 -0
  3. package/dist/Prebuilt/AppContext.d.ts +1 -1
  4. package/dist/Prebuilt/components/Chat/ChatFooter.d.ts +7 -0
  5. package/dist/Prebuilt/components/Connection/ConnectionIndicator.d.ts +6 -0
  6. package/dist/Prebuilt/components/Connection/TileConnection.d.ts +10 -0
  7. package/dist/Prebuilt/components/Footer/ChatToggle.d.ts +2 -0
  8. package/dist/Prebuilt/components/Footer/RoleAccordion.d.ts +14 -0
  9. package/dist/Prebuilt/components/Footer/RoleOptions.d.ts +6 -0
  10. package/dist/Prebuilt/components/Header/StreamActions.d.ts +11 -0
  11. package/dist/Prebuilt/components/Leave/DesktopLeaveRoom.d.ts +4 -3
  12. package/dist/Prebuilt/components/Leave/EndSessionContent.d.ts +4 -3
  13. package/dist/Prebuilt/components/Leave/LeaveCard.d.ts +1 -2
  14. package/dist/Prebuilt/components/Leave/LeaveSessionContent.d.ts +3 -1
  15. package/dist/Prebuilt/components/Leave/MwebLeaveRoom.d.ts +4 -3
  16. package/dist/Prebuilt/components/MoreSettings/SplitComponents/MwebOptions.d.ts +6 -0
  17. package/dist/Prebuilt/components/Preview/PreviewContainer.d.ts +3 -0
  18. package/dist/Prebuilt/components/Preview/PreviewJoin.d.ts +16 -0
  19. package/dist/Prebuilt/components/RoleChangeRequestModal.d.ts +2 -0
  20. package/dist/Prebuilt/components/SecondaryTiles.d.ts +1 -1
  21. package/dist/Prebuilt/components/SidePaneTabs.d.ts +7 -0
  22. package/dist/Prebuilt/components/VideoLayouts/EqualProminence.d.ts +1 -1
  23. package/dist/Prebuilt/components/VideoLayouts/Grid.d.ts +1 -0
  24. package/dist/Prebuilt/components/VideoLayouts/GridLayout.d.ts +5 -3
  25. package/dist/Prebuilt/components/VideoLayouts/ProminenceLayout.d.ts +6 -3
  26. package/dist/Prebuilt/components/VideoLayouts/RoleProminence.d.ts +1 -1
  27. package/dist/Prebuilt/components/VideoLayouts/ScreenshareLayout.d.ts +1 -1
  28. package/dist/Prebuilt/components/VideoLayouts/interface.d.ts +1 -0
  29. package/dist/Prebuilt/components/hooks/useAutoStartStreaming.d.ts +1 -0
  30. package/dist/Prebuilt/components/hooks/useRedirectToLeave.d.ts +3 -0
  31. package/dist/Prebuilt/components/hooks/useTileLayout.d.ts +2 -1
  32. package/dist/Prebuilt/components/hooks/useVideoTileLayout.d.ts +2 -0
  33. package/dist/Prebuilt/layouts/SidePane.d.ts +4 -1
  34. package/dist/Prebuilt/layouts/VideoStreamingSection.d.ts +2 -1
  35. package/dist/{VirtualBackground-AYDHYLIZ.js → VirtualBackground-37FXUPYO.js} +6 -6
  36. package/dist/VirtualBackground-37FXUPYO.js.map +7 -0
  37. package/dist/{chunk-GQD2AGWW.js → chunk-KBVIZGYW.js} +12 -2
  38. package/dist/{chunk-GQD2AGWW.js.map → chunk-KBVIZGYW.js.map} +2 -2
  39. package/dist/{chunk-RXTHJUMZ.js → chunk-WVGGQZK4.js} +986 -436
  40. package/dist/chunk-WVGGQZK4.js.map +7 -0
  41. package/dist/{chunk-E2M2ZSOL.js → chunk-ZKE2N5LH.js} +2 -2
  42. package/dist/{conference-V2XZGTKU.js → conference-FJJQ4TXX.js} +1136 -1301
  43. package/dist/conference-FJJQ4TXX.js.map +7 -0
  44. package/dist/index.cjs.js +3565 -3092
  45. package/dist/index.cjs.js.map +4 -4
  46. package/dist/index.js +2 -2
  47. package/dist/meta.cjs.json +773 -525
  48. package/dist/meta.esbuild.json +833 -579
  49. package/package.json +8 -7
  50. package/src/Prebuilt/App.tsx +10 -21
  51. package/src/Prebuilt/AppContext.tsx +1 -1
  52. package/src/Prebuilt/IconButton.jsx +10 -0
  53. package/src/Prebuilt/common/PeersSorter.ts +1 -1
  54. package/src/Prebuilt/common/constants.js +1 -2
  55. package/src/Prebuilt/common/utils.js +1 -1
  56. package/src/Prebuilt/components/AppData/AppData.jsx +8 -2
  57. package/src/Prebuilt/components/AppData/useUISettings.js +6 -6
  58. package/src/Prebuilt/components/AudioVideoToggle.jsx +8 -6
  59. package/src/Prebuilt/components/Chat/Chat.jsx +24 -11
  60. package/src/Prebuilt/components/Chat/ChatBody.jsx +20 -21
  61. package/src/Prebuilt/components/Chat/{ChatFooter.jsx → ChatFooter.tsx} +38 -13
  62. package/src/Prebuilt/components/Chat/useEmojiPickerStyles.js +5 -4
  63. package/src/Prebuilt/components/Connection/{ConnectionIndicator.jsx → ConnectionIndicator.tsx} +12 -4
  64. package/src/Prebuilt/components/Connection/{TileConnection.jsx → TileConnection.tsx} +20 -6
  65. package/src/Prebuilt/components/EmojiReaction.jsx +2 -6
  66. package/src/Prebuilt/components/Footer/{ChatToggle.jsx → ChatToggle.tsx} +4 -1
  67. package/src/Prebuilt/components/Footer/Footer.tsx +30 -5
  68. package/src/Prebuilt/components/Footer/ParticipantList.jsx +15 -49
  69. package/src/Prebuilt/components/Footer/{RoleAccordion.jsx → RoleAccordion.tsx} +33 -17
  70. package/src/Prebuilt/components/Footer/RoleOptions.tsx +155 -0
  71. package/src/Prebuilt/components/FullPageProgress.jsx +3 -3
  72. package/src/Prebuilt/components/HMSVideo/Controls.jsx +1 -0
  73. package/src/Prebuilt/components/HMSVideo/HLSQualitySelector.jsx +39 -17
  74. package/src/Prebuilt/components/HMSVideo/HMSVideo.jsx +2 -2
  75. package/src/Prebuilt/components/HMSVideo/VideoProgress.jsx +5 -6
  76. package/src/Prebuilt/components/HMSVideo/VolumeControl.jsx +1 -1
  77. package/src/Prebuilt/components/Header/HeaderComponents.jsx +8 -1
  78. package/src/Prebuilt/components/Header/{StreamActions.jsx → StreamActions.tsx} +23 -9
  79. package/src/Prebuilt/components/Header/common.jsx +5 -2
  80. package/src/Prebuilt/components/IconButtonWithOptions/IconButtonWithOptions.jsx +6 -1
  81. package/src/Prebuilt/components/InsetTile.tsx +15 -8
  82. package/src/Prebuilt/components/Leave/DesktopLeaveRoom.tsx +21 -11
  83. package/src/Prebuilt/components/Leave/EndSessionContent.tsx +2 -5
  84. package/src/Prebuilt/components/Leave/LeaveCard.tsx +1 -3
  85. package/src/Prebuilt/components/Leave/LeaveRoom.tsx +28 -25
  86. package/src/Prebuilt/components/Leave/LeaveSessionContent.tsx +8 -2
  87. package/src/Prebuilt/components/Leave/MwebLeaveRoom.tsx +8 -8
  88. package/src/Prebuilt/components/MoreSettings/ChangeNameContent.jsx +4 -0
  89. package/src/Prebuilt/components/MoreSettings/MoreSettings.tsx +1 -1
  90. package/src/Prebuilt/components/MoreSettings/SplitComponents/DesktopOptions.tsx +9 -23
  91. package/src/Prebuilt/components/MoreSettings/SplitComponents/{MwebOptions.jsx → MwebOptions.tsx} +89 -28
  92. package/src/Prebuilt/components/Notifications/Notifications.jsx +44 -28
  93. package/src/Prebuilt/components/Notifications/ReconnectNotifications.jsx +5 -11
  94. package/src/Prebuilt/components/Pagination.tsx +14 -12
  95. package/src/Prebuilt/components/Preview/{PreviewContainer.jsx → PreviewContainer.tsx} +11 -2
  96. package/src/Prebuilt/components/Preview/PreviewForm.tsx +6 -8
  97. package/src/Prebuilt/components/Preview/{PreviewJoin.jsx → PreviewJoin.tsx} +44 -21
  98. package/src/Prebuilt/components/{RoleChangeRequestModal.jsx → RoleChangeRequestModal.tsx} +36 -17
  99. package/src/Prebuilt/components/ScreenshareTile.jsx +6 -7
  100. package/src/Prebuilt/components/SecondaryTiles.tsx +12 -10
  101. package/src/Prebuilt/components/SidePaneTabs.tsx +120 -0
  102. package/src/Prebuilt/components/TileMenu/TileMenu.jsx +1 -1
  103. package/src/Prebuilt/components/TileMenu/TileMenuContent.jsx +14 -10
  104. package/src/Prebuilt/components/Toast/ToastConfig.jsx +5 -4
  105. package/src/Prebuilt/components/VideoLayouts/EqualProminence.tsx +13 -10
  106. package/src/Prebuilt/components/VideoLayouts/Grid.tsx +36 -34
  107. package/src/Prebuilt/components/VideoLayouts/GridLayout.tsx +33 -15
  108. package/src/Prebuilt/components/VideoLayouts/ProminenceLayout.tsx +45 -31
  109. package/src/Prebuilt/components/VideoLayouts/RoleProminence.tsx +12 -9
  110. package/src/Prebuilt/components/VideoLayouts/ScreenshareLayout.tsx +25 -9
  111. package/src/Prebuilt/components/VideoLayouts/interface.ts +1 -0
  112. package/src/Prebuilt/components/VideoTile.jsx +45 -53
  113. package/src/Prebuilt/components/conference.jsx +71 -74
  114. package/src/Prebuilt/components/hooks/useAutoStartStreaming.tsx +57 -0
  115. package/src/Prebuilt/components/hooks/useMetadata.jsx +19 -28
  116. package/src/Prebuilt/components/hooks/useRedirectToLeave.tsx +34 -0
  117. package/src/Prebuilt/components/hooks/useRoleProminencePeers.tsx +1 -1
  118. package/src/Prebuilt/components/hooks/useTileLayout.tsx +24 -18
  119. package/src/Prebuilt/components/hooks/useVideoTileLayout.ts +4 -0
  120. package/src/Prebuilt/layouts/EmbedView.jsx +1 -11
  121. package/src/Prebuilt/layouts/HLSView.jsx +152 -82
  122. package/src/Prebuilt/layouts/SidePane.tsx +25 -11
  123. package/src/Prebuilt/layouts/VideoStreamingSection.tsx +11 -47
  124. package/src/Prebuilt/plugins/FlyingEmoji.jsx +14 -2
  125. package/src/Prebuilt/plugins/VirtualBackground/VirtualBackground.jsx +3 -3
  126. package/src/Prebuilt/provider/roomLayoutProvider/hooks/useFetchRoomLayout.ts +2 -2
  127. package/src/Prebuilt/services/FeatureFlags.jsx +0 -1
  128. package/src/VideoTile/StyledVideoTile.tsx +1 -0
  129. package/dist/HLSView-PY2FKWX3.js.map +0 -7
  130. package/dist/VirtualBackground-AYDHYLIZ.js.map +0 -7
  131. package/dist/chunk-RXTHJUMZ.js.map +0 -7
  132. package/dist/conference-V2XZGTKU.js.map +0 -7
  133. package/src/Prebuilt/components/AudioLevel/BeamSpeakerLabelsLogging.jsx +0 -16
  134. package/src/Prebuilt/components/Chat/ChatParticipantHeader.jsx +0 -73
  135. package/src/Prebuilt/components/VideoList.jsx +0 -73
  136. /package/dist/{chunk-E2M2ZSOL.js.map → chunk-ZKE2N5LH.js.map} +0 -0
@@ -0,0 +1,155 @@
1
+ import React, { useState } from 'react';
2
+ import { DefaultConferencingScreen_Elements } from '@100mslive/types-prebuilt';
3
+ import { HMSPeer, selectPermissions, useHMSActions, useHMSStore, useHMSVanillaStore } from '@100mslive/react-sdk';
4
+ import {
5
+ MicOffIcon,
6
+ MicOnIcon,
7
+ PersonRectangleIcon,
8
+ RemoveUserIcon,
9
+ VerticalMenuIcon,
10
+ VideoOffIcon,
11
+ VideoOnIcon,
12
+ } from '@100mslive/react-icons';
13
+ import { Dropdown } from '../../../Dropdown';
14
+ import { Flex } from '../../../Layout';
15
+ import { Text } from '../../../Text';
16
+ import { useRoomLayoutConferencingScreen } from '../../provider/roomLayoutProvider/hooks/useRoomLayoutScreen';
17
+ // @ts-ignore: No implicit Any
18
+ import { getMetadata } from '../../common/utils';
19
+
20
+ const dropdownItemCSS = { backgroundColor: '$surface_default', gap: '$4', p: '$8' };
21
+ const optionTextCSS = { fontWeight: '$semiBold', color: '$on_surface_high', textTransform: 'none' };
22
+
23
+ export const RoleOptions = ({ roleName, peerList }: { roleName: string; peerList: HMSPeer[] }) => {
24
+ const [openOptions, setOpenOptions] = useState(false);
25
+ const permissions = useHMSStore(selectPermissions);
26
+ const hmsActions = useHMSActions();
27
+ const { elements } = useRoomLayoutConferencingScreen();
28
+ const { on_stage_role, off_stage_roles = [] } = (elements as DefaultConferencingScreen_Elements)?.on_stage_exp || {};
29
+
30
+ const vanillaStore = useHMSVanillaStore();
31
+ const store = vanillaStore.getState();
32
+
33
+ let allPeersHaveVideoOn = true;
34
+ let allPeersHaveAudioOn = true;
35
+
36
+ peerList.forEach(peer => {
37
+ const isAudioOn = !!peer.audioTrack && store.tracks[peer.audioTrack]?.enabled;
38
+ const isVideoOn = !!peer.videoTrack && store.tracks[peer.videoTrack]?.enabled;
39
+ allPeersHaveAudioOn = allPeersHaveAudioOn && isAudioOn;
40
+ allPeersHaveVideoOn = allPeersHaveVideoOn && isVideoOn;
41
+ });
42
+
43
+ const canMuteRole = permissions?.mute && roleName === on_stage_role;
44
+ const canRemoveRoleFromStage = permissions?.changeRole && roleName === on_stage_role;
45
+ // on stage and off stage roles
46
+ const canRemoveRoleFromRoom =
47
+ permissions?.removeOthers && (on_stage_role === roleName || off_stage_roles?.includes(roleName));
48
+
49
+ if (!(canMuteRole || canRemoveRoleFromStage || canRemoveRoleFromRoom)) {
50
+ return null;
51
+ }
52
+
53
+ const removeAllFromStage = () => {
54
+ peerList.forEach(peer => {
55
+ const prevRole = getMetadata(peer.metadata).prevRole;
56
+ if (prevRole) {
57
+ hmsActions.changeRoleOfPeer(peer.id, prevRole, true);
58
+ }
59
+ });
60
+ };
61
+
62
+ const setTrackEnabled = async (type: 'audio' | 'video', enabled = false) => {
63
+ try {
64
+ await hmsActions.setRemoteTracksEnabled({ roles: [roleName], source: 'regular', type, enabled });
65
+ } catch (e) {
66
+ console.error(e);
67
+ }
68
+ };
69
+
70
+ const removePeersFromRoom = async () => {
71
+ try {
72
+ peerList.forEach(async peer => {
73
+ await hmsActions.removePeer(peer.id, '');
74
+ });
75
+ } catch (e) {
76
+ console.error(e);
77
+ }
78
+ };
79
+
80
+ return (
81
+ <Dropdown.Root open={openOptions} onOpenChange={setOpenOptions}>
82
+ <Dropdown.Trigger
83
+ onClick={e => e.stopPropagation()}
84
+ className="role_actions"
85
+ asChild
86
+ css={{
87
+ p: '$1',
88
+ r: '$0',
89
+ c: '$on_surface_high',
90
+ visibility: openOptions ? 'visible' : 'hidden',
91
+ '&:hover': {
92
+ c: '$on_surface_medium',
93
+ },
94
+ '@md': {
95
+ visibility: 'visible',
96
+ },
97
+ }}
98
+ >
99
+ <Flex>
100
+ <VerticalMenuIcon />
101
+ </Flex>
102
+ </Dropdown.Trigger>
103
+ <Dropdown.Content
104
+ onClick={e => e.stopPropagation()}
105
+ css={{ w: 'max-content', maxWidth: '$64', bg: '$surface_default', py: 0 }}
106
+ align="end"
107
+ >
108
+ {canRemoveRoleFromStage && (
109
+ <Dropdown.Item
110
+ css={{ ...dropdownItemCSS, borderBottom: '1px solid $border_bright' }}
111
+ onClick={removeAllFromStage}
112
+ >
113
+ <PersonRectangleIcon />
114
+ <Text variant="sm" css={optionTextCSS}>
115
+ Remove all from Stage
116
+ </Text>
117
+ </Dropdown.Item>
118
+ )}
119
+
120
+ {canMuteRole && (
121
+ <>
122
+ <Dropdown.Item css={dropdownItemCSS} onClick={() => setTrackEnabled('audio', !allPeersHaveAudioOn)}>
123
+ {allPeersHaveAudioOn ? <MicOffIcon /> : <MicOnIcon />}
124
+ <Text variant="sm" css={optionTextCSS}>
125
+ {allPeersHaveAudioOn ? 'Mute' : 'Unmute'} Audio
126
+ </Text>
127
+ </Dropdown.Item>
128
+
129
+ <Dropdown.Item
130
+ css={{ ...dropdownItemCSS, borderTop: '1px solid $border_bright' }}
131
+ onClick={() => setTrackEnabled('video', !allPeersHaveVideoOn)}
132
+ >
133
+ {allPeersHaveVideoOn ? <VideoOffIcon /> : <VideoOnIcon />}
134
+ <Text variant="sm" css={optionTextCSS}>
135
+ {allPeersHaveVideoOn ? 'Mute' : 'Unmute'} Video
136
+ </Text>
137
+ </Dropdown.Item>
138
+ </>
139
+ )}
140
+
141
+ {canRemoveRoleFromRoom && (
142
+ <Dropdown.Item
143
+ css={{ ...dropdownItemCSS, borderTop: '1px solid $border_bright', color: '$alert_error_default' }}
144
+ onClick={removePeersFromRoom}
145
+ >
146
+ <RemoveUserIcon />
147
+ <Text variant="sm" css={{ ...optionTextCSS, color: 'inherit' }}>
148
+ Remove all from Room
149
+ </Text>
150
+ </Dropdown.Item>
151
+ )}
152
+ </Dropdown.Content>
153
+ </Dropdown.Root>
154
+ );
155
+ };
@@ -3,10 +3,10 @@ import { Flex } from '../../Layout';
3
3
  import { Loading } from '../../Loading';
4
4
  import { Text } from '../../Text';
5
5
 
6
- const FullPageProgress = ({ loaderColor = '$primary_default', loadingText = '' }) => (
7
- <Flex direction="column" justify="center" align="center" css={{ size: '100%', color: loaderColor }}>
6
+ const FullPageProgress = ({ loaderColor = '$primary_default', text = '', css = {} }) => (
7
+ <Flex direction="column" justify="center" align="center" css={{ size: '100%', color: loaderColor, ...css }}>
8
8
  <Loading color="currentColor" size={100} />
9
- {loadingText ? <Text css={{ mt: '$10', color: '$on_surface_high' }}>{loadingText}</Text> : null}
9
+ {text ? <Text css={{ mt: '$10', color: '$on_surface_high' }}>{text}</Text> : null}
10
10
  </Flex>
11
11
  );
12
12
 
@@ -3,6 +3,7 @@ import { Flex, styled } from '../../../';
3
3
  export const VideoControls = styled(Flex, {
4
4
  justifyContent: 'center',
5
5
  alignItems: 'center',
6
+ alignSelf: 'stretch',
6
7
  width: '100%',
7
8
  gap: '$2',
8
9
  });
@@ -1,12 +1,10 @@
1
- import React, { useState } from 'react';
2
- import { CheckCircleIcon, SettingsIcon } from '@100mslive/react-icons';
1
+ import React from 'react';
2
+ import { CheckIcon, SettingsIcon } from '@100mslive/react-icons';
3
3
  import { Box, Dropdown, Flex, Text, Tooltip } from '../../../';
4
4
 
5
- export function HLSQualitySelector({ layers, onQualityChange, selection, isAuto }) {
6
- const [qualityDropDownOpen, setQualityDropDownOpen] = useState(false);
7
-
5
+ export function HLSQualitySelector({ open, onOpen, layers, onQualityChange, selection, isAuto }) {
8
6
  return (
9
- <Dropdown.Root open={qualityDropDownOpen} onOpenChange={value => setQualityDropDownOpen(value)}>
7
+ <Dropdown.Root open={open} onOpenChange={value => onOpen(value)}>
10
8
  <Dropdown.Trigger asChild data-testid="quality_selector">
11
9
  <Flex
12
10
  css={{
@@ -24,6 +22,7 @@ export function HLSQualitySelector({ layers, onQualityChange, selection, isAuto
24
22
  h: '$9',
25
23
  display: 'inline-flex',
26
24
  alignItems: 'center',
25
+ c: '$on_surface_high',
27
26
  }}
28
27
  >
29
28
  <SettingsIcon />
@@ -44,7 +43,7 @@ export function HLSQualitySelector({ layers, onQualityChange, selection, isAuto
44
43
  mx: '$2',
45
44
  w: '$2',
46
45
  h: '$2',
47
- background: '$on_primary_high',
46
+ background: '$on_surface_medium',
48
47
  r: '$1',
49
48
  }}
50
49
  />
@@ -60,7 +59,15 @@ export function HLSQualitySelector({ layers, onQualityChange, selection, isAuto
60
59
  <Dropdown.Content
61
60
  sideOffset={5}
62
61
  align="end"
63
- css={{ height: 'auto', maxHeight: '$96', w: '$64', bg: '$surface_bright' }}
62
+ css={{
63
+ height: 'auto',
64
+ maxHeight: '$52',
65
+ w: '$40',
66
+ bg: '$surface_bright',
67
+ py: '$4',
68
+ gap: '$4',
69
+ display: 'grid',
70
+ }}
64
71
  >
65
72
  {layers.map(layer => {
66
73
  return (
@@ -68,16 +75,26 @@ export function HLSQualitySelector({ layers, onQualityChange, selection, isAuto
68
75
  onClick={() => onQualityChange(layer)}
69
76
  key={layer.width}
70
77
  css={{
71
- bg: '$surface_bright',
78
+ bg:
79
+ !isAuto && layer.width === selection?.width && layer.height === selection?.height
80
+ ? '$surface_default'
81
+ : '$surface_bright',
72
82
  '&:hover': {
73
- bg: '$surface_default',
83
+ bg: '$surface_brighter',
74
84
  },
85
+ p: '$2 $4 $2 $8',
86
+ h: '$12',
87
+ gap: '$2',
75
88
  }}
76
89
  >
77
- <Text>{getQualityText(layer)}</Text>
78
- <Text css={{ flex: '1 1 0', c: '$on_surface_low', pl: '$2' }}>{getBitrateText(layer)}</Text>
90
+ <Text variant="caption" css={{ fontWeight: '$semiBold' }}>
91
+ {getQualityText(layer)}
92
+ </Text>
93
+ <Text variant="caption" css={{ flex: '1 1 0', c: '$on_surface_low', pl: '$2' }}>
94
+ {getBitrateText(layer)}
95
+ </Text>
79
96
  {!isAuto && layer.width === selection?.width && layer.height === selection?.height && (
80
- <CheckCircleIcon />
97
+ <CheckIcon width="16px" height="16px" />
81
98
  )}
82
99
  </Dropdown.Item>
83
100
  );
@@ -86,14 +103,19 @@ export function HLSQualitySelector({ layers, onQualityChange, selection, isAuto
86
103
  onClick={() => onQualityChange({ height: 'auto' })}
87
104
  key="auto"
88
105
  css={{
89
- bg: '$surface_bright',
106
+ bg: !isAuto ? '$surface_bright' : '$surface_default',
90
107
  '&:hover': {
91
- bg: '$surface_default',
108
+ bg: '$surface_brighter',
92
109
  },
110
+ p: '$2 $4 $2 $8',
111
+ h: '$12',
112
+ gap: '$2',
93
113
  }}
94
114
  >
95
- <Text css={{ flex: '1 1 0' }}>Auto</Text>
96
- {isAuto && <CheckCircleIcon />}
115
+ <Text variant="caption" css={{ fontWeight: '$semiBold', flex: '1 1 0' }}>
116
+ Auto
117
+ </Text>
118
+ {isAuto && <CheckIcon width="16px" height="16px" />}
97
119
  </Dropdown.Item>
98
120
  </Dropdown.Content>
99
121
  )}
@@ -1,9 +1,9 @@
1
1
  import React, { forwardRef } from 'react';
2
2
  import { Flex } from '../../../';
3
3
 
4
- export const HMSVideo = forwardRef(({ children }, videoRef) => {
4
+ export const HMSVideo = forwardRef(({ children, ...props }, videoRef) => {
5
5
  return (
6
- <Flex data-testid="hms-video" css={{ size: '100%' }} direction="column">
6
+ <Flex data-testid="hms-video" css={{ size: '100%', position: 'relative' }} direction="column" {...props}>
7
7
  <video style={{ flex: '1 1 0', margin: '0 auto', minHeight: '0' }} ref={videoRef} playsInline />
8
8
  {children}
9
9
  </Flex>
@@ -44,7 +44,7 @@ export const VideoProgress = ({ onValueChange, hlsPlayer }) => {
44
44
  return hlsPlayer.getVideoElement() ? (
45
45
  <Flex
46
46
  ref={progressRootRef}
47
- css={{ paddingLeft: '$8', paddingRight: '$8', cursor: 'pointer' }}
47
+ css={{ cursor: 'pointer', h: '$4', alignSelf: 'stretch' }}
48
48
  onClick={onProgressChangeHandler}
49
49
  >
50
50
  <Box
@@ -53,23 +53,22 @@ export const VideoProgress = ({ onValueChange, hlsPlayer }) => {
53
53
  display: 'inline',
54
54
  width: `${videoProgress}%`,
55
55
  background: '$primary_default',
56
- height: '0.3rem',
57
56
  }}
58
57
  />
59
58
  <Box
60
59
  id="video-buffer"
61
60
  css={{
62
61
  width: `${bufferProgress - videoProgress}%`,
63
- background: '$primary_dim',
64
- height: '0.3rem',
62
+ background: '$on_surface_high',
63
+ opacity: '25%',
65
64
  }}
66
65
  />
67
66
  <Box
68
67
  id="video-rest"
69
68
  css={{
70
69
  width: `${100 - bufferProgress}%`,
71
- background: '$surface_brighter',
72
- height: '0.3rem',
70
+ background: '$on_surface_high',
71
+ opacity: '10%',
73
72
  }}
74
73
  />
75
74
  </Flex>
@@ -9,7 +9,7 @@ export const VolumeControl = ({ hlsPlayer }) => {
9
9
  return (
10
10
  <Flex
11
11
  align="center"
12
- css={{ color: '$on_primary_high' }}
12
+ css={{ color: '$on_surface_high' }}
13
13
  onMouseOver={event => {
14
14
  event.stopPropagation();
15
15
  setShowSlider(true);
@@ -1,4 +1,4 @@
1
- import React, { useState } from 'react';
1
+ import React, { useEffect, useState } from 'react';
2
2
  import { useMedia } from 'react-use';
3
3
  import { selectDominantSpeaker, selectIsConnectedToRoom, useHMSStore } from '@100mslive/react-sdk';
4
4
  import { VolumeOneIcon } from '@100mslive/react-icons';
@@ -41,6 +41,13 @@ export const Logo = () => {
41
41
  const isConnected = useHMSStore(selectIsConnectedToRoom);
42
42
  const [hideImage, setHideImage] = useState(false);
43
43
  // Hide logo for now as there is not enough space
44
+ useEffect(() => {
45
+ if (hideImage) {
46
+ setHideImage(false);
47
+ }
48
+ // eslint-disable-next-line react-hooks/exhaustive-deps
49
+ }, [logo]);
50
+
44
51
  if (isConnected && isMobile) {
45
52
  return null;
46
53
  }
@@ -11,26 +11,31 @@ import {
11
11
  useRecordingStreaming,
12
12
  } from '@100mslive/react-sdk';
13
13
  import { AlertTriangleIcon, CrossIcon, RecordIcon } from '@100mslive/react-icons';
14
- import { Box, Button, config as cssConfig, Flex, HorizontalDivider, Loading, Popover, Text, Tooltip } from '../../../';
14
+ import { Box, Button, config as cssConfig, Flex, HorizontalDivider, Loading, Popover, Text, Tooltip } from '../../..';
15
15
  import { Sheet } from '../../../Sheet';
16
+ // @ts-ignore
16
17
  import { ToastManager } from '../Toast/ToastManager';
18
+ // @ts-ignore
17
19
  import { AdditionalRoomState, getRecordingText } from './AdditionalRoomState';
20
+ // @ts-ignore
18
21
  import { useSetAppDataByKey } from '../AppData/useUISettings';
22
+ // @ts-ignore
19
23
  import { formatTime } from '../../common/utils';
24
+ // @ts-ignore
20
25
  import { APP_DATA } from '../../common/constants';
21
26
 
22
27
  export const LiveStatus = () => {
23
28
  const { isHLSRunning, isRTMPRunning } = useRecordingStreaming();
24
29
  const hlsState = useHMSStore(selectHLSState);
25
30
  const isMobile = useMedia(cssConfig.media.md);
26
- const intervalRef = useRef(null);
31
+ const intervalRef = useRef<NodeJS.Timeout | null>(null);
27
32
 
28
33
  const [liveTime, setLiveTime] = useState(0);
29
34
 
30
35
  const startTimer = useCallback(() => {
31
36
  intervalRef.current = setInterval(() => {
32
- if (hlsState?.running) {
33
- setLiveTime(Date.now() - hlsState?.variants[0]?.startedAt.getTime());
37
+ if (hlsState?.running && hlsState?.variants[0]?.startedAt) {
38
+ setLiveTime(Date.now() - hlsState.variants[0].startedAt.getTime());
34
39
  }
35
40
  }, 1000);
36
41
  }, [hlsState?.running, hlsState?.variants]);
@@ -90,6 +95,7 @@ export const RecordingStatus = () => {
90
95
 
91
96
  return (
92
97
  <Tooltip
98
+ boxCss={{ zIndex: 1 }}
93
99
  title={getRecordingText({
94
100
  isBrowserRecordingOn,
95
101
  isServerRecordingOn,
@@ -130,7 +136,7 @@ const StartRecording = () => {
130
136
  </Popover.Trigger>
131
137
  <Popover.Portal>
132
138
  <Popover.Content align="end" sideOffset={8} css={{ w: '$64' }}>
133
- <Text variant="body" css={{ color: '$on_surface_medium' }}>
139
+ <Text variant="body1" css={{ color: '$on_surface_medium' }}>
134
140
  Are you sure you want to end the recording?
135
141
  </Text>
136
142
  <Button
@@ -142,8 +148,9 @@ const StartRecording = () => {
142
148
  try {
143
149
  await hmsActions.stopRTMPAndRecording();
144
150
  } catch (error) {
151
+ const err = error as Error;
145
152
  ToastManager.addToast({
146
- title: error.message,
153
+ title: err.message,
147
154
  variant: 'error',
148
155
  });
149
156
  }
@@ -170,14 +177,15 @@ const StartRecording = () => {
170
177
  record: true,
171
178
  });
172
179
  } catch (error) {
173
- if (error.message.includes('stream already running')) {
180
+ const err = error as Error;
181
+ if (err.message.includes('stream already running')) {
174
182
  ToastManager.addToast({
175
183
  title: 'Recording already running',
176
184
  variant: 'error',
177
185
  });
178
186
  } else {
179
187
  ToastManager.addToast({
180
- title: error.message,
188
+ title: err.message,
181
189
  variant: 'error',
182
190
  });
183
191
  }
@@ -215,7 +223,13 @@ export const StreamActions = () => {
215
223
  );
216
224
  };
217
225
 
218
- export const StopRecordingInSheet = ({ onStopRecording, onClose }) => {
226
+ export const StopRecordingInSheet = ({
227
+ onStopRecording,
228
+ onClose,
229
+ }: {
230
+ onStopRecording: () => void;
231
+ onClose: () => void;
232
+ }) => {
219
233
  return (
220
234
  <Sheet.Root open={true}>
221
235
  <Sheet.Content>
@@ -25,11 +25,13 @@ export const CamaraFlipActions = () => {
25
25
 
26
26
  const videoTrackId = useHMSStore(selectLocalVideoTrackID);
27
27
  const localVideoTrack = useHMSStore(selectVideoTrackByID(videoTrackId));
28
-
28
+ if (!videoInput || !videoInput?.length || !localVideoTrack?.facingMode) {
29
+ return null;
30
+ }
29
31
  return (
30
32
  <Box>
31
33
  <IconButton
32
- disabled={!videoInput?.length || !isVideoOn || !localVideoTrack?.facingMode}
34
+ disabled={!isVideoOn}
33
35
  onClick={async () => {
34
36
  try {
35
37
  await actions.switchCamera();
@@ -117,6 +119,7 @@ const AudioOutputSelectionSheet = ({ outputDevices, outputSelected, onChange, ch
117
119
  {outputDevices.map(audioDevice => {
118
120
  return (
119
121
  <SelectWithLabel
122
+ key={audioDevice.deviceId}
120
123
  label={audioDevice.label}
121
124
  id={audioDevice.deviceId}
122
125
  checked={audioDevice.deviceId === outputSelected}
@@ -14,6 +14,10 @@ const IconSection = styled(IconButton, {
14
14
  borderTopRightRadius: 0,
15
15
  borderColor: '$border_default',
16
16
  borderBottomRightRadius: 0,
17
+ position: 'relative',
18
+ '&:not([disabled]):focus-visible': {
19
+ zIndex: 1,
20
+ },
17
21
  '@md': {
18
22
  mx: 0,
19
23
  borderTopRightRadius: '$1',
@@ -30,8 +34,9 @@ const OptionsSection = styled(IconButton, {
30
34
  borderColor: '$border_default',
31
35
  borderBottomLeftRadius: 0,
32
36
  borderLeftWidth: 0,
37
+ position: 'relative',
33
38
  '&:not([disabled]):focus-visible': {
34
- boxShadow: 'none',
39
+ zIndex: 1,
35
40
  },
36
41
  '@md': {
37
42
  display: 'none',
@@ -14,6 +14,7 @@ import { AudioVideoToggle } from './AudioVideoToggle';
14
14
  import VideoTile from './VideoTile';
15
15
  // @ts-ignore: No implicit Any
16
16
  import { useSetAppDataByKey } from './AppData/useUISettings';
17
+ import { useVideoTileContext } from './hooks/useVideoTileLayout';
17
18
  // @ts-ignore: No implicit Any
18
19
  import { APP_DATA } from '../common/constants';
19
20
 
@@ -22,7 +23,11 @@ const MinimisedTile = ({ setMinimised }: { setMinimised: (value: boolean) => voi
22
23
  <Flex align="center" css={{ gap: '$6', r: '$1', bg: '$surface_default', p: '$4', color: '$on_surface_high' }}>
23
24
  <AudioVideoToggle hideOptions={true} />
24
25
  <Text>You</Text>
25
- <IconButton onClick={() => setMinimised(false)} css={{ bg: 'transparent', border: 'transparent' }}>
26
+ <IconButton
27
+ className="__cancel-drag-event"
28
+ onClick={() => setMinimised(false)}
29
+ css={{ bg: 'transparent', border: 'transparent' }}
30
+ >
26
31
  <ExpandIcon />
27
32
  </IconButton>
28
33
  </Flex>
@@ -41,12 +46,11 @@ export const InsetTile = () => {
41
46
  const [minimised, setMinimised] = useSetAppDataByKey(APP_DATA.minimiseInset);
42
47
  const videoTrack = useHMSStore(selectVideoTrackByID(localPeer?.videoTrack));
43
48
  const isAllowedToPublish = useHMSStore(selectIsAllowedToPublish);
44
- const aspectRatio =
45
- videoTrack?.width && videoTrack?.height
46
- ? videoTrack.width / videoTrack.height
47
- : isMobile
48
- ? defaultMobileAspectRatio
49
- : desktopAspectRatio;
49
+ const videoTileProps = useVideoTileContext();
50
+ let aspectRatio = isMobile ? defaultMobileAspectRatio : desktopAspectRatio;
51
+ if (videoTrack?.width && videoTrack?.height && !isMobile) {
52
+ aspectRatio = videoTrack.width / videoTrack.height;
53
+ }
50
54
  let height = insetHeightPx;
51
55
  let width = height * aspectRatio;
52
56
  // Convert to 16/9 in landscape mode with a max width of 240
@@ -82,7 +86,7 @@ export const InsetTile = () => {
82
86
  }
83
87
 
84
88
  return (
85
- <Draggable bounds="parent" nodeRef={nodeRef}>
89
+ <Draggable bounds="parent" nodeRef={nodeRef} cancel=".__cancel-drag-event">
86
90
  <Box
87
91
  ref={nodeRef}
88
92
  css={{
@@ -114,6 +118,9 @@ export const InsetTile = () => {
114
118
  height={height}
115
119
  containerCSS={{ background: '$surface_default' }}
116
120
  canMinimise
121
+ isDragabble
122
+ {...videoTileProps}
123
+ hideParticipantNameOnTile
117
124
  />
118
125
  )}
119
126
  </Box>
@@ -15,11 +15,9 @@ import { useDropdownList } from '../hooks/useDropdownList';
15
15
 
16
16
  export const DesktopLeaveRoom = ({
17
17
  leaveRoom,
18
- stopStream,
19
18
  screenType,
20
19
  }: {
21
- leaveRoom: () => void;
22
- stopStream: () => Promise<void>;
20
+ leaveRoom: (args: { endstream: boolean }) => void;
23
21
  screenType: keyof ConferencingScreen;
24
22
  }) => {
25
23
  const [open, setOpen] = useState(false);
@@ -51,7 +49,7 @@ export const DesktopLeaveRoom = ({
51
49
  if (screenType === 'hls_live_streaming') {
52
50
  setShowLeaveRoomAlert(true);
53
51
  } else {
54
- leaveRoom();
52
+ leaveRoom({ endstream: false });
55
53
  }
56
54
  }}
57
55
  >
@@ -75,7 +73,15 @@ export const DesktopLeaveRoom = ({
75
73
  </MenuTriggerButton>
76
74
  </Dropdown.Trigger>
77
75
  <Dropdown.Content css={{ p: 0, w: '$100' }} alignOffset={-50} sideOffset={10}>
78
- <Dropdown.Item css={{ bg: '$surface_default' }} onClick={leaveRoom} data-testid="just_leave_btn">
76
+ <Dropdown.Item
77
+ css={{
78
+ bg: '$surface_dim',
79
+ color: '$on_surface_low',
80
+ '&:hover': { bg: '$surface_default', color: '$on_surface_high' },
81
+ }}
82
+ onClick={() => leaveRoom({ endstream: false })}
83
+ data-testid="just_leave_btn"
84
+ >
79
85
  <LeaveCard
80
86
  title={showStream ? 'Leave Stream' : 'Leave Session'}
81
87
  subtitle={`Others will continue after you leave. You can join the ${
@@ -83,14 +89,20 @@ export const DesktopLeaveRoom = ({
83
89
  } again.`}
84
90
  bg=""
85
91
  titleColor="$on_surface_high"
86
- subtitleColor="$on_surface_low"
87
92
  icon={<ExitIcon height={24} width={24} style={{ transform: 'rotate(180deg)' }} />}
88
- onClick={leaveRoom}
93
+ onClick={() => leaveRoom({ endstream: false })}
89
94
  css={{ p: 0 }}
90
95
  />
91
96
  </Dropdown.Item>
92
97
  {isStreamingOn && permissions?.hlsStreaming ? (
93
- <Dropdown.Item css={{ bg: '$alert_error_dim' }} data-testid="end_room_btn">
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
+ }}
104
+ data-testid="end_room_btn"
105
+ >
94
106
  <LeaveCard
95
107
  title={showStream ? 'End Stream' : 'End Session'}
96
108
  subtitle={`The ${
@@ -98,7 +110,6 @@ export const DesktopLeaveRoom = ({
98
110
  } will end for everyone. You can't undo this action.`}
99
111
  bg=""
100
112
  titleColor="$alert_error_brighter"
101
- subtitleColor="$alert_error_bright"
102
113
  icon={<StopIcon height={24} width={24} />}
103
114
  onClick={() => {
104
115
  setOpen(false);
@@ -117,7 +128,7 @@ export const DesktopLeaveRoom = ({
117
128
  if (screenType === 'hls_live_streaming') {
118
129
  setShowLeaveRoomAlert(true);
119
130
  } else {
120
- leaveRoom();
131
+ leaveRoom({ endstream: false });
121
132
  }
122
133
  }}
123
134
  key="LeaveRoom"
@@ -137,7 +148,6 @@ export const DesktopLeaveRoom = ({
137
148
  <Dialog.Content css={{ w: 'min(420px, 90%)', p: '$8', bg: '$surface_dim' }}>
138
149
  <EndSessionContent
139
150
  setShowEndStreamAlert={setShowEndStreamAlert}
140
- stopStream={stopStream}
141
151
  leaveRoom={leaveRoom}
142
152
  isStreamingOn={isStreamingOn}
143
153
  isModal