@100mslive/roomkit-react 0.1.8-alpha.0 → 0.1.9-alpha.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (142) hide show
  1. package/dist/{HLSView-IQRPLYNH.js → HLSView-U53QN3AC.js} +3 -3
  2. package/dist/Modal/Dialog.d.ts +402 -1706
  3. package/dist/Prebuilt/App.d.ts +6 -0
  4. package/dist/Prebuilt/AppContext.d.ts +2 -0
  5. package/dist/Prebuilt/AppStateContext.d.ts +16 -0
  6. package/dist/Prebuilt/components/ConferenceScreen.d.ts +2 -0
  7. package/dist/Prebuilt/components/Footer/PaginatedParticipants.d.ts +5 -0
  8. package/dist/Prebuilt/components/Footer/PollsToggle.d.ts +2 -0
  9. package/dist/Prebuilt/components/Footer/RoleAccordion.d.ts +10 -3
  10. package/dist/Prebuilt/components/LeaveScreen.d.ts +2 -0
  11. package/dist/Prebuilt/components/MwebLandscapePrompt.d.ts +2 -0
  12. package/dist/Prebuilt/components/Notifications/AutoplayBlockedModal.d.ts +2 -0
  13. package/dist/Prebuilt/components/Notifications/HLSFailureModal.d.ts +2 -0
  14. package/dist/Prebuilt/components/Notifications/InitErrorModal.d.ts +2 -0
  15. package/dist/Prebuilt/components/Notifications/Notifications.d.ts +2 -0
  16. package/dist/Prebuilt/components/Notifications/PeerNotifications.d.ts +1 -0
  17. package/dist/Prebuilt/components/Notifications/PermissionErrorModal.d.ts +2 -0
  18. package/dist/Prebuilt/components/Notifications/ReconnectNotifications.d.ts +2 -0
  19. package/dist/Prebuilt/components/Notifications/TrackBulkUnmuteModal.d.ts +2 -0
  20. package/dist/Prebuilt/components/Notifications/TrackNotifications.d.ts +1 -0
  21. package/dist/Prebuilt/components/Notifications/TrackUnmuteModal.d.ts +2 -0
  22. package/dist/Prebuilt/components/Polls/Polls.d.ts +2 -0
  23. package/dist/Prebuilt/components/Preview/PreviewJoin.d.ts +1 -2
  24. package/dist/Prebuilt/components/Preview/PreviewScreen.d.ts +2 -0
  25. package/dist/Prebuilt/components/hooks/useRedirectToLeave.d.ts +1 -1
  26. package/dist/{VirtualBackground-GP4ATXD3.js → VirtualBackground-PMLQPJB6.js} +3 -5
  27. package/dist/{VirtualBackground-GP4ATXD3.js.map → VirtualBackground-PMLQPJB6.js.map} +1 -1
  28. package/dist/chunk-ANQRGVIX.js +14441 -0
  29. package/dist/chunk-ANQRGVIX.js.map +7 -0
  30. package/dist/{chunk-Z3O2WGWV.js → chunk-XQ2NRKIW.js} +66 -3
  31. package/dist/chunk-XQ2NRKIW.js.map +7 -0
  32. package/dist/context/DialogContext.d.ts +6 -0
  33. package/dist/hooks/useDialogContainerSelector.d.ts +1 -0
  34. package/dist/index.cjs.js +10956 -9818
  35. package/dist/index.cjs.js.map +4 -4
  36. package/dist/index.d.ts +1 -0
  37. package/dist/index.js +6 -2
  38. package/dist/meta.cjs.json +4076 -3201
  39. package/dist/meta.esbuild.json +4391 -3623
  40. package/dist/utils/animations.d.ts +11 -0
  41. package/package.json +6 -7
  42. package/src/AudioLevel/AudioLevel.tsx +1 -1
  43. package/src/Modal/Dialog.tsx +31 -3
  44. package/src/Prebuilt/App.tsx +49 -97
  45. package/src/Prebuilt/AppContext.tsx +6 -0
  46. package/src/Prebuilt/AppStateContext.tsx +71 -0
  47. package/src/Prebuilt/common/constants.js +36 -1
  48. package/src/Prebuilt/common/utils.js +47 -0
  49. package/src/Prebuilt/components/AppData/AppData.jsx +6 -1
  50. package/src/Prebuilt/components/AppData/useSidepane.js +23 -1
  51. package/src/Prebuilt/components/AppData/useUISettings.js +49 -5
  52. package/src/Prebuilt/components/Chip.tsx +6 -2
  53. package/src/Prebuilt/components/{conference.jsx → ConferenceScreen.tsx} +34 -46
  54. package/src/Prebuilt/components/Footer/Footer.tsx +5 -0
  55. package/src/Prebuilt/components/Footer/PaginatedParticipants.tsx +125 -0
  56. package/src/Prebuilt/components/Footer/ParticipantList.jsx +55 -24
  57. package/src/Prebuilt/components/Footer/PollsToggle.tsx +22 -0
  58. package/src/Prebuilt/components/Footer/RoleAccordion.tsx +87 -85
  59. package/src/Prebuilt/components/Footer/RoleOptions.tsx +1 -1
  60. package/src/Prebuilt/components/Header/StreamActions.tsx +5 -3
  61. package/src/Prebuilt/components/Leave/DesktopLeaveRoom.tsx +4 -5
  62. package/src/Prebuilt/components/Leave/LeaveRoom.tsx +0 -4
  63. package/src/Prebuilt/components/{PostLeave.jsx → LeaveScreen.tsx} +6 -13
  64. package/src/Prebuilt/components/MoreSettings/ChangeNameModal.jsx +2 -3
  65. package/src/Prebuilt/components/MoreSettings/EmbedUrl.jsx +2 -3
  66. package/src/Prebuilt/components/MoreSettings/SplitComponents/MwebOptions.tsx +18 -1
  67. package/src/Prebuilt/components/{MwebLandscapePrompt.jsx → MwebLandscapePrompt.tsx} +10 -11
  68. package/src/Prebuilt/components/Notifications/{AutoplayBlockedModal.jsx → AutoplayBlockedModal.tsx} +2 -1
  69. package/src/Prebuilt/components/Notifications/{HLSFailureModal.jsx → HLSFailureModal.tsx} +10 -8
  70. package/src/Prebuilt/components/Notifications/{InitErrorModal.jsx → InitErrorModal.tsx} +5 -2
  71. package/src/Prebuilt/components/Notifications/{Notifications.jsx → Notifications.tsx} +41 -27
  72. package/src/Prebuilt/components/Notifications/{PeerNotifications.jsx → PeerNotifications.tsx} +3 -0
  73. package/src/Prebuilt/components/Notifications/{PermissionErrorModal.jsx → PermissionErrorModal.tsx} +6 -4
  74. package/src/Prebuilt/components/Notifications/{ReconnectNotifications.jsx → ReconnectNotifications.tsx} +11 -6
  75. package/src/Prebuilt/components/Notifications/{TrackBulkUnmuteModal.jsx → TrackBulkUnmuteModal.tsx} +9 -3
  76. package/src/Prebuilt/components/Notifications/{TrackUnmuteModal.jsx → TrackUnmuteModal.tsx} +9 -3
  77. package/src/Prebuilt/components/Notifications/index.tsx +1 -0
  78. package/src/Prebuilt/components/Polls/CreatePollQuiz/PollsQuizMenu.jsx +229 -0
  79. package/src/Prebuilt/components/Polls/CreatePollQuiz/Timer.jsx +71 -0
  80. package/src/Prebuilt/components/Polls/CreateQuestions/CreateQuestions.jsx +132 -0
  81. package/src/Prebuilt/components/Polls/CreateQuestions/DeleteQuestionModal.jsx +66 -0
  82. package/src/Prebuilt/components/Polls/CreateQuestions/QuestionForm.jsx +251 -0
  83. package/src/Prebuilt/components/Polls/CreateQuestions/SavedQuestion.jsx +57 -0
  84. package/src/Prebuilt/components/Polls/Polls.tsx +28 -0
  85. package/src/Prebuilt/components/Polls/Voting/PollResultSummary.jsx +125 -0
  86. package/src/Prebuilt/components/Polls/Voting/QuestionCard.jsx +249 -0
  87. package/src/Prebuilt/components/Polls/Voting/StandardVoting.jsx +40 -0
  88. package/src/Prebuilt/components/Polls/Voting/TimedVoting.jsx +36 -0
  89. package/src/Prebuilt/components/Polls/Voting/Voting.jsx +99 -0
  90. package/src/Prebuilt/components/Polls/common/MultipleChoiceOptions.jsx +101 -0
  91. package/src/Prebuilt/components/Polls/common/OptionInputWithDelete.jsx +25 -0
  92. package/src/Prebuilt/components/Polls/common/SingleChoiceOptions.jsx +125 -0
  93. package/src/Prebuilt/components/Polls/common/StatusIndicator.jsx +47 -0
  94. package/src/Prebuilt/components/Polls/common/VoteCount.jsx +28 -0
  95. package/src/Prebuilt/components/Polls/common/VoteProgress.jsx +17 -0
  96. package/src/Prebuilt/components/Polls/common/VoterList.jsx +22 -0
  97. package/src/Prebuilt/components/Polls/common/Votes.jsx +72 -0
  98. package/src/Prebuilt/components/Preview/PreviewForm.tsx +3 -2
  99. package/src/Prebuilt/components/Preview/PreviewJoin.tsx +29 -21
  100. package/src/Prebuilt/components/Preview/{PreviewContainer.tsx → PreviewScreen.tsx} +2 -19
  101. package/src/Prebuilt/components/RaiseHand.jsx +1 -1
  102. package/src/Prebuilt/components/RoleChangeModal.jsx +2 -3
  103. package/src/Prebuilt/components/RoleChangeRequest/RequestPrompt.tsx +2 -3
  104. package/src/Prebuilt/components/Settings/SettingsModal.jsx +2 -3
  105. package/src/Prebuilt/components/Settings/StartRecording.jsx +15 -4
  106. package/src/Prebuilt/components/SidePaneTabs.tsx +32 -6
  107. package/src/Prebuilt/components/StatsForNerds.jsx +2 -3
  108. package/src/Prebuilt/components/Streaming/Common.jsx +31 -21
  109. package/src/Prebuilt/components/VideoLayouts/ScreenshareLayout.tsx +8 -9
  110. package/src/Prebuilt/components/VideoTile.jsx +28 -39
  111. package/src/Prebuilt/components/hooks/useAutoStartStreaming.tsx +3 -3
  112. package/src/Prebuilt/components/hooks/useDropdownSelection.jsx +1 -1
  113. package/src/Prebuilt/components/hooks/useRedirectToLeave.tsx +9 -17
  114. package/src/Prebuilt/components/pdfAnnotator/pdfFileOptions.jsx +2 -3
  115. package/src/Prebuilt/components/pdfAnnotator/submitPdf.jsx +1 -1
  116. package/src/Prebuilt/components/pdfAnnotator/uploadedFile.jsx +2 -3
  117. package/src/Prebuilt/layouts/EmbedView.jsx +47 -60
  118. package/src/Prebuilt/layouts/PDFView.jsx +49 -99
  119. package/src/Prebuilt/layouts/SidePane.tsx +9 -4
  120. package/src/Prebuilt/layouts/VideoStreamingSection.tsx +2 -2
  121. package/src/Prebuilt/primitives/DialogContent.jsx +4 -5
  122. package/src/context/DialogContext.tsx +13 -0
  123. package/src/hooks/useDialogContainerSelector.tsx +7 -0
  124. package/src/index.ts +1 -0
  125. package/src/utils/animations.ts +6 -0
  126. package/dist/Prebuilt/components/PrebuiltDialogPortal.d.ts +0 -4
  127. package/dist/Prebuilt/components/Preview/PreviewContainer.d.ts +0 -3
  128. package/dist/chunk-2H5NIZB7.js +0 -70
  129. package/dist/chunk-2H5NIZB7.js.map +0 -7
  130. package/dist/chunk-GLYGPYNS.js +0 -7125
  131. package/dist/chunk-GLYGPYNS.js.map +0 -7
  132. package/dist/chunk-Z3O2WGWV.js.map +0 -7
  133. package/dist/conference-JD35TNH4.js +0 -6503
  134. package/dist/conference-JD35TNH4.js.map +0 -7
  135. package/src/Prebuilt/components/GoLiveButton.jsx +0 -42
  136. package/src/Prebuilt/components/PrebuiltDialogPortal.tsx +0 -6
  137. package/src/Prebuilt/components/Streaming/HLSStreaming.jsx +0 -220
  138. package/src/Prebuilt/components/Streaming/RTMPStreaming.jsx +0 -334
  139. package/src/Prebuilt/components/Streaming/StreamingLanding.jsx +0 -76
  140. /package/dist/{HLSView-IQRPLYNH.js.map → HLSView-U53QN3AC.js.map} +0 -0
  141. /package/{src/Prebuilt/components/Notifications/index.jsx → dist/Prebuilt/components/Notifications/index.d.ts} +0 -0
  142. /package/src/Prebuilt/components/Notifications/{TrackNotifications.jsx → TrackNotifications.tsx} +0 -0
