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

Sign up to get free protection for your applications and to get access to all the features.
Files changed (130) hide show
  1. package/dist/{HLSView-PY2FKWX3.js → HLSView-HNVYG5VE.js} +208 -118
  2. package/dist/HLSView-HNVYG5VE.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 +4 -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/VideoLayouts/EqualProminence.d.ts +1 -1
  22. package/dist/Prebuilt/components/VideoLayouts/Grid.d.ts +1 -0
  23. package/dist/Prebuilt/components/VideoLayouts/GridLayout.d.ts +5 -3
  24. package/dist/Prebuilt/components/VideoLayouts/ProminenceLayout.d.ts +6 -3
  25. package/dist/Prebuilt/components/VideoLayouts/RoleProminence.d.ts +1 -1
  26. package/dist/Prebuilt/components/VideoLayouts/ScreenshareLayout.d.ts +1 -1
  27. package/dist/Prebuilt/components/VideoLayouts/interface.d.ts +1 -0
  28. package/dist/Prebuilt/components/hooks/useAutoStartStreaming.d.ts +1 -0
  29. package/dist/Prebuilt/components/hooks/useRedirectToLeave.d.ts +3 -0
  30. package/dist/Prebuilt/components/hooks/useTileLayout.d.ts +2 -1
  31. package/dist/Prebuilt/components/hooks/useVideoTileLayout.d.ts +2 -0
  32. package/dist/Prebuilt/layouts/SidePane.d.ts +4 -1
  33. package/dist/Prebuilt/layouts/VideoStreamingSection.d.ts +2 -1
  34. package/dist/{VirtualBackground-AYDHYLIZ.js → VirtualBackground-UM2FOUHQ.js} +3 -3
  35. package/dist/{chunk-E2M2ZSOL.js → chunk-364HP22I.js} +2 -2
  36. package/dist/{chunk-RXTHJUMZ.js → chunk-LYSAET4G.js} +946 -390
  37. package/dist/chunk-LYSAET4G.js.map +7 -0
  38. package/dist/{chunk-GQD2AGWW.js → chunk-POE7H4IE.js} +12 -2
  39. package/dist/{chunk-GQD2AGWW.js.map → chunk-POE7H4IE.js.map} +2 -2
  40. package/dist/{conference-V2XZGTKU.js → conference-UWLJHMB2.js} +1116 -1316
  41. package/dist/conference-UWLJHMB2.js.map +7 -0
  42. package/dist/index.cjs.js +6080 -5631
  43. package/dist/index.cjs.js.map +4 -4
  44. package/dist/index.js +2 -2
  45. package/dist/meta.cjs.json +741 -493
  46. package/dist/meta.esbuild.json +782 -529
  47. package/package.json +8 -7
  48. package/src/Prebuilt/App.tsx +10 -21
  49. package/src/Prebuilt/AppContext.tsx +1 -1
  50. package/src/Prebuilt/IconButton.jsx +10 -0
  51. package/src/Prebuilt/common/PeersSorter.ts +1 -1
  52. package/src/Prebuilt/common/constants.js +1 -2
  53. package/src/Prebuilt/common/utils.js +1 -1
  54. package/src/Prebuilt/components/AppData/AppData.jsx +8 -2
  55. package/src/Prebuilt/components/AppData/useUISettings.js +6 -6
  56. package/src/Prebuilt/components/AudioVideoToggle.jsx +8 -6
  57. package/src/Prebuilt/components/Chat/Chat.jsx +23 -6
  58. package/src/Prebuilt/components/Chat/ChatBody.jsx +20 -21
  59. package/src/Prebuilt/components/Chat/{ChatFooter.jsx → ChatFooter.tsx} +38 -13
  60. package/src/Prebuilt/components/Chat/ChatParticipantHeader.jsx +38 -27
  61. package/src/Prebuilt/components/Chat/useEmojiPickerStyles.js +5 -4
  62. package/src/Prebuilt/components/Connection/{ConnectionIndicator.jsx → ConnectionIndicator.tsx} +12 -4
  63. package/src/Prebuilt/components/Connection/{TileConnection.jsx → TileConnection.tsx} +20 -6
  64. package/src/Prebuilt/components/EmojiReaction.jsx +2 -6
  65. package/src/Prebuilt/components/Footer/{ChatToggle.jsx → ChatToggle.tsx} +13 -3
  66. package/src/Prebuilt/components/Footer/Footer.tsx +15 -6
  67. package/src/Prebuilt/components/Footer/ParticipantList.jsx +15 -47
  68. package/src/Prebuilt/components/Footer/{RoleAccordion.jsx → RoleAccordion.tsx} +33 -17
  69. package/src/Prebuilt/components/Footer/RoleOptions.tsx +155 -0
  70. package/src/Prebuilt/components/FullPageProgress.jsx +3 -3
  71. package/src/Prebuilt/components/HMSVideo/Controls.jsx +1 -0
  72. package/src/Prebuilt/components/HMSVideo/HLSQualitySelector.jsx +39 -17
  73. package/src/Prebuilt/components/HMSVideo/HMSVideo.jsx +2 -2
  74. package/src/Prebuilt/components/HMSVideo/VideoProgress.jsx +5 -6
  75. package/src/Prebuilt/components/HMSVideo/VolumeControl.jsx +1 -1
  76. package/src/Prebuilt/components/Header/{StreamActions.jsx → StreamActions.tsx} +23 -9
  77. package/src/Prebuilt/components/Header/common.jsx +5 -2
  78. package/src/Prebuilt/components/IconButtonWithOptions/IconButtonWithOptions.jsx +6 -1
  79. package/src/Prebuilt/components/InsetTile.tsx +14 -8
  80. package/src/Prebuilt/components/Leave/DesktopLeaveRoom.tsx +21 -11
  81. package/src/Prebuilt/components/Leave/EndSessionContent.tsx +2 -5
  82. package/src/Prebuilt/components/Leave/LeaveCard.tsx +1 -3
  83. package/src/Prebuilt/components/Leave/LeaveRoom.tsx +28 -25
  84. package/src/Prebuilt/components/Leave/LeaveSessionContent.tsx +8 -2
  85. package/src/Prebuilt/components/Leave/MwebLeaveRoom.tsx +8 -8
  86. package/src/Prebuilt/components/MoreSettings/ChangeNameContent.jsx +4 -0
  87. package/src/Prebuilt/components/MoreSettings/MoreSettings.tsx +1 -1
  88. package/src/Prebuilt/components/MoreSettings/SplitComponents/DesktopOptions.tsx +9 -23
  89. package/src/Prebuilt/components/MoreSettings/SplitComponents/{MwebOptions.jsx → MwebOptions.tsx} +88 -27
  90. package/src/Prebuilt/components/Notifications/Notifications.jsx +30 -21
  91. package/src/Prebuilt/components/Notifications/ReconnectNotifications.jsx +5 -11
  92. package/src/Prebuilt/components/Pagination.tsx +14 -12
  93. package/src/Prebuilt/components/Preview/{PreviewContainer.jsx → PreviewContainer.tsx} +11 -2
  94. package/src/Prebuilt/components/Preview/PreviewForm.tsx +6 -8
  95. package/src/Prebuilt/components/Preview/{PreviewJoin.jsx → PreviewJoin.tsx} +43 -19
  96. package/src/Prebuilt/components/{RoleChangeRequestModal.jsx → RoleChangeRequestModal.tsx} +32 -15
  97. package/src/Prebuilt/components/ScreenshareTile.jsx +6 -7
  98. package/src/Prebuilt/components/SecondaryTiles.tsx +12 -10
  99. package/src/Prebuilt/components/TileMenu/TileMenu.jsx +1 -1
  100. package/src/Prebuilt/components/TileMenu/TileMenuContent.jsx +14 -10
  101. package/src/Prebuilt/components/Toast/ToastConfig.jsx +5 -4
  102. package/src/Prebuilt/components/VideoLayouts/EqualProminence.tsx +13 -10
  103. package/src/Prebuilt/components/VideoLayouts/Grid.tsx +36 -34
  104. package/src/Prebuilt/components/VideoLayouts/GridLayout.tsx +33 -15
  105. package/src/Prebuilt/components/VideoLayouts/ProminenceLayout.tsx +45 -31
  106. package/src/Prebuilt/components/VideoLayouts/RoleProminence.tsx +12 -9
  107. package/src/Prebuilt/components/VideoLayouts/ScreenshareLayout.tsx +25 -9
  108. package/src/Prebuilt/components/VideoLayouts/interface.ts +1 -0
  109. package/src/Prebuilt/components/VideoTile.jsx +45 -53
  110. package/src/Prebuilt/components/conference.jsx +71 -74
  111. package/src/Prebuilt/components/hooks/useAutoStartStreaming.tsx +57 -0
  112. package/src/Prebuilt/components/hooks/useMetadata.jsx +12 -3
  113. package/src/Prebuilt/components/hooks/useRedirectToLeave.tsx +34 -0
  114. package/src/Prebuilt/components/hooks/useRoleProminencePeers.tsx +1 -1
  115. package/src/Prebuilt/components/hooks/useTileLayout.tsx +24 -18
  116. package/src/Prebuilt/components/hooks/useVideoTileLayout.ts +4 -0
  117. package/src/Prebuilt/layouts/EmbedView.jsx +1 -11
  118. package/src/Prebuilt/layouts/HLSView.jsx +152 -82
  119. package/src/Prebuilt/layouts/SidePane.tsx +15 -3
  120. package/src/Prebuilt/layouts/VideoStreamingSection.tsx +11 -47
  121. package/src/Prebuilt/plugins/FlyingEmoji.jsx +14 -2
  122. package/src/Prebuilt/services/FeatureFlags.jsx +0 -1
  123. package/src/VideoTile/StyledVideoTile.tsx +1 -0
  124. package/dist/HLSView-PY2FKWX3.js.map +0 -7
  125. package/dist/chunk-RXTHJUMZ.js.map +0 -7
  126. package/dist/conference-V2XZGTKU.js.map +0 -7
  127. package/src/Prebuilt/components/AudioLevel/BeamSpeakerLabelsLogging.jsx +0 -16
  128. package/src/Prebuilt/components/VideoList.jsx +0 -73
  129. /package/dist/{VirtualBackground-AYDHYLIZ.js.map → VirtualBackground-UM2FOUHQ.js.map} +0 -0
  130. /package/dist/{chunk-E2M2ZSOL.js.map → chunk-364HP22I.js.map} +0 -0
