@100mslive/roomkit-react 0.2.8-alpha.0 → 0.2.8-alpha.10

Sign up to get free protection for your applications and to get access to all the features.
Files changed (108) hide show
  1. package/dist/HLSView-FBEGJ3L7.js +1396 -0
  2. package/dist/HLSView-FBEGJ3L7.js.map +7 -0
  3. package/dist/Prebuilt/common/hooks.d.ts +3 -0
  4. package/dist/Prebuilt/components/Chat/MwebChatOption.d.ts +1 -1
  5. package/dist/Prebuilt/components/HMSVideo/FullscreenButton.d.ts +5 -0
  6. package/dist/Prebuilt/components/HMSVideo/HLSAutoplayBlockedPrompt.d.ts +5 -0
  7. package/dist/Prebuilt/components/HMSVideo/HLSCaptionSelector.d.ts +1 -2
  8. package/dist/Prebuilt/components/HMSVideo/HLSQualitySelector.d.ts +13 -0
  9. package/dist/Prebuilt/components/HMSVideo/MwebHLSViewTitle.d.ts +2 -0
  10. package/dist/Prebuilt/components/HMSVideo/PlayButton.d.ts +6 -0
  11. package/dist/Prebuilt/components/HMSVideo/PlayPauseButton.d.ts +6 -0
  12. package/dist/Prebuilt/components/HMSVideo/PlayerContext.d.ts +8 -0
  13. package/dist/Prebuilt/components/HMSVideo/SeekControls.d.ts +7 -0
  14. package/dist/Prebuilt/components/HMSVideo/VideoProgress.d.ts +5 -0
  15. package/dist/Prebuilt/components/HMSVideo/VideoTime.d.ts +2 -0
  16. package/dist/Prebuilt/components/HMSVideo/VolumeControl.d.ts +2 -0
  17. package/dist/Prebuilt/components/HMSVideo/index.d.ts +26 -0
  18. package/dist/Prebuilt/components/HMSVideo/utils.d.ts +8 -0
  19. package/dist/Prebuilt/components/Leave/DesktopLeaveRoom.d.ts +2 -1
  20. package/dist/Prebuilt/components/Leave/LeaveRoom.d.ts +2 -1
  21. package/dist/Prebuilt/components/Leave/MwebLeaveRoom.d.ts +2 -3
  22. package/dist/Prebuilt/components/MwebLandscapePrompt.d.ts +1 -1
  23. package/dist/Prebuilt/components/RaiseHand.d.ts +5 -0
  24. package/dist/Prebuilt/components/SidePaneTabs.d.ts +1 -1
  25. package/dist/Sheet/Sheet.d.ts +1 -0
  26. package/dist/{chunk-72B32WVR.js → chunk-R2JJJQR3.js} +1684 -1316
  27. package/dist/chunk-R2JJJQR3.js.map +7 -0
  28. package/dist/index.cjs.js +2866 -2053
  29. package/dist/index.cjs.js.map +4 -4
  30. package/dist/index.js +1 -1
  31. package/dist/meta.cjs.json +786 -299
  32. package/dist/meta.esbuild.json +805 -307
  33. package/package.json +7 -6
  34. package/src/Button/Button.tsx +4 -4
  35. package/src/Fieldset/Fieldset.tsx +1 -1
  36. package/src/Input/PasswordInput.stories.tsx +1 -1
  37. package/src/Pagination/StyledPagination.stories.tsx +2 -2
  38. package/src/Prebuilt/IconButton.tsx +1 -1
  39. package/src/Prebuilt/common/hooks.ts +21 -0
  40. package/src/Prebuilt/components/AppData/useSidepane.js +34 -7
  41. package/src/Prebuilt/components/AudioVideoToggle.tsx +2 -1
  42. package/src/Prebuilt/components/AuthToken.jsx +1 -1
  43. package/src/Prebuilt/components/Chat/Chat.tsx +41 -1
  44. package/src/Prebuilt/components/Chat/ChatFooter.tsx +33 -13
  45. package/src/Prebuilt/components/Chat/MwebChatOption.tsx +1 -1
  46. package/src/Prebuilt/components/ConferenceScreen.tsx +48 -7
  47. package/src/Prebuilt/components/EmojiReaction.jsx +33 -23
  48. package/src/Prebuilt/components/Footer/Footer.tsx +0 -1
  49. package/src/Prebuilt/components/Footer/RoleOptions.tsx +138 -125
  50. package/src/Prebuilt/components/HMSVideo/Controls.jsx +1 -1
  51. package/src/Prebuilt/components/HMSVideo/FullscreenButton.tsx +13 -0
  52. package/src/Prebuilt/components/HMSVideo/HLSAutoplayBlockedPrompt.tsx +72 -0
  53. package/src/Prebuilt/components/HMSVideo/HLSCaptionSelector.tsx +4 -2
  54. package/src/Prebuilt/components/HMSVideo/HLSQualitySelector.tsx +248 -0
  55. package/src/Prebuilt/components/HMSVideo/HMSVideo.jsx +17 -7
  56. package/src/Prebuilt/components/HMSVideo/MwebHLSViewTitle.tsx +84 -0
  57. package/src/Prebuilt/components/HMSVideo/PlayButton.tsx +27 -0
  58. package/src/Prebuilt/components/HMSVideo/PlayPauseButton.tsx +27 -0
  59. package/src/Prebuilt/components/HMSVideo/PlayerContext.tsx +15 -0
  60. package/src/Prebuilt/components/HMSVideo/SeekControls.tsx +22 -0
  61. package/src/Prebuilt/components/HMSVideo/VideoProgress.tsx +95 -0
  62. package/src/Prebuilt/components/HMSVideo/VideoTime.tsx +43 -0
  63. package/src/Prebuilt/components/HMSVideo/{VolumeControl.jsx → VolumeControl.tsx} +6 -4
  64. package/src/Prebuilt/components/HMSVideo/{index.js → index.ts} +6 -2
  65. package/src/Prebuilt/components/HMSVideo/{HMSVIdeoUtils.js → utils.ts} +5 -5
  66. package/src/Prebuilt/components/Header/StreamActions.tsx +1 -1
  67. package/src/Prebuilt/components/IconButtonWithOptions/IconButtonWithOptions.tsx +1 -1
  68. package/src/Prebuilt/components/Leave/DesktopLeaveRoom.tsx +50 -46
  69. package/src/Prebuilt/components/Leave/LeaveRoom.tsx +15 -4
  70. package/src/Prebuilt/components/Leave/MwebLeaveRoom.tsx +46 -27
  71. package/src/Prebuilt/components/MoreSettings/MoreSettings.tsx +3 -1
  72. package/src/Prebuilt/components/MoreSettings/SplitComponents/DesktopOptions.tsx +37 -31
  73. package/src/Prebuilt/components/MoreSettings/SplitComponents/MwebOptions.tsx +12 -8
  74. package/src/Prebuilt/components/MwebLandscapePrompt.tsx +14 -3
  75. package/src/Prebuilt/components/Notifications/HandRaisedNotifications.tsx +5 -2
  76. package/src/Prebuilt/components/Notifications/PeerNotifications.tsx +1 -1
  77. package/src/Prebuilt/components/Polls/Voting/QuestionCard.jsx +19 -8
  78. package/src/Prebuilt/components/Polls/Voting/Voting.tsx +3 -2
  79. package/src/Prebuilt/components/Polls/common/OptionInputWithDelete.tsx +1 -1
  80. package/src/Prebuilt/components/Polls/common/utils.ts +2 -2
  81. package/src/Prebuilt/components/RaiseHand.tsx +24 -0
  82. package/src/Prebuilt/components/RoomDetails/RoomDetailsPane.tsx +41 -14
  83. package/src/Prebuilt/components/SidePaneTabs.tsx +56 -48
  84. package/src/Prebuilt/components/StatsForNerds.jsx +14 -6
  85. package/src/Prebuilt/components/Streaming/Common.jsx +1 -1
  86. package/src/Prebuilt/components/TileMenu/TileMenuContent.tsx +2 -2
  87. package/src/Prebuilt/components/Toast/ToastBatcher.js +8 -1
  88. package/src/Prebuilt/components/Toast/ToastConfig.jsx +17 -0
  89. package/src/Prebuilt/components/VideoLayouts/RoleProminence.tsx +1 -1
  90. package/src/Prebuilt/components/hooks/useRoleProminencePeers.tsx +2 -1
  91. package/src/Prebuilt/components/pdfAnnotator/shareScreenOptions.jsx +2 -2
  92. package/src/Prebuilt/components/pdfAnnotator/uploadedFile.jsx +1 -1
  93. package/src/Prebuilt/layouts/HLSView.jsx +359 -178
  94. package/src/Prebuilt/layouts/SidePane.tsx +145 -59
  95. package/src/Prebuilt/layouts/VideoStreamingSection.tsx +22 -2
  96. package/src/Prebuilt/primitives/DialogContent.jsx +1 -1
  97. package/src/Prebuilt/provider/roomLayoutProvider/index.tsx +1 -1
  98. package/src/Sheet/Sheet.tsx +7 -3
  99. package/dist/HLSView-37B2YVTC.js +0 -987
  100. package/dist/HLSView-37B2YVTC.js.map +0 -7
  101. package/dist/chunk-72B32WVR.js.map +0 -7
  102. package/src/Prebuilt/components/HMSVideo/FullscreenButton.jsx +0 -18
  103. package/src/Prebuilt/components/HMSVideo/HLSAutoplayBlockedPrompt.jsx +0 -35
  104. package/src/Prebuilt/components/HMSVideo/HLSQualitySelector.jsx +0 -127
  105. package/src/Prebuilt/components/HMSVideo/PlayButton.jsx +0 -13
  106. package/src/Prebuilt/components/HMSVideo/VideoProgress.jsx +0 -76
  107. package/src/Prebuilt/components/HMSVideo/VideoTime.jsx +0 -33
  108. package/src/Prebuilt/components/RaiseHand.jsx +0 -17
