@100mslive/roomkit-react 0.1.8-alpha.0 → 0.1.9-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 (142) hide show
  1. package/dist/{HLSView-IQRPLYNH.js → HLSView-U53QN3AC.js} +3 -3
  2. package/dist/Modal/Dialog.d.ts +402 -1706
  3. package/dist/Prebuilt/App.d.ts +6 -0
  4. package/dist/Prebuilt/AppContext.d.ts +2 -0
  5. package/dist/Prebuilt/AppStateContext.d.ts +16 -0
  6. package/dist/Prebuilt/components/ConferenceScreen.d.ts +2 -0
  7. package/dist/Prebuilt/components/Footer/PaginatedParticipants.d.ts +5 -0
  8. package/dist/Prebuilt/components/Footer/PollsToggle.d.ts +2 -0
  9. package/dist/Prebuilt/components/Footer/RoleAccordion.d.ts +10 -3
  10. package/dist/Prebuilt/components/LeaveScreen.d.ts +2 -0
  11. package/dist/Prebuilt/components/MwebLandscapePrompt.d.ts +2 -0
  12. package/dist/Prebuilt/components/Notifications/AutoplayBlockedModal.d.ts +2 -0
  13. package/dist/Prebuilt/components/Notifications/HLSFailureModal.d.ts +2 -0
  14. package/dist/Prebuilt/components/Notifications/InitErrorModal.d.ts +2 -0
  15. package/dist/Prebuilt/components/Notifications/Notifications.d.ts +2 -0
  16. package/dist/Prebuilt/components/Notifications/PeerNotifications.d.ts +1 -0
  17. package/dist/Prebuilt/components/Notifications/PermissionErrorModal.d.ts +2 -0
  18. package/dist/Prebuilt/components/Notifications/ReconnectNotifications.d.ts +2 -0
  19. package/dist/Prebuilt/components/Notifications/TrackBulkUnmuteModal.d.ts +2 -0
  20. package/dist/Prebuilt/components/Notifications/TrackNotifications.d.ts +1 -0
  21. package/dist/Prebuilt/components/Notifications/TrackUnmuteModal.d.ts +2 -0
  22. package/dist/Prebuilt/components/Polls/Polls.d.ts +2 -0
  23. package/dist/Prebuilt/components/Preview/PreviewJoin.d.ts +1 -2
  24. package/dist/Prebuilt/components/Preview/PreviewScreen.d.ts +2 -0
  25. package/dist/Prebuilt/components/hooks/useRedirectToLeave.d.ts +1 -1
  26. package/dist/{VirtualBackground-GP4ATXD3.js → VirtualBackground-PMLQPJB6.js} +3 -5
  27. package/dist/{VirtualBackground-GP4ATXD3.js.map → VirtualBackground-PMLQPJB6.js.map} +1 -1
  28. package/dist/chunk-ANQRGVIX.js +14441 -0
  29. package/dist/chunk-ANQRGVIX.js.map +7 -0
  30. package/dist/{chunk-Z3O2WGWV.js → chunk-XQ2NRKIW.js} +66 -3
  31. package/dist/chunk-XQ2NRKIW.js.map +7 -0
  32. package/dist/context/DialogContext.d.ts +6 -0
  33. package/dist/hooks/useDialogContainerSelector.d.ts +1 -0
  34. package/dist/index.cjs.js +10956 -9818
  35. package/dist/index.cjs.js.map +4 -4
  36. package/dist/index.d.ts +1 -0
  37. package/dist/index.js +6 -2
  38. package/dist/meta.cjs.json +4076 -3201
  39. package/dist/meta.esbuild.json +4391 -3623
  40. package/dist/utils/animations.d.ts +11 -0
  41. package/package.json +6 -7
  42. package/src/AudioLevel/AudioLevel.tsx +1 -1
  43. package/src/Modal/Dialog.tsx +31 -3
  44. package/src/Prebuilt/App.tsx +49 -97
  45. package/src/Prebuilt/AppContext.tsx +6 -0
  46. package/src/Prebuilt/AppStateContext.tsx +71 -0
  47. package/src/Prebuilt/common/constants.js +36 -1
  48. package/src/Prebuilt/common/utils.js +47 -0
  49. package/src/Prebuilt/components/AppData/AppData.jsx +6 -1
  50. package/src/Prebuilt/components/AppData/useSidepane.js +23 -1
  51. package/src/Prebuilt/components/AppData/useUISettings.js +49 -5
  52. package/src/Prebuilt/components/Chip.tsx +6 -2
  53. package/src/Prebuilt/components/{conference.jsx → ConferenceScreen.tsx} +34 -46
  54. package/src/Prebuilt/components/Footer/Footer.tsx +5 -0
  55. package/src/Prebuilt/components/Footer/PaginatedParticipants.tsx +125 -0
  56. package/src/Prebuilt/components/Footer/ParticipantList.jsx +55 -24
  57. package/src/Prebuilt/components/Footer/PollsToggle.tsx +22 -0
  58. package/src/Prebuilt/components/Footer/RoleAccordion.tsx +87 -85
  59. package/src/Prebuilt/components/Footer/RoleOptions.tsx +1 -1
  60. package/src/Prebuilt/components/Header/StreamActions.tsx +5 -3
  61. package/src/Prebuilt/components/Leave/DesktopLeaveRoom.tsx +4 -5
  62. package/src/Prebuilt/components/Leave/LeaveRoom.tsx +0 -4
  63. package/src/Prebuilt/components/{PostLeave.jsx → LeaveScreen.tsx} +6 -13
  64. package/src/Prebuilt/components/MoreSettings/ChangeNameModal.jsx +2 -3
  65. package/src/Prebuilt/components/MoreSettings/EmbedUrl.jsx +2 -3
  66. package/src/Prebuilt/components/MoreSettings/SplitComponents/MwebOptions.tsx +18 -1
  67. package/src/Prebuilt/components/{MwebLandscapePrompt.jsx → MwebLandscapePrompt.tsx} +10 -11
  68. package/src/Prebuilt/components/Notifications/{AutoplayBlockedModal.jsx → AutoplayBlockedModal.tsx} +2 -1
  69. package/src/Prebuilt/components/Notifications/{HLSFailureModal.jsx → HLSFailureModal.tsx} +10 -8
  70. package/src/Prebuilt/components/Notifications/{InitErrorModal.jsx → InitErrorModal.tsx} +5 -2
  71. package/src/Prebuilt/components/Notifications/{Notifications.jsx → Notifications.tsx} +41 -27
  72. package/src/Prebuilt/components/Notifications/{PeerNotifications.jsx → PeerNotifications.tsx} +3 -0
  73. package/src/Prebuilt/components/Notifications/{PermissionErrorModal.jsx → PermissionErrorModal.tsx} +6 -4
  74. package/src/Prebuilt/components/Notifications/{ReconnectNotifications.jsx → ReconnectNotifications.tsx} +11 -6
  75. package/src/Prebuilt/components/Notifications/{TrackBulkUnmuteModal.jsx → TrackBulkUnmuteModal.tsx} +9 -3
  76. package/src/Prebuilt/components/Notifications/{TrackUnmuteModal.jsx → TrackUnmuteModal.tsx} +9 -3
  77. package/src/Prebuilt/components/Notifications/index.tsx +1 -0
  78. package/src/Prebuilt/components/Polls/CreatePollQuiz/PollsQuizMenu.jsx +229 -0
  79. package/src/Prebuilt/components/Polls/CreatePollQuiz/Timer.jsx +71 -0
  80. package/src/Prebuilt/components/Polls/CreateQuestions/CreateQuestions.jsx +132 -0
  81. package/src/Prebuilt/components/Polls/CreateQuestions/DeleteQuestionModal.jsx +66 -0
  82. package/src/Prebuilt/components/Polls/CreateQuestions/QuestionForm.jsx +251 -0
  83. package/src/Prebuilt/components/Polls/CreateQuestions/SavedQuestion.jsx +57 -0
  84. package/src/Prebuilt/components/Polls/Polls.tsx +28 -0
  85. package/src/Prebuilt/components/Polls/Voting/PollResultSummary.jsx +125 -0
  86. package/src/Prebuilt/components/Polls/Voting/QuestionCard.jsx +249 -0
  87. package/src/Prebuilt/components/Polls/Voting/StandardVoting.jsx +40 -0
  88. package/src/Prebuilt/components/Polls/Voting/TimedVoting.jsx +36 -0
  89. package/src/Prebuilt/components/Polls/Voting/Voting.jsx +99 -0
  90. package/src/Prebuilt/components/Polls/common/MultipleChoiceOptions.jsx +101 -0
  91. package/src/Prebuilt/components/Polls/common/OptionInputWithDelete.jsx +25 -0
  92. package/src/Prebuilt/components/Polls/common/SingleChoiceOptions.jsx +125 -0
  93. package/src/Prebuilt/components/Polls/common/StatusIndicator.jsx +47 -0
  94. package/src/Prebuilt/components/Polls/common/VoteCount.jsx +28 -0
  95. package/src/Prebuilt/components/Polls/common/VoteProgress.jsx +17 -0
  96. package/src/Prebuilt/components/Polls/common/VoterList.jsx +22 -0
  97. package/src/Prebuilt/components/Polls/common/Votes.jsx +72 -0
  98. package/src/Prebuilt/components/Preview/PreviewForm.tsx +3 -2
  99. package/src/Prebuilt/components/Preview/PreviewJoin.tsx +29 -21
  100. package/src/Prebuilt/components/Preview/{PreviewContainer.tsx → PreviewScreen.tsx} +2 -19
  101. package/src/Prebuilt/components/RaiseHand.jsx +1 -1
  102. package/src/Prebuilt/components/RoleChangeModal.jsx +2 -3
  103. package/src/Prebuilt/components/RoleChangeRequest/RequestPrompt.tsx +2 -3
  104. package/src/Prebuilt/components/Settings/SettingsModal.jsx +2 -3
  105. package/src/Prebuilt/components/Settings/StartRecording.jsx +15 -4
  106. package/src/Prebuilt/components/SidePaneTabs.tsx +32 -6
  107. package/src/Prebuilt/components/StatsForNerds.jsx +2 -3
  108. package/src/Prebuilt/components/Streaming/Common.jsx +31 -21
  109. package/src/Prebuilt/components/VideoLayouts/ScreenshareLayout.tsx +8 -9
  110. package/src/Prebuilt/components/VideoTile.jsx +28 -39
  111. package/src/Prebuilt/components/hooks/useAutoStartStreaming.tsx +3 -3
  112. package/src/Prebuilt/components/hooks/useDropdownSelection.jsx +1 -1
  113. package/src/Prebuilt/components/hooks/useRedirectToLeave.tsx +9 -17
  114. package/src/Prebuilt/components/pdfAnnotator/pdfFileOptions.jsx +2 -3
  115. package/src/Prebuilt/components/pdfAnnotator/submitPdf.jsx +1 -1
  116. package/src/Prebuilt/components/pdfAnnotator/uploadedFile.jsx +2 -3
  117. package/src/Prebuilt/layouts/EmbedView.jsx +47 -60
  118. package/src/Prebuilt/layouts/PDFView.jsx +49 -99
  119. package/src/Prebuilt/layouts/SidePane.tsx +9 -4
  120. package/src/Prebuilt/layouts/VideoStreamingSection.tsx +2 -2
  121. package/src/Prebuilt/primitives/DialogContent.jsx +4 -5
  122. package/src/context/DialogContext.tsx +13 -0
  123. package/src/hooks/useDialogContainerSelector.tsx +7 -0
  124. package/src/index.ts +1 -0
  125. package/src/utils/animations.ts +6 -0
  126. package/dist/Prebuilt/components/PrebuiltDialogPortal.d.ts +0 -4
  127. package/dist/Prebuilt/components/Preview/PreviewContainer.d.ts +0 -3
  128. package/dist/chunk-2H5NIZB7.js +0 -70
  129. package/dist/chunk-2H5NIZB7.js.map +0 -7
  130. package/dist/chunk-GLYGPYNS.js +0 -7125
  131. package/dist/chunk-GLYGPYNS.js.map +0 -7
  132. package/dist/chunk-Z3O2WGWV.js.map +0 -7
  133. package/dist/conference-JD35TNH4.js +0 -6503
  134. package/dist/conference-JD35TNH4.js.map +0 -7
  135. package/src/Prebuilt/components/GoLiveButton.jsx +0 -42
  136. package/src/Prebuilt/components/PrebuiltDialogPortal.tsx +0 -6
  137. package/src/Prebuilt/components/Streaming/HLSStreaming.jsx +0 -220
  138. package/src/Prebuilt/components/Streaming/RTMPStreaming.jsx +0 -334
  139. package/src/Prebuilt/components/Streaming/StreamingLanding.jsx +0 -76
  140. /package/dist/{HLSView-IQRPLYNH.js.map → HLSView-U53QN3AC.js.map} +0 -0
  141. /package/{src/Prebuilt/components/Notifications/index.jsx → dist/Prebuilt/components/Notifications/index.d.ts} +0 -0
  142. /package/src/Prebuilt/components/Notifications/{TrackNotifications.jsx → TrackNotifications.tsx} +0 -0
