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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (166) hide show
  1. package/dist/{HLSView-T267ZHOS.js → HLSView-CTAJQUU4.js} +7 -11
  2. package/dist/{HLSView-T267ZHOS.js.map → HLSView-CTAJQUU4.js.map} +1 -1
  3. package/dist/PinnedTrackView-CQKONH4O.js +102 -0
  4. package/dist/PinnedTrackView-CQKONH4O.js.map +7 -0
  5. package/dist/Popover/index.d.ts +1 -0
  6. package/dist/Prebuilt/App.d.ts +25 -0
  7. package/dist/Prebuilt/index.d.ts +1 -0
  8. package/dist/Prebuilt/provider/roomLayoutProvider/index.d.ts +1 -1
  9. package/dist/Sheet/Sheet.d.ts +3093 -0
  10. package/dist/Sheet/index.d.ts +1 -0
  11. package/dist/Theme/ThemeProvider.d.ts +4 -286
  12. package/dist/Theme/stitches.config.d.ts +1 -1
  13. package/dist/{VirtualBackground-BCKXNDTD.js → VirtualBackground-GGGBJYVY.js} +31 -7
  14. package/dist/VirtualBackground-GGGBJYVY.js.map +7 -0
  15. package/dist/chunk-I2FJWE74.js +827 -0
  16. package/dist/chunk-I2FJWE74.js.map +7 -0
  17. package/dist/{chunk-NLZVUXR3.js → chunk-L2SX7GBO.js} +3020 -2189
  18. package/dist/chunk-L2SX7GBO.js.map +7 -0
  19. package/dist/chunk-NOKIGB6Y.js +1100 -0
  20. package/dist/chunk-NOKIGB6Y.js.map +7 -0
  21. package/dist/chunk-TJNDX446.js +67 -0
  22. package/dist/chunk-TJNDX446.js.map +7 -0
  23. package/dist/{chunk-3HMUOAD6.js → conference-OEO7VOJD.js} +3136 -653
  24. package/dist/conference-OEO7VOJD.js.map +7 -0
  25. package/dist/index.cjs.js +15733 -15498
  26. package/dist/index.cjs.js.map +4 -4
  27. package/dist/index.js +4 -8
  28. package/dist/meta.cjs.json +3248 -3039
  29. package/dist/meta.esbuild.json +3398 -3386
  30. package/dist/utils/animations.d.ts +16 -0
  31. package/package.json +8 -11
  32. package/src/Button/Button.tsx +4 -4
  33. package/src/Dropdown/Dropdown.tsx +2 -2
  34. package/src/IconButton/IconButton.tsx +4 -2
  35. package/src/Pagination/StyledPagination.tsx +1 -0
  36. package/src/Popover/index.tsx +2 -1
  37. package/src/Prebuilt/{App.jsx → App.tsx} +95 -48
  38. package/src/Prebuilt/Prebuilt.stories.tsx +22 -8
  39. package/src/Prebuilt/common/constants.js +1 -2
  40. package/src/Prebuilt/common/hooks.js +8 -0
  41. package/src/Prebuilt/common/utils.js +15 -0
  42. package/src/Prebuilt/components/AppData/AppData.jsx +1 -2
  43. package/src/Prebuilt/components/AppData/useUISettings.js +0 -5
  44. package/src/Prebuilt/components/AudioVideoToggle.jsx +69 -26
  45. package/src/Prebuilt/components/AuthToken.jsx +3 -2
  46. package/src/Prebuilt/components/Chat/ChatSelector.jsx +1 -1
  47. package/src/Prebuilt/components/Connection/TileConnection.jsx +0 -1
  48. package/src/Prebuilt/components/EmojiReaction.jsx +23 -73
  49. package/src/Prebuilt/components/EndSessionContent.jsx +57 -0
  50. package/src/Prebuilt/components/EqualProminence.jsx +180 -0
  51. package/src/Prebuilt/components/ErrorBoundary.jsx +4 -10
  52. package/src/Prebuilt/components/Footer/EmojiCard.jsx +34 -0
  53. package/src/Prebuilt/components/Footer/Footer.jsx +73 -0
  54. package/src/Prebuilt/components/{Header → Footer}/ParticipantList.jsx +5 -5
  55. package/src/Prebuilt/components/Header/ConferencingHeader.jsx +27 -7
  56. package/src/Prebuilt/components/Header/HeaderComponents.jsx +16 -14
  57. package/src/Prebuilt/components/Header/StreamActions.jsx +101 -36
  58. package/src/Prebuilt/components/Header/StreamingHeader.jsx +1 -1
  59. package/src/Prebuilt/components/Header/common.jsx +164 -0
  60. package/src/Prebuilt/components/IconButtonWithOptions/IconButtonWithOptions.jsx +1 -2
  61. package/src/Prebuilt/components/LeaveCard.jsx +19 -0
  62. package/src/Prebuilt/components/LeaveRoom.jsx +35 -143
  63. package/src/Prebuilt/components/LeaveSessionContent.jsx +45 -0
  64. package/src/Prebuilt/components/MoreSettings/ActionTile.jsx +55 -0
  65. package/src/Prebuilt/components/MoreSettings/ChangeNameContent.jsx +96 -0
  66. package/src/Prebuilt/components/MoreSettings/ChangeNameModal.jsx +31 -54
  67. package/src/Prebuilt/components/MoreSettings/EmbedUrl.jsx +48 -73
  68. package/src/Prebuilt/components/MoreSettings/MoreSettings.jsx +5 -221
  69. package/src/Prebuilt/components/MoreSettings/MuteAllContent.jsx +61 -0
  70. package/src/Prebuilt/components/MoreSettings/MuteAllModal.jsx +32 -49
  71. package/src/Prebuilt/components/MoreSettings/SplitComponents/DesktopLeaveRoom.jsx +129 -0
  72. package/src/Prebuilt/components/MoreSettings/SplitComponents/DesktopOptions.jsx +219 -0
  73. package/src/Prebuilt/components/MoreSettings/SplitComponents/MwebLeaveRoom.jsx +100 -0
  74. package/src/Prebuilt/components/MoreSettings/SplitComponents/MwebOptions.jsx +259 -0
  75. package/src/Prebuilt/components/Notifications/Notifications.jsx +0 -2
  76. package/src/Prebuilt/components/Notifications/ReconnectNotifications.jsx +0 -4
  77. package/src/Prebuilt/components/PIP/PIPComponent.jsx +30 -26
  78. package/src/Prebuilt/components/PIP/PIPManager.js +13 -0
  79. package/src/Prebuilt/components/PIP/index.jsx +2 -7
  80. package/src/Prebuilt/components/Pagination.jsx +4 -4
  81. package/src/Prebuilt/components/Preview/PreviewContainer.jsx +5 -13
  82. package/src/Prebuilt/components/Preview/PreviewForm.jsx +9 -5
  83. package/src/Prebuilt/components/Preview/PreviewJoin.jsx +20 -27
  84. package/src/Prebuilt/components/RaiseHand.jsx +27 -0
  85. package/src/Prebuilt/components/ScreenShare.jsx +1 -1
  86. package/src/Prebuilt/components/ScreenshareDisplay.jsx +2 -2
  87. package/src/Prebuilt/components/ScreenshareTile.jsx +2 -2
  88. package/src/Prebuilt/components/Settings/DeviceSettings.jsx +2 -1
  89. package/src/Prebuilt/components/Settings/LayoutSettings.jsx +1 -24
  90. package/src/Prebuilt/components/Settings/SettingsModal.jsx +152 -17
  91. package/src/Prebuilt/components/ShareMenuIcon.jsx +1 -0
  92. package/src/Prebuilt/components/TileMenu/TileMenu.jsx +133 -0
  93. package/src/Prebuilt/components/TileMenu/TileMenuContent.jsx +313 -0
  94. package/src/Prebuilt/components/VideoList.jsx +5 -33
  95. package/src/Prebuilt/components/VideoTile.jsx +30 -8
  96. package/src/Prebuilt/components/conference.jsx +14 -1
  97. package/src/Prebuilt/components/init/Init.jsx +0 -27
  98. package/src/Prebuilt/components/init/initUtils.js +0 -23
  99. package/src/Prebuilt/components/pdfAnnotator/pdfFileOptions.jsx +2 -1
  100. package/src/Prebuilt/components/pdfAnnotator/pdfInfo.jsx +1 -1
  101. package/src/Prebuilt/components/pdfAnnotator/shareScreenOptions.jsx +19 -8
  102. package/src/Prebuilt/components/pdfAnnotator/uploadedFile.jsx +1 -0
  103. package/src/Prebuilt/images/pdf-share.png +0 -0
  104. package/src/Prebuilt/images/screen-share.png +0 -0
  105. package/src/Prebuilt/index.ts +1 -0
  106. package/src/Prebuilt/layouts/EmbedView.jsx +0 -1
  107. package/src/Prebuilt/layouts/InsetView.jsx +65 -24
  108. package/src/Prebuilt/layouts/PDFView.jsx +0 -1
  109. package/src/Prebuilt/layouts/SidePane.jsx +8 -7
  110. package/src/Prebuilt/layouts/WhiteboardView.jsx +2 -4
  111. package/src/Prebuilt/layouts/mainView.jsx +22 -31
  112. package/src/Prebuilt/layouts/screenShareView.jsx +0 -2
  113. package/src/Prebuilt/plugins/VirtualBackground/VirtualBackground.jsx +25 -1
  114. package/src/Prebuilt/plugins/whiteboard/index.js +1 -1
  115. package/src/Prebuilt/primitives/DialogContent.jsx +1 -1
  116. package/src/Prebuilt/provider/roomLayoutProvider/index.tsx +1 -1
  117. package/src/Sheet/Sheet.mdx +19 -0
  118. package/src/Sheet/Sheet.stories.tsx +103 -0
  119. package/src/Sheet/Sheet.tsx +118 -0
  120. package/src/Sheet/index.ts +1 -0
  121. package/src/Theme/ThemeProvider.tsx +10 -13
  122. package/src/Theme/base.config.ts +1 -1
  123. package/src/Theme/stitches.config.ts +1 -1
  124. package/src/TileMenu/StyledMenuTile.tsx +2 -2
  125. package/src/TileMenu/TileMenu.tsx +2 -0
  126. package/src/VideoTile/StyledVideoTile.tsx +5 -0
  127. package/src/utils/animations.ts +18 -0
  128. package/dist/ActiveSpeakerView-AGL73O6U.css +0 -11
  129. package/dist/ActiveSpeakerView-AGL73O6U.css.map +0 -7
  130. package/dist/ActiveSpeakerView-UPFD5RXA.js +0 -39
  131. package/dist/ActiveSpeakerView-UPFD5RXA.js.map +0 -7
  132. package/dist/HLSView-64OG755F.css +0 -11
  133. package/dist/HLSView-64OG755F.css.map +0 -7
  134. package/dist/PinnedTrackView-O4FHHHOV.js +0 -70
  135. package/dist/PinnedTrackView-O4FHHHOV.js.map +0 -7
  136. package/dist/PinnedTrackView-YWAZ2342.css +0 -11
  137. package/dist/PinnedTrackView-YWAZ2342.css.map +0 -7
  138. package/dist/VirtualBackground-BCKXNDTD.js.map +0 -7
  139. package/dist/chunk-3HMUOAD6.js.map +0 -7
  140. package/dist/chunk-6GXDYWD5.js +0 -243
  141. package/dist/chunk-6GXDYWD5.js.map +0 -7
  142. package/dist/chunk-NLZVUXR3.js.map +0 -7
  143. package/dist/chunk-ORPC2GYB.js +0 -58
  144. package/dist/chunk-ORPC2GYB.js.map +0 -7
  145. package/dist/chunk-YE4RPJYG.js +0 -811
  146. package/dist/chunk-YE4RPJYG.js.map +0 -7
  147. package/dist/conference-7KHWJZLG.css +0 -11
  148. package/dist/conference-7KHWJZLG.css.map +0 -7
  149. package/dist/conference-ETISNCLN.js +0 -3697
  150. package/dist/conference-ETISNCLN.js.map +0 -7
  151. package/dist/index.cjs.css +0 -11
  152. package/dist/index.cjs.css.map +0 -7
  153. package/dist/index.css +0 -11
  154. package/dist/index.css.map +0 -7
  155. package/dist/transcription-JJQ4UAIK.js +0 -356
  156. package/dist/transcription-JJQ4UAIK.js.map +0 -7
  157. package/src/Prebuilt/common/useSortedPeers.js +0 -28
  158. package/src/Prebuilt/components/BottomActionSheet/BottomActionSheet.jsx +0 -96
  159. package/src/Prebuilt/components/BottomActionSheet/BottomActionSheet.stories.tsx +0 -46
  160. package/src/Prebuilt/components/Footer/ConferencingFooter.jsx +0 -101
  161. package/src/Prebuilt/components/Footer/StreamingFooter.jsx +0 -71
  162. package/src/Prebuilt/components/Footer.jsx +0 -8
  163. package/src/Prebuilt/components/MoreSettings/ChangeSelfRole.jsx +0 -67
  164. package/src/Prebuilt/components/TileMenu.jsx +0 -268
  165. package/src/Prebuilt/index.d.ts +0 -20
  166. package/src/Prebuilt/index.js +0 -2