@@ -1,5 +1,4 @@
1
1
  import React, { Fragment, useCallback, useEffect, useMemo, useRef, useState } from 'react';
2
- import { useMedia } from 'react-use';
3
2
  import {
4
3
  selectAudioTrackByPeerID,
5
4
  selectIsPeerAudioEnabled,
@@ -19,7 +18,7 @@ import TileMenu, { isSameTile } from './TileMenu/TileMenu';
19
18
  import { Avatar } from '../../Avatar';
20
19
  import { Box, Flex } from '../../Layout';
21
20
  import { VideoTileStats } from '../../Stats';
22
- import { config as cssConfig, keyframes } from '../../Theme';
21
+ import { keyframes } from '../../Theme';
23
22
  import { Video } from '../../Video';
24
23
  import { StyledVideoTile } from '../../VideoTile';
25
24
  import { getVideoTileLabel } from './peerTileUtils';
@@ -40,6 +39,7 @@ const Tile = ({
40
39
  hideParticipantNameOnTile = false,
41
40
  roundedVideoTile = true,
42
41
  hideAudioMuteOnTile = false,
42
+ hideMetadataOnTile = false,
43
43
  }) => {
44
44
  const trackSelector = trackId ? selectVideoTrackByID(trackId) : selectVideoTrackByPeerID(peerId);
45
45
  const track = useHMSStore(trackSelector);
@@ -81,7 +81,6 @@ const Tile = ({
81
81
  }
82
82
  return 'large';
83
83
  }, [width, height]);
84
- const isMobile = useMedia(cssConfig.media.md);
85
84
 
86
85
  return (
87
86
  <StyledVideoTile.Root
@@ -103,44 +102,42 @@ const Tile = ({
103
102
  <VideoTileStats audioTrackID={audioTrack?.id} videoTrackID={track?.id} peerID={peerId} isLocal={isLocal} />
104
103
  ) : null}
105
104
 
106
- {track ? (
107
- <Video
108
- trackId={track?.id}
109
- attach={isLocal ? undefined : !isAudioOnly}
110
- mirror={
111
- mirrorLocalVideo &&
112
- peerId === localPeerID &&
113
- track?.source === 'regular' &&
114
- track?.facingMode !== 'environment'
115
- }
116
- noRadius={!roundedVideoTile}
117
- data-testid="participant_video_tile"
118
- css={{
119
- objectFit,
120
- filter: isVideoDegraded ? 'blur($space$2)' : undefined,
121
- bg: 'transparent',
122
- }}
123
- />
124
- ) : null}
105
+ <Video
106
+ trackId={track?.id}
107
+ attach={isLocal ? undefined : !isAudioOnly}
108
+ mirror={
109
+ mirrorLocalVideo &&
110
+ peerId === localPeerID &&
111
+ track?.source === 'regular' &&
112
+ track?.facingMode !== 'environment'
113
+ }
114
+ noRadius={!roundedVideoTile}
115
+ data-testid="participant_video_tile"
116
+ css={{
117
+ objectFit,
118
+ filter: isVideoDegraded ? 'blur($space$2)' : undefined,
119
+ bg: 'transparent',
120
+ }}
121
+ />
122
+
125
123
  {isVideoMuted || (!isLocal && isAudioOnly) ? (
126
124
  <StyledVideoTile.AvatarContainer>
127
125
  <Avatar name={peerName || ''} data-testid="participant_avatar_icon" size={avatarSize} />
128
126
  </StyledVideoTile.AvatarContainer>
129
127
  ) : null}
130
128
 
131
- {showAudioMuted({
132
- hideAudioMute: hideAudioMuteOnTile,
133
- isAudioMuted,
134
- }) ? (
135
- <StyledVideoTile.AudioIndicator
136
- data-testid="participant_audio_mute_icon"
137
- size={width && height && (width < 180 || height < 180) ? 'small' : 'medium'}
138
- >
139
- <MicOffIcon />
140
- </StyledVideoTile.AudioIndicator>
141
- ) : (
142
- <AudioLevel trackId={audioTrack?.id} />
143
- )}
129
+ {!hideAudioMuteOnTile ? (
130
+ isAudioMuted ? (
131
+ <StyledVideoTile.AudioIndicator
132
+ data-testid="participant_audio_mute_icon"
133
+ size={width && height && (width < 180 || height < 180) ? 'small' : 'medium'}
134
+ >
135
+ <MicOffIcon />
136
+ </StyledVideoTile.AudioIndicator>
137
+ ) : (
138
+ <AudioLevel trackId={audioTrack?.id} />
139
+ )
140
+ ) : null}
144
141
  {isMouseHovered || isDragabble ? (
145
142
  <TileMenu
146
143
  peerID={peerId}
@@ -150,25 +147,24 @@ const Tile = ({
150
147
  enableSpotlightingPeer={enableSpotlightingPeer}
151
148
  />
152
149
  ) : null}
153
- <PeerMetadata peerId={peerId} />
154
- {isMobile ? null : (
155
- <TileConnection
156
- hideLabel={hideParticipantNameOnTile}
157
- name={label}
158
- isTile
159
- peerId={peerId}
160
- width={width}
161
- pinned={pinned}
162
- spotlighted={spotlighted}
163
- />
164
- )}
150
+ {!hideMetadataOnTile && <PeerMetadata peerId={peerId} />}
151
+
152
+ <TileConnection
153
+ hideLabel={hideParticipantNameOnTile}
154
+ name={label}
155
+ isTile
156
+ peerId={peerId}
157
+ width={width}
158
+ pinned={pinned}
159
+ spotlighted={spotlighted}
160
+ />
165
161
  </StyledVideoTile.Container>
166
162
  ) : null}
167
163
  </StyledVideoTile.Root>
168
164
  );
169
165
  };