@@ -1,19 +1,23 @@
1
1
  /* eslint-disable no-case-declarations */
2
2
  import React, { useCallback, useEffect } from 'react';
3
- import { useNavigate, useParams } from 'react-router-dom';
4
3
  import {
5
4
  HMSNotificationTypes,
5
+ HMSRoleChangeRequest,
6
6
  HMSRoomState,
7
7
  selectHasPeerHandRaised,
8
+ selectLocalPeerID,
9
+ selectPeerNameByID,
8
10
  selectRoomState,
9
11
  useCustomEvent,
10
12
  useHMSNotifications,
11
13
  useHMSStore,
12
14
  useHMSVanillaStore,
13
15
  } from '@100mslive/react-sdk';
14
- import { Button } from '../../../';
16
+ import { Button } from '../../..';
15
17
  import { useUpdateRoomLayout } from '../../provider/roomLayoutProvider';
18
+ // @ts-ignore: No implicit Any
16
19
  import { ToastBatcher } from '../Toast/ToastBatcher';
20
+ // @ts-ignore: No implicit Any
17
21
  import { ToastManager } from '../Toast/ToastManager';
18
22
  import { AutoplayBlockedModal } from './AutoplayBlockedModal';
19
23
  import { InitErrorModal } from './InitErrorModal';
