@100mslive/roomkit-react 0.3.7 → 0.3.8-alpha.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (38) hide show
  1. package/dist/{HLSView-J76FQQDB.js → HLSView-HUMJOIWO.js} +35 -17
  2. package/dist/{HLSView-J76FQQDB.js.map → HLSView-HUMJOIWO.js.map} +3 -3
  3. package/dist/Prebuilt/common/constants.d.ts +1 -0
  4. package/dist/Prebuilt/common/hooks.d.ts +10 -0
  5. package/dist/Prebuilt/components/FullPageProgress.d.ts +8 -0
  6. package/dist/Prebuilt/components/HMSVideo/utils.d.ts +1 -0
  7. package/dist/Prebuilt/components/VirtualBackground/VBHandler.d.ts +3 -3
  8. package/dist/{chunk-VKO5HF7B.js → chunk-IDAPJGWC.js} +346 -362
  9. package/dist/chunk-IDAPJGWC.js.map +7 -0
  10. package/dist/index.cjs.js +300 -299
  11. package/dist/index.cjs.js.map +4 -4
  12. package/dist/index.js +1 -1
  13. package/dist/meta.cjs.json +87 -62
  14. package/dist/meta.esbuild.json +99 -74
  15. package/package.json +6 -6
  16. package/src/Prebuilt/common/constants.ts +1 -0
  17. package/src/Prebuilt/common/hooks.ts +72 -1
  18. package/src/Prebuilt/components/AppData/AppData.tsx +1 -0
  19. package/src/Prebuilt/components/ConferenceScreen.tsx +0 -2
  20. package/src/Prebuilt/components/{FullPageProgress.jsx → FullPageProgress.tsx} +10 -1
  21. package/src/Prebuilt/components/HMSVideo/VideoProgress.tsx +3 -2
  22. package/src/Prebuilt/components/HMSVideo/VideoTime.tsx +16 -7
  23. package/src/Prebuilt/components/HMSVideo/utils.ts +10 -0
  24. package/src/Prebuilt/components/Header/StreamActions.tsx +3 -25
  25. package/src/Prebuilt/components/MoreSettings/SplitComponents/MwebOptions.tsx +4 -26
  26. package/src/Prebuilt/components/Notifications/PeerNotifications.tsx +1 -11
  27. package/src/Prebuilt/components/Preview/PreviewJoin.tsx +4 -9
  28. package/src/Prebuilt/components/Preview/PreviewScreen.tsx +0 -3
  29. package/src/Prebuilt/components/RoomDetails/RoomDetailsPane.tsx +2 -2
  30. package/src/Prebuilt/components/Settings/StartRecording.jsx +4 -37
  31. package/src/Prebuilt/components/Toast/ToastConfig.jsx +0 -22
  32. package/src/Prebuilt/components/VirtualBackground/VBHandler.tsx +3 -3
  33. package/src/Prebuilt/components/VirtualBackground/VBOption.tsx +3 -1
  34. package/src/Prebuilt/components/VirtualBackground/VBPicker.tsx +23 -7
  35. package/src/Prebuilt/components/VirtualBackground/VBToggle.tsx +5 -3
  36. package/src/Prebuilt/layouts/SidePane.tsx +1 -1
  37. package/src/Prebuilt/layouts/VideoStreamingSection.tsx +0 -2
  38. package/dist/chunk-VKO5HF7B.js.map +0 -7
@@ -3,20 +3,27 @@ import { useMedia } from 'react-use';
3
3
  import { HMSHLSPlayer } from '@100mslive/hls-player';
4
4
  import { JoinForm_JoinBtnType } from '@100mslive/types-prebuilt/elements/join_form';
5
5
  import {
6
+ HMSRecording,
6
7
  parsedUserAgent,
7
8
  selectAvailableRoleNames,
8
9
  selectIsConnectedToRoom,
9
10
  selectPeerCount,
10
11
  selectPeerMetadata,
11
12
  selectPeers,
13
+ selectRecordingState,
12
14
  selectRemotePeers,
15
+ useHMSActions,
13
16
  useHMSStore,
14
17
  useHMSVanillaStore,
15
18
  } from '@100mslive/react-sdk';
