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

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 (136) hide show
  1. package/dist/{HLSView-PY2FKWX3.js → HLSView-QMU5JK7U.js} +208 -118
  2. package/dist/HLSView-QMU5JK7U.js.map +7 -0
  3. package/dist/Prebuilt/AppContext.d.ts +1 -1
  4. package/dist/Prebuilt/components/Chat/ChatFooter.d.ts +7 -0
  5. package/dist/Prebuilt/components/Connection/ConnectionIndicator.d.ts +6 -0
  6. package/dist/Prebuilt/components/Connection/TileConnection.d.ts +10 -0
  7. package/dist/Prebuilt/components/Footer/ChatToggle.d.ts +2 -0
  8. package/dist/Prebuilt/components/Footer/RoleAccordion.d.ts +14 -0
  9. package/dist/Prebuilt/components/Footer/RoleOptions.d.ts +6 -0
  10. package/dist/Prebuilt/components/Header/StreamActions.d.ts +11 -0
  11. package/dist/Prebuilt/components/Leave/DesktopLeaveRoom.d.ts +4 -3
  12. package/dist/Prebuilt/components/Leave/EndSessionContent.d.ts +4 -3
  13. package/dist/Prebuilt/components/Leave/LeaveCard.d.ts +1 -2
  14. package/dist/Prebuilt/components/Leave/LeaveSessionContent.d.ts +3 -1
  15. package/dist/Prebuilt/components/Leave/MwebLeaveRoom.d.ts +4 -3
  16. package/dist/Prebuilt/components/MoreSettings/SplitComponents/MwebOptions.d.ts +6 -0
  17. package/dist/Prebuilt/components/Preview/PreviewContainer.d.ts +3 -0
  18. package/dist/Prebuilt/components/Preview/PreviewJoin.d.ts +16 -0
  19. package/dist/Prebuilt/components/RoleChangeRequestModal.d.ts +2 -0
  20. package/dist/Prebuilt/components/SecondaryTiles.d.ts +1 -1
  21. package/dist/Prebuilt/components/SidePaneTabs.d.ts +7 -0
  22. package/dist/Prebuilt/components/VideoLayouts/EqualProminence.d.ts +1 -1
  23. package/dist/Prebuilt/components/VideoLayouts/Grid.d.ts +1 -0
  24. package/dist/Prebuilt/components/VideoLayouts/GridLayout.d.ts +5 -3
  25. package/dist/Prebuilt/components/VideoLayouts/ProminenceLayout.d.ts +6 -3
  26. package/dist/Prebuilt/components/VideoLayouts/RoleProminence.d.ts +1 -1
  27. package/dist/Prebuilt/components/VideoLayouts/ScreenshareLayout.d.ts +1 -1
  28. package/dist/Prebuilt/components/VideoLayouts/interface.d.ts +1 -0
  29. package/dist/Prebuilt/components/hooks/useAutoStartStreaming.d.ts +1 -0
  30. package/dist/Prebuilt/components/hooks/useRedirectToLeave.d.ts +3 -0
  31. package/dist/Prebuilt/components/hooks/useTileLayout.d.ts +2 -1
  32. package/dist/Prebuilt/components/hooks/useVideoTileLayout.d.ts +2 -0
  33. package/dist/Prebuilt/layouts/SidePane.d.ts +4 -1
  34. package/dist/Prebuilt/layouts/VideoStreamingSection.d.ts +2 -1
  35. package/dist/{VirtualBackground-AYDHYLIZ.js → VirtualBackground-37FXUPYO.js} +6 -6
  36. package/dist/VirtualBackground-37FXUPYO.js.map +7 -0
  37. package/dist/{chunk-GQD2AGWW.js → chunk-KBVIZGYW.js} +12 -2
  38. package/dist/{chunk-GQD2AGWW.js.map → chunk-KBVIZGYW.js.map} +2 -2
  39. package/dist/{chunk-RXTHJUMZ.js → chunk-WVGGQZK4.js} +986 -436
  40. package/dist/chunk-WVGGQZK4.js.map +7 -0
  41. package/dist/{chunk-E2M2ZSOL.js → chunk-ZKE2N5LH.js} +2 -2
  42. package/dist/{conference-V2XZGTKU.js → conference-FJJQ4TXX.js} +1136 -1301
  43. package/dist/conference-FJJQ4TXX.js.map +7 -0
  44. package/dist/index.cjs.js +3565 -3092
  45. package/dist/index.cjs.js.map +4 -4
  46. package/dist/index.js +2 -2
  47. package/dist/meta.cjs.json +773 -525
  48. package/dist/meta.esbuild.json +833 -579
  49. package/package.json +8 -7
  50. package/src/Prebuilt/App.tsx +10 -21
  51. package/src/Prebuilt/AppContext.tsx +1 -1
  52. package/src/Prebuilt/IconButton.jsx +10 -0
  53. package/src/Prebuilt/common/PeersSorter.ts +1 -1
  54. package/src/Prebuilt/common/constants.js +1 -2
  55. package/src/Prebuilt/common/utils.js +1 -1
  56. package/src/Prebuilt/components/AppData/AppData.jsx +8 -2
  57. package/src/Prebuilt/components/AppData/useUISettings.js +6 -6
  58. package/src/Prebuilt/components/AudioVideoToggle.jsx +8 -6
  59. package/src/Prebuilt/components/Chat/Chat.jsx +24 -11
  60. package/src/Prebuilt/components/Chat/ChatBody.jsx +20 -21
  61. package/src/Prebuilt/components/Chat/{ChatFooter.jsx → ChatFooter.tsx} +38 -13
  62. package/src/Prebuilt/components/Chat/useEmojiPickerStyles.js +5 -4
  63. package/src/Prebuilt/components/Connection/{ConnectionIndicator.jsx → ConnectionIndicator.tsx} +12 -4
  64. package/src/Prebuilt/components/Connection/{TileConnection.jsx → TileConnection.tsx} +20 -6
  65. package/src/Prebuilt/components/EmojiReaction.jsx +2 -6
  66. package/src/Prebuilt/components/Footer/{ChatToggle.jsx → ChatToggle.tsx} +4 -1
  67. package/src/Prebuilt/components/Footer/Footer.tsx +30 -5
  68. package/src/Prebuilt/components/Footer/ParticipantList.jsx +15 -49
  69. package/src/Prebuilt/components/Footer/{RoleAccordion.jsx → RoleAccordion.tsx} +33 -17
  70. package/src/Prebuilt/components/Footer/RoleOptions.tsx +155 -0
  71. package/src/Prebuilt/components/FullPageProgress.jsx +3 -3
  72. package/src/Prebuilt/components/HMSVideo/Controls.jsx +1 -0
  73. package/src/Prebuilt/components/HMSVideo/HLSQualitySelector.jsx +39 -17
  74. package/src/Prebuilt/components/HMSVideo/HMSVideo.jsx +2 -2
  75. package/src/Prebuilt/components/HMSVideo/VideoProgress.jsx +5 -6
  76. package/src/Prebuilt/components/HMSVideo/VolumeControl.jsx +1 -1
  77. package/src/Prebuilt/components/Header/HeaderComponents.jsx +8 -1
  78. package/src/Prebuilt/components/Header/{StreamActions.jsx → StreamActions.tsx} +23 -9
  79. package/src/Prebuilt/components/Header/common.jsx +5 -2
  80. package/src/Prebuilt/components/IconButtonWithOptions/IconButtonWithOptions.jsx +6 -1
  81. package/src/Prebuilt/components/InsetTile.tsx +15 -8
  82. package/src/Prebuilt/components/Leave/DesktopLeaveRoom.tsx +21 -11
  83. package/src/Prebuilt/components/Leave/EndSessionContent.tsx +2 -5
  84. package/src/Prebuilt/components/Leave/LeaveCard.tsx +1 -3
  85. package/src/Prebuilt/components/Leave/LeaveRoom.tsx +28 -25
  86. package/src/Prebuilt/components/Leave/LeaveSessionContent.tsx +8 -2
  87. package/src/Prebuilt/components/Leave/MwebLeaveRoom.tsx +8 -8
  88. package/src/Prebuilt/components/MoreSettings/ChangeNameContent.jsx +4 -0
  89. package/src/Prebuilt/components/MoreSettings/MoreSettings.tsx +1 -1
  90. package/src/Prebuilt/components/MoreSettings/SplitComponents/DesktopOptions.tsx +9 -23
  91. package/src/Prebuilt/components/MoreSettings/SplitComponents/{MwebOptions.jsx → MwebOptions.tsx} +89 -28
  92. package/src/Prebuilt/components/Notifications/Notifications.jsx +44 -28
  93. package/src/Prebuilt/components/Notifications/ReconnectNotifications.jsx +5 -11
  94. package/src/Prebuilt/components/Pagination.tsx +14 -12
  95. package/src/Prebuilt/components/Preview/{PreviewContainer.jsx → PreviewContainer.tsx} +11 -2
  96. package/src/Prebuilt/components/Preview/PreviewForm.tsx +6 -8
  97. package/src/Prebuilt/components/Preview/{PreviewJoin.jsx → PreviewJoin.tsx} +44 -21
  98. package/src/Prebuilt/components/{RoleChangeRequestModal.jsx → RoleChangeRequestModal.tsx} +36 -17
  99. package/src/Prebuilt/components/ScreenshareTile.jsx +6 -7
  100. package/src/Prebuilt/components/SecondaryTiles.tsx +12 -10
  101. package/src/Prebuilt/components/SidePaneTabs.tsx +120 -0
  102. package/src/Prebuilt/components/TileMenu/TileMenu.jsx +1 -1
  103. package/src/Prebuilt/components/TileMenu/TileMenuContent.jsx +14 -10
  104. package/src/Prebuilt/components/Toast/ToastConfig.jsx +5 -4
  105. package/src/Prebuilt/components/VideoLayouts/EqualProminence.tsx +13 -10
  106. package/src/Prebuilt/components/VideoLayouts/Grid.tsx +36 -34
  107. package/src/Prebuilt/components/VideoLayouts/GridLayout.tsx +33 -15
  108. package/src/Prebuilt/components/VideoLayouts/ProminenceLayout.tsx +45 -31
  109. package/src/Prebuilt/components/VideoLayouts/RoleProminence.tsx +12 -9
  110. package/src/Prebuilt/components/VideoLayouts/ScreenshareLayout.tsx +25 -9
  111. package/src/Prebuilt/components/VideoLayouts/interface.ts +1 -0
  112. package/src/Prebuilt/components/VideoTile.jsx +45 -53
  113. package/src/Prebuilt/components/conference.jsx +71 -74
  114. package/src/Prebuilt/components/hooks/useAutoStartStreaming.tsx +57 -0
  115. package/src/Prebuilt/components/hooks/useMetadata.jsx +19 -28
  116. package/src/Prebuilt/components/hooks/useRedirectToLeave.tsx +34 -0
  117. package/src/Prebuilt/components/hooks/useRoleProminencePeers.tsx +1 -1
  118. package/src/Prebuilt/components/hooks/useTileLayout.tsx +24 -18
  119. package/src/Prebuilt/components/hooks/useVideoTileLayout.ts +4 -0
  120. package/src/Prebuilt/layouts/EmbedView.jsx +1 -11
  121. package/src/Prebuilt/layouts/HLSView.jsx +152 -82
  122. package/src/Prebuilt/layouts/SidePane.tsx +25 -11
  123. package/src/Prebuilt/layouts/VideoStreamingSection.tsx +11 -47
  124. package/src/Prebuilt/plugins/FlyingEmoji.jsx +14 -2
  125. package/src/Prebuilt/plugins/VirtualBackground/VirtualBackground.jsx +3 -3
  126. package/src/Prebuilt/provider/roomLayoutProvider/hooks/useFetchRoomLayout.ts +2 -2
  127. package/src/Prebuilt/services/FeatureFlags.jsx +0 -1
  128. package/src/VideoTile/StyledVideoTile.tsx +1 -0
  129. package/dist/HLSView-PY2FKWX3.js.map +0 -7
  130. package/dist/VirtualBackground-AYDHYLIZ.js.map +0 -7
  131. package/dist/chunk-RXTHJUMZ.js.map +0 -7
  132. package/dist/conference-V2XZGTKU.js.map +0 -7
  133. package/src/Prebuilt/components/AudioLevel/BeamSpeakerLabelsLogging.jsx +0 -16
  134. package/src/Prebuilt/components/Chat/ChatParticipantHeader.jsx +0 -73
  135. package/src/Prebuilt/components/VideoList.jsx +0 -73
  136. /package/dist/{chunk-E2M2ZSOL.js.map → chunk-ZKE2N5LH.js.map} +0 -0
