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

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 (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,10 +1,11 @@
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
7
  selectRoomState,
8
+ useCustomEvent,
8
9
  useHMSNotifications,
9
10
  useHMSStore,
10
11
  } from '@100mslive/react-sdk';
@@ -20,19 +21,31 @@ import { ReconnectNotifications } from './ReconnectNotifications';
20
21
  import { TrackBulkUnmuteModal } from './TrackBulkUnmuteModal';
21
22
  import { TrackNotifications } from './TrackNotifications';
22
23
  import { TrackUnmuteModal } from './TrackUnmuteModal';
23
- import { useIsHeadless, useSubscribedNotifications } from '../AppData/useUISettings';
24
+ import { useIsNotificationDisabled, useSubscribedNotifications } from '../AppData/useUISettings';
25
+ import { useRedirectToLeave } from '../hooks/useRedirectToLeave';
24
26
  import { getMetadata } from '../../common/utils';
25
-
27
+ import { ROLE_CHANGE_DECLINED } from '../../common/constants';
26
28
  export function Notifications() {
27
29
  const notification = useHMSNotifications();
28
30
  const navigate = useNavigate();
31
+ const params = useParams();
29
32
  const subscribedNotifications = useSubscribedNotifications() || {};
30
- const isHeadless = useIsHeadless();
31
33
  const roomState = useHMSStore(selectRoomState);
32
34
  const updateRoomLayoutForRole = useUpdateRoomLayout();
35
+ const isNotificationDisabled = useIsNotificationDisabled();
36
+ const { redirectToLeave } = useRedirectToLeave();
37
+
38
+ const handleRoleChangeDenied = useCallback(request => {
39
+ ToastManager.addToast({
40
+ title: `${request.peerName} denied your request to join the ${request.role.name} role`,
41
+ variant: 'error',
42
+ });
43
+ }, []);
44
+
45
+ useCustomEvent({ type: ROLE_CHANGE_DECLINED, onEvent: handleRoleChangeDenied });
33
46
 
34
47
  useEffect(() => {
35
- if (!notification) {
48
+ if (!notification || isNotificationDisabled) {
36
49
  return;
37
50
  }
38
51
  switch (notification.type) {
@@ -43,11 +56,11 @@ export function Notifications() {
43
56
  // Don't toast message when metadata is updated and raiseHand is false.
44
57
  // Don't toast message in case of local peer.
45
58
  const metadata = getMetadata(notification.data?.metadata);
46
- if (!metadata?.isHandRaised || notification.data.isLocal || isHeadless) return;
59
+ if (!metadata?.isHandRaised || notification.data.isLocal) return;
47
60
 
48
61
  console.debug('Metadata updated', notification.data);
49
62
  if (!subscribedNotifications.METADATA_UPDATED) return;
50
- ToastBatcher.showToast({ notification });
63
+ ToastBatcher.showToast({ notification, type: 'RAISE_HAND' });
51
64
  break;
52
65
  case HMSNotificationTypes.NAME_UPDATED:
53
66
  console.log(notification.data.id + ' changed their name to ' + notification.data.name);
@@ -69,7 +82,7 @@ export function Notifications() {
69
82
  <Button
70
83
  onClick={() => {
71
84
  ToastManager.removeToast(toastId);
72
- window.location.reload();
85
+ navigate(`/${params.roomId}${params.role ? `/${params.role}` : ''}`);
73
86
  }}
74
87
  >
75
88
  Rejoin
@@ -80,11 +93,7 @@ export function Notifications() {
80
93
  }
81
94
  // goto leave for terminal if any action is not performed within 2secs
82
95
  // 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);
96
+ redirectToLeave(1000);
88
97
  return;
89
98
  }
90
99
  // Autoplay error or user denied screen share (cancelled browser pop-up)
@@ -122,11 +131,7 @@ export function Notifications() {
122
131
  title: `${notification.message}.
123
132
  ${notification.data.reason && `Reason: ${notification.data.reason}`}`,
124
133
  });
125
- setTimeout(() => {
126
- const leaveLocation = window.location.pathname.replace('meeting', 'leave');
127
- navigate(leaveLocation);
128
- ToastManager.clearAllToast();
129
- }, 2000);
134
+ redirectToLeave(1000);
130
135
  break;
131
136
  case HMSNotificationTypes.DEVICE_CHANGE_UPDATE:
132
137
  ToastManager.addToast({
@@ -139,10 +144,14 @@ export function Notifications() {
139
144
  // eslint-disable-next-line react-hooks/exhaustive-deps
140
145
  }, [notification, subscribedNotifications.ERROR, subscribedNotifications.METADATA_UPDATED]);
141
146
 
147
+ if (isNotificationDisabled) {
148
+ return null;
149
+ }
150
+
142
151
  return (
143
152
  <>
144
- {!isHeadless && <TrackUnmuteModal />}
145
- {!isHeadless && <TrackBulkUnmuteModal />}
153
+ <TrackUnmuteModal />
154
+ <TrackBulkUnmuteModal />
146
155
  <TrackNotifications />
147
156
  <PeerNotifications />
148
157
  <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,16 @@ 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 }) => {
248
+ export const PreviewControls = ({ hideSettings }: { hideSettings: boolean }) => {
227
249
  const isVideoOn = useHMSStore(selectIsLocalVideoEnabled);
250
+ const isMobile = useMedia(cssConfig.media.md);
251
+
228
252
  return (
229
253
  <Flex
230
254
  justify="between"
@@ -235,7 +259,7 @@ export const PreviewControls = ({ hideSettings }) => {
235
259
  >
236
260
  <Flex css={{ gap: '$4' }}>
237
261
  <AudioVideoToggle compact />
238
- <Suspense fallback="">{isVideoOn ? <VirtualBackground /> : null}</Suspense>
262
+ <Suspense fallback="">{isVideoOn && !isMobile ? <VirtualBackground /> : null}</Suspense>
239
263
  </Flex>
240
264
  {!hideSettings ? <PreviewSettings /> : null}
241
265
  </Flex>
@@ -3,32 +3,35 @@ 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
  }
27
30
 
28
31
  hmsActions.preview({ asRole: roleChangeRequest.role.name });
29
- }, [hmsActions, roleChangeRequest, isHeadless]);
32
+ }, [hmsActions, roleChangeRequest]);
30
33
 
31
- if (!roleChangeRequest?.role || isHeadless) {
34
+ if (!roleChangeRequest?.role) {
32
35
  return null;
33
36
  }
34
37
 
@@ -46,8 +49,8 @@ export const RoleChangeRequestModal = () => {
46
49
  mt: '$6',
47
50
  }}
48
51
  >
49
- <PreviewTile name={name} />
50
- <PreviewControls />
52
+ <PreviewTile name={name || ''} />
53
+ <PreviewControls hideSettings={true} />
51
54
  </Flex>
52
55
  </>
53
56
  );
@@ -58,27 +61,41 @@ export const RoleChangeRequestModal = () => {
58
61
  onOpenChange={async value => {
59
62
  if (!value) {
60
63
  await hmsActions.rejectChangeRole(roleChangeRequest);
61
- await hmsActions.sendDirectMessage('', roleChangeRequest.requestedBy?.id, ROLE_CHANGE_DECLINED);
64
+ sendEvent({ ...roleChangeRequest, peerName: name }, { peerId: roleChangeRequest.requestedBy?.id });
62
65
  await hmsActions.cancelMidCallPreview();
66
+ await updateMetaData({ isHandRaised: false });
63
67
  }
64
68
  }}
65
69
  body={body}
66
- onAction={() => {
67
- hmsActions.acceptChangeRole(roleChangeRequest);
68
- setPrevRole(currentRole);
70
+ onAction={async () => {
71
+ await hmsActions.acceptChangeRole(roleChangeRequest);
72
+ await updateMetaData({ isHandRaised: false, prevRole: currentRole });
69
73
  }}
70
74
  actionText="Accept"
71
75
  />
72
76
  );
73
77
  };
74
78
 
75
- const RequestDialog = ({ open = true, onOpenChange, title, body, actionText = 'Accept', onAction, Icon }) => (
79
+ const RequestDialog = ({
80
+ open = true,
81
+ onOpenChange,
82
+ title,
83
+ body,
84
+ actionText = 'Accept',
85
+ onAction,
86
+ }: {
87
+ open?: boolean;
88
+ onOpenChange: (value: boolean) => void;
89
+ title: string;
90
+ body: React.ReactNode;
91
+ actionText?: string;
92
+ onAction: () => void;
93
+ }) => (
76
94
  <Dialog.Root open={open} onOpenChange={onOpenChange}>
77
95
  <Dialog.Portal>
78
96
  <Dialog.Overlay />
79
97
  <Dialog.Content css={{ p: '$10' }}>
80
98
  <Dialog.Title css={{ p: 0, display: 'flex', flexDirection: 'row', gap: '$md', justifyContent: 'center' }}>
81
- {Icon ? Icon : null}
82
99
  <Text variant="h6">{title}</Text>
83
100
  </Dialog.Title>
84
101
  <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
  };
@@ -73,7 +73,7 @@ const TileMenu = ({
73
73
  <StyledMenuTile.Root open={open} onOpenChange={setOpen}>
74
74
  <StyledMenuTile.Trigger
75
75
  data-testid="participant_menu_btn"
76
- css={{ bg: `${theme.colors.background_dim.value}A3` }}
76
+ css={{ bg: `${theme.colors.background_dim.value}A3`, p: '$2', w: 'unset', h: 'unset' }}
77
77
  onClick={e => e.stopPropagation()}
78
78
  className={isMobile ? '__cancel-drag-event' : ''}
79
79
  >