@100mslive/roomkit-react 0.1.4 → 0.1.6-alpha.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (197) hide show
  1. package/dist/{HLSView-CTAJQUU4.js → HLSView-PY2FKWX3.js} +191 -123
  2. package/dist/HLSView-PY2FKWX3.js.map +7 -0
  3. package/dist/Prebuilt/App.d.ts +3 -0
  4. package/dist/Prebuilt/AppContext.d.ts +13 -0
  5. package/dist/Prebuilt/common/PeersSorter.d.ts +21 -0
  6. package/dist/Prebuilt/components/Footer/Footer.d.ts +6 -0
  7. package/dist/Prebuilt/components/Header/Header.d.ts +2 -0
  8. package/dist/Prebuilt/components/InsetTile.d.ts +2 -0
  9. package/dist/Prebuilt/components/Leave/DesktopLeaveRoom.d.ts +7 -0
  10. package/dist/Prebuilt/components/Leave/EndSessionContent.d.ts +8 -0
  11. package/dist/Prebuilt/components/Leave/LeaveAtoms.d.ts +2196 -0
  12. package/dist/Prebuilt/components/Leave/LeaveCard.d.ts +12 -0
  13. package/dist/Prebuilt/components/Leave/LeaveRoom.d.ts +5 -0
  14. package/dist/Prebuilt/components/Leave/LeaveSessionContent.d.ts +6 -0
  15. package/dist/Prebuilt/components/Leave/MwebLeaveRoom.d.ts +7 -0
  16. package/dist/Prebuilt/components/MoreSettings/MoreSettings.d.ts +6 -0
  17. package/dist/Prebuilt/components/MoreSettings/SplitComponents/DesktopOptions.d.ts +6 -0
  18. package/dist/Prebuilt/components/Pagination.d.ts +6 -0
  19. package/dist/Prebuilt/components/Preview/PreviewForm.d.ts +10 -0
  20. package/dist/Prebuilt/components/SecondaryTiles.d.ts +3 -0
  21. package/dist/Prebuilt/components/VideoLayouts/EqualProminence.d.ts +3 -0
  22. package/dist/Prebuilt/components/VideoLayouts/Grid.d.ts +5 -0
  23. package/dist/Prebuilt/components/VideoLayouts/GridLayout.d.ts +10 -0
  24. package/dist/Prebuilt/components/VideoLayouts/ProminenceLayout.d.ts +12 -0
  25. package/dist/Prebuilt/components/VideoLayouts/RoleProminence.d.ts +3 -0
  26. package/dist/Prebuilt/components/VideoLayouts/ScreenshareLayout.d.ts +3 -0
  27. package/dist/Prebuilt/components/VideoLayouts/interface.d.ts +8 -0
  28. package/dist/Prebuilt/components/hooks/useRoleProminencePeers.d.ts +5 -0
  29. package/dist/Prebuilt/components/hooks/useTileLayout.d.ts +12 -0
  30. package/dist/Prebuilt/components/hooks/useVideoTileLayout.d.ts +11 -0
  31. package/dist/Prebuilt/layouts/SidePane.d.ts +6 -0
  32. package/dist/Prebuilt/layouts/VideoStreamingSection.d.ts +6 -0
  33. package/dist/Prebuilt/plugins/whiteboard/ToggleWhiteboard.d.ts +5 -0
  34. package/dist/Prebuilt/provider/roomLayoutProvider/hooks/useFetchRoomLayout.d.ts +1 -0
  35. package/dist/Prebuilt/provider/roomLayoutProvider/hooks/useInsetEnabled.d.ts +1 -0
  36. package/dist/Prebuilt/provider/roomLayoutProvider/hooks/useRoomLayoutScreen.d.ts +17 -0
  37. package/dist/Prebuilt/provider/roomLayoutProvider/index.d.ts +6 -1
  38. package/dist/{VirtualBackground-GGGBJYVY.js → VirtualBackground-AYDHYLIZ.js} +5 -11
  39. package/dist/VirtualBackground-AYDHYLIZ.js.map +7 -0
  40. package/dist/{chunk-TJNDX446.js → chunk-E2M2ZSOL.js} +8 -5
  41. package/dist/chunk-E2M2ZSOL.js.map +7 -0
  42. package/dist/chunk-GQD2AGWW.js +888 -0
  43. package/dist/chunk-GQD2AGWW.js.map +7 -0
  44. package/dist/{chunk-L2SX7GBO.js → chunk-RXTHJUMZ.js} +2462 -4738
  45. package/dist/chunk-RXTHJUMZ.js.map +7 -0
  46. package/dist/conference-V2XZGTKU.js +5927 -0
  47. package/dist/conference-V2XZGTKU.js.map +7 -0
  48. package/dist/index.cjs.js +9414 -15534
  49. package/dist/index.cjs.js.map +4 -4
  50. package/dist/index.js +2 -2
  51. package/dist/meta.cjs.json +2156 -3347
  52. package/dist/meta.esbuild.json +2601 -3885
  53. package/package.json +7 -7
  54. package/src/Button/Button.tsx +2 -2
  55. package/src/Prebuilt/App.tsx +49 -33
  56. package/src/Prebuilt/{AppContext.jsx → AppContext.tsx} +11 -3
  57. package/src/Prebuilt/IconButton.jsx +1 -0
  58. package/src/Prebuilt/Prebuilt.stories.tsx +1 -0
  59. package/src/Prebuilt/common/{PeersSorter.js → PeersSorter.ts} +15 -10
  60. package/src/Prebuilt/common/constants.js +3 -112
  61. package/src/Prebuilt/common/hooks.js +34 -1
  62. package/src/Prebuilt/common/utils.js +0 -8
  63. package/src/Prebuilt/components/AppData/AppData.jsx +3 -13
  64. package/src/Prebuilt/components/AppData/useUISettings.js +0 -4
  65. package/src/Prebuilt/components/AudioVideoToggle.jsx +6 -0
  66. package/src/Prebuilt/components/AuthToken.jsx +11 -42
  67. package/src/Prebuilt/components/Chat/Chat.jsx +57 -26
  68. package/src/Prebuilt/components/Chat/ChatBody.jsx +92 -32
  69. package/src/Prebuilt/components/Chat/ChatFooter.jsx +72 -48
  70. package/src/Prebuilt/components/Chat/ChatParticipantHeader.jsx +73 -0
  71. package/src/Prebuilt/components/Chat/ChatSelector.jsx +16 -17
  72. package/src/Prebuilt/components/Chat/ChatSelectorContainer.jsx +81 -0
  73. package/src/Prebuilt/components/Connection/TileConnection.jsx +30 -12
  74. package/src/Prebuilt/components/EmojiReaction.jsx +18 -17
  75. package/src/Prebuilt/components/Footer/ChatToggle.jsx +1 -7
  76. package/src/Prebuilt/components/Footer/Footer.tsx +89 -0
  77. package/src/Prebuilt/components/Footer/ParticipantList.jsx +213 -173
  78. package/src/Prebuilt/components/Footer/RoleAccordion.jsx +78 -0
  79. package/src/Prebuilt/components/HMSVideo/Controls.jsx +2 -2
  80. package/src/Prebuilt/components/HMSVideo/HLSQualitySelector.jsx +33 -10
  81. package/src/Prebuilt/components/HMSVideo/PlayButton.jsx +1 -1
  82. package/src/Prebuilt/components/HMSVideo/VideoTime.jsx +3 -3
  83. package/src/Prebuilt/components/HMSVideo/VolumeControl.jsx +38 -9
  84. package/src/Prebuilt/components/Header/{ConferencingHeader.jsx → Header.tsx} +9 -7
  85. package/src/Prebuilt/components/Header/HeaderComponents.jsx +13 -4
  86. package/src/Prebuilt/components/Header/StreamActions.jsx +33 -60
  87. package/src/Prebuilt/components/Header/index.tsx +1 -0
  88. package/src/Prebuilt/components/IconButtonWithOptions/IconButtonWithOptions.jsx +17 -3
  89. package/src/Prebuilt/components/InsetTile.tsx +122 -0
  90. package/src/Prebuilt/components/{MoreSettings/SplitComponents/DesktopLeaveRoom.jsx → Leave/DesktopLeaveRoom.tsx} +50 -18
  91. package/src/Prebuilt/components/{EndSessionContent.jsx → Leave/EndSessionContent.tsx} +19 -9
  92. package/src/Prebuilt/components/Leave/LeaveAtoms.tsx +26 -0
  93. package/src/Prebuilt/components/{LeaveCard.jsx → Leave/LeaveCard.tsx} +22 -3
  94. package/src/Prebuilt/components/Leave/LeaveRoom.tsx +63 -0
  95. package/src/Prebuilt/components/{LeaveSessionContent.jsx → Leave/LeaveSessionContent.tsx} +13 -5
  96. package/src/Prebuilt/components/{MoreSettings/SplitComponents/MwebLeaveRoom.jsx → Leave/MwebLeaveRoom.tsx} +38 -13
  97. package/src/Prebuilt/components/MetaActions.jsx +15 -23
  98. package/src/Prebuilt/components/MoreSettings/ActionTile.jsx +5 -0
  99. package/src/Prebuilt/components/MoreSettings/ChangeNameContent.jsx +12 -7
  100. package/src/Prebuilt/components/MoreSettings/ChangeNameModal.jsx +1 -1
  101. package/src/Prebuilt/components/MoreSettings/FullScreenItem.jsx +1 -4
  102. package/src/Prebuilt/components/MoreSettings/MoreSettings.tsx +27 -0
  103. package/src/Prebuilt/components/MoreSettings/SplitComponents/{DesktopOptions.jsx → DesktopOptions.tsx} +86 -75
  104. package/src/Prebuilt/components/MoreSettings/SplitComponents/MwebOptions.jsx +20 -19
  105. package/src/Prebuilt/components/Notifications/HLSFailureModal.jsx +3 -1
  106. package/src/Prebuilt/components/Notifications/Notifications.jsx +18 -11
  107. package/src/Prebuilt/components/Notifications/PeerNotifications.jsx +14 -2
  108. package/src/Prebuilt/components/Notifications/PermissionErrorModal.jsx +10 -4
  109. package/src/Prebuilt/components/PIP/PIPComponent.jsx +7 -16
  110. package/src/Prebuilt/components/PIP/PIPManager.js +1 -0
  111. package/src/Prebuilt/components/{Pagination.jsx → Pagination.tsx} +35 -6
  112. package/src/Prebuilt/components/Playlist/Playlist.jsx +1 -6
  113. package/src/Prebuilt/components/PostLeave.jsx +7 -7
  114. package/src/Prebuilt/components/Preview/PreviewContainer.jsx +5 -13
  115. package/src/Prebuilt/components/Preview/{PreviewForm.jsx → PreviewForm.tsx} +14 -4
  116. package/src/Prebuilt/components/Preview/PreviewJoin.jsx +9 -7
  117. package/src/Prebuilt/components/RaiseHand.jsx +0 -7
  118. package/src/Prebuilt/components/RoleChangeRequestModal.jsx +82 -6
  119. package/src/Prebuilt/components/ScreenshareDisplay.jsx +4 -10
  120. package/src/Prebuilt/components/ScreenshareTile.jsx +41 -33
  121. package/src/Prebuilt/components/SecondaryTiles.tsx +34 -0
  122. package/src/Prebuilt/components/Settings/LayoutSettings.jsx +2 -12
  123. package/src/Prebuilt/components/Settings/NotificationSettings.jsx +3 -9
  124. package/src/Prebuilt/components/Settings/SettingsModal.jsx +3 -9
  125. package/src/Prebuilt/components/StatsForNerds.jsx +3 -1
  126. package/src/Prebuilt/components/TileMenu/TileMenu.jsx +15 -16
  127. package/src/Prebuilt/components/TileMenu/TileMenuContent.jsx +21 -19
  128. package/src/Prebuilt/components/Toast/ToastConfig.jsx +53 -11
  129. package/src/Prebuilt/components/VideoLayouts/EqualProminence.tsx +62 -0
  130. package/src/Prebuilt/components/VideoLayouts/Grid.tsx +41 -0
  131. package/src/Prebuilt/components/VideoLayouts/GridLayout.tsx +92 -0
  132. package/src/Prebuilt/components/VideoLayouts/ProminenceLayout.tsx +60 -0
  133. package/src/Prebuilt/components/VideoLayouts/RoleProminence.tsx +56 -0
  134. package/src/Prebuilt/components/VideoLayouts/ScreenshareLayout.tsx +36 -0
  135. package/src/Prebuilt/components/VideoLayouts/interface.ts +9 -0
  136. package/src/Prebuilt/components/VideoTile.jsx +93 -43
  137. package/src/Prebuilt/components/conference.jsx +24 -20
  138. package/src/Prebuilt/components/hooks/useMetadata.jsx +7 -0
  139. package/src/Prebuilt/components/hooks/useRoleProminencePeers.tsx +38 -0
  140. package/src/Prebuilt/components/hooks/useTileLayout.tsx +121 -0
  141. package/src/Prebuilt/components/hooks/useVideoTileLayout.ts +22 -0
  142. package/src/Prebuilt/components/pdfAnnotator/pdfFileOptions.jsx +5 -72
  143. package/src/Prebuilt/components/pdfAnnotator/submitPdf.jsx +4 -45
  144. package/src/Prebuilt/components/pdfAnnotator/uploadedFile.jsx +2 -17
  145. package/src/Prebuilt/components/peerTileUtils.jsx +1 -1
  146. package/src/Prebuilt/images/empty-chat.svg +12 -0
  147. package/src/Prebuilt/layouts/EmbedView.jsx +17 -40
  148. package/src/Prebuilt/layouts/HLSView.jsx +83 -66
  149. package/src/Prebuilt/layouts/PDFView.jsx +1 -11
  150. package/src/Prebuilt/layouts/SidePane.tsx +96 -0
  151. package/src/Prebuilt/layouts/{mainView.jsx → VideoStreamingSection.tsx} +38 -47
  152. package/src/Prebuilt/layouts/WhiteboardView.jsx +10 -34
  153. package/src/Prebuilt/plugins/VirtualBackground/VirtualBackground.jsx +1 -4
  154. package/src/Prebuilt/plugins/whiteboard/{ToggleWhiteboard.jsx → ToggleWhiteboard.tsx} +5 -9
  155. package/src/Prebuilt/primitives/DialogContent.jsx +15 -11
  156. package/src/Prebuilt/provider/roomLayoutProvider/constants/index.ts +17 -2
  157. package/src/Prebuilt/provider/roomLayoutProvider/hooks/useFetchRoomLayout.ts +36 -13
  158. package/src/Prebuilt/provider/roomLayoutProvider/hooks/useInsetEnabled.ts +10 -0
  159. package/src/Prebuilt/provider/roomLayoutProvider/hooks/useRoomLayoutScreen.ts +65 -0
  160. package/src/Prebuilt/provider/roomLayoutProvider/index.tsx +17 -6
  161. package/dist/HLSView-CTAJQUU4.js.map +0 -7
  162. package/dist/PinnedTrackView-CQKONH4O.js +0 -102
  163. package/dist/PinnedTrackView-CQKONH4O.js.map +0 -7
  164. package/dist/VirtualBackground-GGGBJYVY.js.map +0 -7
  165. package/dist/chunk-I2FJWE74.js +0 -827
  166. package/dist/chunk-I2FJWE74.js.map +0 -7
  167. package/dist/chunk-L2SX7GBO.js.map +0 -7
  168. package/dist/chunk-NOKIGB6Y.js +0 -1100
  169. package/dist/chunk-NOKIGB6Y.js.map +0 -7
  170. package/dist/chunk-TJNDX446.js.map +0 -7
  171. package/dist/conference-OEO7VOJD.js +0 -8995
  172. package/dist/conference-OEO7VOJD.js.map +0 -7
  173. package/src/Prebuilt/components/Chat/ChatHeader.jsx +0 -67
  174. package/src/Prebuilt/components/EqualProminence.jsx +0 -180
  175. package/src/Prebuilt/components/FirstPersonDisplay.jsx +0 -50
  176. package/src/Prebuilt/components/Footer/Footer.jsx +0 -73
  177. package/src/Prebuilt/components/Header/Header.jsx +0 -8
  178. package/src/Prebuilt/components/Header/StreamingHeader.jsx +0 -54
  179. package/src/Prebuilt/components/LeaveRoom.jsx +0 -94
  180. package/src/Prebuilt/components/MoreSettings/MoreSettings.jsx +0 -10
  181. package/src/Prebuilt/components/Notifications/MessageNotifications.jsx +0 -25
  182. package/src/Prebuilt/components/gridView.jsx +0 -85
  183. package/src/Prebuilt/components/hooks/useFeatures.js +0 -22
  184. package/src/Prebuilt/components/hooks/useNavigation.js +0 -19
  185. package/src/Prebuilt/components/hooks/useSkipPreview.jsx +0 -20
  186. package/src/Prebuilt/components/pdfAnnotator/pdfErrorView.jsx +0 -29
  187. package/src/Prebuilt/images/Logo.svg +0 -8
  188. package/src/Prebuilt/layouts/ActiveSpeakerView.jsx +0 -34
  189. package/src/Prebuilt/layouts/InsetView.jsx +0 -260
  190. package/src/Prebuilt/layouts/PinnedTrackView.jsx +0 -59
  191. package/src/Prebuilt/layouts/SidePane.jsx +0 -52
  192. package/src/Prebuilt/layouts/mainGridView.jsx +0 -98
  193. package/src/Prebuilt/layouts/screenShareView.jsx +0 -183
  194. /package/{src/Prebuilt/components/Header/index.jsx → dist/Prebuilt/components/Header/index.d.ts} +0 -0
  195. /package/src/Prebuilt/components/{ScreenShare.jsx → ScreenShareToggle.jsx} +0 -0
  196. /package/src/{assets → Prebuilt/images}/android-perm-1.png +0 -0
  197. /package/src/{assets → Prebuilt/images}/ios-perm-0.png +0 -0