@@ -23,22 +27,25 @@ import { ReconnectNotifications } from './ReconnectNotifications';
23
27
  import { TrackBulkUnmuteModal } from './TrackBulkUnmuteModal';
24
28
  import { TrackNotifications } from './TrackNotifications';
25
29
  import { TrackUnmuteModal } from './TrackUnmuteModal';
30
+ // @ts-ignore: No implicit Any
31
+ import { usePollViewToggle } from '../AppData/useSidepane';
32
+ // @ts-ignore: No implicit Any
26
33
  import { useIsNotificationDisabled, useSubscribedNotifications } from '../AppData/useUISettings';
27
- import { useRedirectToLeave } from '../hooks/useRedirectToLeave';
34
+ // @ts-ignore: No implicit Any
28
35
  import { getMetadata } from '../../common/utils';
36
+ // @ts-ignore: No implicit Any
29
37
  import { ROLE_CHANGE_DECLINED } from '../../common/constants';
30
38
  export function Notifications() {
39
+ const localPeerID = useHMSStore(selectLocalPeerID);
31
40
  const notification = useHMSNotifications();
32
- const navigate = useNavigate();
33
- const params = useParams();
34
41
  const subscribedNotifications = useSubscribedNotifications() || {};
35
42
  const roomState = useHMSStore(selectRoomState);
36
43
  const updateRoomLayoutForRole = useUpdateRoomLayout();
37
44
  const isNotificationDisabled = useIsNotificationDisabled();
38
- const { redirectToLeave } = useRedirectToLeave();
39
45
  const vanillaStore = useHMSVanillaStore();
46
+ const togglePollView = usePollViewToggle();
40
47
 
41
- const handleRoleChangeDenied = useCallback(request => {
48
+ const handleRoleChangeDenied = useCallback((request: HMSRoleChangeRequest & { peerName: string }) => {
42
49
  ToastManager.addToast({
43
50
  title: `${request.peerName} denied your request to join the ${request.role.name} role`,
44
51
  variant: 'error',
@@ -85,28 +92,13 @@ export function Notifications() {
85
92
  title: `Error: ${notification.data?.message}`,
86
93
  });
87
94
  } else {
88
- // show button action when the error is terminal
89
- const toastId = ToastManager.addToast({
95
+ ToastManager.addToast({
90
96
  title:
91
97
  notification.data?.message ||
92
98
  'We couldn’t reconnect you. When you’re back online, try joining the room.',
93
- inlineAction: true,
94
- action: (
95
- <Button
96
- onClick={() => {
97
- ToastManager.removeToast(toastId);
98
- navigate(`/${params.roomId}${params.role ? `/${params.role}` : ''}`);
99
- }}
100
- >
101
- Rejoin
102
- </Button>
103
- ),
104
99
  close: false,
105
100
  });
106
101
  }
107
- // goto leave for terminal if any action is not performed within 2secs
108
- // if network is still unavailable going to preview will throw an error
109
- redirectToLeave(1000);
110
102
  return;
111
103
  }
112
104
  // Autoplay error or user denied screen share (cancelled browser pop-up)
@@ -122,11 +114,11 @@ export function Notifications() {
122
114
  });
123
115
  break;
124
116
  case HMSNotificationTypes.ROLE_UPDATED: {
125
- if (notification.data?.isLocal) {
117
+ if (notification.data?.isLocal && notification.data?.roleName) {
126
118
  ToastManager.addToast({
127
119
  title: `You are now a ${notification.data.roleName}`,
128
120
  });
129
- updateRoomLayoutForRole(notification.data.roleName);
121
+ updateRoomLayoutForRole?.(notification.data.roleName);
130
122
  }
131
123
  break;
132
124
  }
@@ -145,13 +137,35 @@ export function Notifications() {
145
137
  title: `${notification.message}.
146
138
  ${notification.data.reason && `Reason: ${notification.data.reason}`}`,
147
139
  });
148
- redirectToLeave(1000);
149
140
  break;
150
141
  case HMSNotificationTypes.DEVICE_CHANGE_UPDATE:
151
142
  ToastManager.addToast({
152
143
  title: notification.message,
153
144
  });
154
145
  break;
146
+
147
+ case HMSNotificationTypes.POLL_STARTED:
148
+ if (notification.data.startedBy !== localPeerID) {
149
+ const pollStartedBy = vanillaStore.getState(selectPeerNameByID(notification.data.startedBy));
150
+ ToastManager.addToast({
151
+ title: `${pollStartedBy} started a ${notification.data.type}: ${notification.data.title}`,
152
+ action: (
153
+ <Button
154
+ onClick={() => togglePollView(notification.data.id)}
155
+ variant="standard"
156
+ css={{
157
+ backgroundColor: '$surface_bright',
158
+ fontWeight: '$semiBold',
159
+ color: '$on_surface_high',
160
+ p: '$xs $md',
161
+ }}
162
+ >
163
+ Vote
164
+ </Button>
165
+ ),
166
+ });
167
+ }
168
+ break;
155
169
  default:
156
170
  break;
157
171
  }
@@ -171,7 +185,7 @@ export function Notifications() {
171
185
  <ReconnectNotifications />
172
186
  <AutoplayBlockedModal />
173
187
  <PermissionErrorModal />
174
- <InitErrorModal notification={notification} />
188
+ <InitErrorModal />
175
189
  </>
176
190
  );
177
191
  }
@@ -1,7 +1,10 @@
1
1
  import { useEffect } from 'react';
2
2
  import { HMSNotificationTypes, useHMSNotifications } from '@100mslive/react-sdk';
3
+ // @ts-ignore: No implicit Any
3
4
  import { ToastBatcher } from '../Toast/ToastBatcher';
5
+ // @ts-ignore: No implicit Any
4
6
  import { useSubscribedNotifications } from '../AppData/useUISettings';
7
+ // @ts-ignore: No implicit Any
5
8
  import { SUBSCRIBED_NOTIFICATIONS } from '../../common/constants';
6
9
 
7
10
  const notificationTypes = [
@@ -1,10 +1,12 @@
1
1
  import React, { useEffect, useState } from 'react';
2
2
  import { useMedia } from 'react-use';
3
3
  import { HMSNotificationTypes, useHMSNotifications } from '@100mslive/react-sdk';
4
- import { Button, config as cssConfig, Dialog, Flex, Text } from '../../../';
4
+ import { Button, config as cssConfig, Dialog, Flex, Text } from '../../..';
5
+ // @ts-ignore: No implicit Any
5
6
  import androidPermissionAlert from '../../images/android-perm-1.png';
7
+ // @ts-ignore: No implicit Any
6
8
  import iosPermissions from '../../images/ios-perm-0.png';
7
- import { PrebuiltDialogPortal } from '../PrebuiltDialogPortal';
9
+ // @ts-ignore: No implicit Any
8
10
  import { isAndroid, isIOS } from '../../common/constants';
9
11
 
10
12
  export function PermissionErrorModal() {
@@ -40,7 +42,7 @@ export function PermissionErrorModal() {
40
42
 
41
43
  return deviceType ? (
42
44
  <Dialog.Root open={!!deviceType}>
43
- <PrebuiltDialogPortal>
45
+ <Dialog.Portal>
44
46
  <Dialog.Overlay />
45
47
  <Dialog.Content css={{ w: 'min(380px, 90%)', p: '$8' }}>
46
48
  <Dialog.Title
@@ -119,7 +121,7 @@ export function PermissionErrorModal() {
119
121
  </Flex>
120
122
  ) : null}
121
123
  </Dialog.Content>
122
- </PrebuiltDialogPortal>
124
+ </Dialog.Portal>
123
125
  </Dialog.Root>
124
126
  ) : null;
125
127
  }
@@ -1,7 +1,9 @@
1
1
  import React, { useEffect, useState } from 'react';
2
2
  import { HMSNotificationTypes, useHMSNotifications } from '@100mslive/react-sdk';
3
- import { Dialog, Flex, Loading, Text } from '../../../';
3
+ import { Dialog, Flex, Loading, Text } from '../../..';
4
+ // @ts-ignore: No implicit Any
4
5
  import { ToastConfig } from '../Toast/ToastConfig';
6
+ // @ts-ignore: No implicit Any
5
7
  import { ToastManager } from '../Toast/ToastManager';
6
8
 
7
9
  const notificationTypes = [
@@ -9,21 +11,24 @@ const notificationTypes = [
9
11
  HMSNotificationTypes.RECONNECTING,
10
12
  HMSNotificationTypes.ERROR,
11
13
  ];
12
- let notificationId = null;
14
+ let notificationId: string | null = null;
13
15
 
14
16
  export const ReconnectNotifications = () => {
15
17
  const notification = useHMSNotifications(notificationTypes);
16
18
  const [open, setOpen] = useState(false);
17
19
  useEffect(() => {
18
- if (notification?.type === HMSNotificationTypes.ERROR && notification?.data?.isTerminal) {
20
+ if (!notification) {
21
+ return;
22
+ }
23
+ if (notification.type === HMSNotificationTypes.ERROR && notification.data?.isTerminal) {
19
24
  setOpen(false);
20
- } else if (notification?.type === HMSNotificationTypes.RECONNECTED) {
25
+ } else if (notification.type === HMSNotificationTypes.RECONNECTED) {
21
26
  notificationId = ToastManager.replaceToast(notificationId, ToastConfig.RECONNECTED.single());
22
27
  setOpen(false);
23
- } else if (notification?.type === HMSNotificationTypes.RECONNECTING) {
28
+ } else if (notification.type === HMSNotificationTypes.RECONNECTING) {
24
29
  notificationId = ToastManager.replaceToast(
25
30
  notificationId,
26
- ToastConfig.RECONNECTING.single(notification.data.message),
31
+ ToastConfig.RECONNECTING.single(notification.data?.message),
27
32
  );
28
33
  }
29
34
  }, [notification]);
@@ -1,11 +1,17 @@
1
1
  import React, { useEffect, useState } from 'react';
2
- import { HMSNotificationTypes, useHMSActions, useHMSNotifications } from '@100mslive/react-sdk';
2
+ import {
3
+ HMSChangeMultiTrackStateRequest,
4
+ HMSNotificationTypes,
5
+ useHMSActions,
6
+ useHMSNotifications,
7
+ } from '@100mslive/react-sdk';
3
8
  import { MicOnIcon } from '@100mslive/react-icons';
9
+ // @ts-ignore: No implicit Any
4
10
  import { RequestDialog } from '../../primitives/DialogContent';
5
11
 
6
12
  export const TrackBulkUnmuteModal = () => {
7
13
  const hmsActions = useHMSActions();
8
- const [muteNotification, setMuteNotification] = useState(null);
14
+ const [muteNotification, setMuteNotification] = useState<HMSChangeMultiTrackStateRequest | null>(null);
9
15
  const notification = useHMSNotifications([
10
16
  HMSNotificationTypes.CHANGE_MULTI_TRACK_STATE_REQUEST,
11
17
  HMSNotificationTypes.ROOM_ENDED,
@@ -38,7 +44,7 @@ export const TrackBulkUnmuteModal = () => {
38
44
  <RequestDialog
39
45
  title="Track Unmute Request"
40
46
  body={`${peer?.name} has requested you to unmute your tracks.`}
41
- onOpenChange={value => !value && setMuteNotification(null)}
47
+ onOpenChange={(value: boolean) => !value && setMuteNotification(null)}
42
48
  onAction={() => {
43
49
  tracks.forEach(track => {
44
50
  hmsActions.setEnabledTrack(track.id, enabled);
@@ -1,6 +1,12 @@
1
1
  import React, { useEffect, useState } from 'react';
2
- import { HMSNotificationTypes, useHMSActions, useHMSNotifications } from '@100mslive/react-sdk';
2
+ import {
3
+ HMSChangeTrackStateRequest,
4
+ HMSNotificationTypes,
5
+ useHMSActions,
6
+ useHMSNotifications,
7
+ } from '@100mslive/react-sdk';
3
8
  import { MicOnIcon } from '@100mslive/react-icons';
9
+ // @ts-ignore: No implicit Any
4
10
  import { RequestDialog } from '../../primitives/DialogContent';
5
11
 
6
12
  export const TrackUnmuteModal = () => {
@@ -10,7 +16,7 @@ export const TrackUnmuteModal = () => {
10
16
  HMSNotificationTypes.ROOM_ENDED,
11
17
  HMSNotificationTypes.REMOVED_FROM_ROOM,
12
18
  ]);
13
- const [muteNotification, setMuteNotification] = useState(null);
19
+ const [muteNotification, setMuteNotification] = useState<HMSChangeTrackStateRequest | null>(null);
14
20
 
15
21
  useEffect(() => {
16
22
  switch (notification?.type) {
@@ -37,7 +43,7 @@ export const TrackUnmuteModal = () => {
37
43
  return (
38
44
  <RequestDialog
39
45
  title="Track Unmute Request"
40
- onOpenChange={value => !value && setMuteNotification(null)}
46
+ onOpenChange={(value: boolean) => !value && setMuteNotification(null)}
41
47
  body={`${peer?.name} has requested you to unmute your ${track?.source} ${track?.type}.`}
42
48
  onAction={() => {
43
49
  hmsActions.setEnabledTrack(track.id, enabled);
@@ -0,0 +1 @@
1
+ export { Notifications } from './Notifications';
@@ -0,0 +1,229 @@
1
+ // @ts-check
2
+ import React, { useMemo, useState } from 'react';
3
+ import {
4
+ selectLocalPeerRoleName,
5
+ selectPermissions,
6
+ selectPolls,
7
+ useHMSActions,
8
+ useHMSStore,
9
+ } from '@100mslive/react-sdk';
10
+ import { QuestionIcon, StatsIcon } from '@100mslive/react-icons';
11
+ import { Button, Flex, Input, Switch, Text } from '../../../../';
12
+ import { Container, ContentHeader, ErrorText } from '../../Streaming/Common';
13
+ import { usePollViewToggle } from '../../AppData/useSidepane';
14
+ import { usePollViewState } from '../../AppData/useUISettings';
15
+ import { isValidTextInput } from '../../../common/utils';
16
+ import { StatusIndicator } from '../common/StatusIndicator';
17
+ import { INTERACTION_TYPE, POLL_STATE, POLL_VIEWS } from '../../../common/constants';
18
+
19
+ export const PollsQuizMenu = () => {
20
+ const togglePollView = usePollViewToggle();
21
+ const permissions = useHMSStore(selectPermissions);
22
+
23
+ return (
24
+ <Container rounded>
25
+ <ContentHeader content="Polls and Quizzes" onClose={togglePollView} />
26
+ <Flex direction="column" css={{ px: '$10', pb: '$10', overflowY: 'auto' }}>
27
+ {permissions?.pollWrite && <AddMenu />}
28
+ <PrevMenu />
29
+ </Flex>
30
+ </Container>
31
+ );
32
+ };
33
+
34
+ function InteractionSelectionCard({ title, icon, active, onClick }) {
35
+ const activeBorderStyle = active ? '$space$px solid $primary_default' : '$space$px solid $border_bright';
36
+ return (
37
+ <Flex
38
+ onClick={onClick}
39
+ css={{
40
+ border: activeBorderStyle,
41
+ p: '$4',
42
+ r: '$2',
43
+ w: '100%',
44
+ cursor: 'pointer',
45
+ }}
46
+ align="center"
47
+ >
48
+ <Flex
49
+ css={{
50
+ border: activeBorderStyle,
51
+ p: '$4',
52
+ bg: '$surface_bright',
53
+ c: '$on_surface_high',
54
+ r: '$0',
55
+ }}
56
+ >
57
+ {icon}
58
+ </Flex>
59
+ <Text variant="sub1" css={{ ml: '$md' }}>
60
+ {title}
61
+ </Text>
62
+ </Flex>
63
+ );
64
+ }
65
+
66
+ const AddMenu = () => {
67
+ const actions = useHMSActions();
68
+ const [title, setTitle] = useState('');
69
+ const localPeerRoleName = useHMSStore(selectLocalPeerRoleName);
70
+ const [anonymous, setAnonymous] = useState(false);
71
+ const [hideVoteCount, setHideVoteCount] = useState(false);
72
+ const [error, setError] = useState();
73
+ const [titleError, setTitleError] = useState('');
74
+ const { setPollState } = usePollViewState();
75
+ const [interactionType, setInteractionType] = useState(INTERACTION_TYPE.POLL);
76
+
77
+ const handleCreate = id => {
78
+ setPollState({
79
+ [POLL_STATE.pollInView]: id,
80
+ [POLL_STATE.view]: POLL_VIEWS.CREATE_QUESTIONS,
81
+ });
82
+ };
83
+
84
+ const validateTitle = useMemo(() => {
85
+ if (!isValidTextInput(title)) {
86
+ if (title) {
87
+ setTitleError('The title should have between 2-100 characters');
88
+ }
89
+ return true;
90
+ } else {
91
+ setTitleError('');
92
+ return false;
93
+ }
94
+ }, [title]);
95
+ // const [timer, setTimer] = useState(10);
96
+ // const [showTimerDropDown, setShowTimerDropDown] = useState(false);
97
+
98
+ return (
99
+ <>
100
+ <Text variant="caption" css={{ c: '$on_surface_medium', mb: '$md' }}>
101
+ Select the type you want to continue with
102
+ </Text>
103
+ <Flex css={{ w: '100%', gap: '$10', mb: '$md' }}>
104
+ <InteractionSelectionCard
105
+ title={INTERACTION_TYPE.POLL}
106
+ icon={<StatsIcon width={32} height={32} />}
107
+ onClick={() => setInteractionType(INTERACTION_TYPE.POLL)}
108
+ active={interactionType === INTERACTION_TYPE.POLL}
109
+ />
110
+ <InteractionSelectionCard
111
+ title={INTERACTION_TYPE.QUIZ}
112
+ icon={<QuestionIcon width={32} height={32} />}
113
+ onClick={() => setInteractionType(INTERACTION_TYPE.QUIZ)}
114
+ active={interactionType === INTERACTION_TYPE.QUIZ}
115
+ />
116
+ </Flex>
117
+ <Flex direction="column">
118
+ <Text variant="body2" css={{ mb: '$4' }}>{`Name this ${interactionType.toLowerCase()}`}</Text>
119
+ <Input
120
+ type="text"
121
+ value={title}
122
+ onChange={event => setTitle(event.target.value)}
123
+ css={{
124
+ backgroundColor: '$surface_bright',
125
+ border: '1px solid $border_default',
126
+ }}
127
+ />
128
+ <Flex align="center" css={{ mt: '$10' }}>
129
+ <Switch onCheckedChange={value => setHideVoteCount(value)} css={{ mr: '$6' }} />
130
+ <Text variant="body2" css={{ c: '$on_surface_medium' }}>
131
+ Hide Vote Count
132
+ </Text>
133
+ </Flex>
134
+ <Flex align="center" css={{ mt: '$10' }}>
135
+ <Switch onCheckedChange={value => setAnonymous(value)} css={{ mr: '$6' }} />
136
+ <Text variant="body2" css={{ c: '$on_surface_medium' }}>
137
+ Make Results Anonymous
138
+ </Text>
139
+ </Flex>
140
+ {/* <Timer
141
+ timer={timer}
142
+ setTimer={setTimer}
143
+ showTimerDropDown={showTimerDropDown}
144
+ setShowTimerDropDown={setShowTimerDropDown}
145
+ /> */}
146
+
147
+ <Button
148
+ variant="primary"
149
+ disabled={validateTitle}
150
+ css={{ mt: '$10' }}
151
+ onClick={async () => {
152
+ const id = Date.now().toString();
153
+ await actions.interactivityCenter
154
+ .createPoll({
155
+ id,
156
+ title,
157
+ anonymous,
158
+ rolesThatCanViewResponses: hideVoteCount && localPeerRoleName ? [localPeerRoleName] : undefined,
159
+ type: interactionType.toLowerCase(),
160
+ // duration: showTimerDropDown ? timer : undefined,
161
+ })
162
+ .then(() => handleCreate(id))
163
+ .catch(err => setError(err.message));
164
+ }}
165
+ >
166
+ Create {interactionType}
167
+ </Button>
168
+ <ErrorText error={error || titleError} />
169
+ </Flex>
170
+ </>
171
+ );
172
+ };
173
+
174
+ const PrevMenu = () => {
175
+ const polls = useHMSStore(selectPolls)?.filter(poll => poll.state === 'started' || poll.state === 'stopped');
176
+ return polls?.length ? (
177
+ <Flex
178
+ css={{
179
+ borderTop: '$space$px solid $border_bright',
180
+ mt: '$10',
181
+ pt: '$10',
182
+ }}
183
+ >
184
+ <Flex direction="column" css={{ w: '100%' }}>
185
+ <Text variant="h6" css={{ c: '$on_surface_high' }}>
186
+ Previous Polls and Quizzes
187
+ </Text>
188
+ <Flex direction="column" css={{ gap: '$10', mt: '$8' }}>
189
+ {polls.map(poll => (
190
+ <InteractionCard
191
+ key={poll.id}
192
+ id={poll.id}
193
+ title={poll.title}
194
+ isLive={poll.state === 'started'}
195
+ isTimed={(poll.duration || 0) > 0}
196
+ />
197
+ ))}
198
+ </Flex>
199
+ </Flex>
200
+ </Flex>
201
+ ) : null;
202
+ };
203
+
204
+ const InteractionCard = ({ id, title, isLive, isTimed }) => {
205
+ const { setPollState } = usePollViewState();
206
+
207
+ const goToVote = id => {
208
+ setPollState({
209
+ [POLL_STATE.pollInView]: id,
210
+ [POLL_STATE.view]: POLL_VIEWS.VOTE,
211
+ });
212
+ };
213
+
214
+ return (
215
+ <Flex direction="column" css={{ backgroundColor: '$surface_bright', borderRadius: '$1', p: '$8' }}>
216
+ <Flex css={{ w: '100%', justifyContent: 'space-between', mb: '$sm' }}>
217
+ <Text variant="sub1" css={{ c: '$on_surface_high', fontWeight: '$semiBold' }}>
218
+ {title}
219
+ </Text>
220
+ <StatusIndicator isLive={isLive} shouldShowTimer={isLive && isTimed} />
221
+ </Flex>
222
+ <Flex css={{ w: '100%', gap: '$4' }} justify="end">
223
+ <Button variant="primary" onClick={() => goToVote(id)}>
224
+ View
225
+ </Button>
226
+ </Flex>
227
+ </Flex>
228
+ );
229
+ };
@@ -0,0 +1,71 @@
1
+ // @ts-check
2
+ import React, { useRef, useState } from 'react';
3
+ import { Dropdown, Flex, Switch, Text } from '../../../../';
4
+ import { DialogDropdownTrigger } from '../../../primitives/DropdownTrigger';
5
+ import { useDropdownSelection } from '../../hooks/useDropdownSelection';
6
+
7
+ const timerSettings = {
8
+ 10: '10 secs',
9
+ 15: '15 secs',
10
+ 20: '20 secs',
11
+ 25: '25 secs',
12
+ 30: '30 secs',
13
+ 60: '1 min',
14
+ 120: '2 mins',
15
+ 300: '5 mins',
16
+ };
17
+
18
+ export const Timer = ({ timer, setTimer, showTimerDropDown, setShowTimerDropDown }) => {
19
+ const selectionBg = useDropdownSelection();
20
+ const [timerDropdownToggle, setTimerDropdownToggle] = useState(false);
21
+ const timerDropdownRef = useRef();
22
+
23
+ return (
24
+ <Flex justify="between" align="center" css={{ mt: '$10' }}>
25
+ <Flex align="center">
26
+ <Switch checked={showTimerDropDown} onCheckedChange={setShowTimerDropDown} css={{ mr: '$6' }} />
27
+ <Text variant="body2" css={{ c: '$on_surface_medium' }}>
28
+ Timer
29
+ </Text>
30
+ </Flex>
31
+ <Flex align="center">
32
+ {showTimerDropDown ? (
33
+ <Dropdown.Root open={timerDropdownToggle} onOpenChange={setTimerDropdownToggle}>
34
+ <DialogDropdownTrigger
35
+ ref={timerDropdownRef}
36
+ title={timerSettings[timer]}
37
+ open={timerDropdownToggle}
38
+ titleCss={{ c: '$on_surface_high', ml: '$md' }}
39
+ />
40
+ <Dropdown.Portal>
41
+ <Dropdown.Content
42
+ align="start"
43
+ sideOffset={8}
44
+ css={{
45
+ w: timerDropdownRef.current?.clientWidth,
46
+ zIndex: 1000,
47
+ }}
48
+ >
49
+ {Object.keys(timerSettings).map(value => {
50
+ const val = parseInt(value);
51
+ return (
52
+ <Dropdown.Item
53
+ key={value}
54
+ onSelect={() => setTimer(val)}
55
+ css={{
56
+ px: '$9',
57
+ bg: timer === val ? selectionBg : undefined,
58
+ }}
59
+ >
60
+ {timerSettings[val]}
61
+ </Dropdown.Item>
62
+ );
63
+ })}
64
+ </Dropdown.Content>
65
+ </Dropdown.Portal>
66
+ </Dropdown.Root>
67
+ ) : null}
68
+ </Flex>
69
+ </Flex>
70
+ );
71
+ };