@@ -1,12 +1,15 @@
1
1
  /* eslint-disable no-case-declarations */
2
- import React, { useEffect } from 'react';
3
- import { useNavigate } from 'react-router-dom';
2
+ import React, { useCallback, useEffect } from 'react';
3
+ import { useNavigate, useParams } from 'react-router-dom';
4
4
  import {
5
5
  HMSNotificationTypes,
6
6
  HMSRoomState,
7
+ selectPeerMetadata,
7
8
  selectRoomState,
9
+ useCustomEvent,
8
10
  useHMSNotifications,
9
11
  useHMSStore,
12
+ useHMSVanillaStore,
10
13
  } from '@100mslive/react-sdk';
11
14
  import { Button } from '../../../';
12
15
  import { useUpdateRoomLayout } from '../../provider/roomLayoutProvider';
@@ -20,19 +23,32 @@ import { ReconnectNotifications } from './ReconnectNotifications';
20
23
  import { TrackBulkUnmuteModal } from './TrackBulkUnmuteModal';
21
24
  import { TrackNotifications } from './TrackNotifications';
22
25
  import { TrackUnmuteModal } from './TrackUnmuteModal';
23
- import { useIsHeadless, useSubscribedNotifications } from '../AppData/useUISettings';
26
+ import { useIsNotificationDisabled, useSubscribedNotifications } from '../AppData/useUISettings';
27
+ import { useRedirectToLeave } from '../hooks/useRedirectToLeave';
24
28
  import { getMetadata } from '../../common/utils';
