@100mslive/roomkit-react 0.1.0 → 0.1.2-alpha.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (241) hide show
  1. package/README.md +18 -0
  2. package/dist/Accordion/Accordion.d.ts +62 -138
  3. package/dist/Accordion/index.d.ts +62 -138
  4. package/dist/{ActiveSpeakerView-H3VYXANB.js → ActiveSpeakerView-4XPIRZOK.js} +6 -6
  5. package/dist/{HLSView-6BVBCQM7.css → ActiveSpeakerView-ADEYHQMU.css} +2 -2
  6. package/dist/{PinnedTrackView-QQ5FDXJX.css.map → ActiveSpeakerView-ADEYHQMU.css.map} +2 -2
  7. package/dist/Avatar/Avatar.d.ts +31 -69
  8. package/dist/Button/Button.d.ts +31 -69
  9. package/dist/Checkbox/Checkbox.d.ts +62 -138
  10. package/dist/Collapsible/Collapsible.d.ts +93 -207
  11. package/dist/Divider/Divider.d.ts +62 -138
  12. package/dist/Dropdown/Dropdown.d.ts +372 -828
  13. package/dist/Fieldset/Fieldset.d.ts +31 -69
  14. package/dist/Footer/Footer.d.ts +248 -552
  15. package/dist/{conference-KN6OKGDU.css → HLSView-DWEEMZ6Z.css} +2 -2
  16. package/dist/{HLSView-6BVBCQM7.css.map → HLSView-DWEEMZ6Z.css.map} +2 -2
  17. package/dist/{HLSView-3RDXRV7Y.js → HLSView-I26CVF5U.js} +16 -16
  18. package/dist/HLSView-I26CVF5U.js.map +7 -0
  19. package/dist/IconButton/IconButton.d.ts +31 -69
  20. package/dist/Input/Input.d.ts +189 -417
  21. package/dist/Label/Label.d.ts +31 -69
  22. package/dist/Layout/Box.d.ts +31 -69
  23. package/dist/Layout/Flex.d.ts +31 -69
  24. package/dist/Link/Link.d.ts +31 -69
  25. package/dist/Modal/Dialog.d.ts +248 -552
  26. package/dist/Modal/DialogContent.d.ts +217 -483
  27. package/dist/Pagination/StyledPagination.d.ts +124 -276
  28. package/dist/{PinnedTrackView-QQ5FDXJX.css → PinnedTrackView-5DPVVOZW.css} +2 -2
  29. package/dist/{conference-KN6OKGDU.css.map → PinnedTrackView-5DPVVOZW.css.map} +2 -2
  30. package/dist/{PinnedTrackView-453PELNU.js → PinnedTrackView-GGTCNH5V.js} +6 -6
  31. package/dist/Popover/index.d.ts +93 -207
  32. package/dist/Prebuilt/provider/roomLayoutProvider/constants/index.d.ts +2 -0
  33. package/dist/Prebuilt/provider/roomLayoutProvider/hooks/useFetchRoomLayout.d.ts +9 -0
  34. package/dist/Prebuilt/provider/roomLayoutProvider/index.d.ts +9 -0
  35. package/dist/Progress/index.d.ts +62 -138
  36. package/dist/RadioGroup/RadioGroup.d.ts +93 -207
  37. package/dist/ReactSelect/ReactSelect.d.ts +310 -690
  38. package/dist/Select/Select.d.ts +93 -207
  39. package/dist/Slider/Slider.d.ts +31 -69
  40. package/dist/Stats/StyledStats.d.ts +186 -414
  41. package/dist/Switch/Switch.d.ts +31 -69
  42. package/dist/Tabs/Tabs.d.ts +124 -276
  43. package/dist/Text/Text.d.ts +31 -69
  44. package/dist/Theme/ThemeProvider.d.ts +63 -140
  45. package/dist/Theme/base.config.d.ts +31 -53
  46. package/dist/Theme/index.d.ts +0 -1
  47. package/dist/Theme/stitches.config.d.ts +404 -915
  48. package/dist/TileMenu/StyledMenuTile.d.ts +217 -483
  49. package/dist/Toast/Toast.d.ts +187 -415
  50. package/dist/Video/Video.d.ts +31 -69
  51. package/dist/VideoList/StyledVideoList.d.ts +93 -207
  52. package/dist/VideoTile/StyledVideoTile.d.ts +279 -621
  53. package/dist/{VirtualBackground-LHYBWUT5.js → VirtualBackground-ZRRE4DUA.js} +4 -3
  54. package/dist/{VirtualBackground-LHYBWUT5.js.map → VirtualBackground-ZRRE4DUA.js.map} +2 -2
  55. package/dist/{chunk-KYYP6ZVK.js → chunk-4ISMCWQA.js} +49 -146
  56. package/dist/chunk-4ISMCWQA.js.map +7 -0
  57. package/dist/{chunk-7YUYZ64D.js → chunk-KKLZ7K2L.js} +577 -898
  58. package/dist/chunk-KKLZ7K2L.js.map +7 -0
  59. package/dist/{chunk-HCAGFNXW.js → chunk-LUND6FLY.js} +1490 -1134
  60. package/dist/chunk-LUND6FLY.js.map +7 -0
  61. package/dist/chunk-MYK3T45M.js +58 -0
  62. package/dist/chunk-MYK3T45M.js.map +7 -0
  63. package/dist/{chunk-XRJXE6UO.js → chunk-THORW2WT.js} +4 -4
  64. package/dist/{chunk-XRJXE6UO.js.map → chunk-THORW2WT.js.map} +1 -1
  65. package/dist/{conference-IDNRO4WK.js → conference-5TDUAQ6K.js} +593 -532
  66. package/dist/conference-5TDUAQ6K.js.map +7 -0
  67. package/dist/{ActiveSpeakerView-REZLWPPI.css → conference-BDCDGBIS.css} +2 -2
  68. package/dist/{ActiveSpeakerView-REZLWPPI.css.map → conference-BDCDGBIS.css.map} +2 -2
  69. package/dist/index.cjs.css +1 -1
  70. package/dist/index.cjs.css.map +2 -2
  71. package/dist/index.cjs.js +3450 -3418
  72. package/dist/index.cjs.js.map +4 -4
  73. package/dist/index.css +1 -1
  74. package/dist/index.css.map +2 -2
  75. package/dist/index.js +4 -8
  76. package/dist/meta.cjs.json +761 -490
  77. package/dist/meta.esbuild.json +857 -589
  78. package/dist/{transcription-BTSB7FZH.js → transcription-PYTSSAOB.js} +3 -3
  79. package/package.json +14 -9
  80. package/src/Accordion/Accordion.tsx +3 -3
  81. package/src/AudioLevel/AudioLevel.tsx +1 -1
  82. package/src/Avatar/Avatar.tsx +8 -3
  83. package/src/Button/Button.tsx +76 -20
  84. package/src/Checkbox/Checkbox.tsx +4 -4
  85. package/src/Collapsible/Collapsible.tsx +1 -1
  86. package/src/Divider/Divider.tsx +2 -2
  87. package/src/Divider/HorizontalDivider.stories.tsx +2 -2
  88. package/src/Divider/VerticalDivider.stories.tsx +1 -1
  89. package/src/Dropdown/Dropdown.stories.tsx +3 -3
  90. package/src/Dropdown/Dropdown.tsx +16 -14
  91. package/src/IconButton/IconButton.tsx +8 -7
  92. package/src/Input/Input.tsx +9 -8
  93. package/src/Input/PasswordInput.stories.tsx +2 -2
  94. package/src/Label/Label.tsx +1 -1
  95. package/src/Link/Link.tsx +4 -4
  96. package/src/Loading/Loading.tsx +7 -10
  97. package/src/Modal/Dialog.stories.tsx +2 -2
  98. package/src/Modal/DialogContent.tsx +3 -3
  99. package/src/Pagination/StyledPagination.tsx +4 -4
  100. package/src/Popover/Popover.stories.tsx +5 -5
  101. package/src/Popover/index.tsx +1 -1
  102. package/src/Prebuilt/App.jsx +101 -68
  103. package/src/Prebuilt/IconButton.jsx +2 -2
  104. package/src/Prebuilt/Prebuilt.stories.tsx +8 -2
  105. package/src/Prebuilt/common/constants.js +0 -1
  106. package/src/Prebuilt/common/utils.js +0 -6
  107. package/src/Prebuilt/components/AppData/AppData.jsx +7 -4
  108. package/src/Prebuilt/components/AppData/useUISettings.js +0 -4
  109. package/src/Prebuilt/components/AudioVideoToggle.jsx +73 -20
  110. package/src/Prebuilt/components/BottomActionSheet/BottomActionSheet.jsx +1 -1
  111. package/src/Prebuilt/components/Chat/Chat.jsx +6 -2
  112. package/src/Prebuilt/components/Chat/ChatBody.jsx +13 -11
  113. package/src/Prebuilt/components/Chat/ChatFooter.jsx +2 -2
  114. package/src/Prebuilt/components/Chat/ChatHeader.jsx +3 -3
  115. package/src/Prebuilt/components/Chat/ChatSelector.jsx +2 -2
  116. package/src/Prebuilt/components/Chat/useEmojiPickerStyles.js +6 -6
  117. package/src/Prebuilt/components/Chip.jsx +24 -0
  118. package/src/Prebuilt/components/Connection/ConnectionIndicator.jsx +6 -6
  119. package/src/Prebuilt/components/Connection/TileConnection.jsx +2 -2
  120. package/src/Prebuilt/components/Connection/connectionQualityUtils.js +4 -4
  121. package/src/Prebuilt/components/EmojiReaction.jsx +13 -10
  122. package/src/Prebuilt/components/ErrorBoundary.jsx +2 -2
  123. package/src/Prebuilt/components/FullPageProgress.jsx +5 -3
  124. package/src/Prebuilt/components/GoLiveButton.jsx +1 -4
  125. package/src/Prebuilt/components/HMSVideo/HLSQualitySelector.jsx +2 -2
  126. package/src/Prebuilt/components/HMSVideo/PlayButton.jsx +1 -1
  127. package/src/Prebuilt/components/HMSVideo/VideoProgress.jsx +3 -3
  128. package/src/Prebuilt/components/HMSVideo/VideoTime.jsx +3 -1
  129. package/src/Prebuilt/components/HMSVideo/VolumeControl.jsx +1 -1
  130. package/src/Prebuilt/components/Header/AdditionalRoomState.jsx +17 -17
  131. package/src/Prebuilt/components/Header/AmbientMusic.jsx +1 -1
  132. package/src/Prebuilt/components/Header/ConferencingHeader.jsx +4 -6
  133. package/src/Prebuilt/components/Header/HeaderComponents.jsx +10 -5
  134. package/src/Prebuilt/components/Header/ParticipantFilter.jsx +2 -2
  135. package/src/Prebuilt/components/Header/ParticipantList.jsx +2 -2
  136. package/src/Prebuilt/components/Header/StreamActions.jsx +9 -19
  137. package/src/Prebuilt/components/Header/StreamingHeader.jsx +5 -6
  138. package/src/Prebuilt/components/HlsStatsOverlay.jsx +2 -2
  139. package/src/Prebuilt/components/IconButtonWithOptions/IconButtonWithOptions.jsx +102 -0
  140. package/src/Prebuilt/components/IconButtonWithOptions/IconButtonWithOptions.stories.tsx +40 -0
  141. package/src/Prebuilt/components/LeaveRoom.jsx +11 -11
  142. package/src/Prebuilt/components/MetaActions.jsx +2 -2
  143. package/src/Prebuilt/components/MoreSettings/BulkRoleChangeModal.jsx +2 -2
  144. package/src/Prebuilt/components/MoreSettings/ChangeSelfRole.jsx +1 -1
  145. package/src/Prebuilt/components/MoreSettings/MoreSettings.jsx +1 -0
  146. package/src/Prebuilt/components/Notifications/HLSFailureModal.jsx +69 -0
  147. package/src/Prebuilt/components/Notifications/Notifications.jsx +1 -3
  148. package/src/Prebuilt/components/Notifications/PermissionErrorModal.jsx +108 -26
  149. package/src/Prebuilt/components/Notifications/ReconnectNotifications.jsx +1 -1
  150. package/src/Prebuilt/components/PIP/pipUtils.js +2 -2
  151. package/src/Prebuilt/components/Playlist/Playlist.jsx +4 -4
  152. package/src/Prebuilt/components/Playlist/PlaylistControls.jsx +3 -3
  153. package/src/Prebuilt/components/Playlist/PlaylistItem.jsx +3 -3
  154. package/src/Prebuilt/components/Playlist/VideoPlayer.jsx +4 -4
  155. package/src/Prebuilt/components/PostLeave.jsx +4 -4
  156. package/src/Prebuilt/components/Preview/PreviewContainer.jsx +17 -6
  157. package/src/Prebuilt/components/Preview/PreviewForm.jsx +74 -0
  158. package/src/Prebuilt/components/Preview/PreviewJoin.jsx +100 -37
  159. package/src/Prebuilt/components/RoleChangeModal.jsx +3 -3
  160. package/src/Prebuilt/components/ScreenshareDisplay.jsx +2 -2
  161. package/src/Prebuilt/components/Settings/DeviceSettings.jsx +3 -9
  162. package/src/Prebuilt/components/Settings/SettingsModal.jsx +8 -32
  163. package/src/Prebuilt/components/Settings/StartRecording.jsx +4 -12
  164. package/src/Prebuilt/components/Settings/SwitchWithLabel.jsx +2 -3
  165. package/src/Prebuilt/components/Settings/common.js +26 -0
  166. package/src/Prebuilt/components/StatsForNerds.jsx +5 -5
  167. package/src/Prebuilt/components/Streaming/Common.jsx +11 -11
  168. package/src/Prebuilt/components/Streaming/HLSStreaming.jsx +6 -12
  169. package/src/Prebuilt/components/Streaming/RTMPStreaming.jsx +4 -6
  170. package/src/Prebuilt/components/Streaming/StreamingLanding.jsx +4 -4
  171. package/src/Prebuilt/components/TileMenu.jsx +7 -7
  172. package/src/Prebuilt/components/Toast/ToastConfig.jsx +12 -20
  173. package/src/Prebuilt/components/conference.jsx +9 -2
  174. package/src/Prebuilt/components/hooks/useDropdownSelection.jsx +1 -4
  175. package/src/Prebuilt/components/pdfAnnotator/pdfErrorView.jsx +2 -2
  176. package/src/Prebuilt/components/pdfAnnotator/pdfFileOptions.jsx +1 -1
  177. package/src/Prebuilt/components/pdfAnnotator/pdfHeader.jsx +1 -1
  178. package/src/Prebuilt/components/pdfAnnotator/pdfInfo.jsx +2 -2
  179. package/src/Prebuilt/components/pdfAnnotator/shareScreenOptions.jsx +12 -20
  180. package/src/Prebuilt/components/pdfAnnotator/uploadedFile.jsx +4 -4
  181. package/src/Prebuilt/images/Logo.svg +8 -0
  182. package/src/Prebuilt/images/first_person.png +0 -0
  183. package/src/Prebuilt/images/rtmp.png +0 -0
  184. package/src/Prebuilt/index.d.ts +6 -1
  185. package/src/Prebuilt/layouts/HLSView.jsx +1 -1
  186. package/src/Prebuilt/layouts/InsetView.jsx +0 -3
  187. package/src/Prebuilt/layouts/NonPublisherView.jsx +2 -2
  188. package/src/Prebuilt/layouts/SidePane.jsx +1 -1
  189. package/src/Prebuilt/layouts/WaitingView.jsx +2 -2
  190. package/src/Prebuilt/layouts/mainView.jsx +42 -5
  191. package/src/Prebuilt/plugins/FlyingEmoji.jsx +2 -2
  192. package/src/Prebuilt/plugins/VirtualBackground/VirtualBackground.jsx +1 -0
  193. package/src/Prebuilt/plugins/whiteboard/ToggleWhiteboard.jsx +1 -3
  194. package/src/Prebuilt/primitives/DialogContent.jsx +4 -4
  195. package/src/Prebuilt/primitives/DropdownTrigger.jsx +3 -3
  196. package/src/Prebuilt/provider/roomLayoutProvider/constants/index.ts +33 -0
  197. package/src/Prebuilt/provider/roomLayoutProvider/hooks/useFetchRoomLayout.ts +57 -0
  198. package/src/Prebuilt/provider/roomLayoutProvider/index.tsx +26 -0
  199. package/src/Progress/index.tsx +2 -2
  200. package/src/RadioGroup/RadioGroup.tsx +3 -3
  201. package/src/ReactSelect/ReactSelect.stories.tsx +7 -7
  202. package/src/ReactSelect/ReactSelect.tsx +8 -8
  203. package/src/Select/Select.tsx +6 -6
  204. package/src/Slider/Slider.tsx +5 -5
  205. package/src/Stats/Stats.tsx +12 -2
  206. package/src/Stats/StyledStats.tsx +3 -3
  207. package/src/Switch/Switch.tsx +5 -5
  208. package/src/Tabs/Tabs.stories.tsx +2 -2
  209. package/src/Tabs/Tabs.tsx +2 -2
  210. package/src/Text/Text.tsx +2 -2
  211. package/src/Theme/ThemeProvider.tsx +4 -7
  212. package/src/Theme/ThemeStory.jsx +17 -19
  213. package/src/Theme/base.config.ts +31 -59
  214. package/src/Theme/index.tsx +0 -1
  215. package/src/Theme/stitches.config.ts +2 -7
  216. package/src/TileMenu/StyledMenuTile.tsx +11 -8
  217. package/src/Toast/Toast.tsx +10 -9
  218. package/src/Tooltip/Tooltip.stories.tsx +1 -1
  219. package/src/Tooltip/Tooltip.tsx +4 -4
  220. package/src/Video/Video.tsx +1 -1
  221. package/src/VideoTile/StyledVideoTile.tsx +12 -12
  222. package/src/assets/android-perm-0.png +0 -0
  223. package/src/assets/android-perm-1.png +0 -0
  224. package/src/assets/ios-perm-0.png +0 -0
  225. package/src/fixtures/chats.ts +1 -1
  226. package/dist/HLSView-3RDXRV7Y.js.map +0 -7
  227. package/dist/Theme/themes.d.ts +0 -64
  228. package/dist/chunk-7YUYZ64D.js.map +0 -7
  229. package/dist/chunk-HCAGFNXW.js.map +0 -7
  230. package/dist/chunk-KYYP6ZVK.js.map +0 -7
  231. package/dist/chunk-ULXGBUSC.js +0 -65
  232. package/dist/chunk-ULXGBUSC.js.map +0 -7
  233. package/dist/conference-IDNRO4WK.js.map +0 -7
  234. package/src/Prebuilt/components/Preview/PreviewName.jsx +0 -37
  235. package/src/Prebuilt/components/Streaming/RTMPIcon.jsx +0 -24
  236. package/src/Prebuilt/hms.js +0 -7
  237. package/src/Prebuilt/plugins/confetti.jsx +0 -60
  238. package/src/Theme/themes.ts +0 -70
  239. /package/dist/{ActiveSpeakerView-H3VYXANB.js.map → ActiveSpeakerView-4XPIRZOK.js.map} +0 -0
  240. /package/dist/{PinnedTrackView-453PELNU.js.map → PinnedTrackView-GGTCNH5V.js.map} +0 -0
  241. /package/dist/{transcription-BTSB7FZH.js.map → transcription-PYTSSAOB.js.map} +0 -0