@@ -37,36 +37,46 @@ export const StreamCard = ({ title, subtitle, Icon, imgSrc = '', css = {}, onCli
37
37
  );
38
38
  };
39
39
 
40
- export const ContentHeader = ({ onBack, title, content }) => {
40
+ export const ContentHeader = ({ onBack, onClose, title = '', content }) => {
41
41
  return (
42
- <Flex css={{ w: '100%', py: '$8', px: '$10', cursor: 'pointer' }}>
43
- <Text
44
- css={{ p: '$2', bg: '$surface_bright', r: '$round', alignSelf: 'center' }}
45
- onClick={onBack}
46
- data-testid="go_back"
47
- >
48
- <ChevronLeftIcon width={16} height={16} />
49
- </Text>
50
- <Box css={{ flex: '1 1 0', mx: '$8' }}>
42
+ <Flex
43
+ css={{ w: '100%', py: '$8', px: '$10', cursor: 'pointer', borderBottom: '1px solid $border_bright', mb: '$8' }}
44
+ >
45
+ {onBack ? (
51
46
  <Text
52
- variant="tiny"
53
47
  css={{
54
- textTransform: 'uppercase',
55
- fontWeight: '$semiBold',
56
- color: '$on_surface_medium',
48
+ alignSelf: 'center',
49
+ mr: '$8',
57
50
  }}
51
+ onClick={onBack}
52
+ data-testid="go_back"
58
53
  >
59
- {title}
54
+ <ChevronLeftIcon />
60
55
  </Text>
56
+ ) : null}
57
+ <Box css={{ flex: '1 1 0' }}>
58
+ {title ? (
59
+ <Text
60
+ variant="tiny"
61
+ css={{
62
+ textTransform: 'uppercase',
63
+ fontWeight: '$semiBold',
64
+ color: '$on_surface_medium',
65
+ }}
66
+ >
67
+ {title}
68
+ </Text>
69
+ ) : null}
61
70
  <Text variant="h6">{content}</Text>
62
71
  </Box>
63
- <IconButton onClick={onBack} css={{ alignSelf: 'flex-start' }} data-testid="close_stream_section">
64
- <CrossIcon width={16} height={16} />
65
- </IconButton>
72
+ {onClose ? (
73
+ <IconButton onClick={onClose} css={{ alignSelf: 'flex-start' }} data-testid="close_stream_section">
74
+ <CrossIcon />
75
+ </IconButton>
76
+ ) : null}
66
77
  </Flex>
67
78
  );
68
79
  };
69
-
70
80
  export const Container = ({ children, rounded = false }) => {
71
81
  return (
72
82
  <Box
@@ -76,7 +86,7 @@ export const Container = ({ children, rounded = false }) => {
76
86
  position: 'absolute',
77
87
  top: 0,
78
88
  left: 0,
79
- bg: '$surface_default',
89
+ bg: '$surface_dim',
80
90
  transform: 'translateX(10%)',
81
91
  animation: `${slideLeftAndFade('10%')} 100ms ease-out forwards`,
82
92
  display: 'flex',
@@ -125,7 +135,7 @@ export const ErrorText = ({ error }) => {
125
135
  return null;
126
136
  }
127
137
  return (
128
- <Text variant="sm" css={{ mb: '$8', color: '$alert_error_default' }}>
138
+ <Text variant="sm" css={{ my: '$4', color: '$alert_error_default' }}>
129
139
  {error}
130
140
  </Text>
131
141
  );
@@ -19,15 +19,14 @@ export const ScreenshareLayout = ({ peers, onPageChange, onPageSize, edgeToEdge
19
19
  const [page, setPage] = useState(0);
20
20
  const activeSharePeer = peersSharing[page];
21
21
  const isMobile = useMedia(cssConfig.media.md);
22
- const secondaryPeers = useMemo(
23
- () =>
24
- isMobile
25
- ? activeSharePeer
26
- ? [activeSharePeer, ...peers.filter(p => p.id !== activeSharePeer?.id)]
27
- : peers //keep active sharing peer as first tile
28
- : peers.filter(p => p.id !== activeSharePeer?.id),
29
- [activeSharePeer, peers, isMobile],
30
- );
22
+ const secondaryPeers = useMemo(() => {
23
+ if (isMobile) {
24
+ return activeSharePeer
25
+ ? [activeSharePeer, ...peers.filter(p => p.id !== activeSharePeer?.id)] //keep active sharing peer as first tile
26
+ : peers;
27
+ }
28
+ return peers.filter(p => p.id !== activeSharePeer?.id);
29
+ }, [activeSharePeer, peers, isMobile]);
31
30
  useEffect(() => {
32
31
  setActiveScreenSharePeer(isMobile ? '' : activeSharePeer?.id);
33
32
  return () => {
@@ -1,5 +1,5 @@
1
- import React, { Fragment, useCallback, useMemo, useRef, useState } from 'react';
2
- import { useMedia } from 'react-use';
1
+ import React, { Fragment, useCallback, useMemo, useState } from 'react';
2
+ import { useMeasure, useMedia } from 'react-use';
3
3
  import {
4
4
  selectAudioTrackByPeerID,
5
5
  selectHasPeerHandRaised,
@@ -23,6 +23,7 @@ import { Video } from '../../Video';
23
23
  import { StyledVideoTile } from '../../VideoTile';
24
24
  import { getVideoTileLabel } from './peerTileUtils';
25
25
  import { useSetAppDataByKey, useUISettings } from './AppData/useUISettings';
26
+ import { calculateAvatarAndAttribBoxSize } from '../common/utils';
26
27
  import { APP_DATA, SESSION_STORE_KEY, UI_SETTINGS } from '../common/constants';
27
28
 
28
29
  const Tile = ({
@@ -71,29 +72,14 @@ const Tile = ({
71
72
  setIsMouseHovered(event.type === 'mouseenter');
72
73
  }, []);
73
74
 
74
- const ref = useRef(null);
75
- const calculatedHeight = ref.current?.clientHeight || '';
76
- const calculatedWidth = ref.current?.clientWidth || '';
75
+ const [ref, { width: calculatedWidth, height: calculatedHeight }] = useMeasure();
77
76
 
78
77
  const isTileBigEnoughToShowStats = calculatedHeight >= 180 && calculatedWidth >= 180;
79
78
 
80
- const [avatarSize, attribBoxSize] = useMemo(() => {
81
- if (!calculatedWidth || !calculatedHeight) {
82
- return [undefined, undefined];
83
- }
84
- let avatarSize = 'large';
85
- if (calculatedWidth <= 150 || calculatedHeight <= 150) {
86
- avatarSize = 'small';
87
- } else if (calculatedWidth <= 300 || calculatedHeight <= 300) {
88
- avatarSize = 'medium';
89
- }
90
- let attribBoxSize = 'medium';
91
- if (calculatedWidth <= 180 || calculatedHeight <= 180) {
92
- attribBoxSize = 'small';
93
- }
94
-
95
- return [avatarSize, attribBoxSize];
96
- }, [calculatedWidth, calculatedHeight]);
79
+ const [avatarSize, attribBoxSize] = useMemo(
80
+ () => calculateAvatarAndAttribBoxSize(calculatedWidth, calculatedHeight),
81
+ [calculatedWidth, calculatedHeight],
82
+ );
97
83
 
98
84
  return (
99
85
  <StyledVideoTile.Root
@@ -133,23 +119,27 @@ const Tile = ({
133
119
  bg: 'transparent',
134
120
  }}
135
121
  />
122
+ {calculatedWidth > 0 && calculatedHeight > 0 ? (
123
+ <>
124
+ {isVideoMuted || (!isLocal && isAudioOnly) ? (
125
+ <StyledVideoTile.AvatarContainer>
126
+ <Avatar name={peerName || ''} data-testid="participant_avatar_icon" size={avatarSize} />
127
+ </StyledVideoTile.AvatarContainer>
128
+ ) : null}
136
129
 
137
- {isVideoMuted || (!isLocal && isAudioOnly) ? (
138
- <StyledVideoTile.AvatarContainer>
139
- <Avatar name={peerName || ''} data-testid="participant_avatar_icon" size={avatarSize} />
140
- </StyledVideoTile.AvatarContainer>
141
- ) : null}
142
-
143
- {!hideAudioMuteOnTile ? (
144
- isAudioMuted ? (
145
- <StyledVideoTile.AudioIndicator data-testid="participant_audio_mute_icon" size={attribBoxSize}>
146
- <MicOffIcon />
147
- </StyledVideoTile.AudioIndicator>
148
- ) : (
149
- <StyledVideoTile.AudioIndicator size={attribBoxSize}>
150
- <AudioLevel trackId={audioTrack?.id} size={attribBoxSize} />
151
- </StyledVideoTile.AudioIndicator>
152
- )
130
+ {!hideAudioMuteOnTile ? (
131
+ isAudioMuted ? (
132
+ <StyledVideoTile.AudioIndicator data-testid="participant_audio_mute_icon" size={attribBoxSize}>
133
+ <MicOffIcon />
134
+ </StyledVideoTile.AudioIndicator>
135
+ ) : (
136
+ <StyledVideoTile.AudioIndicator size={attribBoxSize}>
137
+ <AudioLevel trackId={audioTrack?.id} size={attribBoxSize} />
138
+ </StyledVideoTile.AudioIndicator>
139
+ )
140
+ ) : null}
141
+ {!hideMetadataOnTile && <PeerMetadata peerId={peerId} size={attribBoxSize} />}
142
+ </>
153
143
  ) : null}
154
144
  {isMouseHovered || (isDragabble && isMobile) ? (
155
145
  <TileMenu
@@ -160,7 +150,6 @@ const Tile = ({
160
150
  enableSpotlightingPeer={enableSpotlightingPeer}
161
151
  />
162
152
  ) : null}
163
- {!hideMetadataOnTile && <PeerMetadata peerId={peerId} size={attribBoxSize} />}
164
153
 
165
154
  <TileConnection
166
155
  hideLabel={hideParticipantNameOnTile}
@@ -20,12 +20,12 @@ export const useAutoStartStreaming = () => {
20
20
  const showStreamingUI = useShowStreamingUI();
21
21
  const hmsActions = useHMSActions();
22
22
  const isConnected = useHMSStore(selectIsConnectedToRoom);
23
- const { isHLSRunning } = useRecordingStreaming();
23
+ const { isHLSRunning, isRTMPRunning } = useRecordingStreaming();
24
24
  const streamStartedRef = useRef(false);
25
25
 
26
26
  const startHLS = useCallback(async () => {
27
27
  try {
28
- if (isHLSStarted || !showStreamingUI || isHLSRunning) {
28
+ if (isHLSStarted || !showStreamingUI || isHLSRunning || isRTMPRunning) {
29
29
  return;
30
30
  }
31
31
  setHLSStarted(true);
@@ -38,7 +38,7 @@ export const useAutoStartStreaming = () => {
38
38
  streamStartedRef.current = false;
39
39
  setHLSStarted(false);
40
40
  }
41
- }, [hmsActions, isHLSRunning, isHLSStarted, setHLSStarted, showStreamingUI]);
41
+ }, [hmsActions, isHLSRunning, isHLSStarted, setHLSStarted, showStreamingUI, isRTMPRunning]);
42
42
 
43
43
  useEffect(() => {
44
44
  if (!isHLSStarted && !isHLSRunning) {
@@ -1,3 +1,3 @@
1
1
  export const useDropdownSelection = () => {
2
- return '$primary_dim';
2
+ return '$surface_bright';
3
3
  };
@@ -1,33 +1,25 @@
1
1
  import { useCallback } from 'react';
2
- import { useNavigate, useParams } from 'react-router-dom';
3
2
  import { useHMSPrebuiltContext } from '../../AppContext';
4
3
  // @ts-ignore: No implicit Any
5
4
  import { PictureInPicture } from '../PIP/PIPManager';
6
5
  // @ts-ignore: No implicit Any
7
6
  import { ToastManager } from '../Toast/ToastManager';
8
- import { useRoomLayoutLeaveScreen } from '../../provider/roomLayoutProvider/hooks/useRoomLayoutScreen';
9
7
 
10
8
  export const useRedirectToLeave = () => {
11
- const { isLeaveScreenEnabled } = useRoomLayoutLeaveScreen();
12
9
  const { onLeave } = useHMSPrebuiltContext();
13
- const params = useParams();
14
- const navigate = useNavigate();
15
10
 
16
11
  const redirect = useCallback(
17
12
  (timeout = 0) => {
18
- setTimeout(() => {
19
- const prefix = isLeaveScreenEnabled ? '/leave/' : '/';
20
- if (params.role) {
21
- navigate(prefix + params.roomId + '/' + params.role);
22
- } else {
23
- navigate(prefix + params.roomId);
24
- }
25
- PictureInPicture.stop().catch(() => console.error('stopping pip'));
26
- ToastManager.clearAllToast();
27
- onLeave?.();
28
- }, timeout);
13
+ return new Promise<void>(resolve => {
14
+ setTimeout(() => {
15
+ PictureInPicture.stop().catch(() => console.error('stopping pip'));
16
+ ToastManager.clearAllToast();
17
+ onLeave?.();
18
+ resolve();
19
+ }, timeout);
20
+ });
29
21
  },
30
- [isLeaveScreenEnabled, navigate, onLeave, params.role, params.roomId],
22
+ [onLeave],
31
23
  );
32
24
 
33
25
  return { redirectToLeave: redirect };
@@ -1,7 +1,6 @@
1
1
  import React, { useState } from 'react';
2
2
  import { Dialog, Flex } from '../../../';
3
3
  import { DialogInputFile } from '../../primitives/DialogContent';
4
- import { PrebuiltDialogPortal } from '../PrebuiltDialogPortal';
5
4
  import { PDFHeader } from './pdfHeader';
6
5
  import { SubmitPDF } from './submitPdf';
7
6
  import { UploadedFile } from './uploadedFile';
@@ -11,7 +10,7 @@ export function PDFFileOptions({ onOpenChange }) {
11
10
 
12
11
  return !pdfFile ? (
13
12
  <Dialog.Root defaultOpen onOpenChange={onOpenChange}>
14
- <PrebuiltDialogPortal>
13
+ <Dialog.Portal>
15
14
  <Dialog.Overlay />
16
15
  <Dialog.Content
17
16
  css={{
@@ -35,7 +34,7 @@ export function PDFFileOptions({ onOpenChange }) {
35
34
  <SubmitPDF pdfFile={pdfFile} onOpenChange={onOpenChange} />
36
35
  </Flex>
37
36
  </Dialog.Content>
38
- </PrebuiltDialogPortal>
37
+ </Dialog.Portal>
39
38
  </Dialog.Root>
40
39
  ) : (
41
40
  <UploadedFile pdfFile={pdfFile} setPDFFile={setPDFFile} onOpenChange={onOpenChange} />
@@ -31,7 +31,7 @@ export const SubmitPDF = ({ pdfFile, onOpenChange }) => {
31
31
  type="submit"
32
32
  onClick={() => {
33
33
  if (pdfFile) {
34
- setPDFConfig({ state: true, file: pdfFile });
34
+ setPDFConfig(pdfFile);
35
35
  onOpenChange(false);
36
36
  }
37
37
  }}
@@ -2,7 +2,6 @@ import React from 'react';
2
2
  import { TrashIcon } from '@100mslive/react-icons';
3
3
  import { Dialog, Flex, Text } from '../../../';
4
4
  import { DialogRow } from '../../primitives/DialogContent';
5
- import { PrebuiltDialogPortal } from '../PrebuiltDialogPortal';
6
5
  import { PDFHeader } from './pdfHeader';
7
6
  import { PDFInfo } from './pdfInfo';
8
7
  import { SubmitPDF } from './submitPdf';
@@ -11,7 +10,7 @@ export const UploadedFile = ({ pdfFile, setPDFFile, onOpenChange }) => {
11
10
  const [fileName, ext] = pdfFile.name.split('.');
12
11
  return (
13
12
  <Dialog.Root defaultOpen onOpenChange={onOpenChange}>
14
- <PrebuiltDialogPortal>
13
+ <Dialog.Portal>
15
14
  <Dialog.Overlay />
16
15
  <Dialog.Content
17
16
  css={{
@@ -66,7 +65,7 @@ export const UploadedFile = ({ pdfFile, setPDFFile, onOpenChange }) => {
66
65
  <SubmitPDF pdfFile={pdfFile} onOpenChange={onOpenChange} />
67
66
  </Flex>
68
67
  </Dialog.Content>
69
- </PrebuiltDialogPortal>
68
+ </Dialog.Portal>
70
69
  </Dialog.Root>
71
70
  );
72
71
  };
@@ -1,26 +1,21 @@
1
- import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';
2
- import {
3
- selectPeers,
4
- selectPeerScreenSharing,
5
- throwErrorHandler,
6
- useHMSStore,
7
- useScreenShare,
8
- } from '@100mslive/react-sdk';
1
+ import React, { useEffect, useMemo } from 'react';
2
+ import { selectAppData, selectPeers, selectPeerScreenSharing, useEmbedShare, useHMSStore } from '@100mslive/react-sdk';
9
3
  import { SecondaryTiles } from '../components/SecondaryTiles';
4
+ import { ToastManager } from '../components/Toast/ToastManager';
10
5
  import { ProminenceLayout } from '../components/VideoLayouts/ProminenceLayout';
11
6
  import { Box } from '../../Layout';
12
- import { useSetAppDataByKey } from '../components/AppData/useUISettings';
7
+ import { useResetEmbedConfig, useSetAppDataByKey } from '../components/AppData/useUISettings';
13
8
  import { APP_DATA } from '../common/constants';
14
9
 
15
10
  export const EmbedView = () => {
16
11
  return (
17
- <EmbebScreenShareView>
12
+ <EmbedScreenShareView>
18
13
  <EmbedComponent />
19
- </EmbebScreenShareView>
14
+ </EmbedScreenShareView>
20
15
  );
21
16
  };
22
17
 
23
- export const EmbebScreenShareView = ({ children }) => {
18
+ export const EmbedScreenShareView = ({ children }) => {
24
19
  const peers = useHMSStore(selectPeers);
25
20
 
26
21
  const peerPresenting = useHMSStore(selectPeerScreenSharing);
@@ -44,62 +39,54 @@ export const EmbebScreenShareView = ({ children }) => {
44
39
  </ProminenceLayout.Root>
45
40
  );
46
41
  };
47
-
42
+ /**
43
+ * EmbedView is responsible for rendering the iframe and managing the screen sharing functionality.
44
+ */
48
45
  const EmbedComponent = () => {
49
- const { amIScreenSharing, toggleScreenShare } = useScreenShare(throwErrorHandler);
50
- const [embedConfig, setEmbedConfig] = useSetAppDataByKey(APP_DATA.embedConfig);
51
- const [wasScreenShared, setWasScreenShared] = useState(false);
52
- // to handle - https://github.com/facebook/react/issues/24502
53
- const screenShareAttemptInProgress = useRef(false);
54
- const src = embedConfig.url;
55
- const iframeRef = useRef();
56
-
57
- const resetEmbedConfig = useCallback(() => {
58
- if (src) {
59
- setEmbedConfig({ url: '' });
60
- }
61
- }, [src, setEmbedConfig]);
46
+ const embedConfig = useHMSStore(selectAppData(APP_DATA.embedConfig));
47
+ const resetConfig = useResetEmbedConfig();
62
48
 
63
- useEffect(() => {
64
- if (embedConfig.shareScreen && !amIScreenSharing && !wasScreenShared && !screenShareAttemptInProgress.current) {
65
- screenShareAttemptInProgress.current = true;
66
- // start screenshare on load for others in the room to see
67
- toggleScreenShare({
68
- forceCurrentTab: true,
69
- cropElement: iframeRef.current,
70
- })
71
- .then(() => {
72
- setWasScreenShared(true);
73
- })
74
- .catch(resetEmbedConfig)
75
- .finally(() => {
76
- screenShareAttemptInProgress.current = false;
77
- });
78
- }
79
- // eslint-disable-next-line react-hooks/exhaustive-deps
80
- }, []);
49
+ // need to send resetConfig to clear configuration, if stop screenshare occurs.
50
+ const { iframeRef, startEmbedShare, isEmbedShareInProgress } = useEmbedShare(resetConfig);
81
51
 
82
52
  useEffect(() => {
83
- // reset embed when screenshare is closed from anywhere
84
- if (wasScreenShared && !amIScreenSharing) {
85
- resetEmbedConfig();
86
- }
87
- return () => {
88
- // close screenshare when this component is being unmounted
89
- if (wasScreenShared && amIScreenSharing) {
90
- resetEmbedConfig();
91
- toggleScreenShare(); // stop
53
+ (async () => {
54
+ if (embedConfig && !isEmbedShareInProgress) {
55
+ try {
56
+ await startEmbedShare(embedConfig);
57
+ } catch (err) {
58
+ resetConfig();
59
+ ToastManager.addToast({
60
+ title: `Error while sharing embed url ${err.message || ''}`,
61
+ variant: 'error',
62
+ });
63
+ }
92
64
  }
93
- };
94
- }, [wasScreenShared, amIScreenSharing, resetEmbedConfig, toggleScreenShare]);
65
+ })();
66
+ }, [isEmbedShareInProgress, embedConfig, startEmbedShare, resetConfig]);
95
67
 
96
68
  return (
97
- <Box ref={iframeRef} css={{ size: '100%' }}>
69
+ <Box
70
+ css={{
71
+ mx: '$8',
72
+ flex: '3 1 0',
73
+ '@lg': {
74
+ flex: '2 1 0',
75
+ display: 'flex',
76
+ alignItems: 'center',
77
+ },
78
+ }}
79
+ >
98
80
  <iframe
99
- src={src}
100
- title={src}
101
- style={{ width: '100%', height: '100%', border: 0 }}
102
- allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture fullscreen"
81
+ title="Embed View"
82
+ ref={iframeRef}
83
+ style={{
84
+ width: '100%',
85
+ height: '100%',
86
+ border: 0,
87
+ borderRadius: '0.75rem',
88
+ }}
89
+ allow="autoplay; clipboard-write;"
103
90
  referrerPolicy="no-referrer"
104
91
  />
105
92
  </Box>
@@ -1,111 +1,61 @@
1
- import React, { useCallback, useEffect, useRef, useState } from 'react';
2
- import { throwErrorHandler, useScreenShare } from '@100mslive/react-sdk';
1
+ import React, { useEffect } from 'react';
2
+ import { usePDFShare } from '@100mslive/react-sdk';
3
+ import { ToastManager } from '../components/Toast/ToastManager';
3
4
  import { Box } from '../../Layout';
4
- import { ThemeTypes, useTheme } from '../../Theme';
5
- import { EmbebScreenShareView } from './EmbedView';
6
- import { useSetAppDataByKey } from '../components/AppData/useUISettings';
7
- import { APP_DATA, isChrome } from '../common/constants';
5
+ import { EmbedScreenShareView } from './EmbedView';
6
+ import { usePDFConfig, useResetPDFConfig } from '../components/AppData/useUISettings';
8
7
 
8
+ /**
9
+ * PDFView is responsible for rendering the PDF iframe and managing the screen sharing functionality.
10
+ */
9
11
  export const PDFView = () => {
10
- return (
11
- <EmbebScreenShareView>
12
- <PDFEmbedComponent />
13
- </EmbebScreenShareView>
14
- );
15
- };
12
+ const pdfConfig = usePDFConfig();
13
+ const resetConfig = useResetPDFConfig();
16
14
 
17
- export const PDFEmbedComponent = () => {
18
- const ref = useRef();
19
- const themeType = useTheme().themeType;
20
- const [isPDFLoaded, setIsPDFLoaded] = useState(false);
21
- let pdfJSURL = process.env.REACT_APP_PDFJS_IFRAME_URL;
22
- const { amIScreenSharing, toggleScreenShare } = useScreenShare(throwErrorHandler);
23
- const [pdfConfig, setPDFConfig] = useSetAppDataByKey(APP_DATA.pdfConfig);
24
- if (pdfConfig.url && !pdfConfig.file) {
25
- pdfJSURL = pdfJSURL + '?file=' + encodeURIComponent(pdfConfig.url);
26
- }
27
- const [wasScreenShared, setWasScreenShared] = useState(false);
28
- // to handle - https://github.com/facebook/react/issues/24502
29
- const screenShareAttemptInProgress = useRef(false);
30
- const iframeRef = useRef();
15
+ // need to send resetConfig to clear configuration, if stop screenshare occurs.
16
+ const { iframeRef, startPDFShare, isPDFShareInProgress } = usePDFShare(resetConfig);
31
17
 
32
- const resetEmbedConfig = useCallback(() => {
33
- setPDFConfig({ state: false });
34
- }, [setPDFConfig]);
35
- useEffect(() => {
36
- if (isPDFLoaded && ref.current) {
37
- ref.current.contentWindow.postMessage(
38
- {
39
- theme: themeType === ThemeTypes.dark ? 2 : 1,
40
- },
41
- '*',
42
- );
43
- }
44
- }, [isPDFLoaded, themeType]);
45
18
  useEffect(() => {
46
- if (!amIScreenSharing && !wasScreenShared && !screenShareAttemptInProgress.current) {
47
- screenShareAttemptInProgress.current = true;
48
- // start screenshare on load for others in the room to see
49
- toggleScreenShare({
50
- forceCurrentTab: isChrome,
51
- cropElement: iframeRef.current,
52
- preferCurrentTab: isChrome,
53
- })
54
- .then(() => {
55
- setWasScreenShared(true);
56
- })
57
- .catch(resetEmbedConfig)
58
- .finally(() => {
59
- screenShareAttemptInProgress.current = false;
19
+ (async () => {
20
+ try {
21
+ if (!isPDFShareInProgress && pdfConfig) {
22
+ await startPDFShare(pdfConfig);
23
+ }
24
+ } catch (err) {
25
+ resetConfig();
26
+ ToastManager.addToast({
27
+ title: `Error while sharing annotator ${err.message || ''}`,
28
+ variant: 'error',
60
29
  });
61
- }
62
- // eslint-disable-next-line react-hooks/exhaustive-deps
63
- }, []);
64
-
65
- useEffect(() => {
66
- // reset embed when screenshare is closed from anywhere
67
- if (wasScreenShared && !amIScreenSharing) {
68
- resetEmbedConfig();
69
- }
70
- return () => {
71
- // close screenshare when this component is being unmounted
72
- if (wasScreenShared && amIScreenSharing) {
73
- resetEmbedConfig();
74
- toggleScreenShare(); // stop
75
30
  }
76
- };
77
- }, [wasScreenShared, amIScreenSharing, resetEmbedConfig, toggleScreenShare]);
78
-
31
+ })();
32
+ }, [isPDFShareInProgress, pdfConfig, resetConfig, startPDFShare]);
79
33
  return (
80
- <Box ref={iframeRef} css={{ size: '100%' }}>
81
- <iframe
82
- src={pdfJSURL}
83
- title="PDF Annotator"
84
- ref={ref}
85
- style={{
86
- width: '100%',
87
- height: '100%',
88
- border: 0,
89
- borderRadius: '0.75rem',
90
- }}
91
- allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture fullscreen"
92
- referrerPolicy="no-referrer"
93
- onLoad={() => {
94
- if (ref.current && pdfConfig.file) {
95
- // setting theme dark -> 2 and light -> 1
96
- requestAnimationFrame(() => {
97
- ref.current.contentWindow.postMessage(
98
- {
99
- file: pdfConfig.file,
100
- theme: themeType === ThemeTypes.dark ? 2 : 1,
101
- },
102
- '*',
103
- );
104
- setIsPDFLoaded(true);
105
- }, 1000);
106
- }
34
+ <EmbedScreenShareView>
35
+ <Box
36
+ css={{
37
+ mx: '$8',
38
+ flex: '3 1 0',
39
+ '@lg': {
40
+ flex: '2 1 0',
41
+ display: 'flex',
42
+ alignItems: 'center',
43
+ },
107
44
  }}
108
- />
109
- </Box>
45
+ >
46
+ <iframe
47
+ title="Embed View"
48
+ ref={iframeRef}
49
+ style={{
50
+ width: '100%',
51
+ height: '100%',
52
+ border: 0,
53
+ borderRadius: '0.75rem',
54
+ }}
55
+ allow="autoplay; clipboard-write;"
56
+ referrerPolicy="no-referrer"
57
+ />
58
+ </Box>
59
+ </EmbedScreenShareView>
110
60
  );
111
61
  };