170
166
 
171
- const metaStyles = { top: '$4', left: '$4' };
167
+ const metaStyles = { top: '$4', left: '$4', width: '$14', height: '$14' };
172
168
 
173
169
  const heightAnimation = value =>
174
170
  keyframes({
@@ -233,7 +229,7 @@ const PeerMetadata = ({ peerId }) => {
233
229
  ) : null}
234
230
  {isBRB ? (
235
231
  <StyledVideoTile.AttributeBox css={metaStyles} data-testid="brb_icon_onTile">
236
- <BrbTileIcon width={24} height={24} />
232
+ <BrbTileIcon width={22} height={22} />
237
233
  </StyledVideoTile.AttributeBox>
238
234
  ) : null}
239
235
  </Fragment>
@@ -242,8 +238,4 @@ const PeerMetadata = ({ peerId }) => {
242
238
 
243
239
  const VideoTile = React.memo(Tile);
244
240
 
245
- const showAudioMuted = ({ hideAudioMute, isAudioMuted }) => {
246
- return isAudioMuted && !hideAudioMute;
247
- };
248
-
249
241
  export default VideoTile;
@@ -23,14 +23,13 @@ import {
23
23
  useRoomLayoutConferencingScreen,
24
24
  useRoomLayoutPreviewScreen,
25
25
  } from '../provider/roomLayoutProvider/hooks/useRoomLayoutScreen';
26
- import { useAuthToken, useIsHeadless, useSetAppDataByKey } from './AppData/useUISettings';
27
- import { APP_DATA, EMOJI_REACTION_TYPE, isAndroid, isIOS, isIPadOS } from '../common/constants';
26
+ import { useAuthToken, useSetAppDataByKey } from './AppData/useUISettings';
27
+ import { APP_DATA, isAndroid, isIOS, isIPadOS } from '../common/constants';
28
28
 
29
29
  const Conference = () => {
30
30
  const navigate = useNavigate();
31
31
  const { roomId, role } = useParams();
32
- const isHeadless = useIsHeadless();
33
- const { userName } = useHMSPrebuiltContext();
32
+ const { userName, endpoints } = useHMSPrebuiltContext();
34
33
  const screenProps = useRoomLayoutConferencingScreen();
35
34
  const { isPreviewScreenEnabled } = useRoomLayoutPreviewScreen();
36
35
  const roomState = useHMSStore(selectRoomState);
@@ -42,11 +41,11 @@ const Conference = () => {
42
41
  const authTokenInAppData = useAuthToken();
43
42
  const headerRef = useRef();
44
43
  const footerRef = useRef();
44
+ const isMobileDevice = isAndroid || isIOS || isIPadOS;
45
45
  const dropdownListRef = useRef();
46
- const performAutoHide = hideControls && (isAndroid || isIOS || isIPadOS);
47
46
  const [isHLSStarted] = useSetAppDataByKey(APP_DATA.hlsStarted);
48
47
  const toggleControls = () => {
49
- if (dropdownListRef.current?.length === 0) {
48
+ if (dropdownListRef.current?.length === 0 && isMobileDevice) {
50
49
  setHideControls(value => !value);
51
50
  }
52
51
  };
@@ -58,14 +57,14 @@ const Conference = () => {
58
57
  clearTimeout(timeout);
59
58
  timeout = setTimeout(() => {
60
59
  if (dropdownListRef.current.length === 0) {
61
- setHideControls(true);
60
+ setHideControls(isMobileDevice);
62
61
  }
63
62
  }, 5000);
64
63
  }
65
64
  return () => {
66
65
  clearTimeout(timeout);
67
66
  };
68
- }, [dropdownList, hideControls]);
67
+ }, [dropdownList, hideControls, isMobileDevice]);
69
68
 
70
69
  useEffect(() => {
71
70
  if (!roomId) {
@@ -90,9 +89,7 @@ const Conference = () => {
90
89
  .join({
91
90
  userName,
92
91
  authToken: authTokenInAppData,
93
- initEndpoint: process.env.REACT_APP_ENV
94
- ? `https://${process.env.REACT_APP_ENV}-init.100ms.live/init`
95
- : undefined,
92
+ initEndpoint: endpoints?.init,
96
93
  initialSettings: {
97
94
  isAudioMuted: !isPreviewScreenEnabled,
98
95
  isVideoMuted: !isPreviewScreenEnabled,
@@ -101,14 +98,7 @@ const Conference = () => {
101
98
  })
102
99
  .catch(console.error);
103
100
  }
104
- }, [authTokenInAppData, hmsActions, isConnectedToRoom, isPreviewScreenEnabled, roomState, userName]);
105
-
106
- useEffect(() => {
107
- // beam doesn't need to store messages, saves on unnecessary store updates in large calls
108
- if (isHeadless) {
109
- hmsActions.ignoreMessageTypes(['chat', EMOJI_REACTION_TYPE]);
110
- }
111
- }, [isHeadless, hmsActions]);
101
+ }, [authTokenInAppData, endpoints?.init, hmsActions, isConnectedToRoom, isPreviewScreenEnabled, roomState, userName]);
112
102
 
113
103
  useEffect(() => {
114
104
  return () => {
@@ -117,71 +107,78 @@ const Conference = () => {
117
107
  }, []);
118
108
 
119
109
  if (!isConnectedToRoom) {
120
- return <FullPageProgress loadingText="Joining..." />;
121
- }
122
-
123
- if (isHLSStarted) {
124
- return <FullPageProgress loadingText="Starting live stream..." />;
110
+ return <FullPageProgress text="Joining..." />;
125
111
  }
126
112
 
127
113
  return (
128
- <Flex css={{ size: '100%', overflow: 'hidden' }} direction="column">
129
- {!screenProps.hideSections.includes('header') && (
130
- <Box
131
- ref={headerRef}
132
- css={{
133
- h: '$18',
134
- transition: 'margin 0.3s ease-in-out',
135
- marginTop: performAutoHide ? `-${headerRef.current?.clientHeight}px` : 'none',
136
- '@md': {
137
- h: '$17',
138
- },
139
- }}
140
- data-testid="header"
141
- >
142
- <Header elements={screenProps.elements} screenType={screenProps.screenType} />
114
+ <>
115
+ {isHLSStarted ? (
116
+ <Box css={{ position: 'fixed', zIndex: 100, w: '100%', h: '100%', left: 0, top: 0 }}>
117
+ <FullPageProgress text="Starting live stream..." css={{ opacity: 0.8, bg: '$background_dim' }} />
143
118
  </Box>
144
- )}
145
- <Box
146
- css={{
147
- w: '100%',
148
- flex: '1 1 0',
149
- minHeight: 0,
150
- px: '$10',
151
- paddingBottom: 'env(safe-area-inset-bottom)',
152
- '@lg': {
153
- px: '$4',
154
- },
155
- }}
156
- id="conferencing"
157
- data-testid="conferencing"
158
- onClick={toggleControls}
159
- >
160
- <VideoStreamingSection screenType={screenProps.screenType} elements={screenProps.elements} />
161
- </Box>
162
- {!screenProps.hideSections.includes('footer') && (
119
+ ) : null}
120
+ <Flex css={{ size: '100%', overflow: 'hidden' }} direction="column">
121
+ {!screenProps.hideSections.includes('header') && (
122
+ <Box
123
+ ref={headerRef}
124
+ css={{
125
+ h: '$18',
126
+ transition: 'margin 0.3s ease-in-out',
127
+ marginTop: hideControls ? `-${headerRef.current?.clientHeight}px` : 'none',
128
+ '@md': {
129
+ h: '$17',
130
+ },
131
+ }}
132
+ data-testid="header"
133
+ >
134
+ <Header elements={screenProps.elements} screenType={screenProps.screenType} />
135
+ </Box>
136
+ )}
163
137
  <Box
164
- ref={footerRef}
165
138
  css={{
166
- flexShrink: 0,
167
- maxHeight: '$24',
168
- transition: 'margin 0.3s ease-in-out',
169
- bg: '$background_dim',
170
- marginBottom: performAutoHide ? `-${footerRef.current?.clientHeight}px` : undefined,
171
- '@md': {
172
- maxHeight: 'unset',
173
- bg: screenProps.screenType === 'hls_live_streaming' ? 'transparent' : '$background_dim',
139
+ w: '100%',
140
+ flex: '1 1 0',
141
+ minHeight: 0,
142
+ px: screenProps?.elements?.video_tile_layout?.grid?.edge_to_edge ? 0 : '$10', // TODO: padding to be controlled by section/element
143
+ paddingBottom: 'env(safe-area-inset-bottom)',
144
+ '@lg': {
145
+ px: 0,
174
146
  },
175
147
  }}
176
- data-testid="footer"
148
+ id="conferencing"
149
+ data-testid="conferencing"
150
+ onClick={toggleControls}
177
151
  >
178
- <Footer elements={screenProps.elements} screenType={screenProps.screenType} />
152
+ <VideoStreamingSection
153
+ screenType={screenProps.screenType}
154
+ elements={screenProps.elements}
155
+ hideControls={hideControls}
156
+ />
179
157
  </Box>
180
- )}
181
- <RoleChangeRequestModal />
182
- <HLSFailureModal />
183
- <ActivatedPIP />
184
- </Flex>
158
+ {!screenProps.hideSections.includes('footer') && (
159
+ <Box
160
+ ref={footerRef}
161
+ css={{
162
+ flexShrink: 0,
163
+ maxHeight: '$24',
164
+ transition: 'margin 0.3s ease-in-out',
165
+ bg: '$background_dim',
166
+ marginBottom: hideControls ? `-${footerRef.current?.clientHeight}px` : undefined,
167
+ '@md': {
168
+ maxHeight: 'unset',
169
+ bg: screenProps.screenType === 'hls_live_streaming' ? 'transparent' : '$background_dim',
170
+ },
171
+ }}
172
+ data-testid="footer"
173
+ >
174
+ <Footer elements={screenProps.elements} screenType={screenProps.screenType} />
175
+ </Box>
176
+ )}
177
+ <RoleChangeRequestModal />
178
+ <HLSFailureModal />
179
+ <ActivatedPIP />
180
+ </Flex>
181
+ </>
185
182
  );
186
183
  };
187
184
 
@@ -0,0 +1,57 @@
1
+ import { useCallback, useEffect, useRef } from 'react';
2
+ import {
3
+ HMSException,
4
+ selectIsConnectedToRoom,
5
+ selectPermissions,
6
+ useHMSActions,
7
+ useHMSStore,
8
+ useRecordingStreaming,
9
+ } from '@100mslive/react-sdk';
10
+ // @ts-ignore: No implicit Any
11
+ import { useSetAppDataByKey } from '../AppData/useUISettings';
12
+ // @ts-ignore: No implicit Any
13
+ import { useShowStreamingUI } from '../../common/hooks';
14
+ // @ts-ignore: No implicit Any
15
+ import { APP_DATA } from '../../common/constants';
16
+
17
+ export const useAutoStartStreaming = () => {
18
+ const [isHLSStarted, setHLSStarted] = useSetAppDataByKey(APP_DATA.hlsStarted);
19
+ const permissions = useHMSStore(selectPermissions);
20
+ const showStreamingUI = useShowStreamingUI();
21
+ const hmsActions = useHMSActions();
22
+ const isConnected = useHMSStore(selectIsConnectedToRoom);
23
+ const { isHLSRunning } = useRecordingStreaming();
24
+ const streamStartedRef = useRef(false);
25
+
26
+ const startHLS = useCallback(async () => {
27
+ try {
28
+ if (isHLSStarted || !showStreamingUI || isHLSRunning) {
29
+ return;
30
+ }
31
+ setHLSStarted(true);
32
+ streamStartedRef.current = true;
33
+ await hmsActions.startHLSStreaming();
34
+ } catch (error) {
35
+ if ((error as HMSException).message?.includes('beam already started')) {
36
+ return;
37
+ }
38
+ streamStartedRef.current = false;
39
+ setHLSStarted(false);
40
+ }
41
+ }, [hmsActions, isHLSRunning, isHLSStarted, setHLSStarted, showStreamingUI]);
42
+
43
+ useEffect(() => {
44
+ if (!isHLSStarted && !isHLSRunning) {
45
+ streamStartedRef.current = false;
46
+ }
47
+ }, [isHLSStarted, isHLSRunning]);
48
+
49
+ useEffect(() => {
50
+ if (!isConnected || streamStartedRef.current || !permissions?.hlsStreaming) {
51
+ return;
52
+ }
53
+ // Is a streaming kit and broadcaster joins
54
+ startHLS();
55
+ // eslint-disable-next-line react-hooks/exhaustive-deps
56
+ }, [isConnected]);
57
+ };
@@ -1,19 +1,28 @@
1
1
  import { useCallback, useState } from 'react';
2
- import { selectLocalPeerID, selectPeerMetadata, useHMSActions, useHMSStore } from '@100mslive/react-sdk';
2
+ import {
3
+ selectLocalPeerID,
4
+ selectPeerMetadata,
5
+ useHMSActions,
6
+ useHMSStore,
7
+ useHMSVanillaStore,
8
+ } from '@100mslive/react-sdk';
3
9
 
4
10
  export const useMyMetadata = () => {
5
11
  const hmsActions = useHMSActions();
6
12
  const localPeerId = useHMSStore(selectLocalPeerID);
13
+ const vanillaStore = useHMSVanillaStore();
7
14
  const metaData = useHMSStore(selectPeerMetadata(localPeerId));
8
15
  const [isHandRaised, setHandRaised] = useState(metaData?.isHandRaised || false);
9
16
  const [isBRBOn, setBRBOn] = useState(metaData?.isBRBOn || false); // BRB = be right back
10
17
 
11
18
  const update = async updatedFields => {
12
19
  try {
13
- await hmsActions.changeMetadata(Object.assign(metaData, updatedFields));
20
+ // get current state from store and merge updated fields
21
+ const currentMetadata = vanillaStore.getState(selectPeerMetadata(localPeerId));
22
+ await hmsActions.changeMetadata(Object.assign(currentMetadata, updatedFields));
14
23
  return true;
15
24
  } catch (error) {
16
- console.error('failed to update metadata ', metaData, updatedFields);
25
+ console.error('failed to update metadata ', updatedFields);
17
26
  }
18
27
  };
19
28
 
@@ -0,0 +1,34 @@
1
+ import { useCallback } from 'react';
2
+ import { useNavigate, useParams } from 'react-router-dom';
3
+ import { useHMSPrebuiltContext } from '../../AppContext';
4
+ // @ts-ignore: No implicit Any
5
+ import { PictureInPicture } from '../PIP/PIPManager';
6
+ // @ts-ignore: No implicit Any
7
+ import { ToastManager } from '../Toast/ToastManager';
8
+ import { useRoomLayoutLeaveScreen } from '../../provider/roomLayoutProvider/hooks/useRoomLayoutScreen';
9
+
10
+ export const useRedirectToLeave = () => {
11
+ const { isLeaveScreenEnabled } = useRoomLayoutLeaveScreen();
12
+ const { onLeave } = useHMSPrebuiltContext();
13
+ const params = useParams();
14
+ const navigate = useNavigate();
15
+
16
+ const redirect = useCallback(
17
+ (timeout = 0) => {
18
+ setTimeout(() => {
19
+ const prefix = isLeaveScreenEnabled ? '/leave/' : '/';
20
+ if (params.role) {
21
+ navigate(prefix + params.roomId + '/' + params.role);
22
+ } else {
23
+ navigate(prefix + params.roomId);
24
+ }
25
+ PictureInPicture.stop().catch(() => console.error('stopping pip'));
26
+ ToastManager.clearAllToast();
27
+ onLeave?.();
28
+ }, timeout);
29
+ },
30
+ [isLeaveScreenEnabled, navigate, onLeave, params.role, params.roomId],
31
+ );
32
+
33
+ return { redirectToLeave: redirect };
34
+ };
@@ -12,7 +12,7 @@ export const useRoleProminencePeers = (prominentRoles: string[], peers: HMSPeer[
12
12
  if (pinnedTrack) {
13
13
  if (pinnedTrack.peerId === peer.id) {
14
14
  acc[0].push(peer);
15
- } else {
15
+ } else if (!(isInsetEnabled && peer.isLocal)) {
16
16
  acc[1].push(peer);
17
17
  }
18
18
  return acc;
@@ -10,7 +10,6 @@ import {
10
10
  import { config as cssConfig } from '../../../Theme';
11
11
 
12
12
  const aspectRatioConfig = { default: [1 / 1, 4 / 3, 16 / 9], mobile: [1 / 1, 3 / 4, 9 / 16] };
13
- const gap = 8; // gap between flex items
14
13
 
15
14
  export const usePagesWithTiles = ({ peers, maxTileCount }: { peers: HMSPeer[]; maxTileCount: number }) => {
16
15
  const vanillaStore = useHMSVanillaStore();
@@ -39,9 +38,11 @@ export const usePagesWithTiles = ({ peers, maxTileCount }: { peers: HMSPeer[]; m
39
38
  export const useTileLayout = ({
40
39
  pageList,
41
40
  maxTileCount,
41
+ edgeToEdge = false,
42
42
  }: {
43
43
  pageList: TrackWithPeerAndDimensions[][];
44
44
  maxTileCount: number;
45
+ edgeToEdge?: boolean;
45
46
  }) => {
46
47
  const vanillaStore = useHMSVanillaStore();
47
48
  const [ref, { width, height }] = useMeasure<HTMLDivElement>();
@@ -76,6 +77,7 @@ export const useTileLayout = ({
76
77
  return rowElements;
77
78
  });
78
79
 
80
+ const gap = edgeToEdge && isMobile ? 0 : 8; // gap between flex items
79
81
  const maxHeight = height - (maxRows - 1) * gap;
80
82
  const maxRowHeight = maxHeight / matrix.length;
81
83
  const aspectRatios =
@@ -86,25 +88,29 @@ export const useTileLayout = ({
86
88
  for (const row of matrix) {
87
89
  let tileWidth = (width - (row.length - 1) * gap) / row.length;
88
90
  let tileHeight = 0;
89
- const calcHeights = aspectRatios.map(aR => tileWidth / aR);
90
- for (const h of calcHeights) {
91
- if (h < maxRowHeight) {
92
- if (tileHeight < h) {
93
- tileHeight = h;
91
+ if (edgeToEdge) {
92
+ tileHeight = maxRowHeight;
93
+ } else {
94
+ const calcHeights = aspectRatios.map(aR => tileWidth / aR);
95
+ for (const h of calcHeights) {
96
+ if (h < maxRowHeight) {
97
+ if (tileHeight < h) {
98
+ tileHeight = h;
99
+ }
94
100
  }
95
101
  }
96
- }
97
102
 
98
- // tileHeight is not calculated as it could be exceeding the max possible height
99
- // find the max possible width instead
100
- if (tileHeight === 0) {
101
- tileHeight = maxRowHeight;
102
- const calcWidths = aspectRatios.map(aR => tileHeight * aR);
103
- tileWidth = 0;
104
- for (const w of calcWidths) {
105
- if (w < width) {
106
- if (tileWidth < w) {
107
- tileWidth = w;
103
+ // tileHeight is not calculated as it could be exceeding the max possible height
104
+ // find the max possible width instead
105
+ if (tileHeight === 0) {
106
+ tileHeight = maxRowHeight;
107
+ const calcWidths = aspectRatios.map(aR => tileHeight * aR);
108
+ tileWidth = 0;
109
+ for (const w of calcWidths) {
110
+ if (w < width) {
111
+ if (tileWidth < w) {
112
+ tileWidth = w;
113
+ }
108
114
  }
109
115
  }
110
116
  }
@@ -116,6 +122,6 @@ export const useTileLayout = ({
116
122
  }
117
123
  }
118
124
  setPagesWithTiles([...pageList]);
119
- }, [width, height, maxTileCount, pageList, vanillaStore, isMobile]);
125
+ }, [width, height, maxTileCount, pageList, vanillaStore, isMobile, edgeToEdge]);
120
126
  return { pagesWithTiles, ref };
121
127
  };
@@ -5,7 +5,9 @@ type TileContextType = {
5
5
  hideParticipantNameOnTile?: boolean;
6
6
  roundedVideoTile?: boolean;
7
7
  hideAudioMuteOnTile?: boolean;
8
+ hideAudioLevelOnTile?: boolean;
8
9
  objectFit?: 'cover' | 'contain';
10
+ hideMetadataOnTile?: boolean;
9
11
  };
10
12
 
11
13
  export const VideoTileContext = React.createContext<TileContextType>({
@@ -13,7 +15,9 @@ export const VideoTileContext = React.createContext<TileContextType>({
13
15
  hideParticipantNameOnTile: false,
14
16
  roundedVideoTile: true,
15
17
  hideAudioMuteOnTile: false,
18
+ hideAudioLevelOnTile: false,
16
19
  objectFit: 'contain',
20
+ hideMetadataOnTile: false,
17
21
  });
18
22
 
19
23
  export const useVideoTileContext = () => {
@@ -1,7 +1,5 @@
1
1
  import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';
2
2
  import {
3
- selectLocalPeerID,
4
- selectLocalPeerRoleName,
5
3
  selectPeers,
6
4
  selectPeerScreenSharing,
7
5
  throwErrorHandler,
@@ -25,21 +23,13 @@ export const EmbedView = () => {
25
23
  export const EmbebScreenShareView = ({ children }) => {
26
24
  const peers = useHMSStore(selectPeers);
27
25
 
28
- const localPeerID = useHMSStore(selectLocalPeerID);
29
- const localPeerRole = useHMSStore(selectLocalPeerRoleName);
30
26
  const peerPresenting = useHMSStore(selectPeerScreenSharing);
31
- const isPresenterFromMyRole = peerPresenting?.roleName?.toLowerCase() === localPeerRole?.toLowerCase();
32
- const amIPresenting = localPeerID === peerPresenting?.id;
33
- const showPresenterInSmallTile = amIPresenting || isPresenterFromMyRole;
34
27
  const [, setActiveScreenSharePeer] = useSetAppDataByKey(APP_DATA.activeScreensharePeerId);
35
28
 
36
29
  const smallTilePeers = useMemo(() => {
37
30
  const smallTilePeers = peers.filter(peer => peer.id !== peerPresenting?.id);
38
- if (showPresenterInSmallTile && peerPresenting) {
39
- smallTilePeers.unshift(peerPresenting); // put presenter on first page
40
- }
41
31
  return smallTilePeers;
42
- }, [peers, peerPresenting, showPresenterInSmallTile]);
32
+ }, [peers, peerPresenting]);
43
33
 
44
34
  useEffect(() => {
45
35
  setActiveScreenSharePeer(peerPresenting?.id);