@@ -14,20 +14,17 @@ type Props = {
14
14
  type LoadingProps = Props & React.SVGProps<SVGSVGElement>;
15
15
 
16
16
  export const Loading = ({ size = 24, color = 'white', ...props }: LoadingProps) => (
17
- <svg width={size} height={size} viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg" {...props}>
18
- <path
19
- d="M19.8852 12C20.5009 12 21.0071 12.501 20.9311 13.1119C20.7585 14.498 20.2649 15.8303 19.4832 17.0001C18.4943 18.4802 17.0887 19.6337 15.4442 20.3149C13.7996 20.9961 11.99 21.1743 10.2442 20.8271C8.49836 20.4798 6.89471 19.6226 5.63604 18.364C4.37737 17.1053 3.5202 15.5016 3.17293 13.7558C2.82567 12.01 3.0039 10.2004 3.68508 8.55585C4.36627 6.91131 5.51983 5.50571 6.99987 4.51677C8.16971 3.73511 9.50199 3.24152 10.8881 3.06895C11.499 2.99288 12 3.4991 12 4.11476C12 4.73042 11.4976 5.22017 10.8903 5.32108C9.94601 5.47798 9.04141 5.83408 8.23852 6.37055C7.12512 7.1145 6.25733 8.17191 5.74489 9.40905C5.23245 10.6462 5.09837 12.0075 5.35961 13.3209C5.62085 14.6342 6.26568 15.8406 7.21255 16.7875C8.15942 17.7343 9.3658 18.3791 10.6791 18.6404C11.9925 18.9016 13.3538 18.7675 14.591 18.2551C15.8281 17.7427 16.8855 16.8749 17.6294 15.7615C18.1659 14.9586 18.522 14.054 18.6789 13.1097C18.7798 12.5024 19.2696 12 19.8852 12Z"
20
- fill={color}
21
- >
17
+ <svg width={size} height={size} viewBox="0 0 50 50" fill={color} xmlns="http://www.w3.org/2000/svg" {...props}>
18
+ <circle cx="25" cy="25" r="20" stroke="#0074D9" stroke-width="4" stroke-dasharray="70 30" fill="none">
22
19
  <animateTransform
23
- attributeType="XML"
24
20
  attributeName="transform"
21
+ attributeType="XML"
25
22
  type="rotate"
26
- from="0 12 12"
27
- to="360 12 12"
28
- dur="0.75s"
23
+ from="0 25 25"
24
+ to="360 25 25"
25
+ dur="1s"
29
26
  repeatCount="indefinite"
30
27
  />
31
- </path>
28
+ </circle>
32
29
  </svg>
33
30
  );
@@ -30,7 +30,7 @@ const Template: ComponentStory<typeof Dialog.Root> = () => (
30
30
  <Dialog.Portal>
31
31
  <Dialog.Overlay />
32
32
  <Dialog.Content>
33
- <Dialog.Title css={{ c: '$textHighEmp', position: 'relative' }}>
33
+ <Dialog.Title css={{ c: '$on_surface_high', position: 'relative' }}>
34
34
  <Flex direction="row" justify="between" css={{ w: '100%' }}>
35
35
  <Flex justify="start" align="center" gap="3">
36
36
  <InfoIcon />
@@ -41,7 +41,7 @@ const Template: ComponentStory<typeof Dialog.Root> = () => (
41
41
  </Dialog.DefaultClose>
42
42
  </Flex>
43
43
  </Dialog.Title>
44
- <Text variant="body1" css={{ c: '$textMedEmp' }}>
44
+ <Text variant="body1" css={{ c: '$on_surface_medium' }}>
45
45
  Body 2: Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et
46
46
  dolore magna aliqua. Ut enim ad minim veniam,im venitetur adipiscing elit, sed do eiusmod tempor incididunt ut
47
47
  labore et dolore magna aliqua. Ut enim ad minim veniam,im veni
@@ -26,13 +26,13 @@ export const StyledDialogOverlay = styled(DialogPrimitive.Overlay, {
26
26
  export const StyledDialogPortal = styled(DialogPrimitive.Portal, {});
27
27
 
28
28
  export const StyledDialogContent = styled(DialogPrimitive.Content, {
29
- color: '$textMedEmp',
30
- backgroundColor: '$surfaceDefault',
29
+ color: '$on_surface_medium',
30
+ backgroundColor: '$surface_default',
31
31
  borderRadius: '8px',
32
32
  position: 'fixed',
33
33
  top: '50%',
34
34
  left: '50%',
35
- border: '$space$px solid $borderDefault',
35
+ border: '$space$px solid $border_bright',
36
36
  boxShadow: '0 10px 20px rgba(0,0,0,0.19), 0 6px 6px rgba(0,0,0,0.23)',
37
37
  transform: 'translate(-50%, -50%)',
38
38
  zIndex: 999,
@@ -13,12 +13,12 @@ const Root = styled('div', {
13
13
  });
14
14
 
15
15
  const Chevron = styled('button', {
16
- color: '$textPrimary',
16
+ color: '$on_surface_high',
17
17
  '&:focus': {
18
18
  outline: 'none',
19
19
  },
20
20
  '&[disabled]': {
21
- color: '$grayDefault',
21
+ color: '$on_surface_low',
22
22
  cursor: 'not-allowed',
23
23
  },
24
24
  display: 'flex',
@@ -40,14 +40,14 @@ const Dot = styled('button', {
40
40
  borderRadius: '9999px',
41
41
  width: '0.5rem',
42
42
  height: '0.5rem',
43
- backgroundColor: '$textDisabled',
43
+ backgroundColor: '$on_surface_low',
44
44
  padding: '0px',
45
45
  border: 'none',
46
46
  cursor: 'pointer',
47
47
  variants: {
48
48
  active: {
49
49
  true: {
50
- backgroundColor: '$textPrimary',
50
+ backgroundColor: '$on_surface_high',
51
51
  },
52
52
  },
53
53
  },
@@ -35,11 +35,11 @@ const Template: ComponentStory<typeof Popover.Root> = () => (
35
35
  aspectRatio: 1,
36
36
  r: '$round',
37
37
  p: '$2 $2',
38
- bg: '$bgPrimary',
39
- '&:hover': { bg: '$bgSecondary !important' },
38
+ bg: '$background_default',
39
+ '&:hover': { bg: '$background_dim !important' },
40
40
  }}
41
41
  >
42
- <Box css={{ w: '$10', h: '$10', c: '$textPrimary' }}>
42
+ <Box css={{ w: '$10', h: '$10', c: '$on_primary_high' }}>
43
43
  <VerticalMenuIcon />
44
44
  </Box>
45
45
  </Button>
@@ -47,10 +47,10 @@ const Template: ComponentStory<typeof Popover.Root> = () => (
47
47
  <Popover.Content align="center" side="bottom" sideOffset={10}>
48
48
  <Flex css={{ flexDirection: 'column', gap: 10 }} justify="center" align="center">
49
49
  <Flex direction="row" justify="between" css={{ width: '100%' }}>
50
- <Text as="div" variant="caption" css={{ color: '$textMedEmp' }}>
50
+ <Text as="div" variant="caption" css={{ color: '$on_surface_medium' }}>
51
51
  Dimensions
52
52
  </Text>
53
- <Box css={{ color: '$textMedEmp' }}>
53
+ <Box css={{ color: '$on_surface_medium' }}>
54
54
  <CrossIcon width="0.75rem" height="0.75rem" />
55
55
  </Box>
56
56
  </Flex>
@@ -5,7 +5,7 @@ import { popoverAnimation } from '../utils/animations';
5
5
  const StyledContent = styled(Content, {
6
6
  padding: '$6',
7
7
  borderRadius: '$2',
8
- backgroundColor: '$bgSecondary',
8
+ backgroundColor: '$background_default',
9
9
  boxShadow: '$sm',
10
10
  zIndex: 12,
11
11
  ...popoverAnimation,
@@ -1,6 +1,12 @@
1
- import React, { Suspense, useEffect } from 'react';
1
+ import React, { Suspense, useEffect, useRef } from 'react';
2
2
  import { BrowserRouter, MemoryRouter, Navigate, Route, Routes, useParams } from 'react-router-dom';
3
- import { HMSRoomProvider, selectIsConnectedToRoom, useHMSActions, useHMSStore } from '@100mslive/react-sdk';
3
+ import {
4
+ HMSReactiveStore,
5
+ HMSRoomProvider,
6
+ selectIsConnectedToRoom,
7
+ useHMSActions,
8
+ useHMSStore,
9
+ } from '@100mslive/react-sdk';
4
10
  import { AppData } from './components/AppData/AppData';
5
11
  import { BeamSpeakerLabelsLogging } from './components/AudioLevel/BeamSpeakerLabelsLogging';
6
12
  import AuthToken from './components/AuthToken';
@@ -12,14 +18,13 @@ import { Notifications } from './components/Notifications';
12
18
  import PostLeave from './components/PostLeave';
13
19
  import PreviewContainer from './components/Preview/PreviewContainer';
14
20
  import { ToastContainer } from './components/Toast/ToastContainer';
21
+ import { RoomLayoutContext, RoomLayoutProvider } from './provider/roomLayoutProvider/index.tsx';
15
22
  import { Box } from '../Layout';
16
23
  import { globalStyles, HMSThemeProvider } from '../Theme';
17
24
  import { HMSPrebuiltContext, useHMSPrebuiltContext } from './AppContext';
18
- import { hmsActions, hmsNotifications, hmsStats, hmsStore } from './hms.js';
19
- import { Confetti } from './plugins/confetti';
20
25
  import { FlyingEmoji } from './plugins/FlyingEmoji';
21
26
  import { RemoteStopScreenshare } from './plugins/RemoteStopScreenshare';
22
- import { getRoutePrefix, shadeColor } from './common/utils';
27
+ import { getRoutePrefix } from './common/utils';
23
28
  import { FeatureFlags } from './services/FeatureFlags';
24
29
 
25
30
  const Conference = React.lazy(() => import('./components/conference'));
@@ -38,52 +43,77 @@ export const HMSPrebuilt = React.forwardRef(
38
43
  (
39
44
  {
40
45
  roomCode = '',
41
- logo: { url: logoUrl = '' } = {},
46
+ logo,
47
+ typography,
48
+ themes,
42
49
  options: {
43
50
  userName = '',
44
51
  userId = '',
45
- endPoints: { init: initEndpoint = '', tokenByRoomCode = '', tokenByRoomIdRole = '' } = {},
52
+ endpoints: {
53
+ init: initEndpoint = '',
54
+ tokenByRoomCode: tokenByRoomCodeEndpoint = '',
55
+ tokenByRoomIdRole: tokenByRoomIdRoleEndpoint = '',
56
+ roomLayout: roomLayoutEndpoint = '',
57
+ } = {},
46
58
  } = {},
59
+ screens,
47
60
  onLeave,
48
61
  },
49
62
  ref,
50
63
  ) => {
51
64
  const aspectRatio = '1-1';
52
- const color = '#2F80FF';
53
- const theme = 'dark';
54
65
  const metadata = '';
55
- const recordingUrl = '';
56
66
  const { 0: width, 1: height } = aspectRatio.split('-').map(el => parseInt(el));
67
+ const reactiveStore = useRef();
57
68
 
58
- const [hyderated, setHyderated] = React.useState(false);
59
- useEffect(() => setHyderated(true), []);
69
+ const [hydrated, setHydrated] = React.useState(false);
60
70
  useEffect(() => {
61
- if (!ref) {
62
- return;
63
- }
64
- ref.current = {
71
+ setHydrated(true);
72
+ const hms = new HMSReactiveStore();
73
+ const hmsStore = hms.getStore();
74
+ const hmsActions = hms.getActions();
75
+ const hmsNotifications = hms.getNotifications();
76
+ const hmsStats = hms.getStats();
77
+
78
+ reactiveStore.current = {
65
79
  hmsActions,
66
80
  hmsStats,
67
81
  hmsStore,
68
82
  hmsNotifications,
69
83
  };
84
+ }, []);
85
+
86
+ useEffect(() => {
87
+ if (!ref || !reactiveStore.current) {
88
+ return;
89
+ }
90
+
91
+ ref.current = { ...reactiveStore.current };
70
92
  }, [ref]);
71
93
 
72
94
  // leave room when component unmounts
73
95
  useEffect(
74
96
  () => () => {
75
- return hmsActions.leave();
97
+ return reactiveStore.current.hmsActions.leave();
76
98
  },
77
99
  [],
78
100
  );
79
101
 
80
- const endPoints = {
81
- tokenByRoomCode,
102
+ const endpoints = {
103
+ tokenByRoomCode: tokenByRoomCodeEndpoint,
82
104
  init: initEndpoint,
83
- tokenByRoomIdRole,
105
+ tokenByRoomIdRole: tokenByRoomIdRoleEndpoint,
106
+ roomLayout: roomLayoutEndpoint,
107
+ };
108
+
109
+ const overrideLayout = {
110
+ logo,
111
+ themes,
112
+ typography,
113
+ screens,
84
114
  };
85
115
 
86
- if (!hyderated) {
116
+ if (!hydrated) {
87
117
  return null;
88
118
  }
89
119
 
@@ -93,58 +123,61 @@ export const HMSPrebuilt = React.forwardRef(
93
123
  <ErrorBoundary>
94
124
  <HMSPrebuiltContext.Provider
95
125
  value={{
96
- roomId: '',
97
- role: '',
98
126
  roomCode,
99
127
  showPreview: true,
100
128
  showLeave: true,
101
129
  onLeave,
102
130
  userName,
103
131
  userId,
104
- endPoints,
132
+ endpoints,
105
133
  }}
106
134
  >
107
- <HMSThemeProvider
108
- themeType={theme}
109
- aspectRatio={getAspectRatio({ width, height })}
110
- theme={{
111
- colors: {
112
- brandDefault: color,
113
- brandDark: shadeColor(color, -30),
114
- brandLight: shadeColor(color, 30),
115
- brandDisabled: shadeColor(color, 10),
116
- },
117
- fonts: {
118
- sans: ['Roboto', 'Inter', 'sans-serif'],
119
- },
120
- }}
135
+ <HMSRoomProvider
136
+ isHMSStatsOn={FeatureFlags.enableStatsForNerds}
137
+ actions={reactiveStore.current.hmsActions}
138
+ store={reactiveStore.current.hmsStore}
139
+ notifications={reactiveStore.current.hmsNotifications}
140
+ stats={reactiveStore.current.hmsStats}
121
141
  >
122
- <HMSRoomProvider
123
- isHMSStatsOn={FeatureFlags.enableStatsForNerds}
124
- actions={hmsActions}
125
- store={hmsStore}
126
- notifications={hmsNotifications}
127
- stats={hmsStats}
128
- >
129
- <AppData
130
- appDetails={metadata}
131
- recordingUrl={recordingUrl}
132
- logo={logoUrl}
133
- tokenEndpoint={endPoints.tokenByRoomIdRole}
134
- />
135
- <Init />
136
- <Box
137
- css={{
138
- bg: '$mainBg',
139
- size: '100%',
140
- lineHeight: '1.5',
141
- '-webkit-text-size-adjust': '100%',
142
+ <RoomLayoutProvider roomLayoutEndpoint={roomLayoutEndpoint} overrideLayout={overrideLayout}>
143
+ <RoomLayoutContext.Consumer>
144
+ {layout => {
145
+ const theme = layout.themes?.[0] || {};
146
+ const { typography } = layout;
147
+ let fontFamily = ['sans-serif'];
148
+ if (typography?.font_family) {
149
+ fontFamily = [`${typography?.font_family}`, ...fontFamily];
150
+ }
151
+
152
+ return (
153
+ <HMSThemeProvider
154
+ themeType={theme.name}
155
+ aspectRatio={getAspectRatio({ width, height })}
156
+ theme={{
157
+ colors: theme.palette,
158
+ fonts: {
159
+ sans: fontFamily,
160
+ },
161
+ }}
162
+ >
163
+ <AppData appDetails={metadata} tokenEndpoint={tokenByRoomIdRoleEndpoint} />
164
+ <Init />
165
+ <Box
166
+ css={{
167
+ bg: '$background_dim',
168
+ size: '100%',
169
+ lineHeight: '1.5',
170
+ '-webkit-text-size-adjust': '100%',
171
+ }}
172
+ >
173
+ <AppRoutes authTokenByRoomCodeEndpoint={tokenByRoomCodeEndpoint} />
174
+ </Box>
175
+ </HMSThemeProvider>
176
+ );
142
177
  }}
143
- >
144
- <AppRoutes authTokenByRoomCodeEndpoint={endPoints.tokenByRoomCode} />
145
- </Box>
146
- </HMSRoomProvider>
147
- </HMSThemeProvider>
178
+ </RoomLayoutContext.Consumer>
179
+ </RoomLayoutProvider>
180
+ </HMSRoomProvider>
148
181
  </HMSPrebuiltContext.Provider>
149
182
  </ErrorBoundary>
150
183
  );
@@ -179,7 +212,7 @@ const RouteList = () => {
179
212
  <Route
180
213
  path=":roomId/:role"
181
214
  element={
182
- <Suspense fallback={<FullPageProgress />}>
215
+ <Suspense fallback={<FullPageProgress loadingText="Loading preview..." />}>
183
216
  <PreviewContainer />
184
217
  </Suspense>
185
218
  }
@@ -187,7 +220,7 @@ const RouteList = () => {
187
220
  <Route
188
221
  path=":roomId"
189
222
  element={
190
- <Suspense fallback={<FullPageProgress />}>
223
+ <Suspense fallback={<FullPageProgress loadingText="Loading preview..." />}>
191
224
  <PreviewContainer />
192
225
  </Suspense>
193
226
  }
@@ -198,7 +231,7 @@ const RouteList = () => {
198
231
  <Route
199
232
  path=":roomId/:role"
200
233
  element={
201
- <Suspense fallback={<FullPageProgress />}>
234
+ <Suspense fallback={<FullPageProgress loadingText="Joining..." />}>
202
235
  <Conference />
203
236
  </Suspense>
204
237
  }
@@ -206,7 +239,7 @@ const RouteList = () => {
206
239
  <Route
207
240
  path=":roomId"
208
241
  element={
209
- <Suspense fallback={<FullPageProgress />}>
242
+ <Suspense fallback={<FullPageProgress loadingText="Joining..." />}>
210
243
  <Conference />
211
244
  </Suspense>
212
245
  }
@@ -218,6 +251,7 @@ const RouteList = () => {
218
251
  <Route path=":roomId" element={<PostLeave />} />
219
252
  </Route>
220
253
  )}
254
+
221
255
  <Route path="/:roomId/:role" element={<Redirector showPreview={showPreview} />} />
222
256
  <Route path="/:roomId/" element={<Redirector showPreview={showPreview} />} />
223
257
  </Routes>
@@ -258,7 +292,6 @@ function AppRoutes({ authTokenByRoomCodeEndpoint }) {
258
292
  <ToastContainer />
259
293
  <Notifications />
260
294
  <BackSwipe />
261
- <Confetti />
262
295
  <FlyingEmoji />
263
296
  <RemoteStopScreenshare />
264
297
  <KeyboardHandler />
@@ -4,13 +4,13 @@ import { styled } from '../Theme';
4
4
  const IconButton = styled(BaseIconButton, {
5
5
  width: '$14',
6
6
  height: '$14',
7
- border: '1px solid $borderLight',
7
+ border: '1px solid $border_bright',
8
8
  r: '$1',
9
9
  variants: {
10
10
  active: {
11
11
  false: {
12
12
  border: '1px solid transparent',
13
- color: '$white',
13
+ color: '$on_primary_high',
14
14
  },
15
15
  },
16
16
  },
@@ -7,14 +7,20 @@ export default {
7
7
  component: HMSPrebuilt,
8
8
  argTypes: {
9
9
  roomCode: { control: { type: 'text' }, defaultValue: 'tsj-obqh-lwx' },
10
+ logo: { control: { type: 'object' }, defaultValue: undefined },
10
11
  },
11
12
  } as Meta<typeof HMSPrebuilt>;
12
13
 
13
- const PrebuiltRoomCodeStory: StoryFn<typeof HMSPrebuilt> = ({ roomCode = '', logo }) => {
14
- return <HMSPrebuilt roomCode={roomCode} logo={logo} />;
14
+ const PrebuiltRoomCodeStory: StoryFn<typeof HMSPrebuilt> = ({ roomCode = '', logo, themes, typography, options }) => {
15
+ return <HMSPrebuilt roomCode={roomCode} logo={logo} options={options} themes={themes} typography={typography} />;
15
16
  };
16
17
 
17
18
  export const Example = PrebuiltRoomCodeStory.bind({});
18
19
  Example.args = {
19
20
  roomCode: 'tsj-obqh-lwx',
21
+ options: {
22
+ endpoints: {
23
+ roomLayout: 'https://demo8271564.mockable.io/v2/layouts/ui',
24
+ },
25
+ },
20
26
  };
@@ -118,7 +118,6 @@ export const APP_DATA = {
118
118
  chatSelector: 'chatSelector',
119
119
  chatDraft: 'chatDraft',
120
120
  appConfig: 'appConfig',
121
- recordingUrl: 'recordingUrl',
122
121
  sidePane: 'sidePane',
123
122
  hlsStats: 'hlsStats',
124
123
  hlsViewerRole: 'hlsViewerRole',
@@ -1,5 +1,3 @@
1
- import { QUERY_PARAM_SKIP_PREVIEW } from './constants';
2
-
3
1
  // eslint-disable-next-line complexity
4
2
  export function shadeColor(color, percent) {
5
3
  let R = parseInt(color.substring(1, 3), 16);
@@ -58,10 +56,6 @@ export const isScreenshareSupported = () => {
58
56
  return typeof navigator.mediaDevices.getDisplayMedia !== 'undefined';
59
57
  };
60
58
 
61
- export const getDefaultMeetingUrl = () => {
62
- return `${window.location.href.replace('meeting', 'preview')}?${QUERY_PARAM_SKIP_PREVIEW}=true`;
63
- };
64
-
65
59
  export const getRoutePrefix = () => {
66
60
  return window.location.pathname.startsWith('/streaming') ? '/streaming' : '';
67
61
  };
@@ -74,7 +74,7 @@ const initialAppData = {
74
74
  [APP_DATA.authToken]: '',
75
75
  };
76
76
 
77
- export const AppData = React.memo(({ appDetails, logo, recordingUrl, tokenEndpoint }) => {
77
+ export const AppData = React.memo(({ appDetails, tokenEndpoint }) => {
78
78
  const hmsActions = useHMSActions();
79
79
  const isConnected = useHMSStore(selectIsConnectedToRoom);
80
80
  const sidePane = useSidepaneState();
@@ -93,6 +93,11 @@ export const AppData = React.memo(({ appDetails, logo, recordingUrl, tokenEndpoi
93
93
 
94
94
  useEffect(() => {
95
95
  hmsActions.initAppData(initialAppData);
96
+ hmsActions.setFrameworkInfo({
97
+ type: 'react-web',
98
+ isPrebuilt: true,
99
+ version: React.version,
100
+ });
96
101
  }, [hmsActions]);
97
102
 
98
103
  useEffect(() => {
@@ -108,16 +113,14 @@ export const AppData = React.memo(({ appDetails, logo, recordingUrl, tokenEndpoi
108
113
 
109
114
  useEffect(() => {
110
115
  const appData = {
111
- [APP_DATA.recordingUrl]: recordingUrl,
112
116
  [APP_DATA.tokenEndpoint]: tokenEndpoint,
113
- [APP_DATA.logo]: logo,
114
117
  [APP_DATA.hlsViewerRole]: getMetadata(appDetails)[DEFAULT_HLS_ROLE_KEY] || DEFAULT_HLS_VIEWER_ROLE,
115
118
  [APP_DATA.appConfig]: getAppDetails(appDetails),
116
119
  };
117
120
  for (const key in appData) {
118
121
  hmsActions.setAppData([key], appData[key]);
119
122
  }
120
- }, [appDetails, logo, recordingUrl, tokenEndpoint, hmsActions]);
123
+ }, [appDetails, tokenEndpoint, hmsActions]);
121
124
 
122
125
  useEffect(() => {
123
126
  if (!preferences.subscribedNotifications) {
@@ -77,10 +77,6 @@ export const useAuthToken = () => {
77
77
  return useHMSStore(selectAppData(APP_DATA.authToken));
78
78
  };
79
79
 
80
- export const useLogo = () => {
81
- return useHMSStore(selectAppData(APP_DATA.logo));
82
- };
83
-
84
80
  export const useUrlToEmbed = () => {
85
81
  return useHMSStore(selectAppData(APP_DATA.embedConfig))?.url;
86
82
  };
@@ -1,50 +1,103 @@
1
1
  import React, { Fragment } from 'react';
2
2
  import {
3
- selectIsConnectedToRoom,
3
+ DeviceType,
4
4
  selectLocalVideoTrackID,
5
5
  selectVideoTrackByID,
6
6
  useAVToggle,
7
+ useDevices,
7
8
  useHMSActions,
8
9
  useHMSStore,
9
10
  } from '@100mslive/react-sdk';
10
11
  import { CameraFlipIcon, MicOffIcon, MicOnIcon, VideoOffIcon, VideoOnIcon } from '@100mslive/react-icons';
12
+ import { IconButtonWithOptions } from './IconButtonWithOptions/IconButtonWithOptions';
11
13
  import { ToastManager } from './Toast/ToastManager';
14
+ import { Text } from '../../Text';
12
15
  import { Tooltip } from '../../Tooltip';
13
16
  import IconButton from '../IconButton';
14
17
  import { isMacOS } from '../common/constants';
15
18
 
19
+ const optionsCSS = { fontWeight: '$semiBold', color: '$on_surface_high', w: '100%', p: '$8' };
20
+
16
21
  export const AudioVideoToggle = () => {
22
+ const { allDevices, selectedDeviceIDs, updateDevice } = useDevices();
23
+ const { videoInput, audioInput } = allDevices;
24
+
25
+ const formattedVideoInputList = videoInput?.map(videoInput => ({
26
+ active: selectedDeviceIDs.videoInput === videoInput.deviceId,
27
+ content: (
28
+ <Text
29
+ variant="sm"
30
+ onClick={() =>
31
+ updateDevice({
32
+ deviceType: DeviceType.videoInput,
33
+ deviceId: videoInput.deviceId,
34
+ })
35
+ }
36
+ css={optionsCSS}
37
+ >
38
+ {videoInput.label}
39
+ </Text>
40
+ ),
41
+ title: videoInput.label,
42
+ }));
43
+
44
+ const formattedAudioInputList = audioInput?.map(audioInput => ({
45
+ active: selectedDeviceIDs.audioInput === audioInput.deviceId,
46
+ content: (
47
+ <Text
48
+ variant="sm"
49
+ onClick={() =>
50
+ updateDevice({
51
+ deviceType: DeviceType.audioInput,
52
+ deviceId: audioInput.deviceId,
53
+ })
54
+ }
55
+ css={optionsCSS}
56
+ >
57
+ {audioInput.label}
58
+ </Text>
59
+ ),
60
+ title: audioInput.label,
61
+ }));
62
+
17
63
  const { isLocalVideoEnabled, isLocalAudioEnabled, toggleAudio, toggleVideo } = useAVToggle();
18
64
  const actions = useHMSActions();
19
- const videoTracKId = useHMSStore(selectLocalVideoTrackID);
20
- const localVideoTrack = useHMSStore(selectVideoTrackByID(videoTracKId));
21
- const isConnectedToRoom = useHMSStore(selectIsConnectedToRoom);
65
+ const videoTrackId = useHMSStore(selectLocalVideoTrackID);
66
+ const localVideoTrack = useHMSStore(selectVideoTrackByID(videoTrackId));
22
67
 
23
68
  return (
24
69
  <Fragment>
25
70
  {toggleAudio ? (
26
- <Tooltip title={`Turn ${isLocalAudioEnabled ? 'off' : 'on'} audio (${isMacOS ? '⌘' : 'ctrl'} + d)`}>
27
- <IconButton active={isLocalAudioEnabled} onClick={toggleAudio} key="toggleAudio" data-testid="audio_btn">
28
- {!isLocalAudioEnabled ? (
29
- <MicOffIcon data-testid="audio_off_btn" />
30
- ) : (
31
- <MicOnIcon data-testid="audio_on_btn" />
32
- )}
33
- </IconButton>
34
- </Tooltip>
71
+ <IconButtonWithOptions
72
+ options={formattedAudioInputList}
73
+ tooltipMessage={`Turn ${isLocalAudioEnabled ? 'off' : 'on'} audio (${isMacOS ? '⌘' : 'ctrl'} + d)`}
74
+ icon={
75
+ !isLocalAudioEnabled ? <MicOffIcon data-testid="audio_off_btn" /> : <MicOnIcon data-testid="audio_on_btn" />
76
+ }
77
+ active={isLocalAudioEnabled}
78
+ onClick={toggleAudio}
79
+ key="toggleAudio"
80
+ />
35
81
  ) : null}
82
+
36
83
  {toggleVideo ? (
37
- <Tooltip title={`Turn ${isLocalVideoEnabled ? 'off' : 'on'} video (${isMacOS ? '⌘' : 'ctrl'} + e)`}>
38
- <IconButton key="toggleVideo" active={isLocalVideoEnabled} onClick={toggleVideo} data-testid="video_btn">
39
- {!isLocalVideoEnabled ? (
84
+ <IconButtonWithOptions
85
+ options={formattedVideoInputList}
86
+ tooltipMessage={`Turn ${isLocalVideoEnabled ? 'off' : 'on'} video (${isMacOS ? '⌘' : 'ctrl'} + e)`}
87
+ icon={
88
+ !isLocalVideoEnabled ? (
40
89
  <VideoOffIcon data-testid="video_off_btn" />
41
90
  ) : (
42
91
  <VideoOnIcon data-testid="video_on_btn" />
43
- )}
44
- </IconButton>
45
- </Tooltip>
92
+ )
93
+ }
94
+ key="toggleVideo"
95
+ active={isLocalVideoEnabled}
96
+ onClick={toggleVideo}
97
+ />
46
98
  ) : null}
47
- {localVideoTrack?.facingMode && isConnectedToRoom ? (
99
+
100
+ {localVideoTrack?.facingMode ? (
48
101
  <Tooltip title="Switch Camera" key="switchCamera">
49
102
  <IconButton
50
103
  onClick={async () => {