19
+ // @ts-ignore: No implicit any
20
+ import { ToastManager } from '../components/Toast/ToastManager';
16
21
  import { config } from '../../Theme';
17
22
  import { useRoomLayout } from '../provider/roomLayoutProvider';
23
+ // @ts-ignore
24
+ import { useSetAppDataByKey } from '../components/AppData/useUISettings';
18
25
  import { useRoomLayoutConferencingScreen } from '../provider/roomLayoutProvider/hooks/useRoomLayoutScreen';
19
- import { CHAT_SELECTOR } from './constants';
26
+ import { APP_DATA, CHAT_SELECTOR, RTMP_RECORD_DEFAULT_RESOLUTION } from './constants';
20
27
  /**
21
28
  * Hook to execute a callback when alone in room(after a certain 5d of time)
22
29
  * @param {number} thresholdMs The threshold(in ms) after which the callback is executed,
@@ -147,3 +154,67 @@ export const useKeyboardHandler = (isPaused: boolean, hlsPlayer: HMSHLSPlayer) =
147
154
 
148
155
  return handleKeyEvent;
149
156
  };
157
+ export interface RTMPRecordingResolution {
158
+ width: number;
159
+ height: number;
160
+ }
161
+ export const useRecordingHandler = () => {
162
+ const hmsActions = useHMSActions();
163
+ const recordingState: HMSRecording = useHMSStore(selectRecordingState);
164
+ const [isRecordingLoading, setIsRecordingLoading] = useState(false);
165
+ const [recordingStarted, setRecordingState] = useSetAppDataByKey(APP_DATA.recordingStarted);
166
+ useEffect(() => {
167
+ if (recordingState.browser.error && recordingStarted) {
168
+ setRecordingState(false);
169
+ }
170
+ }, [recordingStarted, recordingState.browser.error, setRecordingState]);
171
+ const startRecording = useCallback(
172
+ async (resolution: RTMPRecordingResolution | null = null) => {
173
+ try {
174
+ setRecordingState(true);
175
+ setIsRecordingLoading(true);
176
+ await hmsActions.startRTMPOrRecording({
177
+ resolution: getResolution(resolution),
178
+ record: true,
179
+ });
180
+ } catch (error) {
181
+ const err = error as Error;
182
+ if (err.message.includes('stream already running')) {
183
+ ToastManager.addToast({
184
+ title: 'Recording already running',
185
+ variant: 'error',
186
+ });
187
+ } else {
188
+ ToastManager.addToast({
189
+ title: err.message,
190
+ variant: 'error',
191
+ });
192
+ }
193
+ setRecordingState(false);
194
+ }
195
+ setIsRecordingLoading(false);
196
+ },
197
+ [hmsActions, setRecordingState],
198
+ );
199
+ return {
200
+ recordingStarted,
201
+ startRecording,
202
+ isRecordingLoading,
203
+ };
204
+ };
205
+
206
+ export function getResolution(
207
+ recordingResolution: RTMPRecordingResolution | null,
208
+ ): RTMPRecordingResolution | undefined {
209
+ if (!recordingResolution) {
210
+ return undefined;
211
+ }
212
+ const resolution: RTMPRecordingResolution = RTMP_RECORD_DEFAULT_RESOLUTION;
213
+ if (recordingResolution.width) {
214
+ resolution.width = recordingResolution.width;
215
+ }
216
+ if (recordingResolution.height) {
217
+ resolution.height = recordingResolution.height;
218
+ }
219
+ return resolution;
220
+ }
@@ -62,6 +62,7 @@ const initialAppData = {
62
62
  [APP_DATA.minimiseInset]: false,
63
63
  [APP_DATA.activeScreensharePeerId]: '',
64
64
  [APP_DATA.disableNotifications]: false,
65
+ [APP_DATA.loadingEffects]: false,
65
66
  [APP_DATA.background]: 'none',
66
67
  [APP_DATA.pollState]: {
67
68
  [POLL_STATE.pollInView]: '',
@@ -22,7 +22,6 @@ import { useHMSPrebuiltContext } from '../AppContext';
22
22
  import { VideoStreamingSection } from '../layouts/VideoStreamingSection';
23
23
  // @ts-ignore: No implicit Any
24
24
  import { EmojiReaction } from './EmojiReaction';
25
- // @ts-ignore: No implicit Any
26
25
  import FullPageProgress from './FullPageProgress';
27
26
  import { Header } from './Header';
28
27
  import { PreviousRoleInMetadata } from './PreviousRoleInMetadata';
@@ -34,7 +33,6 @@ import {
34
33
  // @ts-ignore: No implicit Any
35
34
  import { useAuthToken, useSetAppDataByKey } from './AppData/useUISettings';
36
35
  import { useLandscapeHLSStream, useMobileHLSStream } from '../common/hooks';
37
- // @ts-ignore: No implicit Any
38
36
  import { APP_DATA, isAndroid, isIOS, isIPadOS } from '../common/constants';
39
37
 
40
38
  export const ConferenceScreen = () => {
@@ -2,8 +2,17 @@ import React from 'react';
2
2
  import { Flex } from '../../Layout';
3
3
  import { Loading } from '../../Loading';
4
4
  import { Text } from '../../Text';
5
+ import { CSS } from '../../Theme';
5
6
 
6
- const FullPageProgress = ({ loaderColor = '$primary_default', text = '', css = {} }) => (
7
+ const FullPageProgress = ({
8
+ loaderColor = '$primary_default',
9
+ text = '',
10
+ css = {},
11
+ }: {
12
+ loaderColor?: string;
13
+ text?: string;
14
+ css?: CSS;
15
+ }) => (
7
16
  <Flex direction="column" justify="center" align="center" css={{ size: '100%', color: loaderColor, ...css }}>
8
17
  <Loading color="currentColor" size={100} />
9
18
  {text ? <Text css={{ mt: '$10', color: '$on_surface_high' }}>{text}</Text> : null}
@@ -1,7 +1,7 @@
1
1
  import React, { useCallback, useEffect, useState } from 'react';
2
2
  import { Box, Flex, Slider } from '../../..';
3
3
  import { useHMSPlayerContext } from './PlayerContext';
4
- import { getPercentage } from './utils';
4
+ import { getDuration, getPercentage } from './utils';
5
5
 
6
6
  export const VideoProgress = ({
7
7
  seekProgress,
@@ -19,7 +19,7 @@ export const VideoProgress = ({
19
19
  if (!videoEl) {
20
20
  return;
21
21
  }
22
- const duration = isFinite(videoEl.duration) ? videoEl.duration : videoEl.seekable?.end(0) || 0;
22
+ const duration = getDuration(videoEl);
23
23
  const videoProgress = Math.floor(getPercentage(videoEl.currentTime, duration));
24
24
  let bufferProgress = 0;
25
25
  if (videoEl.buffered.length > 0) {
@@ -42,6 +42,7 @@ export const VideoProgress = ({
42
42
  if (!videoEl) {
43
43
  return;
44
44
  }
45
+ setProgress();
45
46
  videoEl.addEventListener('timeupdate', timeupdateHandler);
46
47
  return function cleanup() {
47
48
  videoEl?.removeEventListener('timeupdate', timeupdateHandler);
@@ -1,30 +1,39 @@
1
- import React, { useEffect, useState } from 'react';
1
+ import React, { useCallback, useEffect, useState } from 'react';
2
2
  import { HMSHLSPlayerEvents } from '@100mslive/hls-player';
3
3
  import { Text } from '../../../Text';
4
4
  import { useHMSPlayerContext } from './PlayerContext';
5
- import { getDurationFromSeconds } from './utils';
5
+ import { getDuration, getDurationFromSeconds } from './utils';
6
6
 
7
7
  export const VideoTime = () => {
8
8
  const { hlsPlayer } = useHMSPlayerContext();
9
- const [videoTime, setVideoTime] = useState('');
10
9
 
11
- useEffect(() => {
12
- const timeupdateHandler = (currentTime: number) => {
10
+ const [videoTime, setVideoTime] = useState(getDurationFromSeconds(0));
11
+
12
+ const updateTime = useCallback(
13
+ (currentTime: number) => {
13
14
  const videoEl = hlsPlayer?.getVideoElement();
14
15
  if (videoEl) {
15
- const duration = isFinite(videoEl.duration) ? videoEl.duration : videoEl.seekable.end(0) || 0;
16
+ const duration = getDuration(videoEl);
16
17
  setVideoTime(getDurationFromSeconds(duration - currentTime));
17
18
  } else {
18
19
  setVideoTime(getDurationFromSeconds(currentTime));
19
20
  }
21
+ },
22
+ [hlsPlayer],
23
+ );
24
+ useEffect(() => {
25
+ const timeupdateHandler = (currentTime: number) => {
26
+ updateTime(currentTime);
20
27
  };
21
28
  if (hlsPlayer) {
22
29
  hlsPlayer.on(HMSHLSPlayerEvents.CURRENT_TIME, timeupdateHandler);
30
+ const videoEl = hlsPlayer?.getVideoElement();
31
+ updateTime(videoEl.currentTime);
23
32
  }
24
33
  return function cleanup() {
25
34
  hlsPlayer?.off(HMSHLSPlayerEvents.CURRENT_TIME, timeupdateHandler);
26
35
  };
27
- }, [hlsPlayer]);
36
+ }, [hlsPlayer, updateTime]);
28
37
 
29
38
  return hlsPlayer ? (
30
39
  <Text
@@ -25,3 +25,13 @@ export function getDurationFromSeconds(timeInSeconds: number) {
25
25
  }
26
26
  return videoTimeStr;
27
27
  }
28
+
29
+ export function getDuration(videoEl: HTMLVideoElement): number {
30
+ if (isFinite(videoEl.duration)) {
31
+ return videoEl.duration;
32
+ }
33
+ if (videoEl.seekable.length > 0) {
34
+ return videoEl.seekable.end(0);
35
+ }
36
+ return 0;
37
+ }
@@ -20,12 +20,9 @@ import { ToastManager } from '../Toast/ToastManager';
20
20
  // @ts-ignore
21
21
  import { AdditionalRoomState, getRecordingText } from './AdditionalRoomState';
22
22
  import { useRoomLayoutConferencingScreen } from '../../provider/roomLayoutProvider/hooks/useRoomLayoutScreen';
23
- // @ts-ignore
24
- import { useSetAppDataByKey } from '../AppData/useUISettings';
23
+ import { useRecordingHandler } from '../../common/hooks';
25
24
  // @ts-ignore
26
25
  import { formatTime } from '../../common/utils';
27
- // @ts-ignore
28
- import { APP_DATA } from '../../common/constants';
29
26
 
30
27
  export const LiveStatus = () => {
31
28
  const { isHLSRunning, isRTMPRunning } = useRecordingStreaming();
@@ -147,7 +144,7 @@ export const RecordingPauseStatus = () => {
147
144
  const StartRecording = () => {
148
145
  const permissions = useHMSStore(selectPermissions);
149
146
  const [open, setOpen] = useState(false);
150
- const [recordingStarted, setRecordingState] = useSetAppDataByKey(APP_DATA.recordingStarted);
147
+ const { startRecording, recordingStarted } = useRecordingHandler();
151
148
  const { isBrowserRecordingOn, isStreamingOn, isHLSRunning } = useRecordingStreaming();
152
149
  const hmsActions = useHMSActions();
153
150
  if (!permissions?.browserRecording || isHLSRunning) {
@@ -201,26 +198,7 @@ const StartRecording = () => {
201
198
  icon
202
199
  disabled={recordingStarted || isStreamingOn}
203
200
  onClick={async () => {
204
- try {
205
- setRecordingState(true);
206
- await hmsActions.startRTMPOrRecording({
207
- record: true,
208
- });
209
- } catch (error) {
210
- const err = error as Error;
211
- if (err.message.includes('stream already running')) {
212
- ToastManager.addToast({
213
- title: 'Recording already running',
214
- variant: 'error',
215
- });
216
- } else {
217
- ToastManager.addToast({
218
- title: err.message,
219
- variant: 'error',
220
- });
221
- }
222
- setRecordingState(false);
223
- }
201
+ await startRecording();
224
202
  }}
225
203
  >
226
204
  {recordingStarted ? <Loading size={24} color="currentColor" /> : <RecordIcon />}
@@ -54,7 +54,7 @@ import { useShowPolls } from '../../AppData/useUISettings';
54
54
  import { useDropdownList } from '../../hooks/useDropdownList';
55
55
  import { useMyMetadata } from '../../hooks/useMetadata';
56
56
  import { useUnreadPollQuizPresent } from '../../hooks/useUnreadPollQuizPresent';
57
- import { useLandscapeHLSStream, useMobileHLSStream } from '../../../common/hooks';
57
+ import { useLandscapeHLSStream, useMobileHLSStream, useRecordingHandler } from '../../../common/hooks';
58
58
  // @ts-ignore: No implicit any
59
59
  import { getFormattedCount } from '../../../common/utils';
60
60
  // @ts-ignore: No implicit any
@@ -88,7 +88,6 @@ export const MwebOptions = ({
88
88
  const [openSettingsSheet, setOpenSettingsSheet] = useState(false);
89
89
  const [showEmojiCard, setShowEmojiCard] = useState(false);
90
90
  const [showRecordingOn, setShowRecordingOn] = useState(false);
91
- const [isRecordingLoading, setIsRecordingLoading] = useState(false);
92
91
  const toggleParticipants = useSidepaneToggle(SIDE_PANE_OPTIONS.PARTICIPANTS);
93
92
  const { showPolls } = useShowPolls();
94
93
  const togglePollView = usePollViewToggle();
@@ -102,7 +101,7 @@ export const MwebOptions = ({
102
101
  const isLandscapeHLSStream = useLandscapeHLSStream();
103
102
  const toggleVB = useSidepaneToggle(SIDE_PANE_OPTIONS.VB);
104
103
  const isLocalVideoEnabled = useHMSStore(selectIsLocalVideoEnabled);
105
-
104
+ const { startRecording, isRecordingLoading } = useRecordingHandler();
106
105
  useDropdownList({ open: openModals.size > 0 || openOptionsSheet || openSettingsSheet, name: 'MoreSettings' });
107
106
 
108
107
  const updateState = (modalName: string, value: boolean) => {
@@ -260,29 +259,8 @@ export const MwebOptions = ({
260
259
  setShowRecordingOn(true);
261
260
  } else {
262
261
  // start recording
263
- setIsRecordingLoading(true);
264
- try {
265
- await hmsActions.startRTMPOrRecording({
266
- record: true,
267
- });
268
- setOpenOptionsSheet(false);
269
- setIsRecordingLoading(false);
270
- } catch (error) {
271
- // @ts-ignore
272
- if (error.message.includes('stream already running')) {
273
- ToastManager.addToast({
274
- title: 'Recording already running',
275
- variant: 'error',
276
- });
277
- } else {
278
- ToastManager.addToast({
279
- // @ts-ignore
280
- title: error.message,
281
- variant: 'error',
282
- });
283
- }
284
- setIsRecordingLoading(false);
285
- }
262
+ await startRecording();
263
+ setOpenOptionsSheet(false);
286
264
  }
287
265
  if (isHLSRunning) {
288
266
  setOpenOptionsSheet(false);
@@ -7,11 +7,7 @@ import { useSetSubscribedChatSelector, useSubscribedNotifications } from '../App
7
7
  // @ts-ignore: No implicit Any
8
8
  import { CHAT_SELECTOR, SUBSCRIBED_NOTIFICATIONS } from '../../common/constants';
9
9
 
10
- const notificationTypes = [
11
- HMSNotificationTypes.PEER_LIST,
12
- HMSNotificationTypes.PEER_JOINED,
13
- HMSNotificationTypes.PEER_LEFT,
14
- ];
10
+ const notificationTypes = [HMSNotificationTypes.PEER_JOINED, HMSNotificationTypes.PEER_LEFT];
15
11
 
16
12
  export const PeerNotifications = () => {
17
13
  const notification = useHMSNotifications(notificationTypes);
@@ -26,11 +22,6 @@ export const PeerNotifications = () => {
26
22
 
27
23
  console.debug(`[${notification.type}]`, notification);
28
24
  switch (notification.type) {
29
- case HMSNotificationTypes.PEER_LIST:
30
- if (!isPeerJoinSubscribed || notification.data.length === 0) {
31
- return;
32
- }
33
- break;
34
25
  case HMSNotificationTypes.PEER_JOINED:
35
26
  if (!isPeerJoinSubscribed) {
36
27
  return;
@@ -47,7 +38,6 @@ export const PeerNotifications = () => {
47
38
  default:
48
39
  return;
49
40
  }
50
-
51
41
  ToastBatcher.showToast({ notification });
52
42
  }, [notification, isPeerJoinSubscribed, isPeerLeftSubscribed, selectedPeer.id, setPeerSelector]);
53
43
 
@@ -2,6 +2,7 @@ import React, { Fragment, useCallback, useEffect, useMemo, useState } from 'reac
2
2
  import { useMeasure, useMedia } from 'react-use';
3
3
  import {
4
4
  HMSRoomState,
5
+ selectAppData,
5
6
  selectIsLocalVideoEnabled,
6
7
  selectLocalPeer,
7
8
  selectRoomState,
@@ -16,24 +17,17 @@ import { MicOffIcon, SettingsIcon } from '@100mslive/react-icons';
16
17
  import { Avatar, Box, config as cssConfig, Flex, flexCenter, styled, StyledVideoTile, Text, Video } from '../../..';
17
18
  import { AudioLevel } from '../../../AudioLevel';
18
19
  import { useHMSPrebuiltContext } from '../../AppContext';
19
- // @ts-ignore: No implicit Any
20
20
  import IconButton from '../../IconButton';
21
21
  import SidePane from '../../layouts/SidePane';
22
- // @ts-ignore: No implicit Any
23
22
  import { AudioVideoToggle } from '../AudioVideoToggle';
24
- // @ts-ignore: No implicit Any
25
23
  import Chip from '../Chip';
26
- // @ts-ignore: No implicit Any
27
24
  import TileConnection from '../Connection/TileConnection';
28
- // @ts-ignore: No implicit Any
29
25
  import FullPageProgress from '../FullPageProgress';
30
26
  // @ts-ignore: No implicit Any
31
27
  import { Logo } from '../Header/HeaderComponents';
32
28
  // @ts-ignore: No implicit Any
33
29
  import SettingsModal from '../Settings/SettingsModal';
34
- // @ts-ignore: No implicit Any
35
30
  import { VBToggle } from '../VirtualBackground/VBToggle';
36
- // @ts-ignore: No implicit Any
37
31
  import PreviewForm from './PreviewForm';
38
32
  import { useRoomLayoutPreviewScreen } from '../../provider/roomLayoutProvider/hooks/useRoomLayoutScreen';
39
33
  // @ts-ignore: No implicit Any
@@ -42,7 +36,7 @@ import { useAuthToken, useUISettings } from '../AppData/useUISettings';
42
36
  import { defaultPreviewPreference, UserPreferencesKeys, useUserPreferences } from '../hooks/useUserPreferences';
43
37
  // @ts-ignore: No implicit Any
44
38
  import { calculateAvatarAndAttribBoxSize, getFormattedCount } from '../../common/utils';
45
- import { UI_SETTINGS } from '../../common/constants';
39
+ import { APP_DATA, UI_SETTINGS } from '../../common/constants';
46
40
 
47
41
  const getParticipantChipContent = (peerCount = 0) => {
48
42
  if (peerCount === 0) {
@@ -85,6 +79,7 @@ const PreviewJoin = ({
85
79
  const [previewError, setPreviewError] = useState(false);
86
80
  const { endpoints } = useHMSPrebuiltContext();
87
81
  const { peerCount } = useParticipants();
82
+ const loadingEffects = useHMSStore(selectAppData(APP_DATA.loadingEffects));
88
83
  const { enableJoin, preview, join } = usePreviewJoin({
89
84
  name,
90
85
  token: authToken,
@@ -166,7 +161,7 @@ const PreviewJoin = ({
166
161
  name={name}
167
162
  disabled={!!initialName}
168
163
  onChange={setName}
169
- enableJoin={enableJoin}
164
+ enableJoin={enableJoin && !loadingEffects}
170
165
  onJoin={savePreferenceAndJoin}
171
166
  cannotPublishVideo={!toggleVideo}
172
167
  cannotPublishAudio={!toggleAudio}
@@ -3,14 +3,11 @@ import { useSearchParam } from 'react-use';
3
3
  import { Flex } from '../../..';
4
4
  import { useHMSPrebuiltContext } from '../../AppContext';
5
5
  import { useRoomLayout } from '../../provider/roomLayoutProvider';
6
- // @ts-ignore: No implicit Any
7
6
  import FullPageProgress from '../FullPageProgress';
8
- // @ts-ignore: No implicit Any
9
7
  import PreviewJoin from './PreviewJoin';
10
8
  import { useRoomLayoutPreviewScreen } from '../../provider/roomLayoutProvider/hooks/useRoomLayoutScreen';
11
9
  // @ts-ignore: No implicit Any
12
10
  import { useAuthToken } from '../AppData/useUISettings';
13
- // @ts-ignore: No implicit Any
14
11
  import { QUERY_PARAM_PREVIEW_AS_ROLE } from '../../common/constants';
15
12
 
16
13
  export const PreviewScreen = () => {
@@ -15,7 +15,7 @@ export const RoomDetailsPane = () => {
15
15
  const { description } = useRoomLayoutHeader();
16
16
  const isMwebHLSStream = useMobileHLSStream();
17
17
  return (
18
- <Box css={{ flex: '1 1 0' }}>
18
+ <Box css={{ flex: '1 1 0', position: 'relative' }}>
19
19
  {isMwebHLSStream ? (
20
20
  <Flex direction="row" align="center" gap="2">
21
21
  <Logo />
@@ -41,7 +41,7 @@ const ShowRoomDetailHeader = () => {
41
41
  const toggleDetailsPane = useSidepaneToggle(SIDE_PANE_OPTIONS.ROOM_DETAILS);
42
42
  const isMwebHLSStream = useMobileHLSStream();
43
43
  return (
44
- <Flex direction="column">
44
+ <Flex direction="column" css={{ position: 'sticky', top: 0, bg: '$surface_dim' }}>
45
45
  <Flex justify="between" align="center" css={{ w: '100%' }}>
46
46
  <Text variant="h6">{title}</Text>
47
47
  {!isMwebHLSStream && (
@@ -4,27 +4,13 @@ import { AlertTriangleIcon } from '@100mslive/react-icons';
4
4
  import { Button, Dialog, Flex, Text } from '../../../';
5
5
  import { ResolutionInput } from '../Streaming/ResolutionInput';
6
6
  import { ToastManager } from '../Toast/ToastManager';
7
- import { useSetAppDataByKey } from '../AppData/useUISettings';
8
- import { APP_DATA, RTMP_RECORD_DEFAULT_RESOLUTION } from '../../common/constants';
9
-
10
- export function getResolution(recordingResolution) {
11
- const resolution = {};
12
- if (recordingResolution.width) {
13
- resolution.width = recordingResolution.width;
14
- }
15
- if (recordingResolution.height) {
16
- resolution.height = recordingResolution.height;
17
- }
18
- if (Object.keys(resolution).length > 0) {
19
- return resolution;
20
- }
21
- }
7
+ import { useRecordingHandler } from '../../common/hooks';
8
+ import { RTMP_RECORD_DEFAULT_RESOLUTION } from '../../common/constants';
22
9
 
23
10
  const StartRecording = ({ open, onOpenChange }) => {
24
11
  const permissions = useHMSStore(selectPermissions);
25
12
  const [resolution, setResolution] = useState(RTMP_RECORD_DEFAULT_RESOLUTION);
26
-
27
- const [recordingStarted, setRecordingState] = useSetAppDataByKey(APP_DATA.recordingStarted);
13
+ const { startRecording, recordingStarted } = useRecordingHandler();
28
14
  const { isBrowserRecordingOn, isStreamingOn, isHLSRunning } = useRecordingStreaming();
29
15
  const hmsActions = useHMSActions();
30
16
  if (!permissions?.browserRecording || isHLSRunning) {
@@ -101,26 +87,7 @@ const StartRecording = ({ open, onOpenChange }) => {
101
87
  type="submit"
102
88
  disabled={recordingStarted || isStreamingOn}
103
89
  onClick={async () => {
104
- try {
105
- setRecordingState(true);
106
- await hmsActions.startRTMPOrRecording({
107
- resolution: getResolution(resolution),
108
- record: true,
109
- });
110
- } catch (error) {
111
- if (error.message.includes('stream already running')) {
112
- ToastManager.addToast({
113
- title: 'Recording already running',
114
- variant: 'error',
115
- });
116
- } else {
117
- ToastManager.addToast({
118
- title: error.message,
119
- variant: 'error',
120
- });
121
- }
122
- setRecordingState(false);
123
- }
90
+ await startRecording(resolution);
124
91
  onOpenChange(false);
125
92
  }}
126
93
  >
@@ -72,28 +72,6 @@ const HandRaiseAction = React.forwardRef(({ id = '', isSingleHandRaise = true },
72
72
  });
73
73
 
74
74
  export const ToastConfig = {
75
- PEER_LIST: {
76
- single: function (notification) {
77
- if (notification.data.length === 1) {
78
- return {
79
- title: `${notification.data[0]?.name} joined`,
80
- icon: <PeopleAddIcon />,
81
- };
82
- }
83
- return {
84
- title: `${notification.data[notification.data.length - 1]?.name} and ${
85
- notification.data.length - 1
86
- } others joined`,
87
- icon: <PeopleAddIcon />,
88
- };
89
- },
90
- multiple: notifications => {
91
- return {
92
- title: `${notifications[0].data.name} and ${notifications.length - 1} others joined`,
93
- icon: <PeopleAddIcon />,
94
- };
95
- },
96
- },
97
75
  PEER_JOINED: {
98
76
  single: function (notification) {
99
77
  return {
@@ -4,12 +4,12 @@ export class VBPlugin {
4
4
  private hmsPlugin?: HMSVBPlugin;
5
5
  private effectsPlugin?: HMSEffectsPlugin | undefined;
6
6
 
7
- initialisePlugin = (effectsSDKKey?: string) => {
7
+ initialisePlugin = (effectsSDKKey?: string, onInit?: () => void) => {
8
8
  if (this.getVBObject()) {
9
9
  return;
10
10
  }
11
11
  if (effectsSDKKey) {
12
- this.effectsPlugin = new HMSEffectsPlugin(effectsSDKKey);
12
+ this.effectsPlugin = new HMSEffectsPlugin(effectsSDKKey, onInit);
13
13
  } else {
14
14
  this.hmsPlugin = new HMSVBPlugin(HMSVirtualBackgroundTypes.NONE, HMSVirtualBackgroundTypes.NONE);
15
15
  }
@@ -70,7 +70,7 @@ export class VBPlugin {
70
70
  }
71
71
  };
72
72
 
73
- setPreset = async (preset: string) => {
73
+ setPreset = async (preset: 'quality' | 'balanced') => {
74
74
  if (this.effectsPlugin) {
75
75
  await this.effectsPlugin.setPreset(preset);
76
76
  }
@@ -28,7 +28,9 @@ const Root = ({
28
28
  '&:hover': { border: '4px solid $primary_dim' },
29
29
  ...(mediaURL ? { height: '$20', backgroundImage: `url(${mediaURL})`, backgroundSize: 'cover' } : {}),
30
30
  }}
31
- onClick={async () => await onClick?.()}
31
+ onClick={async () => {
32
+ await onClick?.();
33
+ }}
32
34
  >
33
35
  {children}
34
36
  </Flex>