@100mslive/roomkit-react 0.1.15 → 0.1.16

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 (57) hide show
  1. package/dist/{HLSView-MXBOUQBG.js → HLSView-EMUOLCTM.js} +2 -2
  2. package/dist/Prebuilt/common/PeersSorter.d.ts +1 -0
  3. package/dist/Prebuilt/common/constants.d.ts +7 -4
  4. package/dist/Prebuilt/common/hooks.d.ts +1 -0
  5. package/dist/Prebuilt/components/Footer/ParticipantList.d.ts +17 -0
  6. package/dist/Prebuilt/components/Footer/RoleAccordion.d.ts +3 -2
  7. package/dist/Prebuilt/components/Footer/WhiteboardToggle.d.ts +2 -0
  8. package/dist/Prebuilt/components/Notifications/HandRaisedNotifications.d.ts +1 -0
  9. package/dist/Prebuilt/components/PreviousRoleInMetadata.d.ts +1 -0
  10. package/dist/Prebuilt/components/RemoveParticipant.d.ts +5 -0
  11. package/dist/Prebuilt/components/hooks/useCloseScreenshareWhiteboard.d.ts +4 -0
  12. package/dist/Prebuilt/layouts/WhiteboardView.d.ts +2 -0
  13. package/dist/{chunk-HEOH5H43.js → chunk-ZYR4B4KQ.js} +1886 -7116
  14. package/dist/chunk-ZYR4B4KQ.js.map +7 -0
  15. package/dist/index.cjs.js +2477 -7662
  16. package/dist/index.cjs.js.map +4 -4
  17. package/dist/index.js +1 -1
  18. package/dist/meta.cjs.json +438 -161
  19. package/dist/meta.esbuild.json +443 -166
  20. package/package.json +7 -7
  21. package/src/Prebuilt/AppStateContext.tsx +1 -1
  22. package/src/Prebuilt/common/PeersSorter.ts +12 -5
  23. package/src/Prebuilt/common/constants.ts +5 -6
  24. package/src/Prebuilt/common/hooks.ts +16 -0
  25. package/src/Prebuilt/common/utils.js +5 -6
  26. package/src/Prebuilt/components/AppData/AppData.tsx +1 -16
  27. package/src/Prebuilt/components/Chat/Chat.jsx +7 -30
  28. package/src/Prebuilt/components/Chat/ChatBody.jsx +107 -66
  29. package/src/Prebuilt/components/Chat/ChatFooter.tsx +21 -12
  30. package/src/Prebuilt/components/Chat/ChatSelector.tsx +25 -25
  31. package/src/Prebuilt/components/Chat/ChatSelectorContainer.tsx +15 -16
  32. package/src/Prebuilt/components/Chat/PinnedMessage.tsx +7 -2
  33. package/src/Prebuilt/components/ConferenceScreen.tsx +2 -0
  34. package/src/Prebuilt/components/Footer/ChatToggle.tsx +30 -7
  35. package/src/Prebuilt/components/Footer/Footer.tsx +2 -1
  36. package/src/Prebuilt/components/Footer/PaginatedParticipants.tsx +0 -1
  37. package/src/Prebuilt/components/Footer/{ParticipantList.jsx → ParticipantList.tsx} +169 -127
  38. package/src/Prebuilt/components/Footer/RoleAccordion.tsx +23 -13
  39. package/src/Prebuilt/components/Footer/WhiteboardToggle.tsx +34 -0
  40. package/src/Prebuilt/components/Notifications/HandRaisedNotifications.tsx +35 -0
  41. package/src/Prebuilt/components/Notifications/Notifications.tsx +14 -12
  42. package/src/Prebuilt/components/Notifications/PeerNotifications.tsx +7 -2
  43. package/src/Prebuilt/components/Polls/Voting/QuestionCard.jsx +10 -2
  44. package/src/Prebuilt/components/PreviousRoleInMetadata.tsx +21 -0
  45. package/src/Prebuilt/components/RemoveParticipant.tsx +35 -0
  46. package/src/Prebuilt/components/RoleChangeModal.jsx +1 -1
  47. package/src/Prebuilt/components/SidePaneTabs.tsx +0 -1
  48. package/src/Prebuilt/components/TileMenu/TileMenuContent.tsx +1 -1
  49. package/src/Prebuilt/components/Toast/ToastConfig.jsx +15 -3
  50. package/src/Prebuilt/components/VideoLayouts/GridLayout.tsx +5 -2
  51. package/src/Prebuilt/components/hooks/useCloseScreenshareWhiteboard.tsx +24 -0
  52. package/src/Prebuilt/layouts/VideoStreamingSection.tsx +20 -3
  53. package/src/Prebuilt/layouts/WhiteboardView.tsx +66 -0
  54. package/dist/chunk-HEOH5H43.js.map +0 -7
  55. package/src/Prebuilt/components/AppData/useAppLayout.js +0 -6
  56. package/src/Prebuilt/components/init/initUtils.js +0 -67
  57. /package/dist/{HLSView-MXBOUQBG.js.map → HLSView-EMUOLCTM.js.map} +0 -0