25
-
29
+ import { ROLE_CHANGE_DECLINED } from '../../common/constants';
26
30
  export function Notifications() {
27
31
  const notification = useHMSNotifications();
28
32
  const navigate = useNavigate();
33
+ const params = useParams();
34
+ const vanillaStore = useHMSVanillaStore();
29
35
  const subscribedNotifications = useSubscribedNotifications() || {};
30
- const isHeadless = useIsHeadless();
31
36
  const roomState = useHMSStore(selectRoomState);
32
37
  const updateRoomLayoutForRole = useUpdateRoomLayout();
38
+ const isNotificationDisabled = useIsNotificationDisabled();
39
+ const { redirectToLeave } = useRedirectToLeave();
40
+
41
+ const handleRoleChangeDenied = useCallback(request => {
42
+ ToastManager.addToast({
43
+ title: `${request.peerName} denied your request to join the ${request.role.name} role`,
44
+ variant: 'error',
45
+ });
46
+ }, []);
47
+
48
+ useCustomEvent({ type: ROLE_CHANGE_DECLINED, onEvent: handleRoleChangeDenied });
33
49
 
34
50
  useEffect(() => {
35
- if (!notification) {
51
+ if (!notification || isNotificationDisabled) {
36
52
  return;
37
53
  }
38
54
  switch (notification.type) {
@@ -40,14 +56,14 @@ export function Notifications() {
40
56
  if (roomState !== HMSRoomState.Connected) {
41
57
  return;
42
58
  }
43
- // Don't toast message when metadata is updated and raiseHand is false.
44
- // Don't toast message in case of local peer.
59
+ // Don't show toast message when metadata is updated and raiseHand is false.
60
+ // Don't show toast message in case of local peer.
45
61
  const metadata = getMetadata(notification.data?.metadata);
46
- if (!metadata?.isHandRaised || notification.data.isLocal || isHeadless) return;
62
+ if (!metadata?.isHandRaised || notification.data.isLocal) return;
47
63
 
48
64
  console.debug('Metadata updated', notification.data);
49
65
  if (!subscribedNotifications.METADATA_UPDATED) return;
50
- ToastBatcher.showToast({ notification });
66
+ ToastBatcher.showToast({ notification, type: 'RAISE_HAND' });
51
67
  break;
52
68
  case HMSNotificationTypes.NAME_UPDATED:
53
69
  console.log(notification.data.id + ' changed their name to ' + notification.data.name);
@@ -69,7 +85,7 @@ export function Notifications() {
69
85
  <Button
70
86
  onClick={() => {
71
87
  ToastManager.removeToast(toastId);
72
- window.location.reload();
88
+ navigate(`/${params.roomId}${params.role ? `/${params.role}` : ''}`);
73
89
  }}
74
90
  >
75
91
  Rejoin
@@ -80,11 +96,7 @@ export function Notifications() {
80
96
  }
81
97
  // goto leave for terminal if any action is not performed within 2secs
82
98
  // if network is still unavailable going to preview will throw an error
83
- setTimeout(() => {
84
- const previewLocation = window.location.pathname.replace('meeting', 'leave');
85
- ToastManager.clearAllToast();
86
- navigate(previewLocation);
87
- }, 2000);
99
+ redirectToLeave(1000);
88
100
  return;
89
101
  }
90
102
  // Autoplay error or user denied screen share (cancelled browser pop-up)
@@ -99,14 +111,18 @@ export function Notifications() {
99
111
  title: `Error: ${notification.data?.message} - ${notification.data?.description}`,
100
112
  });
101
113
  break;
102
- case HMSNotificationTypes.ROLE_UPDATED:
114
+ case HMSNotificationTypes.ROLE_UPDATED: {
103
115
  if (notification.data?.isLocal) {
104
- ToastManager.addToast({
105
- title: `You are now a ${notification.data.roleName}`,
106
- });
107
- updateRoomLayoutForRole(notification.data.roleName);
116
+ const { prevRole } = vanillaStore.getState(selectPeerMetadata(notification.data?.id));
117
+ if (prevRole !== notification?.data?.roleName) {
118
+ ToastManager.addToast({
119
+ title: `You are now a ${notification.data.roleName}`,
120
+ });
121
+ updateRoomLayoutForRole(notification.data.roleName);
122
+ }
108
123
  }
109
124
  break;
125
+ }
110
126
  case HMSNotificationTypes.CHANGE_TRACK_STATE_REQUEST:
111
127
  const track = notification.data?.track;
112
128
  if (!notification.data.enabled) {
@@ -122,11 +138,7 @@ export function Notifications() {
122
138
  title: `${notification.message}.
123
139
  ${notification.data.reason && `Reason: ${notification.data.reason}`}`,
124
140
  });
125
- setTimeout(() => {
126
- const leaveLocation = window.location.pathname.replace('meeting', 'leave');
127
- navigate(leaveLocation);
128
- ToastManager.clearAllToast();
129
- }, 2000);
141
+ redirectToLeave(1000);
130
142
  break;
131
143
  case HMSNotificationTypes.DEVICE_CHANGE_UPDATE:
132
144
  ToastManager.addToast({
@@ -139,10 +151,14 @@ export function Notifications() {
139
151
  // eslint-disable-next-line react-hooks/exhaustive-deps
140
152
  }, [notification, subscribedNotifications.ERROR, subscribedNotifications.METADATA_UPDATED]);
141
153
 
154
+ if (isNotificationDisabled) {
155
+ return null;
156
+ }
157
+
142
158
  return (
143
159
  <>
144
- {!isHeadless && <TrackUnmuteModal />}
145
- {!isHeadless && <TrackBulkUnmuteModal />}
160
+ <TrackUnmuteModal />
161
+ <TrackBulkUnmuteModal />
146
162
  <TrackNotifications />
147
163
  <PeerNotifications />
148
164
  <ReconnectNotifications />
@@ -11,7 +11,6 @@ const notificationTypes = [
11
11
  ];
12
12
  let notificationId = null;
13
13
 
14
- const isQA = process.env.REACT_APP_ENV === 'qa';
15
14
  export const ReconnectNotifications = () => {
16
15
  const notification = useHMSNotifications(notificationTypes);
17
16
  const [open, setOpen] = useState(false);
@@ -22,18 +21,13 @@ export const ReconnectNotifications = () => {
22
21
  notificationId = ToastManager.replaceToast(notificationId, ToastConfig.RECONNECTED.single());
23
22
  setOpen(false);
24
23
  } else if (notification?.type === HMSNotificationTypes.RECONNECTING) {
25
- if (isQA) {
26
- ToastManager.removeToast(notificationId);
27
- setOpen(true);
28
- } else {
29
- notificationId = ToastManager.replaceToast(
30
- notificationId,
31
- ToastConfig.RECONNECTING.single(notification.data.message),
32
- );
33
- }
24
+ notificationId = ToastManager.replaceToast(
25
+ notificationId,
26
+ ToastConfig.RECONNECTING.single(notification.data.message),
27
+ );
34
28
  }
35
29
  }, [notification]);
36
- if (!open || !isQA) return null;
30
+ if (!open) return null;
37
31
  return (
38
32
  <Dialog.Root open={open} modal={true}>
39
33
  <Dialog.Portal container={document.getElementById('conferencing')}>
@@ -38,18 +38,20 @@ export const Pagination = ({
38
38
  <StyledPagination.Chevron disabled={disableLeft} onClick={prevPage}>
39
39
  <ChevronLeftIcon width={16} height={16} style={{ cursor: disableLeft ? 'not-allowed' : 'pointer' }} />
40
40
  </StyledPagination.Chevron>
41
- <StyledPagination.Dots>
42
- {[...Array(numPages)].map((_, i) => (
43
- <StyledPagination.Dot
44
- key={i}
45
- active={page === i}
46
- onClick={e => {
47
- e.stopPropagation();
48
- onPageChange(i);
49
- }}
50
- />
51
- ))}
52
- </StyledPagination.Dots>
41
+ {numPages <= 5 ? (
42
+ <StyledPagination.Dots>
43
+ {[...Array(numPages)].map((_, i) => (
44
+ <StyledPagination.Dot
45
+ key={i}
46
+ active={page === i}
47
+ onClick={e => {
48
+ e.stopPropagation();
49
+ onPageChange(i);
50
+ }}
51
+ />
52
+ ))}
53
+ </StyledPagination.Dots>
54
+ ) : null}
53
55
  <StyledPagination.Chevron disabled={disableRight} onClick={nextPage}>
54
56
  <ChevronRightIcon width={16} height={16} style={{ cursor: disableRight ? 'not-allowed' : 'pointer' }} />
55
57
  </StyledPagination.Chevron>
@@ -1,13 +1,17 @@
1
1
  import React from 'react';
2
2
  import { useNavigate, useParams } from 'react-router-dom';
3
3
  import { useSearchParam } from 'react-use';
4
- import { Flex } from '../../../';
4
+ import { Flex } from '../../..';
5
5
  import { useHMSPrebuiltContext } from '../../AppContext';
6
6
  import { useRoomLayout } from '../../provider/roomLayoutProvider';
7
+ // @ts-ignore: No implicit Any
7
8
  import FullPageProgress from '../FullPageProgress';
9
+ // @ts-ignore: No implicit Any
8
10
  import PreviewJoin from './PreviewJoin';
9
11
  import { useRoomLayoutPreviewScreen } from '../../provider/roomLayoutProvider/hooks/useRoomLayoutScreen';
12
+ // @ts-ignore: No implicit Any
10
13
  import { useAuthToken } from '../AppData/useUISettings';
14
+ // @ts-ignore: No implicit Any
11
15
  import { QUERY_PARAM_PREVIEW_AS_ROLE } from '../../common/constants';
12
16
 
13
17
  const PreviewContainer = () => {
@@ -37,7 +41,12 @@ const PreviewContainer = () => {
37
41
  align="center"
38
42
  >
39
43
  {authToken && Object.keys(previewHeader).length > 0 ? (
40
- <PreviewJoin initialName={initialName} skipPreview={skipPreview} asRole={previewAsRole} onJoin={onJoin} />
44
+ <PreviewJoin
45
+ initialName={initialName}
46
+ skipPreview={skipPreview}
47
+ asRole={previewAsRole ?? undefined}
48
+ onJoin={onJoin}
49
+ />
41
50
  ) : (
42
51
  <FullPageProgress />
43
52
  )}
@@ -1,7 +1,7 @@
1
1
  import React from 'react';
2
2
  import { useMedia } from 'react-use';
3
3
  import { JoinForm_JoinBtnType } from '@100mslive/types-prebuilt/elements/join_form';
4
- import { selectPermissions, useHMSStore, useRecordingStreaming } from '@100mslive/react-sdk';
4
+ import { useRecordingStreaming } from '@100mslive/react-sdk';
5
5
  import { RadioIcon } from '@100mslive/react-icons';
6
6
  import { Button, config as cssConfig, Flex, Input, styled } from '../../..';
7
7
  import { useRoomLayout } from '../../provider/roomLayoutProvider';
@@ -26,16 +26,11 @@ const PreviewForm = ({
26
26
  const formSubmit = (e: React.SyntheticEvent) => {
27
27
  e.preventDefault();
28
28
  };
29
- const mediaQueryLg = cssConfig.media.md;
30
- const isMobile = useMedia(mediaQueryLg);
29
+ const isMobile = useMedia(cssConfig.media.md);
31
30
  const { isHLSRunning } = useRecordingStreaming();
32
- const permissions = useHMSStore(selectPermissions);
33
31
  const layout = useRoomLayout();
34
32
  const { join_form: joinForm = {} } = layout?.screens?.preview?.default?.elements || {};
35
- const showGoLive =
36
- joinForm?.join_btn_type === JoinForm_JoinBtnType.JOIN_BTN_TYPE_JOIN_AND_GO_LIVE &&
37
- !isHLSRunning &&
38
- permissions?.hlsStreaming;
33
+ const showGoLive = joinForm?.join_btn_type === JoinForm_JoinBtnType.JOIN_BTN_TYPE_JOIN_AND_GO_LIVE && !isHLSRunning;
39
34
 
40
35
  return (
41
36
  <Form
@@ -55,6 +50,9 @@ const PreviewForm = ({
55
50
  onKeyDown={e => {
56
51
  if (e.key === 'Enter' && name.trim().length > 0) {
57
52
  e.preventDefault();
53
+ if (isMobile) {
54
+ return;
55
+ }
58
56
  onJoin();
59
57
  }
60
58
  }}
@@ -1,4 +1,5 @@
1
1
  import React, { Fragment, Suspense, useCallback, useEffect, useState } from 'react';
2
+ import { useMedia } from 'react-use';
2
3
  import {
3
4
  HMSRoomState,
4
5
  selectIsLocalVideoEnabled,
@@ -12,23 +13,37 @@ import {
12
13
  useRecordingStreaming,
13
14
  } from '@100mslive/react-sdk';
14
15
  import { MicOffIcon, SettingsIcon } from '@100mslive/react-icons';
15
- import { Avatar, Box, Flex, flexCenter, styled, StyledVideoTile, Text, Video } from '../../../';
16
+ import { Avatar, Box, config as cssConfig, Flex, flexCenter, styled, StyledVideoTile, Text, Video } from '../../..';
16
17
  import { useHMSPrebuiltContext } from '../../AppContext';
18
+ // @ts-ignore: No implicit Any
17
19
  import IconButton from '../../IconButton';
18
20
  import { useRoomLayout } from '../../provider/roomLayoutProvider';
21
+ // @ts-ignore: No implicit Any
19
22
  import { AudioVideoToggle } from '../AudioVideoToggle';
23
+ // @ts-ignore: No implicit Any
20
24
  import Chip from '../Chip';
25
+ // @ts-ignore: No implicit Any
21
26
  import TileConnection from '../Connection/TileConnection';
27
+ // @ts-ignore: No implicit Any
22
28
  import FullPageProgress from '../FullPageProgress';
29
+ // @ts-ignore: No implicit Any
23
30
  import { Logo } from '../Header/HeaderComponents';
31
+ // @ts-ignore: No implicit Any
24
32
  import SettingsModal from '../Settings/SettingsModal';
33
+ // @ts-ignore: No implicit Any
25
34
  import { AudioLevel } from '../VideoTile';
35
+ // @ts-ignore: No implicit Any
26
36
  import PreviewForm from './PreviewForm';
37
+ // @ts-ignore: No implicit Any
27
38
  import { useAuthToken, useUISettings } from '../AppData/useUISettings';
39
+ // @ts-ignore: No implicit Any
28
40
  import { defaultPreviewPreference, UserPreferencesKeys, useUserPreferences } from '../hooks/useUserPreferences';
41
+ // @ts-ignore: No implicit Any
29
42
  import { getFormattedCount } from '../../common/utils';
43
+ // @ts-ignore: No implicit Any
30
44
  import { UI_SETTINGS } from '../../common/constants';
31
45
 
46
+ // @ts-ignore: No implicit Any
32
47
  const VirtualBackground = React.lazy(() => import('../../plugins/VirtualBackground/VirtualBackground'));
33
48
 
34
49
  const getParticipantChipContent = (peerCount = 0) => {
@@ -39,7 +54,17 @@ const getParticipantChipContent = (peerCount = 0) => {
39
54
  return `${formattedNum} other${parseInt(formattedNum) === 1 ? '' : 's'} in the session`;
40
55
  };
41
56
 
42
- const PreviewJoin = ({ onJoin, skipPreview, initialName, asRole }) => {
57
+ const PreviewJoin = ({
58
+ onJoin,
59
+ skipPreview,
60
+ initialName,
61
+ asRole,
62
+ }: {
63
+ onJoin: () => void;
64
+ skipPreview?: boolean;
65
+ initialName?: string;
66
+ asRole?: string;
67
+ }) => {
43
68
  const [previewPreference, setPreviewPreference] = useUserPreferences(
44
69
  UserPreferencesKeys.PREVIEW,
45
70
  defaultPreviewPreference,
@@ -47,7 +72,7 @@ const PreviewJoin = ({ onJoin, skipPreview, initialName, asRole }) => {
47
72
  const { isStreamingOn } = useRecordingStreaming();
48
73
  const authToken = useAuthToken();
49
74
  const [name, setName] = useState(initialName || previewPreference.name);
50
- const { isLocalAudioEnabled, isLocalVideoEnabled, toggleAudio, toggleVideo } = useAVToggle();
75
+ const { toggleAudio, toggleVideo } = useAVToggle();
51
76
  const [previewError, setPreviewError] = useState(false);
52
77
  const { endpoints } = useHMSPrebuiltContext();
53
78
  const { peerCount } = useParticipants();
@@ -73,12 +98,10 @@ const PreviewJoin = ({ onJoin, skipPreview, initialName, asRole }) => {
73
98
  const savePreferenceAndJoin = useCallback(() => {
74
99
  setPreviewPreference({
75
100
  name,
76
- isAudioMuted: !isLocalAudioEnabled,
77
- isVideoMuted: !isLocalVideoEnabled,
78
101
  });
79
102
  join();
80
103
  onJoin && onJoin();
81
- }, [join, isLocalAudioEnabled, isLocalVideoEnabled, name, setPreviewPreference, onJoin]);
104
+ }, [join, name, setPreviewPreference, onJoin]);
82
105
  const roomLayout = useRoomLayout();
83
106
 
84
107
  const { preview_header: previewHeader = {} } = roomLayout?.screens?.preview?.default?.elements || {};
@@ -144,11 +167,7 @@ const PreviewJoin = ({ onJoin, skipPreview, initialName, asRole }) => {
144
167
  </Flex>
145
168
  ) : null}
146
169
  <Box css={{ w: '100%', maxWidth: '640px' }}>
147
- <PreviewControls
148
- enableJoin={enableJoin}
149
- savePreferenceAndJoin={savePreferenceAndJoin}
150
- hideSettings={!toggleVideo && !toggleAudio}
151
- />
170
+ <PreviewControls hideSettings={!toggleVideo && !toggleAudio} />
152
171
  <PreviewForm
153
172
  name={name}
154
173
  onChange={setName}
@@ -171,7 +190,7 @@ const Container = styled('div', {
171
190
  px: '$10',
172
191
  });
173
192
 
174
- export const PreviewTile = ({ name, error }) => {
193
+ export const PreviewTile = ({ name, error }: { name: string; error?: boolean }) => {
175
194
  const localPeer = useHMSStore(selectLocalPeer);
176
195
  const { isLocalAudioEnabled, toggleAudio } = useAVToggle();
177
196
  const isVideoOn = useHMSStore(selectIsLocalVideoEnabled);
@@ -179,16 +198,19 @@ export const PreviewTile = ({ name, error }) => {
179
198
  const trackSelector = selectVideoTrackByID(localPeer?.videoTrack);
180
199
  const track = useHMSStore(trackSelector);
181
200
  const showMuteIcon = !isLocalAudioEnabled || !toggleAudio;
182
-
201
+ const videoTrack = useHMSStore(selectVideoTrackByID(localPeer?.videoTrack));
202
+ const isMobile = useMedia(cssConfig.media.md);
203
+ const aspectRatio =
204
+ videoTrack?.width && videoTrack?.height ? videoTrack.width / videoTrack.height : isMobile ? 9 / 16 : 16 / 9;
183
205
  return (
184
206
  <StyledVideoTile.Container
185
207
  css={{
186
208
  bg: '$surface_default',
187
- aspectRatio: 16 / 9,
188
- width: 'min(640px, 80vw)',
209
+ aspectRatio,
210
+ height: 'min(640px, 40vh)',
211
+ maxWidth: '640px',
189
212
  overflow: 'clip',
190
213
  '@md': {
191
- aspectRatio: 9 / 16,
192
214
  width: 'min(220px, 70vw)',
193
215
  maxWidth: '100%',
194
216
  my: '$4',
@@ -217,14 +239,15 @@ export const PreviewTile = ({ name, error }) => {
217
239
  <MicOffIcon />
218
240
  </StyledVideoTile.AudioIndicator>
219
241
  ) : (
220
- <AudioLevel trackId={localPeer.audioTrack} />
242
+ <AudioLevel trackId={localPeer?.audioTrack} />
221
243
  )}
222
244
  </StyledVideoTile.Container>
223
245
  );
224
246
  };
225
247
 
226
- export const PreviewControls = ({ hideSettings }) => {
227
- const isVideoOn = useHMSStore(selectIsLocalVideoEnabled);
248
+ export const PreviewControls = ({ hideSettings }: { hideSettings: boolean }) => {
249
+ const isMobile = useMedia(cssConfig.media.md);
250
+
228
251
  return (
229
252
  <Flex
230
253
  justify="between"
@@ -234,8 +257,8 @@ export const PreviewControls = ({ hideSettings }) => {
234
257
  }}
235
258
  >
236
259
  <Flex css={{ gap: '$4' }}>
237
- <AudioVideoToggle compact />
238
- <Suspense fallback="">{isVideoOn ? <VirtualBackground /> : null}</Suspense>
260
+ <AudioVideoToggle />
261
+ <Suspense fallback="">{!isMobile ? <VirtualBackground /> : null}</Suspense>
239
262
  </Flex>
240
263
  {!hideSettings ? <PreviewSettings /> : null}
241
264
  </Flex>
@@ -3,32 +3,37 @@ import {
3
3
  selectLocalPeerName,
4
4
  selectLocalPeerRoleName,
5
5
  selectRoleChangeRequest,
6
+ useCustomEvent,
6
7
  useHMSActions,
7
8
  useHMSStore,
8
9
  } from '@100mslive/react-sdk';
10
+ // @ts-ignore: No implicit Any
9
11
  import { PreviewControls, PreviewTile } from './Preview/PreviewJoin';
10
- import { Box, Button, Dialog, Flex, Text } from '../../';
11
- import { useIsHeadless } from './AppData/useUISettings';
12
+ import { Box, Button, Dialog, Flex, Text } from '../..';
13
+ // @ts-ignore: No implicit Any
12
14
  import { useMyMetadata } from './hooks/useMetadata';
15
+ // @ts-ignore: No implicit Any
13
16
  import { ROLE_CHANGE_DECLINED } from '../common/constants';
14
17
 
15
18
  export const RoleChangeRequestModal = () => {
16
19
  const hmsActions = useHMSActions();
17
- const isHeadless = useIsHeadless();
18
- const { setPrevRole } = useMyMetadata();
20
+ const { updateMetaData } = useMyMetadata();
19
21
  const currentRole = useHMSStore(selectLocalPeerRoleName);
20
22
  const roleChangeRequest = useHMSStore(selectRoleChangeRequest);
21
23
  const name = useHMSStore(selectLocalPeerName);
24
+ const { sendEvent } = useCustomEvent({ type: ROLE_CHANGE_DECLINED });
22
25
 
23
26
  useEffect(() => {
24
- if (!roleChangeRequest?.role || isHeadless) {
27
+ if (!roleChangeRequest?.role) {
25
28
  return;
26
29
  }
30
+ (async () => {
31
+ await updateMetaData({ prevRole: currentRole });
32
+ await hmsActions.preview({ asRole: roleChangeRequest.role.name });
33
+ })();
34
+ }, [hmsActions, roleChangeRequest, currentRole, updateMetaData]);
27
35
 
28
- hmsActions.preview({ asRole: roleChangeRequest.role.name });
29
- }, [hmsActions, roleChangeRequest, isHeadless]);
30
-
31
- if (!roleChangeRequest?.role || isHeadless) {
36
+ if (!roleChangeRequest?.role) {
32
37
  return null;
33
38
  }
34
39
 
@@ -46,8 +51,8 @@ export const RoleChangeRequestModal = () => {
46
51
  mt: '$6',
47
52
  }}
48
53
  >
49
- <PreviewTile name={name} />
50
- <PreviewControls />
54
+ <PreviewTile name={name || ''} />
55
+ <PreviewControls hideSettings={true} />
51
56
  </Flex>
52
57
  </>
53
58
  );
@@ -58,27 +63,41 @@ export const RoleChangeRequestModal = () => {
58
63
  onOpenChange={async value => {
59
64
  if (!value) {
60
65
  await hmsActions.rejectChangeRole(roleChangeRequest);
61
- await hmsActions.sendDirectMessage('', roleChangeRequest.requestedBy?.id, ROLE_CHANGE_DECLINED);
66
+ sendEvent({ ...roleChangeRequest, peerName: name }, { peerId: roleChangeRequest.requestedBy?.id });
62
67
  await hmsActions.cancelMidCallPreview();
68
+ await updateMetaData({ isHandRaised: false });
63
69
  }
64
70
  }}
65
71
  body={body}
66
- onAction={() => {
67
- hmsActions.acceptChangeRole(roleChangeRequest);
68
- setPrevRole(currentRole);
72
+ onAction={async () => {
73
+ await hmsActions.acceptChangeRole(roleChangeRequest);
74
+ await updateMetaData({ isHandRaised: false });
69
75
  }}
70
76
  actionText="Accept"
71
77
  />
72
78
  );
73
79
  };
74
80
 
75
- const RequestDialog = ({ open = true, onOpenChange, title, body, actionText = 'Accept', onAction, Icon }) => (
81
+ const RequestDialog = ({
82
+ open = true,
83
+ onOpenChange,
84
+ title,
85
+ body,
86
+ actionText = 'Accept',
87
+ onAction,
88
+ }: {
89
+ open?: boolean;
90
+ onOpenChange: (value: boolean) => void;
91
+ title: string;
92
+ body: React.ReactNode;
93
+ actionText?: string;
94
+ onAction: () => void;
95
+ }) => (
76
96
  <Dialog.Root open={open} onOpenChange={onOpenChange}>
77
97
  <Dialog.Portal>
78
98
  <Dialog.Overlay />
79
99
  <Dialog.Content css={{ p: '$10' }}>
80
100
  <Dialog.Title css={{ p: 0, display: 'flex', flexDirection: 'row', gap: '$md', justifyContent: 'center' }}>
81
- {Icon ? Icon : null}
82
101
  <Text variant="h6">{title}</Text>
83
102
  </Dialog.Title>
84
103
  <Box css={{ mt: '$4', mb: '$10' }}>{body}</Box>
@@ -15,7 +15,7 @@ import { Video } from '../../Video';
15
15
  import { StyledVideoTile } from '../../VideoTile';
16
16
  import { getVideoTileLabel } from './peerTileUtils';
17
17
  import { ScreenshareDisplay } from './ScreenshareDisplay';
18
- import { useIsHeadless, useUISettings } from './AppData/useUISettings';
18
+ import { useUISettings } from './AppData/useUISettings';
19
19
  import { UI_SETTINGS } from '../common/constants';
20
20
 
21
21
  const labelStyles = {
@@ -24,7 +24,6 @@ const labelStyles = {
24
24
  textAlign: 'center',
25
25
  c: '$on_surface_high',
26
26
  transform: 'none',
27
- mt: '$2',
28
27
  flexShrink: 0,
29
28
  };
30
29
 
@@ -33,7 +32,6 @@ const Tile = ({ peerId, width = '100%', height = '100%' }) => {
33
32
  const track = useHMSStore(selectScreenShareByPeerID(peerId));
34
33
  const peer = useHMSStore(selectPeerByID(peerId));
35
34
  const isAudioOnly = useUISettings(UI_SETTINGS.isAudioOnly);
36
- const isHeadless = useIsHeadless();
37
35
  const [isMouseHovered, setIsMouseHovered] = useState(false);
38
36
  const showStatsOnTiles = useUISettings(UI_SETTINGS.showStatsOnTiles);
39
37
  const label = getVideoTileLabel({
@@ -59,11 +57,11 @@ const Tile = ({ peerId, width = '100%', height = '100%' }) => {
59
57
  return null;
60
58
  }
61
59
  return (
62
- <StyledVideoTile.Root css={{ width, height, p: 0, mb: '$4', minHeight: 0 }} data-testid="screenshare_tile">
60
+ <StyledVideoTile.Root css={{ width, height, p: 0, minHeight: 0 }} data-testid="screenshare_tile">
63
61
  <StyledVideoTile.Container
64
62
  transparentBg
65
63
  ref={fullscreenRef}
66
- css={{ flexDirection: 'column' }}
64
+ css={{ flexDirection: 'column', gap: '$2' }}
67
65
  onMouseEnter={() => setIsMouseHovered(true)}
68
66
  onMouseLeave={() => {
69
67
  setIsMouseHovered(false);
@@ -72,7 +70,7 @@ const Tile = ({ peerId, width = '100%', height = '100%' }) => {
72
70
  {showStatsOnTiles ? (
73
71
  <VideoTileStats audioTrackID={audioTrack?.id} videoTrackID={track?.id} peerID={peerId} isLocal={isLocal} />
74
72
  ) : null}
75
- {isFullScreenSupported && !isHeadless ? (
73
+ {isFullScreenSupported && isMouseHovered ? (
76
74
  <StyledVideoTile.FullScreenButton onClick={() => setFullscreen(!fullscreen)}>
77
75
  {isFullscreen ? <ShrinkIcon /> : <ExpandIcon />}
78
76
  </StyledVideoTile.FullScreenButton>
@@ -83,10 +81,11 @@ const Tile = ({ peerId, width = '100%', height = '100%' }) => {
83
81
  mirror={peer.isLocal && track?.source === 'regular'}
84
82
  attach={!isAudioOnly}
85
83
  trackId={track.id}
84
+ css={{ minHeight: 0 }}
86
85
  />
87
86
  ) : null}
88
87
  <StyledVideoTile.Info css={labelStyles}>{label}</StyledVideoTile.Info>
89
- {isMouseHovered && !isHeadless && !peer?.isLocal ? (
88
+ {isMouseHovered && !peer?.isLocal ? (
90
89
  <TileMenu isScreenshare peerID={peer?.id} audioTrackID={audioTrack?.id} videoTrackID={track?.id} />
91
90
  ) : null}
92
91
  </StyledVideoTile.Container>
@@ -6,7 +6,7 @@ import { config as cssConfig } from '../../Theme';
6
6
  import { Pagination } from './Pagination';
7
7
  import { usePagesWithTiles } from './hooks/useTileLayout';
8
8
 
9
- export const SecondaryTiles = ({ peers, onPageChange, onPageSize }: LayoutProps) => {
9
+ export const SecondaryTiles = ({ peers, onPageChange, onPageSize, edgeToEdge }: LayoutProps) => {
10
10
  const isMobile = useMedia(cssConfig.media.md);
11
11
  const maxTileCount = isMobile ? 2 : 4;
12
12
  const pagesWithTiles = usePagesWithTiles({ peers, maxTileCount });
@@ -20,15 +20,17 @@ export const SecondaryTiles = ({ peers, onPageChange, onPageSize }: LayoutProps)
20
20
  }, [pageSize, onPageSize]);
21
21
 
22
22
  return (
23
- <ProminenceLayout.SecondarySection tiles={pagesWithTiles[page]}>
24
- <Pagination
25
- page={page}
26
- onPageChange={page => {
27
- setPage(page);
28
- onPageChange?.(page);
29
- }}
30
- numPages={pagesWithTiles.length}
31
- />
23
+ <ProminenceLayout.SecondarySection tiles={pagesWithTiles[page]} edgeToEdge={edgeToEdge}>
24
+ {!edgeToEdge && (
25
+ <Pagination
26
+ page={page}
27
+ onPageChange={page => {
28
+ setPage(page);
29
+ onPageChange?.(page);
30
+ }}
31
+ numPages={pagesWithTiles.length}
32
+ />
33
+ )}
32
34
  </ProminenceLayout.SecondarySection>
33
35
  );
34
36
  };