@@ -1,4 +1,4 @@
1
- import React, { Fragment, useState } from 'react';
1
+ import React, { useState } from 'react';
2
2
  import { useMedia } from 'react-use';
3
3
  import data from '@emoji-mart/data/sets/14/apple.json';
4
4
  import { init } from 'emoji-mart';
@@ -7,9 +7,7 @@ import {
7
7
  selectIsConnectedToRoom,
8
8
  selectLocalPeerID,
9
9
  useCustomEvent,
10
- // useHMSActions,
11
10
  useHMSStore,
12
- // useRecordingStreaming,
13
11
  } from '@100mslive/react-sdk';
14
12
  import { EmojiIcon } from '@100mslive/react-icons';
15
13
  import { EmojiCard } from './Footer/EmojiCard';
@@ -20,11 +18,12 @@ import { config as cssConfig } from '../../Theme';
20
18
  import { Tooltip } from '../../Tooltip';
21
19
  import IconButton from '../IconButton';
22
20
  import { useDropdownList } from './hooks/useDropdownList';
21
+ import { useLandscapeHLSStream, useMobileHLSStream } from '../common/hooks';
23
22
  import { EMOJI_REACTION_TYPE } from '../common/constants';
24
23
 
25
24
  init({ data });
26
25
 
27
- export const EmojiReaction = () => {
26
+ export const EmojiReaction = ({ showCard = false }) => {
28
27
  const [open, setOpen] = useState(false);
29
28
  const isConnected = useHMSStore(selectIsConnectedToRoom);
30
29
  useDropdownList({ open: open, name: 'EmojiReaction' });
@@ -33,6 +32,9 @@ export const EmojiReaction = () => {
33
32
  const localPeerId = useHMSStore(selectLocalPeerID);
34
33
  // const { isStreamingOn } = useRecordingStreaming();
35
34
  const isMobile = useMedia(cssConfig.media.md);
35
+ const isLandscape = useMedia(cssConfig.media.ls);
36
+ const isMobileHLSStream = useMobileHLSStream();
37
+ const isLandscapeStream = useLandscapeHLSStream();
36
38
 
37
39
  const { sendEvent } = useCustomEvent({
38
40
  type: EMOJI_REACTION_TYPE,
@@ -65,24 +67,32 @@ export const EmojiReaction = () => {
65
67
  if (!isConnected) {
66
68
  return null;
67
69
  }
68
- return isMobile ? (
69
- <EmojiCard sendReaction={sendReaction} />
70
- ) : (
71
- <Fragment>
72
- <Dropdown.Root open={open} onOpenChange={setOpen}>
73
- <Dropdown.Trigger asChild data-testid="emoji_reaction_btn">
74
- <IconButton>
75
- <Tooltip title="Emoji reaction">
76
- <Box>
77
- <EmojiIcon />
78
- </Box>
79
- </Tooltip>
80
- </IconButton>
81
- </Dropdown.Trigger>
82
- <Dropdown.Content sideOffset={5} align="center" css={{ p: '$8', bg: '$surface_default' }}>
83
- <EmojiCard sendReaction={sendReaction} />
84
- </Dropdown.Content>
85
- </Dropdown.Root>
86
- </Fragment>
70
+
71
+ if (showCard) {
72
+ return <EmojiCard sendReaction={sendReaction} />;
73
+ }
74
+ return (
75
+ <Dropdown.Root open={open} onOpenChange={setOpen}>
76
+ <Dropdown.Trigger asChild data-testid="emoji_reaction_btn">
77
+ <IconButton
78
+ css={
79
+ isMobile || isLandscape ? { bg: '$surface_default', r: '$round', border: '1px solid $border_bright' } : {}
80
+ }
81
+ >
82
+ <Tooltip title="Emoji reaction">
83
+ <Box>
84
+ <EmojiIcon />
85
+ </Box>
86
+ </Tooltip>
87
+ </IconButton>
88
+ </Dropdown.Trigger>
89
+ <Dropdown.Content
90
+ sideOffset={5}
91
+ align={isMobileHLSStream || isLandscapeStream ? 'end' : 'center'}
92
+ css={{ p: '$8', bg: '$surface_default' }}
93
+ >
94
+ <EmojiCard sendReaction={sendReaction} />
95
+ </Dropdown.Content>
96
+ </Dropdown.Root>
87
97
  );
88
98
  };
@@ -12,7 +12,6 @@ import { EmojiReaction } from '../EmojiReaction';
12
12
  import { LeaveRoom } from '../Leave/LeaveRoom';
13
13
  // @ts-ignore: No implicit Any
14
14
  import { MoreSettings } from '../MoreSettings/MoreSettings';
15
- // @ts-ignore: No implicit Any
16
15
  import { RaiseHand } from '../RaiseHand';
17
16
  // @ts-ignore: No implicit Any
18
17
  import { ScreenshareToggle } from '../ScreenShareToggle';
@@ -1,12 +1,13 @@
1
1
  import React, { useState } from 'react';
2
2
  import { DefaultConferencingScreen_Elements } from '@100mslive/types-prebuilt';
3
+ import { match } from 'ts-pattern';
3
4
  import {
4
5
  HMSPeer,
5
6
  selectPermissions,
6
7
  selectRoleByRoleName,
8
+ selectTracksMap,
7
9
  useHMSActions,
8
10
  useHMSStore,
9
- useHMSVanillaStore,
10
11
  } from '@100mslive/react-sdk';
11
12
  import {
12
13
  MicOffIcon,
@@ -25,26 +26,75 @@ import { useRoomLayoutConferencingScreen } from '../../provider/roomLayoutProvid
25
26
  import { getMetadata } from '../../common/utils';
26
27
 
27
28
  const dropdownItemCSS = { backgroundColor: '$surface_default', gap: '$4', p: '$8' };
28
- const optionTextCSS = { fontWeight: '$semiBold', color: '$on_surface_high', textTransform: 'none' };
29
+ const optionTextCSS = {
30
+ fontWeight: '$semiBold',
31
+ color: '$on_surface_high',
32
+ textTransform: 'none',
33
+ whiteSpace: 'nowrap',
34
+ };
29
35
 
30
- const MuteUnmuteOption = ({ roleName, peerList }: { peerList: HMSPeer[]; roleName: string }) => {
31
- const vanillaStore = useHMSVanillaStore();
32
- const store = vanillaStore.getState();
33
- const hmsActions = useHMSActions();
36
+ const DropdownWrapper = ({ children }: { children: React.ReactNode }) => {
37
+ const [openOptions, setOpenOptions] = useState(false);
38
+ if (React.Children.toArray(children).length === 0) {
39
+ return null;
40
+ }
41
+ return (
42
+ <Dropdown.Root open={openOptions} onOpenChange={setOpenOptions}>
43
+ <Dropdown.Trigger
44
+ data-testid="role_group_options"
45
+ onClick={e => e.stopPropagation()}
46
+ className="role_actions"
47
+ asChild
48
+ css={{
49
+ p: '$1',
50
+ r: '$0',
51
+ c: '$on_surface_high',
52
+ visibility: openOptions ? 'visible' : 'hidden',
53
+ '&:hover': {
54
+ c: '$on_surface_medium',
55
+ },
56
+ '@md': {
57
+ visibility: 'visible',
58
+ },
59
+ }}
60
+ >
61
+ <Flex>
62
+ <VerticalMenuIcon />
63
+ </Flex>
64
+ </Dropdown.Trigger>
65
+ <Dropdown.Content
66
+ onClick={e => e.stopPropagation()}
67
+ css={{ w: 'max-content', bg: '$surface_default', py: 0 }}
68
+ align="end"
69
+ >
70
+ {children}
71
+ </Dropdown.Content>
72
+ </Dropdown.Root>
73
+ );
74
+ };
75
+
76
+ export const RoleOptions = ({ roleName, peerList }: { roleName: string; peerList: HMSPeer[] }) => {
34
77
  const permissions = useHMSStore(selectPermissions);
78
+ const hmsActions = useHMSActions();
79
+ const { elements } = useRoomLayoutConferencingScreen();
80
+ const { on_stage_role, off_stage_roles = [] } = (elements as DefaultConferencingScreen_Elements)?.on_stage_exp || {};
81
+ const canRemoveRoleFromStage = permissions?.changeRole && roleName === on_stage_role;
35
82
  const role = useHMSStore(selectRoleByRoleName(roleName));
83
+ const canPublishAudio = role.publishParams.allowed.includes('audio');
84
+ const canPublishVideo = role.publishParams.allowed.includes('video');
85
+ const tracks = useHMSStore(selectTracksMap);
36
86
 
37
- let allPeersHaveVideoOn = true;
38
- let allPeersHaveAudioOn = true;
87
+ let isVideoOnForSomePeers = false;
88
+ let isAudioOnForSomePeers = false;
39
89
 
40
90
  peerList.forEach(peer => {
41
91
  if (peer.isLocal) {
42
92
  return;
43
93
  }
44
- const isAudioOn = !!peer.audioTrack && store.tracks[peer.audioTrack]?.enabled;
45
- const isVideoOn = !!peer.videoTrack && store.tracks[peer.videoTrack]?.enabled;
46
- allPeersHaveAudioOn = allPeersHaveAudioOn && isAudioOn;
47
- allPeersHaveVideoOn = allPeersHaveVideoOn && isVideoOn;
94
+ const isAudioOn = !!peer.audioTrack && tracks[peer.audioTrack]?.enabled;
95
+ const isVideoOn = !!peer.videoTrack && tracks[peer.videoTrack]?.enabled;
96
+ isAudioOnForSomePeers = isAudioOnForSomePeers || isAudioOn;
97
+ isVideoOnForSomePeers = isVideoOnForSomePeers || isVideoOn;
48
98
  });
49
99
 
50
100
  const setTrackEnabled = async (type: 'audio' | 'video', enabled = false) => {
@@ -55,68 +105,16 @@ const MuteUnmuteOption = ({ roleName, peerList }: { peerList: HMSPeer[]; roleNam
55
105
  }
56
106
  };
57
107
 
58
- return (
59
- <>
60
- {role.publishParams.allowed?.includes('audio') && (
61
- <>
62
- {allPeersHaveAudioOn && permissions?.mute ? (
63
- <Dropdown.Item css={dropdownItemCSS} onClick={() => setTrackEnabled('audio', false)}>
64
- <MicOffIcon />
65
- <Text variant="sm" css={optionTextCSS}>
66
- Mute Audio
67
- </Text>
68
- </Dropdown.Item>
69
- ) : null}
70
-
71
- {!allPeersHaveAudioOn && permissions?.unmute ? (
72
- <Dropdown.Item css={dropdownItemCSS} onClick={() => setTrackEnabled('audio', true)}>
73
- <MicOnIcon />
74
- <Text variant="sm" css={optionTextCSS}>
75
- Unmute Audio
76
- </Text>
77
- </Dropdown.Item>
78
- ) : null}
79
- </>
80
- )}
81
-
82
- {role.publishParams.allowed?.includes('audio') && (
83
- <>
84
- {allPeersHaveVideoOn && permissions?.mute ? (
85
- <Dropdown.Item css={dropdownItemCSS} onClick={() => setTrackEnabled('video', false)}>
86
- <VideoOffIcon />
87
- <Text variant="sm" css={optionTextCSS}>
88
- Mute Video
89
- </Text>
90
- </Dropdown.Item>
91
- ) : null}
92
-
93
- {!allPeersHaveVideoOn && permissions?.unmute ? (
94
- <Dropdown.Item css={dropdownItemCSS} onClick={() => setTrackEnabled('video', true)}>
95
- <VideoOnIcon />
96
- <Text variant="sm" css={optionTextCSS}>
97
- Unmute Video
98
- </Text>
99
- </Dropdown.Item>
100
- ) : null}
101
- </>
102
- )}
103
- </>
104
- );
105
- };
106
-
107
- export const RoleOptions = ({ roleName, peerList }: { roleName: string; peerList: HMSPeer[] }) => {
108
- const [openOptions, setOpenOptions] = useState(false);
109
- const permissions = useHMSStore(selectPermissions);
110
- const hmsActions = useHMSActions();
111
- const { elements } = useRoomLayoutConferencingScreen();
112
- const { on_stage_role, off_stage_roles = [] } = (elements as DefaultConferencingScreen_Elements)?.on_stage_exp || {};
113
- const canMuteOrUnmute = permissions?.mute || permissions?.unmute;
114
- const canRemoveRoleFromStage = permissions?.changeRole && roleName === on_stage_role;
115
108
  // on stage and off stage roles
116
109
  const canRemoveRoleFromRoom =
117
110
  permissions?.removeOthers && (on_stage_role === roleName || off_stage_roles?.includes(roleName));
118
111
 
119
- if (!(canMuteOrUnmute || canRemoveRoleFromStage || canRemoveRoleFromRoom) || peerList.length === 0) {
112
+ if (
113
+ peerList.length === 0 ||
114
+ // if only local peer is present no need to show any options
115
+ (peerList.length === 1 && peerList[0].isLocal) ||
116
+ !role
117
+ ) {
120
118
  return null;
121
119
  }
122
120
 
@@ -140,60 +138,75 @@ export const RoleOptions = ({ roleName, peerList }: { roleName: string; peerList
140
138
  };
141
139
 
142
140
  return (
143
- <Dropdown.Root open={openOptions} onOpenChange={setOpenOptions}>
144
- <Dropdown.Trigger
145
- data-testid="role_group_options"
146
- onClick={e => e.stopPropagation()}
147
- className="role_actions"
148
- asChild
149
- css={{
150
- p: '$1',
151
- r: '$0',
152
- c: '$on_surface_high',
153
- visibility: openOptions ? 'visible' : 'hidden',
154
- '&:hover': {
155
- c: '$on_surface_medium',
156
- },
157
- '@md': {
158
- visibility: 'visible',
159
- },
160
- }}
161
- >
162
- <Flex>
163
- <VerticalMenuIcon />
164
- </Flex>
165
- </Dropdown.Trigger>
166
- <Dropdown.Content
167
- onClick={e => e.stopPropagation()}
168
- css={{ w: 'max-content', maxWidth: '$64', bg: '$surface_default', py: 0 }}
169
- align="end"
170
- >
171
- {canRemoveRoleFromStage && (
172
- <Dropdown.Item
173
- css={{ ...dropdownItemCSS, borderBottom: '1px solid $border_bright' }}
174
- onClick={removeAllFromStage}
175
- >
176
- <PersonRectangleIcon />
177
- <Text variant="sm" css={optionTextCSS}>
178
- Remove all from Stage
179
- </Text>
180
- </Dropdown.Item>
181
- )}
182
-
183
- {canMuteOrUnmute && <MuteUnmuteOption peerList={peerList} roleName={roleName} />}
184
-
185
- {canRemoveRoleFromRoom && (
186
- <Dropdown.Item
187
- css={{ ...dropdownItemCSS, borderTop: '1px solid $border_bright', color: '$alert_error_default' }}
188
- onClick={removePeersFromRoom}
189
- >
190
- <RemoveUserIcon />
191
- <Text variant="sm" css={{ ...optionTextCSS, color: 'inherit' }}>
192
- Remove all from Room
193
- </Text>
194
- </Dropdown.Item>
195
- )}
196
- </Dropdown.Content>
197
- </Dropdown.Root>
141
+ <DropdownWrapper>
142
+ {canRemoveRoleFromStage ? (
143
+ <Dropdown.Item
144
+ css={{ ...dropdownItemCSS, borderBottom: '1px solid $border_bright' }}
145
+ onClick={removeAllFromStage}
146
+ >
147
+ <PersonRectangleIcon />
148
+ <Text variant="sm" css={optionTextCSS}>
149
+ Remove all from Stage
150
+ </Text>
151
+ </Dropdown.Item>
152
+ ) : null}
153
+
154
+ {match({ canPublishAudio, isAudioOnForSomePeers, canMute: permissions?.mute, canUnmute: permissions?.unmute })
155
+ .with({ canPublishAudio: true, isAudioOnForSomePeers: true, canMute: true }, () => {
156
+ return (
157
+ <Dropdown.Item css={dropdownItemCSS} onClick={() => setTrackEnabled('audio', false)}>
158
+ <MicOffIcon />
159
+ <Text variant="sm" css={optionTextCSS}>
160
+ Mute Audio for All
161
+ </Text>
162
+ </Dropdown.Item>
163
+ );
164
+ })
165
+ .with({ canPublishAudio: true, isAudioOnForSomePeers: false, canUnmute: true }, () => {
166
+ return (
167
+ <Dropdown.Item css={dropdownItemCSS} onClick={() => setTrackEnabled('audio', true)}>
168
+ <MicOnIcon />
169
+ <Text variant="sm" css={optionTextCSS}>
170
+ Request to Unmute Audio for All
171
+ </Text>
172
+ </Dropdown.Item>
173
+ );
174
+ })
175
+ .otherwise(() => null)}
176
+ {match({ canPublishVideo, isVideoOnForSomePeers, canMute: permissions?.mute, canUnmute: permissions?.unmute })
177
+ .with({ canPublishVideo: true, isVideoOnForSomePeers: true, canMute: true }, () => {
178
+ return (
179
+ <Dropdown.Item css={dropdownItemCSS} onClick={() => setTrackEnabled('video', false)}>
180
+ <VideoOffIcon />
181
+ <Text variant="sm" css={optionTextCSS}>
182
+ Mute Video for All
183
+ </Text>
184
+ </Dropdown.Item>
185
+ );
186
+ })
187
+ .with({ canPublishVideo: true, isVideoOnForSomePeers: false, canUnmute: true }, () => {
188
+ return (
189
+ <Dropdown.Item css={dropdownItemCSS} onClick={() => setTrackEnabled('video', true)}>
190
+ <VideoOnIcon />
191
+ <Text variant="sm" css={optionTextCSS}>
192
+ Request to Unmute Video for All
193
+ </Text>
194
+ </Dropdown.Item>
195
+ );
196
+ })
197
+ .otherwise(() => null)}
198
+
199
+ {canRemoveRoleFromRoom ? (
200
+ <Dropdown.Item
201
+ css={{ ...dropdownItemCSS, borderTop: '1px solid $border_bright', color: '$alert_error_default' }}
202
+ onClick={removePeersFromRoom}
203
+ >
204
+ <RemoveUserIcon />
205
+ <Text variant="sm" css={{ ...optionTextCSS, color: 'inherit' }}>
206
+ Remove all from Room
207
+ </Text>
208
+ </Dropdown.Item>
209
+ ) : null}
210
+ </DropdownWrapper>
198
211
  );
199
212
  };
@@ -1,4 +1,4 @@
1
- import { Flex, styled } from '../../../';
1
+ import { Flex, styled } from '../../..';
2
2
 
3
3
  export const VideoControls = styled(Flex, {
4
4
  justifyContent: 'center',
@@ -0,0 +1,13 @@
1
+ import React from 'react';
2
+ import { ExpandIcon, ShrinkIcon } from '@100mslive/react-icons';
3
+ import { Flex, IconButton, Tooltip } from '../../..';
4
+
5
+ export const FullScreenButton = ({ isFullScreen, onToggle }: { isFullScreen: boolean; onToggle: () => void }) => {
6
+ return (
7
+ <Tooltip title={`${isFullScreen ? 'Exit' : 'Go'} fullscreen`} side="top">
8
+ <IconButton css={{ margin: '0px' }} onClick={onToggle} key="fullscreen_btn" data-testid="fullscreen_btn">
9
+ <Flex>{isFullScreen ? <ShrinkIcon /> : <ExpandIcon />}</Flex>
10
+ </IconButton>
11
+ </Tooltip>
12
+ );
13
+ };
@@ -0,0 +1,72 @@
1
+ import React from 'react';
2
+ import { useMedia } from 'react-use';
3
+ import { VolumeTwoIcon } from '@100mslive/react-icons';
4
+ import { Button, config, Dialog, IconButton, Text } from '../../..';
5
+ // @ts-ignore
6
+ import { DialogContent, DialogRow } from '../../primitives/DialogContent';
7
+ import { useIsLandscape } from '../../common/hooks';
8
+
9
+ export function HLSAutoplayBlockedPrompt({
10
+ open,
11
+ unblockAutoPlay,
12
+ }: {
13
+ open: boolean;
14
+ unblockAutoPlay: () => Promise<void>;
15
+ }) {
16
+ const isLandscape = useIsLandscape();
17
+ const isMobile = useMedia(config.media.md);
18
+ if ((isMobile || isLandscape) && open) {
19
+ return (
20
+ <IconButton
21
+ css={{
22
+ border: '1px solid white',
23
+ bg: 'white',
24
+ color: '#000',
25
+ r: '$2',
26
+ }}
27
+ onClick={async () => await unblockAutoPlay()}
28
+ >
29
+ <VolumeTwoIcon width="32" height="32" />
30
+ <Text
31
+ variant="body1"
32
+ css={{
33
+ fontWeight: '$semiBold',
34
+ px: '$2',
35
+ color: '#000',
36
+ }}
37
+ >
38
+ Tap To Unmute
39
+ </Text>
40
+ </IconButton>
41
+ );
42
+ }
43
+ return (
44
+ <Dialog.Root
45
+ open={open}
46
+ onOpenChange={async value => {
47
+ if (!value) {
48
+ await unblockAutoPlay();
49
+ }
50
+ }}
51
+ >
52
+ <DialogContent title="Attention" closeable={false}>
53
+ <DialogRow>
54
+ <Text variant="md">
55
+ The browser wants us to get a confirmation for playing the HLS Stream. Please click "play stream" to
56
+ proceed.
57
+ </Text>
58
+ </DialogRow>
59
+ <DialogRow justify="end">
60
+ <Button
61
+ variant="primary"
62
+ onClick={async () => {
63
+ await unblockAutoPlay();
64
+ }}
65
+ >
66
+ Play stream
67
+ </Button>
68
+ </DialogRow>
69
+ </DialogContent>
70
+ </Dialog.Root>
71
+ );
72
+ }
@@ -1,11 +1,13 @@
1
1
  import React from 'react';
2
2
  import { ClosedCaptionIcon, OpenCaptionIcon } from '@100mslive/react-icons';
3
3
  import { IconButton, Tooltip } from '../../../';
4
+ import { useHMSPlayerContext } from './PlayerContext';
4
5
 
5
- export function HLSCaptionSelector({ isEnabled, onClick }: { isEnabled: boolean; onClick: () => void }) {
6
+ export function HLSCaptionSelector({ isEnabled }: { isEnabled: boolean }) {
7
+ const { hlsPlayer } = useHMSPlayerContext();
6
8
  return (
7
9
  <Tooltip title="Subtitles/closed captions" side="top">
8
- <IconButton css={{ p: '$2' }} onClick={() => onClick()}>
10
+ <IconButton css={{ p: '$2' }} onClick={() => hlsPlayer?.toggleCaption()}>
9
11
  {isEnabled ? <ClosedCaptionIcon width="20" height="20px" /> : <OpenCaptionIcon width="20" height="20px" />}
10
12
  </IconButton>
11
13
  </Tooltip>