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

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 (64) hide show
  1. package/dist/AudioLevel/AudioLevel.d.ts +5 -8
  2. package/dist/AudioLevel/index.d.ts +2 -1
  3. package/dist/AudioLevel/useBorderAudioLevel.d.ts +8 -0
  4. package/dist/{HLSView-F5BDZVT2.js → HLSView-IQRPLYNH.js} +8 -6
  5. package/dist/{HLSView-F5BDZVT2.js.map → HLSView-IQRPLYNH.js.map} +2 -2
  6. package/dist/Prebuilt/components/Chip.d.ts +12 -0
  7. package/dist/Prebuilt/components/PrebuiltDialogPortal.d.ts +4 -0
  8. package/dist/Prebuilt/components/RoleChangeRequest/RequestPrompt.d.ts +9 -0
  9. package/dist/VideoTile/StyledVideoTile.d.ts +445 -3
  10. package/dist/{VirtualBackground-THDRYDRA.js → VirtualBackground-GP4ATXD3.js} +3 -3
  11. package/dist/{chunk-JSH7SKEH.js → chunk-2H5NIZB7.js} +2 -2
  12. package/dist/{chunk-CDYRVICT.js → chunk-GLYGPYNS.js} +574 -1196
  13. package/dist/chunk-GLYGPYNS.js.map +7 -0
  14. package/dist/{chunk-U3G743OY.js → chunk-Z3O2WGWV.js} +2 -2
  15. package/dist/{chunk-U3G743OY.js.map → chunk-Z3O2WGWV.js.map} +1 -1
  16. package/dist/{conference-6IVZHILI.js → conference-JD35TNH4.js} +1545 -840
  17. package/dist/conference-JD35TNH4.js.map +7 -0
  18. package/dist/index.cjs.js +5975 -5849
  19. package/dist/index.cjs.js.map +4 -4
  20. package/dist/index.js +4 -2
  21. package/dist/meta.cjs.json +1633 -1399
  22. package/dist/meta.esbuild.json +1689 -1454
  23. package/package.json +6 -6
  24. package/src/AudioLevel/AudioLevel.tsx +79 -30
  25. package/src/AudioLevel/audio-level.png +0 -0
  26. package/src/AudioLevel/index.ts +2 -1
  27. package/src/AudioLevel/useBorderAudioLevel.tsx +34 -0
  28. package/src/Input/Input.tsx +1 -1
  29. package/src/Prebuilt/App.tsx +1 -0
  30. package/src/Prebuilt/components/Chat/ChatBody.jsx +125 -106
  31. package/src/Prebuilt/components/{Chip.jsx → Chip.tsx} +13 -2
  32. package/src/Prebuilt/components/Footer/ParticipantList.jsx +24 -13
  33. package/src/Prebuilt/components/Footer/RoleAccordion.tsx +43 -3
  34. package/src/Prebuilt/components/Leave/DesktopLeaveRoom.tsx +41 -46
  35. package/src/Prebuilt/components/Leave/MwebLeaveRoom.tsx +23 -35
  36. package/src/Prebuilt/components/MoreSettings/ChangeNameModal.jsx +3 -2
  37. package/src/Prebuilt/components/MoreSettings/EmbedUrl.jsx +3 -2
  38. package/src/Prebuilt/components/MwebLandscapePrompt.jsx +58 -0
  39. package/src/Prebuilt/components/Notifications/HLSFailureModal.jsx +3 -2
  40. package/src/Prebuilt/components/Notifications/PermissionErrorModal.jsx +3 -2
  41. package/src/Prebuilt/components/PrebuiltDialogPortal.tsx +6 -0
  42. package/src/Prebuilt/components/Preview/PreviewJoin.tsx +9 -6
  43. package/src/Prebuilt/components/RaiseHand.jsx +4 -11
  44. package/src/Prebuilt/components/RoleChangeModal.jsx +3 -2
  45. package/src/Prebuilt/components/RoleChangeRequest/RequestPrompt.tsx +67 -0
  46. package/src/Prebuilt/components/{RoleChangeRequestModal.tsx → RoleChangeRequest/RoleChangeRequestModal.tsx} +18 -50
  47. package/src/Prebuilt/components/Settings/SettingsModal.jsx +3 -2
  48. package/src/Prebuilt/components/Settings/StartRecording.jsx +3 -2
  49. package/src/Prebuilt/components/StatsForNerds.jsx +3 -2
  50. package/src/Prebuilt/components/VideoTile.jsx +34 -75
  51. package/src/Prebuilt/components/conference.jsx +1 -1
  52. package/src/Prebuilt/components/hooks/useMetadata.jsx +2 -1
  53. package/src/Prebuilt/components/pdfAnnotator/pdfFileOptions.jsx +3 -2
  54. package/src/Prebuilt/components/pdfAnnotator/shareScreenOptions.jsx +4 -29
  55. package/src/Prebuilt/components/pdfAnnotator/uploadedFile.jsx +3 -2
  56. package/src/Prebuilt/layouts/HLSView.jsx +4 -2
  57. package/src/Prebuilt/layouts/SidePane.tsx +0 -1
  58. package/src/Prebuilt/primitives/DialogContent.jsx +5 -4
  59. package/src/VideoTile/StyledVideoTile.tsx +10 -14
  60. package/dist/chunk-CDYRVICT.js.map +0 -7
  61. package/dist/conference-6IVZHILI.js.map +0 -7
  62. /package/dist/Prebuilt/components/{RoleChangeRequestModal.d.ts → RoleChangeRequest/RoleChangeRequestModal.d.ts} +0 -0
  63. /package/dist/{VirtualBackground-THDRYDRA.js.map → VirtualBackground-GP4ATXD3.js.map} +0 -0
  64. /package/dist/{chunk-JSH7SKEH.js.map → chunk-2H5NIZB7.js.map} +0 -0