@@ -1,7 +1,9 @@
1
1
  import React, { Fragment } from 'react';
2
2
  import {
3
3
  DeviceType,
4
+ HMSRoomState,
4
5
  selectLocalVideoTrackID,
6
+ selectRoomState,
5
7
  selectVideoTrackByID,
6
8
  useAVToggle,
7
9
  useDevices,
@@ -18,7 +20,7 @@ import { isMacOS } from '../common/constants';
18
20
 
19
21
  const optionsCSS = { fontWeight: '$semiBold', color: '$on_surface_high', w: '100%', p: '$8' };
20
22
 
21
- export const AudioVideoToggle = () => {
23
+ export const AudioVideoToggle = ({ hideOptions = false }) => {
22
24
  const { allDevices, selectedDeviceIDs, updateDevice } = useDevices();
23
25
  const { videoInput, audioInput } = allDevices;
24
26
 
@@ -64,40 +66,81 @@ export const AudioVideoToggle = () => {
64
66
  const actions = useHMSActions();
65
67
  const videoTrackId = useHMSStore(selectLocalVideoTrackID);
66
68
  const localVideoTrack = useHMSStore(selectVideoTrackByID(videoTrackId));
69
+ const roomState = useHMSStore(selectRoomState);
67
70
 
68
71
  return (
69
72
  <Fragment>
70
73
  {toggleAudio ? (
71
- <IconButtonWithOptions
72
- options={formattedAudioInputList}
73
- tooltipMessage={`Turn ${isLocalAudioEnabled ? 'off' : 'on'} audio (${isMacOS ? '⌘' : 'ctrl'} + d)`}
74
- icon={
75
- !isLocalAudioEnabled ? <MicOffIcon data-testid="audio_off_btn" /> : <MicOnIcon data-testid="audio_on_btn" />
76
- }
77
- active={isLocalAudioEnabled}
78
- onClick={toggleAudio}
79
- key="toggleAudio"
80
- />
74
+ hideOptions ? (
75
+ <Tooltip title={`Turn ${isLocalAudioEnabled ? 'off' : 'on'} audio (${isMacOS ? '⌘' : 'ctrl'} + d)`}>
76
+ <IconButton
77
+ active={isLocalAudioEnabled}
78
+ onClick={toggleAudio}
79
+ key="toggleAudio"
80
+ data-testid="audio_btn"
81
+ className="__cancel-drag-event"
82
+ >
83
+ {!isLocalAudioEnabled ? (
84
+ <MicOffIcon data-testid="audio_off_btn" />
85
+ ) : (
86
+ <MicOnIcon data-testid="audio_on_btn" />
87
+ )}
88
+ </IconButton>
89
+ </Tooltip>
90
+ ) : (
91
+ <IconButtonWithOptions
92
+ options={formattedAudioInputList}
93
+ tooltipMessage={`Turn ${isLocalAudioEnabled ? 'off' : 'on'} audio (${isMacOS ? '⌘' : 'ctrl'} + d)`}
94
+ icon={
95
+ !isLocalAudioEnabled ? (
96
+ <MicOffIcon data-testid="audio_off_btn" />
97
+ ) : (
98
+ <MicOnIcon data-testid="audio_on_btn" />
99
+ )
100
+ }
101
+ active={isLocalAudioEnabled}
102
+ onClick={toggleAudio}
103
+ key="toggleAudio"
104
+ />
105
+ )
81
106
  ) : null}
82
107
 
83
108
  {toggleVideo ? (
84
- <IconButtonWithOptions
85
- options={formattedVideoInputList}
86
- tooltipMessage={`Turn ${isLocalVideoEnabled ? 'off' : 'on'} video (${isMacOS ? '⌘' : 'ctrl'} + e)`}
87
- icon={
88
- !isLocalVideoEnabled ? (
89
- <VideoOffIcon data-testid="video_off_btn" />
90
- ) : (
91
- <VideoOnIcon data-testid="video_on_btn" />
92
- )
93
- }
94
- key="toggleVideo"
95
- active={isLocalVideoEnabled}
96
- onClick={toggleVideo}
97
- />
109
+ hideOptions ? (
110
+ <Tooltip title={`Turn ${isLocalVideoEnabled ? 'off' : 'on'} video (${isMacOS ? '⌘' : 'ctrl'} + e)`}>
111
+ <IconButton
112
+ key="toggleVideo"
113
+ active={isLocalVideoEnabled}
114
+ onClick={toggleVideo}
115
+ data-testid="video_btn"
116
+ className="__cancel-drag-event"
117
+ >
118
+ {!isLocalVideoEnabled ? (
119
+ <VideoOffIcon data-testid="video_off_btn" />
120
+ ) : (
121
+ <VideoOnIcon data-testid="video_on_btn" />
122
+ )}
123
+ </IconButton>
124
+ </Tooltip>
125
+ ) : (
126
+ <IconButtonWithOptions
127
+ options={formattedVideoInputList}
128
+ tooltipMessage={`Turn ${isLocalVideoEnabled ? 'off' : 'on'} video (${isMacOS ? '⌘' : 'ctrl'} + e)`}
129
+ icon={
130
+ !isLocalVideoEnabled ? (
131
+ <VideoOffIcon data-testid="video_off_btn" />
132
+ ) : (
133
+ <VideoOnIcon data-testid="video_on_btn" />
134
+ )
135
+ }
136
+ key="toggleVideo"
137
+ active={isLocalVideoEnabled}
138
+ onClick={toggleVideo}
139
+ />
140
+ )
98
141
  ) : null}
99
142
 
100
- {localVideoTrack?.facingMode ? (
143
+ {localVideoTrack?.facingMode && roomState === HMSRoomState.Preview ? (
101
144
  <Tooltip title="Switch Camera" key="switchCamera">
102
145
  <IconButton
103
146
  onClick={async () => {
@@ -22,7 +22,7 @@ import { APP_DATA, QUERY_PARAM_AUTH_TOKEN } from '../common/constants';
22
22
  const AuthToken = React.memo(({ authTokenByRoomCodeEndpoint }) => {
23
23
  const hmsActions = useHMSActions();
24
24
  const tokenEndpoint = useTokenEndpoint();
25
- const { showPreview, roomCode } = useHMSPrebuiltContext();
25
+ const { showPreview, roomCode, userId } = useHMSPrebuiltContext();
26
26
  const location = useLocation();
27
27
  const matches = useMemo(
28
28
  () =>
@@ -46,7 +46,7 @@ const AuthToken = React.memo(({ authTokenByRoomCodeEndpoint }) => {
46
46
  const code = !userRole && (roomCode || urlRoomCode);
47
47
 
48
48
  const getTokenFn = code
49
- ? () => hmsActions.getAuthTokenByRoomCode({ roomCode: code }, { endpoint: authTokenByRoomCodeEndpoint })
49
+ ? () => hmsActions.getAuthTokenByRoomCode({ roomCode: code, userId }, { endpoint: authTokenByRoomCodeEndpoint })
50
50
  : () => getToken(tokenEndpoint, uuid(), userRole, urlRoomId);
51
51
 
52
52
  getTokenFn()
@@ -66,6 +66,7 @@ const AuthToken = React.memo(({ authTokenByRoomCodeEndpoint }) => {
66
66
  authTokenByRoomCodeEndpoint,
67
67
  setAuthTokenInAppData,
68
68
  roomCode,
69
+ userId,
69
70
  ]);
70
71
 
71
72
  if (error.title) {
@@ -10,7 +10,7 @@ import {
10
10
  } from '@100mslive/react-sdk';
11
11
  import { CheckIcon } from '@100mslive/react-icons';
12
12
  import { Box, Dropdown, Flex, HorizontalDivider, Text, Tooltip } from '../../../';
13
- import { ParticipantSearch } from '../Header/ParticipantList';
13
+ import { ParticipantSearch } from '../Footer/ParticipantList';
14
14
  import { useFilteredRoles } from '../../common/hooks';
15
15
 
16
16
  const ChatDotIcon = () => {
@@ -31,7 +31,6 @@ const Wrapper = styled('div', {
31
31
  backgroundColor: '$background_dim',
32
32
  borderRadius: '$1',
33
33
  maxWidth: '85%',
34
- zIndex: 1,
35
34
  '& p,span': {
36
35
  p: '$2 $3',
37
36
  },
@@ -5,44 +5,36 @@ import {
5
5
  selectAvailableRoleNames,
6
6
  selectIsConnectedToRoom,
7
7
  selectLocalPeerID,
8
- selectLocalPeerRoleName,
9
8
  useCustomEvent,
10
9
  useHMSActions,
11
10
  useHMSStore,
12
11
  useRecordingStreaming,
13
12
  } from '@100mslive/react-sdk';
14
13
  import { EmojiIcon } from '@100mslive/react-icons';
14
+ import { EmojiCard } from './Footer/EmojiCard';
15
+ import { ToastManager } from './Toast/ToastManager';
15
16
  import { Dropdown } from '../../Dropdown';
16
- import { Flex } from '../../Layout';
17
- import { Text } from '../../Text';
18
- import { styled } from '../../Theme';
17
+ import { Box } from '../../Layout';
19
18
  import { Tooltip } from '../../Tooltip';
20
19
  import IconButton from '../IconButton';
21
20
  import { useHLSViewerRole } from './AppData/useUISettings';
22
21
  import { useDropdownList } from './hooks/useDropdownList';
23
22
  import { useIsFeatureEnabled } from './hooks/useFeatures';
24
- import { EMOJI_REACTION_TYPE, FEATURE_LIST, HLS_TIMED_METADATA_DOC_URL } from '../common/constants';
23
+ import { EMOJI_REACTION_TYPE, FEATURE_LIST } from '../common/constants';
25
24
 
26
25
  init({ data });
27
26
 
28
- // When changing emojis in the grid, keep in mind that the payload used in sendHLSTimedMetadata has a limit of 100 characters. Using bigger emoji Ids can cause the limit to be exceeded.
29
- const emojiReactionList = [
30
- [{ emojiId: '+1' }, { emojiId: '-1' }, { emojiId: 'wave' }, { emojiId: 'clap' }, { emojiId: 'fire' }],
31
- [{ emojiId: 'tada' }, { emojiId: 'heart_eyes' }, { emojiId: 'joy' }, { emojiId: 'open_mouth' }, { emojiId: 'sob' }],
32
- ];
33
-
34
27
  export const EmojiReaction = () => {
35
28
  const [open, setOpen] = useState(false);
36
- const hmsActions = useHMSActions();
37
29
  const isConnected = useHMSStore(selectIsConnectedToRoom);
30
+ const isFeatureEnabled = useIsFeatureEnabled(FEATURE_LIST.EMOJI_REACTION);
31
+ useDropdownList({ open: open, name: 'EmojiReaction' });
32
+ const hmsActions = useHMSActions();
38
33
  const roles = useHMSStore(selectAvailableRoleNames);
39
- const localPeerRole = useHMSStore(selectLocalPeerRoleName);
40
34
  const localPeerId = useHMSStore(selectLocalPeerID);
41
35
  const hlsViewerRole = useHLSViewerRole();
42
36
  const { isStreamingOn } = useRecordingStreaming();
43
- const isFeatureEnabled = useIsFeatureEnabled(FEATURE_LIST.EMOJI_REACTION);
44
37
  const filteredRoles = useMemo(() => roles.filter(role => role !== hlsViewerRole), [roles, hlsViewerRole]);
45
- useDropdownList({ open: open, name: 'EmojiReaction' });
46
38
 
47
39
  const onEmojiEvent = useCallback(data => {
48
40
  window.showFlyingEmoji(data?.emojiId, data?.senderId);
@@ -61,16 +53,21 @@ export const EmojiReaction = () => {
61
53
  };
62
54
  sendEvent(data, { roleNames: filteredRoles });
63
55
  if (isStreamingOn) {
64
- await hmsActions.sendHLSTimedMetadata([
65
- {
66
- payload: JSON.stringify(data),
67
- duration: 2,
68
- },
69
- ]);
56
+ try {
57
+ await hmsActions.sendHLSTimedMetadata([
58
+ {
59
+ payload: JSON.stringify(data),
60
+ duration: 2,
61
+ },
62
+ ]);
63
+ } catch (error) {
64
+ console.log(error);
65
+ ToastManager.addToast({ title: error.message });
66
+ }
70
67
  }
71
68
  };
72
69
 
73
- if (!isConnected || localPeerRole === hlsViewerRole || !isFeatureEnabled) {
70
+ if (!isConnected || !isFeatureEnabled) {
74
71
  return null;
75
72
  }
76
73
  return (
@@ -79,63 +76,16 @@ export const EmojiReaction = () => {
79
76
  <Dropdown.Trigger asChild data-testid="emoji_reaction_btn">
80
77
  <IconButton>
81
78
  <Tooltip title="Emoji reaction">
82
- <EmojiIcon />
79
+ <Box>
80
+ <EmojiIcon />
81
+ </Box>
83
82
  </Tooltip>
84
83
  </IconButton>
85
84
  </Dropdown.Trigger>
86
85
  <Dropdown.Content sideOffset={5} align="center" css={{ p: '$8', bg: '$surface_default' }}>
87
- {emojiReactionList.map((emojiLine, index) => (
88
- <Flex key={index} justify="between" css={{ mb: '$8' }}>
89
- {emojiLine.map(emoji => (
90
- <EmojiContainer key={emoji.emojiId} onClick={() => sendReaction(emoji.emojiId)}>
91
- <em-emoji id={emoji.emojiId} size="100%" set="apple"></em-emoji>
92
- </EmojiContainer>
93
- ))}
94
- </Flex>
95
- ))}
96
- <div style={{ textAlign: 'center' }}>
97
- <Text
98
- variant="sm"
99
- inline={true}
100
- css={{
101
- color: '$on_primary_medium',
102
- }}
103
- >
104
- Reactions will be timed for Live Streaming viewers.{' '}
105
- </Text>
106
- <Text
107
- variant="sm"
108
- inline={true}
109
- css={{
110
- color: '$primary_bright',
111
- fontWeight: '$semiBold',
112
- }}
113
- >
114
- <a
115
- href={HLS_TIMED_METADATA_DOC_URL}
116
- target="_blank"
117
- rel="noopener noreferrer"
118
- style={{ color: 'inherit', textDecoration: 'none' }}
119
- >
120
- Learn more.
121
- </a>
122
- </Text>
123
- </div>
86
+ <EmojiCard sendReaction={sendReaction} />
124
87
  </Dropdown.Content>
125
88
  </Dropdown.Root>
126
89
  </Fragment>
127
90
  );
128
91
  };
129
-
130
- const EmojiContainer = styled('span', {
131
- position: 'relative',
132
- cursor: 'pointer',
133
- width: '$16',
134
- height: '$16',
135
- p: '$4',
136
- '&:hover': {
137
- p: '7px',
138
- bg: '$surface_brighter',
139
- borderRadius: '$1',
140
- },
141
- });
@@ -0,0 +1,57 @@
1
+ import React from 'react';
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';
7
+
8
+ export const EndSessionContent = ({ setShowEndStreamAlert, stopStream, leaveRoom, isModal = false }) => {
9
+ const showStreamingUI = useShowStreamingUI();
10
+ return (
11
+ <Box>
12
+ <Flex
13
+ css={{
14
+ color: '$alert_error_default',
15
+ display: 'flex',
16
+ alignItems: 'center',
17
+ }}
18
+ >
19
+ <AlertTriangleIcon style={{ marginRight: '0.5rem' }} />
20
+ <Text variant="lg" css={{ color: 'inherit', fontWeight: '$semiBold' }}>
21
+ End {showStreamingUI ? 'Stream' : 'Session'}
22
+ </Text>
23
+ {isModal ? null : (
24
+ <Box css={{ color: '$on_surface_high', ml: 'auto' }} onClick={() => setShowEndStreamAlert(false)}>
25
+ <CrossIcon />
26
+ </Box>
27
+ )}
28
+ </Flex>
29
+ <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.
31
+ </Text>
32
+ <Flex align="center" justify="between" css={{ w: '100%', gap: '$8' }}>
33
+ <Button
34
+ outlined
35
+ variant="standard"
36
+ css={{ w: '100%', '@md': { display: 'none' } }}
37
+ onClick={() => setShowEndStreamAlert(false)}
38
+ >
39
+ Cancel
40
+ </Button>
41
+ <Button
42
+ variant="danger"
43
+ css={{ w: '100%' }}
44
+ onClick={async () => {
45
+ await stopStream();
46
+ leaveRoom();
47
+ setShowEndStreamAlert(false);
48
+ }}
49
+ id="stopStream"
50
+ data-testid="stop_stream_btn"
51
+ >
52
+ End {showStreamingUI ? 'Stream' : 'Session'}
53
+ </Button>
54
+ </Flex>
55
+ </Box>
56
+ );
57
+ };
@@ -0,0 +1,180 @@
1
+ import React, { useEffect, useMemo, useState } from 'react';
2
+ import { useMeasure, useMedia } from 'react-use';
3
+ import {
4
+ getPeersWithTiles,
5
+ selectLocalPeer,
6
+ selectPeers,
7
+ selectRemotePeers,
8
+ selectTracksMap,
9
+ useHMSStore,
10
+ useHMSVanillaStore,
11
+ } from '@100mslive/react-sdk';
12
+ import { Box, Flex } from '../../Layout';
13
+ import { config as cssConfig } from '../../Theme';
14
+ import { InsetTile } from '../layouts/InsetView';
15
+ import { useRoomLayout } from '../provider/roomLayoutProvider';
16
+ import { Pagination } from './Pagination';
17
+ import VideoTile from './VideoTile';
18
+ import { useUISettings } from './AppData/useUISettings';
19
+ import PeersSorter from '../common/PeersSorter';
20
+ import { UI_SETTINGS } from '../common/constants';
21
+
22
+ const aspectRatioConfig = { default: [1 / 1, 4 / 3, 16 / 9], mobile: [1 / 1, 3 / 4, 9 / 16] };
23
+
24
+ export function EqualProminence() {
25
+ const layout = useRoomLayout();
26
+ const { enable_local_tile_inset: isInsetEnabled = true } =
27
+ //@ts-ignore
28
+ layout?.screens?.conferencing?.default?.elements?.video_tile_layout?.grid || {};
29
+ const peers = useHMSStore(isInsetEnabled ? selectRemotePeers : selectPeers);
30
+ const [sortedPeers, setSortedPeers] = useState(peers);
31
+ const localPeer = useHMSStore(selectLocalPeer);
32
+ const vanillaStore = useHMSVanillaStore();
33
+ const isMobile = useMedia(cssConfig.media.md);
34
+ let maxTileCount = useUISettings(UI_SETTINGS.maxTileCount);
35
+ maxTileCount = isMobile ? Math.min(maxTileCount, 6) : maxTileCount;
36
+ const [pagesWithTiles, setPagesWithTiles] = useState([]);
37
+ const [page, setPage] = useState(0);
38
+ const [ref, { width, height }] = useMeasure();
39
+ const peersSorter = useMemo(() => new PeersSorter(vanillaStore), [vanillaStore]);
40
+ const pageSize = pagesWithTiles[0]?.length;
41
+
42
+ useEffect(() => {
43
+ // currentPageIndex should not exceed pages length
44
+ if (page >= pagesWithTiles.length) {
45
+ setPage(0);
46
+ }
47
+ }, [pagesWithTiles.length, page]);
48
+
49
+ useEffect(() => {
50
+ if (width === 0 || height === 0) {
51
+ return;
52
+ }
53
+ const tracksMap = vanillaStore.getState(selectTracksMap);
54
+ const peersWithTiles = getPeersWithTiles(
55
+ sortedPeers.length === 0 ? [localPeer] : sortedPeers,
56
+ tracksMap,
57
+ () => false,
58
+ );
59
+ const noOfPages = Math.ceil(peersWithTiles.length / maxTileCount);
60
+ let remaining = peersWithTiles.length;
61
+ let sliceStart = 0;
62
+ let pagesList = [];
63
+ // split into pages
64
+ for (let i = 0; i < noOfPages; i++) {
65
+ const count = Math.min(remaining, maxTileCount);
66
+ pagesList.push(peersWithTiles.slice(sliceStart, sliceStart + count));
67
+ remaining = remaining - count;
68
+ sliceStart += count;
69
+ }
70
+ // calculate dimesions for each page
71
+ for (const page of pagesList) {
72
+ const noOfTilesInPage = page.length;
73
+ let maxCols =
74
+ noOfTilesInPage > 2 && noOfTilesInPage < 9
75
+ ? Math.ceil(noOfTilesInPage / 2)
76
+ : Math.ceil(Math.sqrt(noOfTilesInPage));
77
+ if (isMobile) {
78
+ maxCols = noOfTilesInPage < 4 ? 1 : Math.min(maxCols, 2);
79
+ }
80
+ let maxRows = Math.ceil(noOfTilesInPage / maxCols);
81
+ let index = 0;
82
+ // convert the current page to a matrix(grid)
83
+ const matrix = new Array(maxRows).fill(null).map((_, i) => {
84
+ const numCols = Math.min(maxCols, noOfTilesInPage - i * maxCols);
85
+ let rowElements = [];
86
+ for (let j = 0; j < numCols; j++) {
87
+ if (index < page.length) {
88
+ rowElements.push(page[index++]);
89
+ }
90
+ }
91
+ return rowElements;
92
+ });
93
+
94
+ const maxHeight = height - (maxRows - 1) * 8;
95
+ const maxRowHeight = maxHeight / matrix.length;
96
+ const aspectRatios =
97
+ isMobile && (noOfTilesInPage === 1 || noOfTilesInPage > 3)
98
+ ? aspectRatioConfig.mobile
99
+ : aspectRatioConfig.default;
100
+ // calculate height and width of each tile in a row
101
+ for (const row of matrix) {
102
+ let tileWidth = (width - (row.length - 1) * 8) / row.length;
103
+ let tileHeight = 0;
104
+ const calcHeights = aspectRatios.map(aR => tileWidth / aR);
105
+ for (const h of calcHeights) {
106
+ if (h < maxRowHeight) {
107
+ if (tileHeight < h) {
108
+ tileHeight = h;
109
+ }
110
+ }
111
+ }
112
+
113
+ // tileHeight is not calculated as it could be exceeding the max possible height
114
+ // find the max possible width instead
115
+ if (tileHeight === 0) {
116
+ tileHeight = maxRowHeight;
117
+ const calcWidths = aspectRatios.map(aR => tileHeight * aR);
118
+ tileWidth = 0;
119
+ for (const w of calcWidths) {
120
+ if (w < width) {
121
+ if (tileWidth < w) {
122
+ tileWidth = w;
123
+ }
124
+ }
125
+ }
126
+ }
127
+ for (let i = 0; i < row.length; i++) {
128
+ row[i].width = tileWidth;
129
+ row[i].height = tileHeight;
130
+ }
131
+ }
132
+ }
133
+ setPagesWithTiles(pagesList);
134
+ }, [width, height, maxTileCount, vanillaStore, sortedPeers, page, isMobile, localPeer]);
135
+
136
+ useEffect(() => {
137
+ if (page !== 0) {
138
+ return;
139
+ }
140
+ peersSorter.setPeersAndTilesPerPage({
141
+ peers,
142
+ tilesPerPage: pageSize || maxTileCount,
143
+ });
144
+ peersSorter.onUpdate(setSortedPeers);
145
+ }, [page, peersSorter, peers, pageSize, maxTileCount]);
146
+
147
+ return (
148
+ <Flex direction="column" css={{ flex: '1 1 0', h: '100%', position: 'relative', minWidth: 0 }}>
149
+ <Box
150
+ ref={ref}
151
+ css={{
152
+ flex: '1 1 0',
153
+ gap: '$4',
154
+ display: 'flex',
155
+ placeContent: 'center',
156
+ alignItems: 'center',
157
+ justifyContent: 'center',
158
+ flexFlow: 'row wrap',
159
+ minHeight: 0,
160
+ }}
161
+ >
162
+ {pagesWithTiles[page]?.map(tile => {
163
+ return (
164
+ <VideoTile
165
+ key={tile.track?.id || tile.peer?.id}
166
+ width={tile.width}
167
+ height={tile.height}
168
+ peerId={tile.peer?.id}
169
+ trackId={tile.track?.id}
170
+ rootCSS={{ padding: 0 }}
171
+ objectFit="contain"
172
+ />
173
+ );
174
+ })}
175
+ </Box>
176
+ {pagesWithTiles.length > 1 && <Pagination page={page} onPageChange={setPage} numPages={pagesWithTiles.length} />}
177
+ {isInsetEnabled && sortedPeers.length > 0 && <InsetTile />}
178
+ </Flex>
179
+ );
180
+ }
@@ -1,5 +1,4 @@
1
1
  import React, { Component } from 'react';
2
- import { logMessage } from 'zipyai';
3
2
  import { CopyIcon } from '@100mslive/react-icons';
4
3
  import { Button } from '../../Button';
5
4
  import { Box, Flex } from '../../Layout';
@@ -16,15 +15,10 @@ export class ErrorBoundary extends Component {
16
15
  componentDidCatch(error, errorInfo) {
17
16
  console.error(`react error boundary - ${error.message}`, error, errorInfo);
18
17
  // Catch errors in any components below and re-render with error message
19
- this.setState(
20
- {
21
- error: error?.message,
22
- errorInfo: errorInfo,
23
- },
24
- () => {
25
- logMessage(`uiError - ${this.state.error} - ${JSON.stringify(this.state.errorInfo)}`);
26
- },
27
- );
18
+ this.setState({
19
+ error: error?.message,
20
+ errorInfo: errorInfo,
21
+ });
28
22
  }
29
23
 
30
24
  render() {
@@ -0,0 +1,34 @@
1
+ import React from 'react';
2
+ import { Flex } from '../../../Layout';
3
+ import { styled } from '../../../Theme';
4
+
5
+ // When changing emojis in the grid, keep in mind that the payload used in sendHLSTimedMetadata has a limit of 100 characters. Using bigger emoji Ids can cause the limit to be exceeded.
6
+ const emojiReactionList = [
7
+ [{ emojiId: '+1' }, { emojiId: '-1' }, { emojiId: 'wave' }, { emojiId: 'clap' }, { emojiId: 'fire' }],
8
+ [{ emojiId: 'tada' }, { emojiId: 'heart_eyes' }, { emojiId: 'joy' }, { emojiId: 'open_mouth' }, { emojiId: 'sob' }],
9
+ ];
10
+
11
+ export const EmojiCard = ({ sendReaction }) => {
12
+ return emojiReactionList.map((emojiLine, index) => (
13
+ <Flex key={index} justify="between" css={{ mb: '$8' }}>
14
+ {emojiLine.map(emoji => (
15
+ <EmojiContainer key={emoji.emojiId} onClick={() => sendReaction(emoji.emojiId)}>
16
+ <em-emoji id={emoji.emojiId} size="100%" set="apple"></em-emoji>
17
+ </EmojiContainer>
18
+ ))}
19
+ </Flex>
20
+ ));
21
+ };
22
+
23
+ const EmojiContainer = styled('span', {
24
+ position: 'relative',
25
+ cursor: 'pointer',
26
+ width: '$16',
27
+ height: '$16',
28
+ p: '$4',
29
+ '&:hover': {
30
+ p: '7px',
31
+ bg: '$surface_brighter',
32
+ borderRadius: '$1',
33
+ },
34
+ });