@@ -6,7 +6,7 @@ export const PlayButton = ({ onClick, isPaused }) => {
6
6
  return (
7
7
  <Tooltip title={isPaused ? 'Play' : 'Pause'} side="top">
8
8
  <IconButton onClick={onClick} data-testid="play_pause_btn">
9
- {isPaused ? <PlayIcon width={32} height={32} /> : <PauseIcon width={32} height={32} />}
9
+ {isPaused ? <PlayIcon width={20} height={20} /> : <PauseIcon width={20} height={20} />}
10
10
  </IconButton>
11
11
  </Tooltip>
12
12
  );
@@ -22,9 +22,9 @@ export const VideoTime = ({ hlsPlayer }) => {
22
22
  <Text
23
23
  css={{
24
24
  minWidth: '$16',
25
- }}
26
- variant={{
27
- '@sm': 'xs',
25
+ c: '$on_surface_medium',
26
+ display: 'flex',
27
+ justifyContent: 'center',
28
28
  }}
29
29
  >
30
30
  {videoTime}
@@ -1,18 +1,33 @@
1
1
  import React, { useState } from 'react';
2
- import { SpeakerIcon } from '@100mslive/react-icons';
2
+ import { VolumeOneIcon, VolumeTwoIcon, VolumeZeroIcon } from '@100mslive/react-icons';
3
3
  import { Flex, Slider } from '../../../';
4
4
 
5
5
  export const VolumeControl = ({ hlsPlayer }) => {
6
6
  const [volume, setVolume] = useState(hlsPlayer?.volume ?? 100);
7
+ const [showSlider, setShowSlider] = useState(false);
7
8
 
8
9
  return (
9
- <Flex align="center" css={{ color: '$on_primary_high' }}>
10
- <SpeakerIcon
11
- style={{ cursor: 'pointer' }}
10
+ <Flex
11
+ align="center"
12
+ css={{ color: '$on_primary_high' }}
13
+ onMouseOver={event => {
14
+ event.stopPropagation();
15
+ setShowSlider(true);
16
+ }}
17
+ onMouseLeave={event => {
18
+ event.stopPropagation();
19
+ setShowSlider(false);
20
+ }}
21
+ >
22
+ <VolumeIcon
23
+ volume={volume}
12
24
  onClick={() => {
13
- setVolume(0);
14
- if (hlsPlayer) {
15
- hlsPlayer.setVolume(0);
25
+ if (volume > 0) {
26
+ setVolume(0);
27
+ hlsPlayer?.setVolume(0);
28
+ } else {
29
+ setVolume(100);
30
+ hlsPlayer?.setVolume(100);
16
31
  }
17
32
  }}
18
33
  />
@@ -23,17 +38,31 @@ export const VolumeControl = ({ hlsPlayer }) => {
23
38
  cursor: 'pointer',
24
39
  '@sm': { w: '$14' },
25
40
  '@xs': { w: '$14' },
41
+ opacity: showSlider ? '1' : '0',
42
+ display: showSlider ? '' : 'none',
43
+ transition: `all .2s ease .5s`,
26
44
  }}
27
45
  min={0}
28
46
  max={100}
29
47
  step={1}
30
48
  value={[volume]}
31
49
  onValueChange={volume => {
32
- hlsPlayer.setVolume(volume);
33
- setVolume(volume);
50
+ hlsPlayer.setVolume(volume[0]);
51
+ setVolume(volume[0]);
34
52
  }}
35
53
  thumbStyles={{ w: '$6', h: '$6' }}
36
54
  />
37
55
  </Flex>
38
56
  );
39
57
  };
58
+
59
+ const VolumeIcon = ({ volume, onClick }) => {
60
+ if (volume === 0) {
61
+ return <VolumeZeroIcon style={{ cursor: 'pointer', transition: 'color 0.3s' }} onClick={onClick} />;
62
+ }
63
+ return volume < 50 ? (
64
+ <VolumeOneIcon style={{ cursor: 'pointer', transition: 'color 0.3s' }} onClick={onClick} />
65
+ ) : (
66
+ <VolumeTwoIcon style={{ cursor: 'pointer', transition: 'color 0.3s' }} onClick={onClick} />
67
+ );
68
+ };
@@ -1,17 +1,19 @@
1
1
  import React from 'react';
2
2
  import { useMedia } from 'react-use';
3
3
  import { HMSRoomState, selectRoomState, useHMSStore } from '@100mslive/react-sdk';
4
- import { config as cssConfig, Flex } from '../../../';
4
+ import { config as cssConfig, Flex } from '../../..';
5
+ // @ts-ignore: No implicit any
5
6
  import { Logo, SpeakerTag } from './HeaderComponents';
7
+ // @ts-ignore: No implicit any
6
8
  import { LiveStatus, RecordingStatus, StreamActions } from './StreamActions';
9
+ // @ts-ignore: No implicit any
7
10
  import { AudioOutputActions, CamaraFlipActions } from './common';
8
11
 
9
- export const ConferencingHeader = () => {
12
+ export const Header = () => {
10
13
  const roomState = useHMSStore(selectRoomState);
11
14
  const isMobile = useMedia(cssConfig.media.md);
12
- const isPreview = roomState === HMSRoomState.Preview;
13
- // no header if there in preview
14
- if (isPreview) {
15
+ // Header should be present only inside the call - not in preview, leave room states
16
+ if (roomState !== HMSRoomState.Connected) {
15
17
  return <></>;
16
18
  }
17
19
  return (
@@ -35,12 +37,12 @@ export const ConferencingHeader = () => {
35
37
  }}
36
38
  >
37
39
  <StreamActions />
38
- {isMobile && (
40
+ {isMobile ? (
39
41
  <>
40
42
  <CamaraFlipActions />
41
43
  <AudioOutputActions />
42
44
  </>
43
- )}
45
+ ) : null}
44
46
  </Flex>
45
47
  </Flex>
46
48
  );
@@ -1,10 +1,9 @@
1
- import React from 'react';
1
+ import React, { 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';
5
5
  import { config as cssConfig, Flex, styled, Text, textEllipsis, VerticalDivider } from '../../../';
6
6
  import { useRoomLayout } from '../../provider/roomLayoutProvider';
7
- import { isStreamingKit } from '../../common/utils';
8
7
 
9
8
  export const SpeakerTag = () => {
10
9
  const dominantSpeaker = useHMSStore(selectDominantSpeaker);
@@ -40,9 +39,19 @@ export const Logo = () => {
40
39
  const logo = roomLayout?.logo?.url;
41
40
  const isMobile = useMedia(cssConfig.media.md);
42
41
  const isConnected = useHMSStore(selectIsConnectedToRoom);
42
+ const [hideImage, setHideImage] = useState(false);
43
43
  // Hide logo for now as there is not enough space
44
- if (isConnected && isMobile && isStreamingKit()) {
44
+ if (isConnected && isMobile) {
45
45
  return null;
46
46
  }
47
- return logo ? <LogoImg src={logo} alt="Brand Logo" /> : null;
47
+ return logo && !hideImage ? (
48
+ <LogoImg
49
+ src={logo}
50
+ alt="Brand Logo"
51
+ onError={e => {
52
+ e.target.onerror = null;
53
+ setHideImage(true);
54
+ }}
55
+ />
56
+ ) : null;
48
57
  };
@@ -13,13 +13,11 @@ import {
13
13
  import { AlertTriangleIcon, CrossIcon, RecordIcon } from '@100mslive/react-icons';
14
14
  import { Box, Button, config as cssConfig, Flex, HorizontalDivider, Loading, Popover, Text, Tooltip } from '../../../';
15
15
  import { Sheet } from '../../../Sheet';
16
- import { ResolutionInput } from '../Streaming/ResolutionInput';
17
- import { getResolution } from '../Streaming/RTMPStreaming';
18
16
  import { ToastManager } from '../Toast/ToastManager';
19
17
  import { AdditionalRoomState, getRecordingText } from './AdditionalRoomState';
20
18
  import { useSetAppDataByKey } from '../AppData/useUISettings';
21
19
  import { formatTime } from '../../common/utils';
22
- import { APP_DATA, RTMP_RECORD_DEFAULT_RESOLUTION } from '../../common/constants';
20
+ import { APP_DATA } from '../../common/constants';
23
21
 
24
22
  export const LiveStatus = () => {
25
23
  const { isHLSRunning, isRTMPRunning } = useRecordingStreaming();
@@ -112,7 +110,6 @@ export const RecordingStatus = () => {
112
110
 
113
111
  const StartRecording = () => {
114
112
  const permissions = useHMSStore(selectPermissions);
115
- const [resolution, setResolution] = useState(RTMP_RECORD_DEFAULT_RESOLUTION);
116
113
  const [open, setOpen] = useState(false);
117
114
  const [recordingStarted, setRecordingState] = useSetAppDataByKey(APP_DATA.recordingStarted);
118
115
  const { isBrowserRecordingOn, isStreamingOn, isHLSRunning } = useRecordingStreaming();
@@ -161,62 +158,38 @@ const StartRecording = () => {
161
158
  );
162
159
  }
163
160
  return (
164
- <Popover.Root open={open} onOpenChange={setOpen}>
165
- <Popover.Trigger asChild>
166
- <Button
167
- data-testid="start_recording"
168
- variant="standard"
169
- icon
170
- disabled={recordingStarted || isStreamingOn}
171
- onClick={() => setOpen(true)}
172
- >
173
- {recordingStarted ? <Loading size={24} color="currentColor" /> : <RecordIcon />}
174
- <Text as="span" css={{ '@md': { display: 'none' }, color: 'currentColor' }}>
175
- {recordingStarted ? 'Starting' : 'Start'} Recording
176
- </Text>
177
- </Button>
178
- </Popover.Trigger>
179
- <Popover.Content align="end" sideOffset={8} css={{ w: '$64' }}>
180
- <ResolutionInput
181
- testId="recording_resolution"
182
- css={{ flexDirection: 'column', alignItems: 'start' }}
183
- onResolutionChange={setResolution}
184
- />
185
- <Button
186
- data-testid="start_recording_confirm"
187
- variant="primary"
188
- icon
189
- css={{ ml: 'auto' }}
190
- type="submit"
191
- disabled={recordingStarted || isStreamingOn}
192
- onClick={async () => {
193
- try {
194
- setRecordingState(true);
195
- await hmsActions.startRTMPOrRecording({
196
- resolution: getResolution(resolution),
197
- record: true,
198
- });
199
- } catch (error) {
200
- if (error.message.includes('stream already running')) {
201
- ToastManager.addToast({
202
- title: 'Recording already running',
203
- variant: 'error',
204
- });
205
- } else {
206
- ToastManager.addToast({
207
- title: error.message,
208
- variant: 'error',
209
- });
210
- }
211
- setRecordingState(false);
212
- }
213
- setOpen(false);
214
- }}
215
- >
216
- Start
217
- </Button>
218
- </Popover.Content>
219
- </Popover.Root>
161
+ <Button
162
+ data-testid="start_recording"
163
+ variant="standard"
164
+ icon
165
+ disabled={recordingStarted || isStreamingOn}
166
+ onClick={async () => {
167
+ try {
168
+ setRecordingState(true);
169
+ await hmsActions.startRTMPOrRecording({
170
+ record: true,
171
+ });
172
+ } catch (error) {
173
+ if (error.message.includes('stream already running')) {
174
+ ToastManager.addToast({
175
+ title: 'Recording already running',
176
+ variant: 'error',
177
+ });
178
+ } else {
179
+ ToastManager.addToast({
180
+ title: error.message,
181
+ variant: 'error',
182
+ });
183
+ }
184
+ setRecordingState(false);
185
+ }
186
+ }}
187
+ >
188
+ {recordingStarted ? <Loading size={24} color="currentColor" /> : <RecordIcon />}
189
+ <Text as="span" css={{ '@md': { display: 'none' }, color: 'currentColor' }}>
190
+ {recordingStarted ? 'Starting' : 'Start'} Recording
191
+ </Text>
192
+ </Button>
220
193
  );
221
194
  };
222
195
 
@@ -0,0 +1 @@
1
+ export { Header } from './Header';
@@ -39,6 +39,10 @@ const OptionsSection = styled(IconButton, {
39
39
  });
40
40
 
41
41
  export const IconButtonWithOptions = ({
42
+ disabled = false,
43
+ onDisabledClick = () => {
44
+ return;
45
+ },
42
46
  tooltipMessage = '',
43
47
  icon,
44
48
  options = [],
@@ -47,8 +51,9 @@ export const IconButtonWithOptions = ({
47
51
  return;
48
52
  },
49
53
  }) => {
50
- const bgCss = { backgroundColor: active ? '$transparent' : '$secondary_dim' };
51
- const iconCss = { color: active ? '$on_surface_high' : '$on_primary_high' };
54
+ const bgCss = { backgroundColor: disabled ? '$surface_brighter' : active ? '$transparent' : '$secondary_dim' };
55
+ const iconCss = { color: disabled ? '$on_surface_low' : active ? '$on_surface_high' : '$on_primary_high' };
56
+
52
57
  return (
53
58
  <Flex>
54
59
  <IconSection css={bgCss} onClick={onClick}>
@@ -59,7 +64,16 @@ export const IconButtonWithOptions = ({
59
64
  </Tooltip>
60
65
  </IconSection>
61
66
  <Dropdown.Root>
62
- <Dropdown.Trigger asChild>
67
+ <Dropdown.Trigger
68
+ asChild
69
+ // onClick does not work
70
+ onPointerDown={e => {
71
+ if (disabled) {
72
+ e.preventDefault();
73
+ onDisabledClick();
74
+ }
75
+ }}
76
+ >
63
77
  <OptionsSection css={bgCss}>
64
78
  <Tooltip title="View Options">
65
79
  <Box css={iconCss}>
@@ -0,0 +1,122 @@
1
+ import React, { useEffect, useRef } from 'react';
2
+ import Draggable from 'react-draggable';
3
+ import { useMedia } from 'react-use';
4
+ import { selectIsAllowedToPublish, selectLocalPeer, selectVideoTrackByID, useHMSStore } from '@100mslive/react-sdk';
5
+ import { ExpandIcon } from '@100mslive/react-icons';
6
+ import { Box, Flex } from '../../Layout';
7
+ import { Text } from '../../Text';
8
+ import { config as cssConfig } from '../../Theme';
9
+ // @ts-ignore: No implicit Any
10
+ import IconButton from '../IconButton';
11
+ // @ts-ignore: No implicit Any
12
+ import { AudioVideoToggle } from './AudioVideoToggle';
13
+ // @ts-ignore: No implicit Any
14
+ import VideoTile from './VideoTile';
15
+ // @ts-ignore: No implicit Any
16
+ import { useSetAppDataByKey } from './AppData/useUISettings';
17
+ // @ts-ignore: No implicit Any
18
+ import { APP_DATA } from '../common/constants';
19
+
20
+ const MinimisedTile = ({ setMinimised }: { setMinimised: (value: boolean) => void }) => {
21
+ return (
22
+ <Flex align="center" css={{ gap: '$6', r: '$1', bg: '$surface_default', p: '$4', color: '$on_surface_high' }}>
23
+ <AudioVideoToggle hideOptions={true} />
24
+ <Text>You</Text>
25
+ <IconButton onClick={() => setMinimised(false)} css={{ bg: 'transparent', border: 'transparent' }}>
26
+ <ExpandIcon />
27
+ </IconButton>
28
+ </Flex>
29
+ );
30
+ };
31
+
32
+ const insetHeightPx = 180;
33
+ const insetMaxWidthPx = 240;
34
+ const defaultMobileAspectRatio = 9 / 16;
35
+ const desktopAspectRatio = 1 / defaultMobileAspectRatio;
36
+
37
+ export const InsetTile = () => {
38
+ const isMobile = useMedia(cssConfig.media.md);
39
+ const isLandscape = useMedia(cssConfig.media.ls);
40
+ const localPeer = useHMSStore(selectLocalPeer);
41
+ const [minimised, setMinimised] = useSetAppDataByKey(APP_DATA.minimiseInset);
42
+ const videoTrack = useHMSStore(selectVideoTrackByID(localPeer?.videoTrack));
43
+ const isAllowedToPublish = useHMSStore(selectIsAllowedToPublish);
44
+ const aspectRatio =
45
+ videoTrack?.width && videoTrack?.height
46
+ ? videoTrack.width / videoTrack.height
47
+ : isMobile
48
+ ? defaultMobileAspectRatio
49
+ : desktopAspectRatio;
50
+ let height = insetHeightPx;
51
+ let width = height * aspectRatio;
52
+ // Convert to 16/9 in landscape mode with a max width of 240
53
+ if (isLandscape && width > insetMaxWidthPx) {
54
+ width = 240;
55
+ height = width / aspectRatio;
56
+ }
57
+
58
+ const nodeRef = useRef<HTMLDivElement>(null);
59
+
60
+ useEffect(() => {
61
+ const node = nodeRef.current;
62
+ if (!node || !window.ResizeObserver) {
63
+ return;
64
+ }
65
+ const resizeObserver = new ResizeObserver(entries => {
66
+ entries.forEach(entry => {
67
+ if (entry.target === node.parentElement) {
68
+ // reset to original position on resize
69
+ node.style.transform = `translate(0,0)`;
70
+ }
71
+ });
72
+ });
73
+ node.parentElement && resizeObserver.observe(node.parentElement);
74
+ return () => {
75
+ node?.parentElement && resizeObserver?.unobserve(node.parentElement);
76
+ resizeObserver?.disconnect();
77
+ };
78
+ }, []);
79
+
80
+ if (!isAllowedToPublish.video && !isAllowedToPublish.audio) {
81
+ return null;
82
+ }
83
+
84
+ return (
85
+ <Draggable bounds="parent" nodeRef={nodeRef}>
86
+ <Box
87
+ ref={nodeRef}
88
+ css={{
89
+ position: 'absolute',
90
+ bottom: 0,
91
+ right: 0,
92
+ zIndex: 11,
93
+ boxShadow: '0 0 8px 0 rgba(0,0,0,0.3)',
94
+ r: '$2',
95
+ ...(!minimised
96
+ ? {
97
+ aspectRatio: aspectRatio,
98
+ h: height,
99
+ }
100
+ : {}),
101
+ }}
102
+ >
103
+ {minimised ? (
104
+ <MinimisedTile setMinimised={setMinimised} />
105
+ ) : (
106
+ <VideoTile
107
+ peerId={localPeer?.id}
108
+ trackid={localPeer?.videoTrack}
109
+ rootCSS={{
110
+ size: '100%',
111
+ padding: 0,
112
+ }}
113
+ width={width}
114
+ height={height}
115
+ containerCSS={{ background: '$surface_default' }}
116
+ canMinimise
117
+ />
118
+ )}
119
+ </Box>
120
+ </Draggable>
121
+ );
122
+ };
@@ -1,31 +1,36 @@
1
1
  import React, { Fragment, useState } from 'react';
2
+ import { ConferencingScreen } from '@100mslive/types-prebuilt';
2
3
  import { selectIsConnectedToRoom, selectPermissions, useHMSStore, useRecordingStreaming } from '@100mslive/react-sdk';
3
4
  import { ExitIcon, StopIcon, VerticalMenuIcon } from '@100mslive/react-icons';
4
- import { Dropdown } from '../../../../Dropdown';
5
- import { Box, Flex } from '../../../../Layout';
6
- import { Dialog } from '../../../../Modal';
7
- import { Tooltip } from '../../../../Tooltip';
8
- import { EndSessionContent } from '../../EndSessionContent';
9
- import { LeaveCard } from '../../LeaveCard';
10
- import { useDropdownList } from '../../hooks/useDropdownList';
11
- import { useShowStreamingUI } from '../../../common/hooks';
5
+ import { Dropdown } from '../../../Dropdown';
6
+ import { Box, Flex } from '../../../Layout';
7
+ import { Dialog } from '../../../Modal';
8
+ import { Tooltip } from '../../../Tooltip';
9
+ import { EndSessionContent } from './EndSessionContent';
10
+ import { LeaveIconButton, MenuTriggerButton } from './LeaveAtoms';
11
+ import { LeaveCard } from './LeaveCard';
12
+ import { LeaveSessionContent } from './LeaveSessionContent';
13
+ // @ts-ignore: No implicit Any
14
+ import { useDropdownList } from '../hooks/useDropdownList';
12
15
 
13
16
  export const DesktopLeaveRoom = ({
14
- menuTriggerButton: MenuTriggerButton,
15
- leaveIconButton: LeaveIconButton,
16
17
  leaveRoom,
17
18
  stopStream,
19
+ screenType,
20
+ }: {
21
+ leaveRoom: () => void;
22
+ stopStream: () => Promise<void>;
23
+ screenType: keyof ConferencingScreen;
18
24
  }) => {
19
25
  const [open, setOpen] = useState(false);
26
+ const [showLeaveRoomAlert, setShowLeaveRoomAlert] = useState(false);
20
27
  const [showEndStreamAlert, setShowEndStreamAlert] = useState(false);
21
28
  const isConnected = useHMSStore(selectIsConnectedToRoom);
22
29
  const permissions = useHMSStore(selectPermissions);
23
30
  const { isStreamingOn } = useRecordingStreaming();
24
- const showStreamingUI = useShowStreamingUI();
31
+ const showStream = permissions?.hlsStreaming && isStreamingOn;
25
32
 
26
- const showStream = showStreamingUI && isStreamingOn;
27
-
28
- useDropdownList({ open, name: 'LeaveRoom' });
33
+ useDropdownList({ open: open || showEndStreamAlert || showLeaveRoomAlert, name: 'LeaveRoom' });
29
34
 
30
35
  if (!permissions || !isConnected) {
31
36
  return null;
@@ -36,14 +41,19 @@ export const DesktopLeaveRoom = ({
36
41
  {permissions.hlsStreaming ? (
37
42
  <Flex>
38
43
  <LeaveIconButton
39
- variant="danger"
40
44
  key="LeaveRoom"
41
45
  data-testid="leave_room_btn"
42
46
  css={{
43
47
  borderTopRightRadius: 0,
44
48
  borderBottomRightRadius: 0,
45
49
  }}
46
- onClick={leaveRoom}
50
+ onClick={() => {
51
+ if (screenType === 'hls_live_streaming') {
52
+ setShowLeaveRoomAlert(true);
53
+ } else {
54
+ leaveRoom();
55
+ }
56
+ }}
47
57
  >
48
58
  <Tooltip title="Leave Room">
49
59
  <Box>
@@ -60,7 +70,7 @@ export const DesktopLeaveRoom = ({
60
70
  },
61
71
  }}
62
72
  >
63
- <MenuTriggerButton variant="danger" data-testid="leave_end_dropdown_trigger">
73
+ <MenuTriggerButton data-testid="leave_end_dropdown_trigger">
64
74
  <VerticalMenuIcon />
65
75
  </MenuTriggerButton>
66
76
  </Dropdown.Trigger>
@@ -102,7 +112,17 @@ export const DesktopLeaveRoom = ({
102
112
  </Dropdown.Root>
103
113
  </Flex>
104
114
  ) : (
105
- <LeaveIconButton onClick={leaveRoom} variant="danger" key="LeaveRoom" data-testid="leave_room_btn">
115
+ <LeaveIconButton
116
+ onClick={() => {
117
+ if (screenType === 'hls_live_streaming') {
118
+ setShowLeaveRoomAlert(true);
119
+ } else {
120
+ leaveRoom();
121
+ }
122
+ }}
123
+ key="LeaveRoom"
124
+ data-testid="leave_room_btn"
125
+ >
106
126
  <Tooltip title="Leave Room">
107
127
  <Box>
108
128
  <ExitIcon style={{ transform: 'rotate(180deg)' }} />
@@ -119,11 +139,23 @@ export const DesktopLeaveRoom = ({
119
139
  setShowEndStreamAlert={setShowEndStreamAlert}
120
140
  stopStream={stopStream}
121
141
  leaveRoom={leaveRoom}
142
+ isStreamingOn={isStreamingOn}
122
143
  isModal
123
144
  />
124
145
  </Dialog.Content>
125
146
  </Dialog.Portal>
126
147
  </Dialog.Root>
148
+
149
+ {screenType === 'hls_live_streaming' ? (
150
+ <Dialog.Root open={showLeaveRoomAlert} modal={false}>
151
+ <Dialog.Portal>
152
+ <Dialog.Overlay />
153
+ <Dialog.Content css={{ w: 'min(420px, 90%)', p: '$8', bg: '$surface_dim' }}>
154
+ <LeaveSessionContent setShowLeaveRoomAlert={setShowLeaveRoomAlert} leaveRoom={leaveRoom} isModal />
155
+ </Dialog.Content>
156
+ </Dialog.Portal>
157
+ </Dialog.Root>
158
+ ) : null}
127
159
  </Fragment>
128
160
  );
129
161
  };
@@ -1,12 +1,22 @@
1
1
  import React from 'react';
2
2
  import { AlertTriangleIcon, CrossIcon } from '@100mslive/react-icons';
3
- import { Button } from '../../Button';
4
- import { Box, Flex } from '../../Layout';
5
- import { Text } from '../../Text';
6
- import { useShowStreamingUI } from '../common/hooks';
3
+ import { Button } from '../../../Button';
4
+ import { Box, Flex } from '../../../Layout';
5
+ import { Text } from '../../../Text';
7
6
 
8
- export const EndSessionContent = ({ setShowEndStreamAlert, stopStream, leaveRoom, isModal = false }) => {
9
- const showStreamingUI = useShowStreamingUI();
7
+ export const EndSessionContent = ({
8
+ setShowEndStreamAlert,
9
+ stopStream,
10
+ leaveRoom,
11
+ isModal = false,
12
+ isStreamingOn = false,
13
+ }: {
14
+ setShowEndStreamAlert: (value: boolean) => void;
15
+ stopStream: () => Promise<void>;
16
+ leaveRoom: () => void;
17
+ isModal?: boolean;
18
+ isStreamingOn: boolean;
19
+ }) => {
10
20
  return (
11
21
  <Box>
12
22
  <Flex
@@ -18,7 +28,7 @@ export const EndSessionContent = ({ setShowEndStreamAlert, stopStream, leaveRoom
18
28
  >
19
29
  <AlertTriangleIcon style={{ marginRight: '0.5rem' }} />
20
30
  <Text variant="lg" css={{ color: 'inherit', fontWeight: '$semiBold' }}>
21
- End {showStreamingUI ? 'Stream' : 'Session'}
31
+ End {isStreamingOn ? 'Stream' : 'Session'}
22
32
  </Text>
23
33
  {isModal ? null : (
24
34
  <Box css={{ color: '$on_surface_high', ml: 'auto' }} onClick={() => setShowEndStreamAlert(false)}>
@@ -27,7 +37,7 @@ export const EndSessionContent = ({ setShowEndStreamAlert, stopStream, leaveRoom
27
37
  )}
28
38
  </Flex>
29
39
  <Text variant="sm" css={{ color: '$on_surface_medium', mb: '$8', mt: '$4' }}>
30
- The {showStreamingUI ? 'stream' : 'session'} will end for everyone. You can't undo this action.
40
+ The {isStreamingOn ? 'stream' : 'session'} will end for everyone. You can't undo this action.
31
41
  </Text>
32
42
  <Flex align="center" justify="between" css={{ w: '100%', gap: '$8' }}>
33
43
  <Button
@@ -49,7 +59,7 @@ export const EndSessionContent = ({ setShowEndStreamAlert, stopStream, leaveRoom
49
59
  id="stopStream"
50
60
  data-testid="stop_stream_btn"
51
61
  >
52
- End {showStreamingUI ? 'Stream' : 'Session'}
62
+ End {isStreamingOn ? 'Stream' : 'Session'}
53
63
  </Button>
54
64
  </Flex>
55
65
  </Box>
@@ -0,0 +1,26 @@
1
+ import { IconButton } from '../../../IconButton';
2
+ import { styled } from '../../../Theme';
3
+
4
+ export const LeaveIconButton = styled(IconButton, {
5
+ color: '$on_primary_high',
6
+ h: '$14',
7
+ px: '$4',
8
+ r: '$1',
9
+ bg: '$alert_error_default',
10
+ '&:not([disabled]):hover': {
11
+ bg: '$alert_error_bright',
12
+ },
13
+ '&:not([disabled]):active': {
14
+ bg: '$alert_error_default',
15
+ },
16
+ '@md': {
17
+ mx: 0,
18
+ },
19
+ });
20
+
21
+ export const MenuTriggerButton = styled(LeaveIconButton, {
22
+ borderLeft: '1px solid $alert_error_dim',
23
+ borderTopLeftRadius: 0,
24
+ borderBottomLeftRadius: 0,
25
+ px: '$2',
26
+ });