@@ -1,10 +1,12 @@
1
- import React from 'react';
1
+ import React, { useCallback, useEffect, useRef, useState } from 'react';
2
2
  import { useMeasure } from 'react-use';
3
3
  import { FixedSizeList } from 'react-window';
4
- import { HMSPeer } from '@100mslive/react-sdk';
4
+ import { HMSPeer, HMSPeerListIterator, useHMSActions } from '@100mslive/react-sdk';
5
+ import { AddCircleIcon } from '@100mslive/react-icons';
5
6
  import { Accordion } from '../../../Accordion';
6
7
  import { Box, Flex } from '../../../Layout';
7
8
  import { Text } from '../../../Text';
9
+ import Chip from '../Chip';
8
10
  // @ts-ignore: No implicit Any
9
11
  import { Participant } from './ParticipantList';
10
12
  import { RoleOptions } from './RoleOptions';
@@ -38,11 +40,34 @@ export const RoleAccordion = ({
38
40
  filter?: { search: string };
39
41
  }) => {
40
42
  const [ref, { width }] = useMeasure<HTMLDivElement>();
43
+ const actions = useHMSActions();
41
44
  const showAcordion = filter?.search ? peerList.some(peer => peer.name.toLowerCase().includes(filter.search)) : true;
45
+ const [hasNext, setHasNext] = useState(false);
46
+ const iteratorRef = useRef<HMSPeerListIterator | null>(null);
42
47
 
43
- if (!showAcordion || (isHandRaisedAccordion && filter?.search) || peerList.length === 0) {
48
+ const loadNext = useCallback(() => {
49
+ if (!roleName || roleName === 'Hand Raised') {
50
+ return;
51
+ }
52
+ if (!iteratorRef.current) {
53
+ iteratorRef.current = actions.getPeerListIterator({ role: roleName });
54
+ }
55
+ iteratorRef.current
56
+ .next()
57
+ .catch(console.error)
58
+ .finally(() => {
59
+ setHasNext(iteratorRef.current ? iteratorRef.current.hasNext() : false);
60
+ });
61
+ }, [actions, roleName]);
62
+
63
+ useEffect(() => {
64
+ loadNext();
65
+ }, [loadNext]);
66
+
67
+ if (!showAcordion || (isHandRaisedAccordion && filter?.search) || (peerList.length === 0 && filter?.search)) {
44
68
  return null;
45
69
  }
70
+
46
71
  const height = ROW_HEIGHT * peerList.length;
47
72
 
48
73
  return (
@@ -86,6 +111,21 @@ export const RoleAccordion = ({
86
111
  >
87
112
  {VirtualizedParticipantItem}
88
113
  </FixedSizeList>
114
+ {hasNext ? (
115
+ <Chip
116
+ icon={<AddCircleIcon />}
117
+ content="Load More"
118
+ onClick={loadNext}
119
+ backgroundColor="$secondary_default"
120
+ css={{
121
+ w: 'max-content',
122
+ borderRadius: '$size$9',
123
+ m: '$2 auto',
124
+ p: '$4',
125
+ cursor: 'pointer',
126
+ }}
127
+ />
128
+ ) : null}
89
129
  </Accordion.Content>
90
130
  </Accordion.Item>
91
131
  </Accordion.Root>
@@ -1,11 +1,14 @@
1
1
  import React, { Fragment, useState } from 'react';
2
2
  import { ConferencingScreen } from '@100mslive/types-prebuilt';
3
+ // @ts-ignore: No implicit Any
3
4
  import { selectIsConnectedToRoom, selectPermissions, useHMSStore, useRecordingStreaming } from '@100mslive/react-sdk';
5
+ // @ts-ignore: No implicit Any
4
6
  import { ExitIcon, StopIcon, VerticalMenuIcon } from '@100mslive/react-icons';
5
7
  import { Dropdown } from '../../../Dropdown';
6
8
  import { Box, Flex } from '../../../Layout';
7
9
  import { Dialog } from '../../../Modal';
8
10
  import { Tooltip } from '../../../Tooltip';
11
+ import { PrebuiltDialogPortal } from '../PrebuiltDialogPortal';
9
12
  import { EndSessionContent } from './EndSessionContent';
10
13
  import { LeaveIconButton, MenuTriggerButton } from './LeaveAtoms';
11
14
  import { LeaveCard } from './LeaveCard';
@@ -29,6 +32,7 @@ export const DesktopLeaveRoom = ({
29
32
  const permissions = useHMSStore(selectPermissions);
30
33
  const { isStreamingOn } = useRecordingStreaming();
31
34
  const showStream = screenType !== 'hls_live_streaming' && isStreamingOn;
35
+ const showLeaveOptions = (permissions?.hlsStreaming && isStreamingOn) || permissions?.endRoom;
32
36
 
33
37
  useDropdownList({ open: open || showEndStreamAlert || showLeaveRoomAlert, name: 'LeaveRoom' });
34
38
 
@@ -38,7 +42,7 @@ export const DesktopLeaveRoom = ({
38
42
 
39
43
  return (
40
44
  <Fragment>
41
- {screenType !== 'hls_live_streaming' && (permissions?.hlsStreaming || permissions?.endRoom) ? (
45
+ {showLeaveOptions ? (
42
46
  <Flex>
43
47
  <LeaveIconButton
44
48
  key="LeaveRoom"
@@ -47,9 +51,7 @@ export const DesktopLeaveRoom = ({
47
51
  borderTopRightRadius: 0,
48
52
  borderBottomRightRadius: 0,
49
53
  }}
50
- onClick={() => {
51
- leaveRoom({ endstream: false });
52
- }}
54
+ onClick={() => setShowLeaveRoomAlert(true)}
53
55
  >
54
56
  <Tooltip title="Leave Room">
55
57
  <Box>
@@ -74,7 +76,7 @@ export const DesktopLeaveRoom = ({
74
76
  <Dropdown.Item
75
77
  css={{
76
78
  bg: '$surface_dim',
77
- color: '$on_surface_low',
79
+ color: '$on_surface_medium',
78
80
  '&:hover': { bg: '$surface_default', color: '$on_surface_high' },
79
81
  }}
80
82
  onClick={() => leaveRoom({ endstream: false })}
@@ -92,42 +94,37 @@ export const DesktopLeaveRoom = ({
92
94
  css={{ p: 0 }}
93
95
  />
94
96
  </Dropdown.Item>
95
- {permissions?.endRoom || permissions?.hlsStreaming ? (
96
- <Dropdown.Item
97
- css={{
98
- bg: '$alert_error_dim',
99
- color: '$alert_error_bright',
100
- '&:hover': { bg: '$alert_error_dim', color: '$alert_error_brighter' },
97
+
98
+ <Dropdown.Item
99
+ css={{
100
+ bg: '$alert_error_dim',
101
+ color: '$alert_error_bright',
102
+ '&:hover': { bg: '$alert_error_dim', color: '$alert_error_brighter' },
103
+ }}
104
+ data-testid="end_room_btn"
105
+ >
106
+ <LeaveCard
107
+ title={showStream ? 'End Stream' : 'End Session'}
108
+ subtitle={`The ${
109
+ showStream ? 'stream' : 'session'
110
+ } will end for everyone. You can't undo this action.`}
111
+ bg=""
112
+ titleColor="$alert_error_brighter"
113
+ icon={<StopIcon height={24} width={24} />}
114
+ onClick={() => {
115
+ setOpen(false);
116
+ setShowEndStreamAlert(true);
101
117
  }}
102
- data-testid="end_room_btn"
103
- >
104
- <LeaveCard
105
- title={showStream ? 'End Stream' : 'End Session'}
106
- subtitle={`The ${
107
- showStream ? 'stream' : 'session'
108
- } will end for everyone. You can't undo this action.`}
109
- bg=""
110
- titleColor="$alert_error_brighter"
111
- icon={<StopIcon height={24} width={24} />}
112
- onClick={() => {
113
- setOpen(false);
114
- setShowEndStreamAlert(true);
115
- }}
116
- css={{ p: 0 }}
117
- />
118
- </Dropdown.Item>
119
- ) : null}
118
+ css={{ p: 0 }}
119
+ />
120
+ </Dropdown.Item>
120
121
  </Dropdown.Content>
121
122
  </Dropdown.Root>
122
123
  </Flex>
123
124
  ) : (
124
125
  <LeaveIconButton
125
126
  onClick={() => {
126
- if (screenType === 'hls_live_streaming') {
127
- setShowLeaveRoomAlert(true);
128
- } else {
129
- leaveRoom({ endstream: false });
130
- }
127
+ setShowLeaveRoomAlert(true);
131
128
  }}
132
129
  key="LeaveRoom"
133
130
  data-testid="leave_room_btn"
@@ -141,7 +138,7 @@ export const DesktopLeaveRoom = ({
141
138
  )}
142
139
 
143
140
  <Dialog.Root open={showEndStreamAlert} modal={false}>
144
- <Dialog.Portal>
141
+ <PrebuiltDialogPortal>
145
142
  <Dialog.Overlay />
146
143
  <Dialog.Content css={{ w: 'min(420px, 90%)', p: '$8', bg: '$surface_dim' }}>
147
144
  <EndSessionContent
@@ -151,19 +148,17 @@ export const DesktopLeaveRoom = ({
151
148
  isModal
152
149
  />
153
150
  </Dialog.Content>
154
- </Dialog.Portal>
151
+ </PrebuiltDialogPortal>
155
152
  </Dialog.Root>
156
153
 
157
- {screenType === 'hls_live_streaming' ? (
158
- <Dialog.Root open={showLeaveRoomAlert} modal={false}>
159
- <Dialog.Portal>
160
- <Dialog.Overlay />
161
- <Dialog.Content css={{ w: 'min(420px, 90%)', p: '$8', bg: '$surface_dim' }}>
162
- <LeaveSessionContent setShowLeaveRoomAlert={setShowLeaveRoomAlert} leaveRoom={leaveRoom} isModal />
163
- </Dialog.Content>
164
- </Dialog.Portal>
165
- </Dialog.Root>
166
- ) : null}
154
+ <Dialog.Root open={showLeaveRoomAlert} modal={false}>
155
+ <PrebuiltDialogPortal>
156
+ <Dialog.Overlay />
157
+ <Dialog.Content css={{ w: 'min(420px, 90%)', p: '$8', bg: '$surface_dim' }}>
158
+ <LeaveSessionContent setShowLeaveRoomAlert={setShowLeaveRoomAlert} leaveRoom={leaveRoom} isModal />
159
+ </Dialog.Content>
160
+ </PrebuiltDialogPortal>
161
+ </Dialog.Root>
167
162
  </Fragment>
168
163
  );
169
164
  };
@@ -30,6 +30,7 @@ export const MwebLeaveRoom = ({
30
30
  const permissions = useHMSStore(selectPermissions);
31
31
  const { isStreamingOn } = useRecordingStreaming();
32
32
  const showStream = screenType !== 'hls_live_streaming' && isStreamingOn;
33
+ const showLeaveOptions = (permissions?.hlsStreaming && isStreamingOn) || permissions?.endRoom;
33
34
 
34
35
  useDropdownList({ open, name: 'LeaveRoom' });
35
36
 
@@ -39,7 +40,7 @@ export const MwebLeaveRoom = ({
39
40
 
40
41
  return (
41
42
  <Fragment>
42
- {screenType !== 'hls_live_streaming' ? (
43
+ {showLeaveOptions ? (
43
44
  <Sheet.Root open={open} onOpenChange={setOpen}>
44
45
  <Sheet.Trigger asChild>
45
46
  <LeaveIconButton
@@ -70,36 +71,24 @@ export const MwebLeaveRoom = ({
70
71
  css={{ pt: 0, mt: '$10', color: '$on_surface_low', '&:hover': { color: '$on_surface_high' } }}
71
72
  />
72
73
 
73
- {permissions?.endRoom || permissions?.hlsStreaming ? (
74
- <LeaveCard
75
- title={showStream ? 'End Stream' : 'End Session'}
76
- subtitle={`The will end the ${
77
- showStream ? 'stream' : 'session'
78
- } for everyone. You can't undo this action.`}
79
- bg="$alert_error_dim"
80
- titleColor="$alert_error_brighter"
81
- css={{ color: '$alert_error_bright', '&:hover': { color: '$alert_error_brighter' } }}
82
- icon={<StopIcon height={24} width={24} />}
83
- onClick={() => {
84
- setOpen(false);
85
- setShowEndStreamAlert(true);
86
- }}
87
- />
88
- ) : null}
74
+ <LeaveCard
75
+ title={showStream ? 'End Stream' : 'End Session'}
76
+ subtitle={`The will end the ${
77
+ showStream ? 'stream' : 'session'
78
+ } for everyone. You can't undo this action.`}
79
+ bg="$alert_error_dim"
80
+ titleColor="$alert_error_brighter"
81
+ css={{ color: '$alert_error_bright', '&:hover': { color: '$alert_error_brighter' } }}
82
+ icon={<StopIcon height={24} width={24} />}
83
+ onClick={() => {
84
+ setOpen(false);
85
+ setShowEndStreamAlert(true);
86
+ }}
87
+ />
89
88
  </Sheet.Content>
90
89
  </Sheet.Root>
91
90
  ) : (
92
- <LeaveIconButton
93
- key="LeaveRoom"
94
- data-testid="leave_room_btn"
95
- onClick={() => {
96
- if (screenType === 'hls_live_streaming') {
97
- setShowLeaveRoomAlert(true);
98
- } else {
99
- leaveRoom({ endstream: false });
100
- }
101
- }}
102
- >
91
+ <LeaveIconButton key="LeaveRoom" data-testid="leave_room_btn" onClick={() => setShowLeaveRoomAlert(true)}>
103
92
  <Tooltip title="Leave Room">
104
93
  <Box>
105
94
  <ExitIcon style={{ transform: 'rotate(180deg)' }} />
@@ -116,13 +105,12 @@ export const MwebLeaveRoom = ({
116
105
  />
117
106
  </Sheet.Content>
118
107
  </Sheet.Root>
119
- {screenType === 'hls_live_streaming' ? (
120
- <Sheet.Root open={showLeaveRoomAlert} onOpenChange={setShowLeaveRoomAlert}>
121
- <Sheet.Content css={{ bg: '$surface_dim', p: '$10', pb: '$12' }}>
122
- <LeaveSessionContent setShowLeaveRoomAlert={setShowLeaveRoomAlert} leaveRoom={leaveRoom} />
123
- </Sheet.Content>
124
- </Sheet.Root>
125
- ) : null}
108
+
109
+ <Sheet.Root open={showLeaveRoomAlert} onOpenChange={setShowLeaveRoomAlert}>
110
+ <Sheet.Content css={{ bg: '$surface_dim', p: '$10', pb: '$12' }}>
111
+ <LeaveSessionContent setShowLeaveRoomAlert={setShowLeaveRoomAlert} leaveRoom={leaveRoom} />
112
+ </Sheet.Content>
113
+ </Sheet.Root>
126
114
  </Fragment>
127
115
  );
128
116
  };
@@ -3,6 +3,7 @@ import { useMedia } from 'react-use';
3
3
  import { selectLocalPeerName, useHMSActions, useHMSStore } from '@100mslive/react-sdk';
4
4
  import { config as cssConfig, Dialog } from '../../../';
5
5
  import { Sheet } from '../../../Sheet';
6
+ import { PrebuiltDialogPortal } from '../PrebuiltDialogPortal';
6
7
  import { ToastManager } from '../Toast/ToastManager';
7
8
  import { ChangeNameContent } from './ChangeNameContent';
8
9
  import { UserPreferencesKeys, useUserPreferences } from '../hooks/useUserPreferences';
@@ -58,12 +59,12 @@ export const ChangeNameModal = ({ onOpenChange, openParentSheet = null }) => {
58
59
 
59
60
  return (
60
61
  <Dialog.Root defaultOpen onOpenChange={onOpenChange}>
61
- <Dialog.Portal>
62
+ <PrebuiltDialogPortal>
62
63
  <Dialog.Overlay />
63
64
  <Dialog.Content css={{ bg: '$surface_dim', width: 'min(400px,80%)', p: '$10' }}>
64
65
  <ChangeNameContent {...props} />
65
66
  </Dialog.Content>
66
- </Dialog.Portal>
67
+ </PrebuiltDialogPortal>
67
68
  </Dialog.Root>
68
69
  );
69
70
  };
@@ -1,6 +1,7 @@
1
1
  import React, { useState } from 'react';
2
2
  import { LinkIcon } from '@100mslive/react-icons';
3
3
  import { Button, Dialog, Dropdown, Flex, Input, Text } from '../../../';
4
+ import { PrebuiltDialogPortal } from '../PrebuiltDialogPortal';
4
5
  import { useSetAppDataByKey } from '../AppData/useUISettings';
5
6
  import { APP_DATA } from '../../common/constants';
6
7
 
@@ -30,7 +31,7 @@ export function EmbedUrlModal({ onOpenChange }) {
30
31
 
31
32
  return (
32
33
  <Dialog.Root defaultOpen onOpenChange={onOpenChange}>
33
- <Dialog.Portal>
34
+ <PrebuiltDialogPortal>
34
35
  <Dialog.Overlay />
35
36
  <Dialog.Content css={{ w: 'min(420px, 90%)', p: '$8', bg: '$surface_dim' }}>
36
37
  <Dialog.Title
@@ -75,7 +76,7 @@ export function EmbedUrlModal({ onOpenChange }) {
75
76
  </Button>
76
77
  </Flex>
77
78
  </Dialog.Content>
78
- </Dialog.Portal>
79
+ </PrebuiltDialogPortal>
79
80
  </Dialog.Root>
80
81
  );
81
82
  }
@@ -0,0 +1,58 @@
1
+ import React, { useEffect, useState } from 'react';
2
+ import { RefreshIcon } from '@100mslive/react-icons';
3
+ import { Button } from '../../Button';
4
+ import { Box, Flex } from '../../Layout';
5
+ import { Dialog } from '../../Modal';
6
+ import { Text } from '../../Text';
7
+ import { PrebuiltDialogPortal } from './PrebuiltDialogPortal';
8
+ import { isAndroid, isIOS } from '../common/constants';
9
+
10
+ export const MwebLandscapePrompt = () => {
11
+ const isMobile = isAndroid || isIOS;
12
+ const [showMwebLandscapePrompt, setShowMwebLandscapePrompt] = useState(false);
13
+
14
+ useEffect(() => {
15
+ const handleResize = () => {
16
+ setShowMwebLandscapePrompt(isMobile && window.innerHeight < window.innerWidth);
17
+ };
18
+
19
+ handleResize();
20
+ window.addEventListener('resize', handleResize);
21
+
22
+ return () => {
23
+ window.removeEventListener('resize', handleResize);
24
+ };
25
+ }, []);
26
+
27
+ return (
28
+ <Dialog.Root open={showMwebLandscapePrompt} onOpenChange={setShowMwebLandscapePrompt}>
29
+ <PrebuiltDialogPortal>
30
+ <Dialog.Overlay />
31
+ <Dialog.Content css={{ w: 'min(420px, 90%)', p: '$8', bg: '$surface_dim' }}>
32
+ <Box>
33
+ <Flex
34
+ css={{
35
+ color: '$primary_default',
36
+ display: 'flex',
37
+ alignItems: 'center',
38
+ }}
39
+ >
40
+ <RefreshIcon style={{ marginRight: '0.5rem' }} />
41
+ <Text variant="lg" css={{ color: '$on_surface_high', fontWeight: '$semiBold' }}>
42
+ Please rotate your device
43
+ </Text>
44
+ </Flex>
45
+ <Text variant="sm" css={{ color: '$on_surface_medium', mb: '$8', mt: '$4' }}>
46
+ We do not support landscape mode as of now, please use the app in portrait mode for the best experience.
47
+ </Text>
48
+ <Flex align="center" justify="between" css={{ w: '100%', gap: '$8' }}>
49
+ <Button outlined variant="standard" css={{ w: '100%' }} onClick={() => setShowMwebLandscapePrompt(false)}>
50
+ Continue anyway
51
+ </Button>
52
+ </Flex>
53
+ </Box>
54
+ </Dialog.Content>
55
+ </PrebuiltDialogPortal>
56
+ </Dialog.Root>
57
+ );
58
+ };
@@ -4,6 +4,7 @@ import { Button } from '../../../Button';
4
4
  import { Flex } from '../../../Layout';
5
5
  import { Dialog } from '../../../Modal';
6
6
  import { Text } from '../../../Text';
7
+ import { PrebuiltDialogPortal } from '../PrebuiltDialogPortal';
7
8
  import { useSetAppDataByKey } from '../AppData/useUISettings';
8
9
  import { APP_DATA } from '../../common/constants';
9
10
 
@@ -37,7 +38,7 @@ export function HLSFailureModal() {
37
38
  }
38
39
  }}
39
40
  >
40
- <Dialog.Portal>
41
+ <PrebuiltDialogPortal>
41
42
  <Dialog.Overlay />
42
43
  <Dialog.Content css={{ w: 'min(360px, 90%)' }}>
43
44
  <Dialog.Title
@@ -65,7 +66,7 @@ export function HLSFailureModal() {
65
66
  </Button>
66
67
  </Flex>
67
68
  </Dialog.Content>
68
- </Dialog.Portal>
69
+ </PrebuiltDialogPortal>
69
70
  </Dialog.Root>
70
71
  ) : null;
71
72
  }
@@ -4,6 +4,7 @@ import { HMSNotificationTypes, useHMSNotifications } from '@100mslive/react-sdk'
4
4
  import { Button, config as cssConfig, Dialog, Flex, Text } from '../../../';
5
5
  import androidPermissionAlert from '../../images/android-perm-1.png';
6
6
  import iosPermissions from '../../images/ios-perm-0.png';
7
+ import { PrebuiltDialogPortal } from '../PrebuiltDialogPortal';
7
8
  import { isAndroid, isIOS } from '../../common/constants';
8
9
 
9
10
  export function PermissionErrorModal() {
@@ -39,7 +40,7 @@ export function PermissionErrorModal() {
39
40
 
40
41
  return deviceType ? (
41
42
  <Dialog.Root open={!!deviceType}>
42
- <Dialog.Portal>
43
+ <PrebuiltDialogPortal>
43
44
  <Dialog.Overlay />
44
45
  <Dialog.Content css={{ w: 'min(380px, 90%)', p: '$8' }}>
45
46
  <Dialog.Title
@@ -118,7 +119,7 @@ export function PermissionErrorModal() {
118
119
  </Flex>
119
120
  ) : null}
120
121
  </Dialog.Content>
121
- </Dialog.Portal>
122
+ </PrebuiltDialogPortal>
122
123
  </Dialog.Root>
123
124
  ) : null;
124
125
  }
@@ -0,0 +1,6 @@
1
+ import React, { ReactNode } from 'react';
2
+ import { Dialog } from '../../Modal';
3
+
4
+ export const PrebuiltDialogPortal = ({ children }: { children: ReactNode }) => (
5
+ <Dialog.Portal container={document.getElementById('prebuilt-container')}>{children}</Dialog.Portal>
6
+ );
@@ -14,6 +14,7 @@ import {
14
14
  } from '@100mslive/react-sdk';
15
15
  import { MicOffIcon, SettingsIcon } from '@100mslive/react-icons';
16
16
  import { Avatar, Box, config as cssConfig, Flex, flexCenter, styled, StyledVideoTile, Text, Video } from '../../..';
17
+ import { AudioLevel } from '../../../AudioLevel';
17
18
  import { useHMSPrebuiltContext } from '../../AppContext';
18
19
  // @ts-ignore: No implicit Any
19
20
  import IconButton from '../../IconButton';
@@ -31,8 +32,6 @@ import { Logo } from '../Header/HeaderComponents';
31
32
  // @ts-ignore: No implicit Any
32
33
  import SettingsModal from '../Settings/SettingsModal';
33
34
  // @ts-ignore: No implicit Any
34
- import { AudioLevel } from '../VideoTile';
35
- // @ts-ignore: No implicit Any
36
35
  import PreviewForm from './PreviewForm';
37
36
  // @ts-ignore: No implicit Any
38
37
  import { useAuthToken, useUISettings } from '../AppData/useUISettings';
@@ -170,7 +169,7 @@ const PreviewJoin = ({
170
169
  <PreviewTile name={name} error={previewError} />
171
170
  </Flex>
172
171
  ) : null}
173
- <Box css={{ w: '100%', maxWidth: `${aspectRatio * 360}px` }}>
172
+ <Box css={{ w: '100%', maxWidth: `${Math.max(aspectRatio, 1) * 360}px` }}>
174
173
  <PreviewControls hideSettings={!toggleVideo && !toggleAudio} />
175
174
  <PreviewForm
176
175
  name={name}
@@ -230,6 +229,7 @@ export const PreviewTile = ({ name, error }: { name: string; error?: boolean })
230
229
  trackId={localPeer.videoTrack}
231
230
  data-testid="preview_tile"
232
231
  />
232
+
233
233
  {!isVideoOn ? (
234
234
  <StyledVideoTile.AvatarContainer>
235
235
  <Avatar name={name} data-testid="preview_avatar_tile" />
@@ -239,12 +239,15 @@ export const PreviewTile = ({ name, error }: { name: string; error?: boolean })
239
239
  ) : !error ? (
240
240
  <FullPageProgress />
241
241
  ) : null}
242
+
242
243
  {showMuteIcon ? (
243
- <StyledVideoTile.AudioIndicator size="medium">
244
+ <StyledVideoTile.AudioIndicator>
244
245
  <MicOffIcon />
245
246
  </StyledVideoTile.AudioIndicator>
246
247
  ) : (
247
- <AudioLevel trackId={localPeer?.audioTrack} />
248
+ <StyledVideoTile.AudioIndicator size="medium">
249
+ <AudioLevel trackId={localPeer?.audioTrack} />
250
+ </StyledVideoTile.AudioIndicator>
248
251
  )}
249
252
  </StyledVideoTile.Container>
250
253
  );
@@ -255,7 +258,7 @@ export const PreviewControls = ({ hideSettings }: { hideSettings: boolean }) =>
255
258
 
256
259
  return (
257
260
  <Flex
258
- justify="between"
261
+ justify={hideSettings && isMobile ? 'center' : 'between'}
259
262
  css={{
260
263
  width: '100%',
261
264
  mt: '$8',
@@ -1,22 +1,15 @@
1
1
  import React from 'react';
2
- import { selectHasPeerHandRaised, selectLocalPeerID, useHMSActions, useHMSStore } from '@100mslive/react-sdk';
3
2
  import { HandIcon } from '@100mslive/react-icons';
4
3
  import { Tooltip } from '../../Tooltip';
5
4
  import IconButton from '../IconButton';
5
+ // @ts-ignore: No implicit Any
6
+ import { useMyMetadata } from './hooks/useMetadata';
6
7
 
7
8
  export const RaiseHand = () => {
8
- const localPeerId = useHMSStore(selectLocalPeerID);
9
- const isHandRaised = useHMSStore(selectHasPeerHandRaised(localPeerId));
10
- const actions = useHMSActions();
11
-
9
+ const { isHandRaised, toggleHandRaise } = useMyMetadata();
12
10
  return (
13
11
  <Tooltip title={isHandRaised ? 'Lower hand' : 'Raise hand'}>
14
- <IconButton
15
- active={!isHandRaised}
16
- onClick={() => {
17
- isHandRaised ? actions.lowerLocalPeerHand() : actions.raiseLocalPeerHand();
18
- }}
19
- >
12
+ <IconButton active={!isHandRaised} onClick={async () => await toggleHandRaise()}>
20
13
  <HandIcon />
21
14
  </IconButton>
22
15
  </Tooltip>
@@ -9,6 +9,7 @@ import { Box, Flex } from '../../Layout';
9
9
  import { Dialog } from '../../Modal';
10
10
  import { Text } from '../../Text';
11
11
  import { Tooltip } from '../../Tooltip';
12
+ import { PrebuiltDialogPortal } from './PrebuiltDialogPortal';
12
13
  import { useDropdownSelection } from './hooks/useDropdownSelection';
13
14
  import { useFilteredRoles } from '../common/hooks';
14
15
  import { textEllipsis } from '../../utils';
@@ -47,7 +48,7 @@ export const RoleChangeModal = ({ peerId, onOpenChange }) => {
47
48
  const peerNameMaxWidth = 200;
48
49
  return (
49
50
  <Dialog.Root defaultOpen onOpenChange={onOpenChange}>
50
- <Dialog.Portal>
51
+ <PrebuiltDialogPortal>
51
52
  <Dialog.Overlay />
52
53
  <Dialog.Content css={{ width: 'min(400px,80%)', p: '$10' }}>
53
54
  <Dialog.Title css={{ p: 0 }} asChild>
@@ -179,7 +180,7 @@ export const RoleChangeModal = ({ peerId, onOpenChange }) => {
179
180
  </Box>
180
181
  </Flex>
181
182
  </Dialog.Content>
182
- </Dialog.Portal>
183
+ </PrebuiltDialogPortal>
183
184
  </Dialog.Root>
184
185
  );
185
186
  };