@@ -116,14 +116,22 @@ export const QuestionCard = ({
116
116
  borderRadius: '$1',
117
117
  p: '$md',
118
118
  mt: '$md',
119
- border: respondedToQuiz ? `1px solid ${isCorrectAnswer ? '$alert_success' : '$alert_error_default'}` : 'none',
119
+ border:
120
+ respondedToQuiz && !isLive
121
+ ? `1px solid ${isCorrectAnswer ? '$alert_success' : '$alert_error_default'}`
122
+ : 'none',
120
123
  }}
121
124
  >
122
125
  <Flex align="center" justify="between">
123
126
  <Text
124
127
  variant="caption"
125
128
  css={{
126
- color: respondedToQuiz ? (isCorrectAnswer ? '$alert_success' : '$alert_error_default') : '$on_surface_low',
129
+ color:
130
+ respondedToQuiz && !isLive
131
+ ? isCorrectAnswer
132
+ ? '$alert_success'
133
+ : '$alert_error_default'
134
+ : '$on_surface_low',
127
135
  fontWeight: '$semiBold',
128
136
  display: 'flex',
129
137
  alignItems: 'center',
@@ -0,0 +1,21 @@
1
+ import { useEffect } from 'react';
2
+ import { selectLocalPeerRoleName, useHMSVanillaStore } from '@100mslive/react-sdk';
3
+ // @ts-ignore: No implicit Any
4
+ import { useMyMetadata } from './hooks/useMetadata';
5
+
6
+ export const PreviousRoleInMetadata = () => {
7
+ const vanillaStore = useHMSVanillaStore();
8
+ const { updateMetaData } = useMyMetadata();
9
+
10
+ useEffect(() => {
11
+ let previousRole = vanillaStore.getState(selectLocalPeerRoleName);
12
+ const unsubscribe = vanillaStore.subscribe(currentRole => {
13
+ if (previousRole !== currentRole) {
14
+ updateMetaData({ prevRole: previousRole });
15
+ previousRole = currentRole;
16
+ }
17
+ }, selectLocalPeerRoleName);
18
+ return unsubscribe;
19
+ }, [vanillaStore]); //eslint-disable-line
20
+ return null;
21
+ };
@@ -0,0 +1,35 @@
1
+ import React from 'react';
2
+ import { HMSPeerID, selectLocalPeerID, selectPermissions, useHMSActions, useHMSStore } from '@100mslive/react-sdk';
3
+ import { PeopleRemoveIcon } from '@100mslive/react-icons';
4
+ // @ts-ignore: No implicit Any
5
+ import { ToastManager } from './Toast/ToastManager';
6
+ import { Dropdown } from '../../Dropdown';
7
+ import { Text } from '../../Text';
8
+
9
+ export const RemoveParticipant = ({ peerId }: { peerId: HMSPeerID }) => {
10
+ const canRemoveOthers = useHMSStore(selectPermissions)?.removeOthers;
11
+ const localPeerId = useHMSStore(selectLocalPeerID);
12
+ const actions = useHMSActions();
13
+
14
+ if (peerId === localPeerId || !canRemoveOthers) {
15
+ return null;
16
+ }
17
+ return (
18
+ <Dropdown.Item
19
+ css={{ color: '$alert_error_default', bg: '$surface_default' }}
20
+ onClick={async () => {
21
+ try {
22
+ await actions.removePeer(peerId, '');
23
+ } catch (error) {
24
+ const ex = error as Error;
25
+ ToastManager.addToast({ title: ex.message, variant: 'error' });
26
+ }
27
+ }}
28
+ >
29
+ <PeopleRemoveIcon />
30
+ <Text variant="sm" css={{ ml: '$4', color: 'inherit', fontWeight: '$semiBold' }}>
31
+ Remove Participant
32
+ </Text>
33
+ </Dropdown.Item>
34
+ );
35
+ };
@@ -170,7 +170,7 @@ export const RoleChangeModal = ({ peerId, onOpenChange }) => {
170
170
  variant="primary"
171
171
  css={{ width: '100%' }}
172
172
  onClick={async () => {
173
- await hmsActions.changeRole(peerId, selectedRole, peer.isLocal ? true : !requestPermission);
173
+ await hmsActions.changeRoleOfPeer(peerId, selectedRole, peer.isLocal ? true : !requestPermission);
174
174
  onOpenChange(false);
175
175
  }}
176
176
  >
@@ -6,7 +6,6 @@ import { CrossIcon } from '@100mslive/react-icons';
6
6
  // @ts-ignore: No implicit Any
7
7
  import { Chat } from './Chat/Chat';
8
8
  import { PaginatedParticipants } from './Footer/PaginatedParticipants';
9
- // @ts-ignore: No implicit Any
10
9
  import { ParticipantList } from './Footer/ParticipantList';
11
10
  import { Box, config as cssConfig, Flex, IconButton, Tabs, Text } from '../..';
12
11
  import { Tooltip } from '../../Tooltip';
@@ -287,7 +287,7 @@ export const TileMenuContent = ({
287
287
  toggleAudio();
288
288
  closeSheetOnClick();
289
289
  }}
290
- data-testid={isVideoEnabled ? 'mute_audio_participant_btn' : 'unmute_audio_participant_btn'}
290
+ data-testid={isAudioEnabled ? 'mute_audio_participant_btn' : 'unmute_audio_participant_btn'}
291
291
  >
292
292
  {isAudioEnabled ? <MicOnIcon height={20} width={20} /> : <MicOffIcon height={20} width={20} />}
293
293
  <span>{isAudioEnabled ? 'Mute' : 'Request Unmute'}</span>
@@ -38,15 +38,27 @@ const HandRaiseAction = React.forwardRef(({ id = '', isSingleHandRaise = true },
38
38
  bring_to_stage_label,
39
39
  on_stage_role,
40
40
  off_stage_roles = [],
41
+ skip_preview_for_role_change = false,
41
42
  } = layout?.screens?.conferencing?.default?.elements.on_stage_exp || {};
42
43
 
43
- const onClickHandler = useCallback(() => {
44
+ const onClickHandler = useCallback(async () => {
44
45
  if (isSingleHandRaise) {
45
- hmsActions.changeRoleOfPeer(id, on_stage_role);
46
+ hmsActions.changeRoleOfPeer(id, on_stage_role, skip_preview_for_role_change);
47
+ if (skip_preview_for_role_change) {
48
+ await hmsActions.lowerRemotePeerHand(id);
49
+ }
46
50
  } else {
47
51
  !isParticipantsOpen && toggleSidepane();
48
52
  }
49
- }, [hmsActions, id, isParticipantsOpen, isSingleHandRaise, on_stage_role, toggleSidepane]);
53
+ }, [
54
+ hmsActions,
55
+ id,
56
+ isParticipantsOpen,
57
+ isSingleHandRaise,
58
+ on_stage_role,
59
+ toggleSidepane,
60
+ skip_preview_for_role_change,
61
+ ]);
50
62
 
51
63
  // show nothing if handRaise is single and peer role is not hls
52
64
  if (isSingleHandRaise && (!peer || !off_stage_roles.includes(peer.roleName))) {
@@ -79,8 +79,8 @@ export const GridLayout = ({
79
79
  };
80
80
 
81
81
  useEffect(() => {
82
- if (mainPage !== 0 || pageSize === 0) {
83
- setSortedPeers(updatedPeers);
82
+ if (mainPage !== 0) {
83
+ peersSorter.stop();
84
84
  return;
85
85
  }
86
86
  peersSorter.setPeersAndTilesPerPage({
@@ -88,6 +88,9 @@ export const GridLayout = ({
88
88
  tilesPerPage: pageSize,
89
89
  });
90
90
  peersSorter.onUpdate(setSortedPeers);
91
+ return () => {
92
+ peersSorter.stop();
93
+ };
91
94
  }, [mainPage, peersSorter, updatedPeers, pageSize]);
92
95
 
93
96
  if (peerSharing) {
@@ -0,0 +1,24 @@
1
+ import { useEffect } from 'react';
2
+ import { usePrevious } from 'react-use';
3
+ import { useScreenShare, useWhiteboard } from '@100mslive/react-sdk';
4
+
5
+ /**
6
+ * close existing screenshare or whiteboard when the other is started
7
+ */
8
+ export const useCloseScreenshareWhiteboard = () => {
9
+ const { amIScreenSharing, toggleScreenShare } = useScreenShare();
10
+ const { isOwner: isWhiteboardOwner, toggle: toggleWhiteboard } = useWhiteboard();
11
+ const prevScreenSharer = usePrevious(amIScreenSharing);
12
+ const prevWhiteboardOwner = usePrevious(isWhiteboardOwner);
13
+
14
+ // if both screenshare and whiteboard are open, close the one that was open earlier
15
+ useEffect(() => {
16
+ if (isWhiteboardOwner && amIScreenSharing) {
17
+ if (prevScreenSharer && !prevWhiteboardOwner) {
18
+ toggleScreenShare?.();
19
+ } else if (prevWhiteboardOwner && !prevScreenSharer) {
20
+ toggleWhiteboard?.();
21
+ }
22
+ }
23
+ }, [isWhiteboardOwner, amIScreenSharing, prevScreenSharer, prevWhiteboardOwner, toggleScreenShare, toggleWhiteboard]);
24
+ };
@@ -4,7 +4,14 @@ import {
4
4
  DefaultConferencingScreen_Elements,
5
5
  HLSLiveStreamingScreen_Elements,
6
6
  } from '@100mslive/types-prebuilt';
7
- import { selectIsConnectedToRoom, selectLocalPeerRoleName, useHMSActions, useHMSStore } from '@100mslive/react-sdk';
7
+ import {
8
+ selectIsConnectedToRoom,
9
+ selectLocalPeerRoleName,
10
+ selectPeerScreenSharing,
11
+ selectWhiteboard,
12
+ useHMSActions,
13
+ useHMSStore,
14
+ } from '@100mslive/react-sdk';
8
15
  // @ts-ignore: No implicit Any
9
16
  import FullPageProgress from '../components/FullPageProgress';
10
17
  import { GridLayout } from '../components/VideoLayouts/GridLayout';
@@ -16,13 +23,14 @@ import { PDFView } from './PDFView';
16
23
  import SidePane from './SidePane';
17
24
  // @ts-ignore: No implicit Any
18
25
  import { WaitingView } from './WaitingView';
19
- // import { useWhiteboardMetadata } from '../plugins/whiteboard';
26
+ import { WhiteboardView } from './WhiteboardView';
20
27
  import {
21
28
  usePDFConfig,
22
29
  useUrlToEmbed,
23
30
  useWaitingViewerRole,
24
31
  // @ts-ignore: No implicit Any
25
32
  } from '../components/AppData/useUISettings';
33
+ import { useCloseScreenshareWhiteboard } from '../components/hooks/useCloseScreenshareWhiteboard';
26
34
  // @ts-ignore: No implicit Any
27
35
  import { SESSION_STORE_KEY } from '../common/constants';
28
36
 
@@ -40,12 +48,15 @@ export const VideoStreamingSection = ({
40
48
  hideControls: boolean;
41
49
  }) => {
42
50
  const localPeerRole = useHMSStore(selectLocalPeerRoleName);
43
- // const { whiteboardOwner: whiteboardShared } = useWhiteboardMetadata();
44
51
  const isConnected = useHMSStore(selectIsConnectedToRoom);
52
+ const peerSharing = useHMSStore(selectPeerScreenSharing);
53
+ const isWhiteboardOpen = useHMSStore(selectWhiteboard)?.open;
54
+
45
55
  const hmsActions = useHMSActions();
46
56
  const waitingViewerRole = useWaitingViewerRole();
47
57
  const urlToIframe = useUrlToEmbed();
48
58
  const pdfAnnotatorActive = usePDFConfig();
59
+ useCloseScreenshareWhiteboard();
49
60
 
50
61
  useEffect(() => {
51
62
  if (!isConnected) {
@@ -75,6 +86,12 @@ export const VideoStreamingSection = ({
75
86
  ViewComponent = <PDFView />;
76
87
  } else if (urlToIframe) {
77
88
  ViewComponent = <EmbedView />;
89
+ } else if (peerSharing) {
90
+ // screen share should take preference over whiteboard
91
+ //@ts-ignore
92
+ ViewComponent = <GridLayout {...(elements as DefaultConferencingScreen_Elements)?.video_tile_layout?.grid} />;
93
+ } else if (isWhiteboardOpen) {
94
+ ViewComponent = <WhiteboardView />;
78
95
  } else {
79
96
  //@ts-ignore
80
97
  ViewComponent = <GridLayout {...(elements as DefaultConferencingScreen_Elements)?.video_tile_layout?.grid} />;
@@ -0,0 +1,66 @@
1
+ import React, { useEffect, useMemo } from 'react';
2
+ import { selectPeers, selectWhiteboard, useHMSStore, useWhiteboard } from '@100mslive/react-sdk';
3
+ import { SecondaryTiles } from '../components/SecondaryTiles';
4
+ import { ProminenceLayout } from '../components/VideoLayouts/ProminenceLayout';
5
+ import { Box } from '../../Layout';
6
+ // @ts-ignore: No implicit Any
7
+ import { useSetAppDataByKey } from '../components/AppData/useUISettings';
8
+ import { APP_DATA } from '../common/constants';
9
+
10
+ const EmbedComponent = () => {
11
+ const { iframeRef } = useWhiteboard();
12
+
13
+ return (
14
+ <Box
15
+ css={{
16
+ mx: '$8',
17
+ flex: '3 1 0',
18
+ '@lg': {
19
+ flex: '2 1 0',
20
+ display: 'flex',
21
+ alignItems: 'center',
22
+ },
23
+ }}
24
+ >
25
+ <iframe
26
+ title="Whiteboard View"
27
+ ref={iframeRef}
28
+ style={{
29
+ width: '100%',
30
+ height: '100%',
31
+ border: 0,
32
+ borderRadius: '0.75rem',
33
+ }}
34
+ allow="autoplay; clipboard-write;"
35
+ referrerPolicy="no-referrer"
36
+ />
37
+ </Box>
38
+ );
39
+ };
40
+
41
+ export const WhiteboardView = () => {
42
+ const peers = useHMSStore(selectPeers);
43
+ const whiteboard = useHMSStore(selectWhiteboard);
44
+ const [, setActiveScreenSharePeer] = useSetAppDataByKey(APP_DATA.activeScreensharePeerId);
45
+
46
+ const smallTilePeers = useMemo(() => {
47
+ const smallTilePeers = peers.filter(peer => peer.id !== whiteboard?.owner);
48
+ return smallTilePeers;
49
+ }, [peers, whiteboard?.owner]);
50
+
51
+ useEffect(() => {
52
+ setActiveScreenSharePeer(whiteboard?.owner || '');
53
+ return () => {
54
+ setActiveScreenSharePeer('');
55
+ };
56
+ }, [whiteboard?.owner, setActiveScreenSharePeer]);
57
+
58
+ return (
59
+ <ProminenceLayout.Root>
60
+ <ProminenceLayout.ProminentSection>
61
+ <EmbedComponent />
62
+ </ProminenceLayout.ProminentSection>
63
+ <SecondaryTiles peers={smallTilePeers} />
64
+ </ProminenceLayout.Root>
65
+ );
66
+ };