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

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 (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
package/package.json CHANGED
@@ -10,7 +10,7 @@
10
10
  "prebuilt",
11
11
  "roomkit"
12
12
  ],
13
- "version": "0.2.8-alpha.0",
13
+ "version": "0.2.8-alpha.10",
14
14
  "author": "100ms",
15
15
  "license": "MIT",
16
16
  "repository": {
@@ -82,11 +82,11 @@
82
82
  "react": ">=17.0.2 <19.0.0"
83
83
  },
84
84
  "dependencies": {
85
- "@100mslive/hls-player": "0.2.8-alpha.0",
85
+ "@100mslive/hls-player": "0.2.8-alpha.10",
86
86
  "@100mslive/hms-noise-cancellation": "0.0.0-alpha.1",
87
- "@100mslive/hms-virtual-background": "1.12.8-alpha.0",
88
- "@100mslive/react-icons": "0.9.8-alpha.0",
89
- "@100mslive/react-sdk": "0.9.8-alpha.0",
87
+ "@100mslive/hms-virtual-background": "1.12.8-alpha.10",
88
+ "@100mslive/react-icons": "0.9.8-alpha.10",
89
+ "@100mslive/react-sdk": "0.9.8-alpha.10",
90
90
  "@100mslive/types-prebuilt": "0.12.7",
91
91
  "@emoji-mart/data": "^1.0.6",
92
92
  "@emoji-mart/react": "^1.0.1",
@@ -118,8 +118,9 @@
118
118
  "react-window": "^1.8.7",
119
119
  "recordrtc": "^5.6.2",
120
120
  "screenfull": "^5.1.0",
121
+ "ts-pattern": "4.3.0",
121
122
  "uuid": "^8.3.2",
122
123
  "worker-timers": "^7.0.40"
123
124
  },
124
- "gitHead": "9eade912c3121837ed2b09ef0047bfbdb6f7cdf2"
125
+ "gitHead": "741a12014783f22c7302df3cbd3b01f2e343c16f"
125
126
  }
@@ -20,22 +20,22 @@ const getOutlinedVariants = (
20
20
  textDisabled: string,
21
21
  ) => {
22
22
  return {
23
- bg: '$transparent',
23
+ bg: 'transparent',
24
24
  border: `solid $space$px $colors${base}`,
25
25
  c: text,
26
26
  '&[disabled]': {
27
27
  c: textDisabled,
28
- bg: '$transparent',
28
+ bg: 'transparent',
29
29
  border: `solid $space$px $colors${disabled}`,
30
30
  cursor: 'not-allowed',
31
31
  },
32
32
  '&:not([disabled]):hover': {
33
33
  border: `solid $space$px $colors${hover}`,
34
- bg: '$transparent',
34
+ bg: 'transparent',
35
35
  },
36
36
  '&:not([disabled]):active': {
37
37
  border: `solid $space$px $colors${active}`,
38
- bg: '$transparent',
38
+ bg: 'transparent',
39
39
  },
40
40
  '&:not([disabled]):focus-visible': {
41
41
  boxShadow: `0 0 0 3px $colors${base}`,
@@ -5,7 +5,7 @@ const StyledFieldset = styled('fieldset', {
5
5
  alignItems: 'center',
6
6
  justifyContent: 'space-between',
7
7
  border: 'none',
8
- backgroundColor: '$transparent',
8
+ backgroundColor: 'transparent',
9
9
  });
10
10
 
11
11
  export const Fieldset = StyledFieldset;
@@ -25,7 +25,7 @@ const Template: ComponentStory<typeof PasswordInput.Root> = args => {
25
25
  showPassword={showPassword}
26
26
  onChange={e => setText(e.target.value)}
27
27
  />
28
- <PasswordInput.Icons ref={ref} css={{ bg: '$transparent' }}>
28
+ <PasswordInput.Icons ref={ref} css={{ bg: 'transparent' }}>
29
29
  <PasswordInput.ShowIcon
30
30
  showPassword={showPassword}
31
31
  onClick={() => {
@@ -41,7 +41,7 @@ const PaginationComponent = ({ page: propsPage, setPage: propsSetPage, numPages
41
41
  disabled={disableLeft}
42
42
  onClick={prevPage}
43
43
  type="button"
44
- css={{ padding: 0, border: 'none', backgroundColor: '$transparent' }}
44
+ css={{ padding: 0, border: 'none', backgroundColor: 'transparent' }}
45
45
  >
46
46
  <ChevronLeftIcon width={16} height={16} style={{ cursor: disableLeft ? 'not-allowed' : 'pointer' }} />
47
47
  </StyledPagination.Chevron>
@@ -54,7 +54,7 @@ const PaginationComponent = ({ page: propsPage, setPage: propsSetPage, numPages
54
54
  disabled={disableRight}
55
55
  onClick={nextPage}
56
56
  type="button"
57
- css={{ padding: 0, border: 'none', backgroundColor: '$transparent' }}
57
+ css={{ padding: 0, border: 'none', backgroundColor: 'transparent' }}
58
58
  >
59
59
  <ChevronRightIcon width={16} height={16} style={{ cursor: disableRight ? 'not-allowed' : 'pointer' }} />
60
60
  </StyledPagination.Chevron>
@@ -11,7 +11,7 @@ const IconButton = styled(BaseIconButton, {
11
11
  active: {
12
12
  true: {
13
13
  color: '$on_surface_high',
14
- backgroundColor: '$transparent',
14
+ backgroundColor: 'transparent',
15
15
  },
16
16
  false: {
17
17
  border: '1px solid transparent',
@@ -1,6 +1,8 @@
1
1
  import { useEffect, useRef, useState } from 'react';
2
+ import { useMedia } from 'react-use';
2
3
  import { JoinForm_JoinBtnType } from '@100mslive/types-prebuilt/elements/join_form';
3
4
  import {
5
+ parsedUserAgent,
4
6
  selectAvailableRoleNames,
5
7
  selectIsConnectedToRoom,
6
8
  selectPeerCount,
@@ -10,6 +12,7 @@ import {
10
12
  useHMSStore,
11
13
  useHMSVanillaStore,
12
14
  } from '@100mslive/react-sdk';
15
+ import { config } from '../../Theme';
13
16
  import { useRoomLayout } from '../provider/roomLayoutProvider';
14
17
  import { useRoomLayoutConferencingScreen } from '../provider/roomLayoutProvider/hooks/useRoomLayoutScreen';
15
18
  import { CHAT_SELECTOR } from './constants';
@@ -100,3 +103,21 @@ export const useParticipants = (params?: { metadata?: { isHandRaised?: boolean }
100
103
  }
101
104
  return { participants: participantList, isConnected, peerCount, rolesWithParticipants };
102
105
  };
106
+
107
+ export const useIsLandscape = () => {
108
+ const isMobile = parsedUserAgent.getDevice().type === 'mobile';
109
+ const isLandscape = useMedia(config.media.ls);
110
+ return isMobile && isLandscape;
111
+ };
112
+
113
+ export const useLandscapeHLSStream = () => {
114
+ const isLandscape = useIsLandscape();
115
+ const { screenType } = useRoomLayoutConferencingScreen();
116
+ return isLandscape && screenType === 'hls_live_streaming';
117
+ };
118
+
119
+ export const useMobileHLSStream = () => {
120
+ const isMobile = useMedia(config.media.md);
121
+ const { screenType } = useRoomLayoutConferencingScreen();
122
+ return isMobile && screenType === 'hls_live_streaming';
123
+ };
@@ -1,4 +1,5 @@
1
1
  import { useCallback } from 'react';
2
+ import { match, P } from 'ts-pattern';
2
3
  import { selectAppData, useHMSActions, useHMSStore, useHMSVanillaStore } from '@100mslive/react-sdk';
3
4
  import { usePollViewState } from './useUISettings';
4
5
  import { APP_DATA, POLL_STATE, POLL_VIEWS, SIDE_PANE_OPTIONS } from '../../common/constants';
@@ -45,13 +46,39 @@ export const usePollViewToggle = () => {
45
46
 
46
47
  const togglePollView = useCallback(
47
48
  id => {
48
- id = typeof id === 'string' ? id : undefined;
49
- const newView = id ? POLL_VIEWS.VOTE : isOpen && view ? null : POLL_VIEWS.CREATE_POLL_QUIZ;
50
- setPollState({
51
- [POLL_STATE.pollInView]: id,
52
- [POLL_STATE.view]: newView,
53
- });
54
- hmsActions.setAppData(APP_DATA.sidePane, newView ? SIDE_PANE_OPTIONS.POLLS : '');
49
+ match({ id, isOpen, view })
50
+ .with(
51
+ {
52
+ id: P.string,
53
+ },
54
+ () => {
55
+ setPollState({
56
+ [POLL_STATE.pollInView]: id,
57
+ [POLL_STATE.view]: POLL_VIEWS.VOTE,
58
+ });
59
+ hmsActions.setAppData(APP_DATA.sidePane, SIDE_PANE_OPTIONS.POLLS);
60
+ },
61
+ )
62
+ .with(
63
+ {
64
+ isOpen: true,
65
+ view: P.when(view => !!view),
66
+ },
67
+ () => {
68
+ setPollState({
69
+ [POLL_STATE.pollInView]: undefined,
70
+ [POLL_STATE.view]: null,
71
+ });
72
+ hmsActions.setAppData(APP_DATA.sidePane, '');
73
+ },
74
+ )
75
+ .otherwise(() => {
76
+ setPollState({
77
+ [POLL_STATE.pollInView]: undefined,
78
+ [POLL_STATE.view]: POLL_VIEWS.CREATE_POLL_QUIZ,
79
+ });
80
+ hmsActions.setAppData(APP_DATA.sidePane, SIDE_PANE_OPTIONS.POLLS);
81
+ });
55
82
  },
56
83
  [hmsActions, view, setPollState, isOpen],
57
84
  );
@@ -57,11 +57,12 @@ export const Options = ({
57
57
  <Dropdown.Item
58
58
  key={option.label}
59
59
  css={{
60
- backgroundColor: selectedDeviceId === option.deviceId ? '$surface_bright' : '$surface_dim',
60
+ backgroundColor: '$surface_dim',
61
61
  p: '$4 $8',
62
62
  h: '$15',
63
63
  fontSize: '$xs',
64
64
  justifyContent: 'space-between',
65
+ color: selectedDeviceId === option.deviceId ? '$primary_bright' : '',
65
66
  }}
66
67
  onClick={() => {
67
68
  onClick(option.deviceId);
@@ -70,7 +70,7 @@ const AuthToken = React.memo(({ authTokenByRoomCodeEndpoint, defaultAuthToken })
70
70
  alignItems: 'center',
71
71
  }}
72
72
  >
73
- <img src={errorImage} height={80} width={80} />
73
+ <img src={errorImage} height={80} width={80} alt="Token Error" />
74
74
  <Text variant="h4" css={{ textAlign: 'center', mb: '$4', mt: '$10' }}>
75
75
  {error.title}
76
76
  </Text>
@@ -2,16 +2,20 @@ import React, { MutableRefObject, useCallback, useRef } from 'react';
2
2
  import { useMedia } from 'react-use';
3
3
  import { VariableSizeList } from 'react-window';
4
4
  import { selectSessionStore, selectUnreadHMSMessagesCount } from '@100mslive/hms-video-store';
5
+ import { match } from 'ts-pattern';
5
6
  import { selectHMSMessagesCount, useHMSActions, useHMSStore, useHMSVanillaStore } from '@100mslive/react-sdk';
6
7
  import { ChevronDownIcon } from '@100mslive/react-icons';
7
8
  import { Button } from '../../../Button';
8
- import { Flex } from '../../../Layout';
9
+ import { Box, Flex } from '../../../Layout';
9
10
  import { config as cssConfig } from '../../../Theme';
11
+ // @ts-ignore: No implicit any
12
+ import { EmojiReaction } from '../EmojiReaction';
10
13
  import { ChatBody } from './ChatBody';
11
14
  import { ChatFooter } from './ChatFooter';
12
15
  import { ChatBlocked, ChatPaused } from './ChatStates';
13
16
  import { PinnedMessage } from './PinnedMessage';
14
17
  import { useRoomLayoutConferencingScreen } from '../../provider/roomLayoutProvider/hooks/useRoomLayoutScreen';
18
+ import { useLandscapeHLSStream, useMobileHLSStream } from '../../common/hooks';
15
19
  import { SESSION_STORE_KEY } from '../../common/constants';
16
20
 
17
21
  export const Chat = () => {
@@ -21,6 +25,9 @@ export const Chat = () => {
21
25
  const vanillaStore = useHMSVanillaStore();
22
26
  const { enabled: isChatEnabled = true } = useHMSStore(selectSessionStore(SESSION_STORE_KEY.CHAT_STATE)) || {};
23
27
  const isMobile = useMedia(cssConfig.media.md);
28
+ const isMobileHLSStream = useMobileHLSStream();
29
+ const isLandscapeStream = useLandscapeHLSStream();
30
+
24
31
  const scrollToBottom = useCallback(
25
32
  (unreadCount = 0) => {
26
33
  if (listRef.current && listRef.current.scrollToItem && unreadCount > 0) {
@@ -46,6 +53,7 @@ export const Chat = () => {
46
53
  >
47
54
  {isMobile && elements?.chat?.is_overlay ? null : <PinnedMessage />}
48
55
  <ChatBody ref={listRef} scrollToBottom={scrollToBottom} />
56
+
49
57
  <ChatPaused />
50
58
  <ChatBlocked />
51
59
  {isMobile && elements?.chat?.is_overlay ? <PinnedMessage /> : null}
@@ -54,6 +62,38 @@ export const Chat = () => {
54
62
  <NewMessageIndicator scrollToBottom={scrollToBottom} listRef={listRef} />
55
63
  </ChatFooter>
56
64
  ) : null}
65
+ {(isMobileHLSStream || isLandscapeStream) && (
66
+ <Box
67
+ css={{
68
+ position: 'absolute',
69
+ ...match({ isLandscapeStream, isChatEnabled })
70
+ .with(
71
+ {
72
+ isLandscapeStream: true,
73
+ isChatEnabled: true,
74
+ },
75
+ () => ({ bottom: '$19', right: '$10' }),
76
+ )
77
+ .with(
78
+ {
79
+ isLandscapeStream: true,
80
+ isChatEnabled: false,
81
+ },
82
+ () => ({ bottom: '$20', right: '$10' }),
83
+ )
84
+ .with(
85
+ {
86
+ isLandscapeStream: false,
87
+ isChatEnabled: true,
88
+ },
89
+ () => ({ bottom: '$20', right: '$8' }),
90
+ )
91
+ .otherwise(() => ({})),
92
+ }}
93
+ >
94
+ <EmojiReaction />
95
+ </Box>
96
+ )}
57
97
  </Flex>
58
98
  );
59
99
  };
@@ -2,22 +2,24 @@ import React, { ReactNode, useCallback, useEffect, useRef, useState } from 'reac
2
2
  import { useMedia } from 'react-use';
3
3
  import data from '@emoji-mart/data';
4
4
  import Picker from '@emoji-mart/react';
5
- import { HMSException, selectLocalPeer, useHMSActions, useHMSStore } from '@100mslive/react-sdk';
5
+ import { HMSException, selectLocalPeer, useAVToggle, useHMSActions, useHMSStore } from '@100mslive/react-sdk';
6
6
  import { EmojiIcon, PauseCircleIcon, SendIcon, VerticalMenuIcon } from '@100mslive/react-icons';
7
7
  import { Box, config as cssConfig, Flex, IconButton as BaseIconButton, Popover, styled, Text } from '../../..';
8
8
  import { IconButton } from '../../../IconButton';
9
- // @ts-ignore
9
+ import { MoreSettings } from '../MoreSettings/MoreSettings';
10
+ import { RaiseHand } from '../RaiseHand';
11
+ // @ts-ignore: No implicit any
10
12
  import { ToastManager } from '../Toast/ToastManager';
11
13
  import { ChatSelectorContainer } from './ChatSelectorContainer';
12
14
  import { useRoomLayoutConferencingScreen } from '../../provider/roomLayoutProvider/hooks/useRoomLayoutScreen';
13
- // @ts-ignore
15
+ // @ts-ignore: No implicit any
14
16
  import { useChatDraftMessage } from '../AppData/useChatState';
15
- // @ts-ignore
17
+ // @ts-ignore: No implicit any
16
18
  import { useSetSubscribedChatSelector, useSubscribeChatSelector } from '../AppData/useUISettings';
17
19
  import { useIsPeerBlacklisted } from '../hooks/useChatBlacklist';
18
- // @ts-ignore
20
+ // @ts-ignore: No implicit any
19
21
  import { useEmojiPickerStyles } from './useEmojiPickerStyles';
20
- import { useDefaultChatSelection } from '../../common/hooks';
22
+ import { useDefaultChatSelection, useLandscapeHLSStream, useMobileHLSStream } from '../../common/hooks';
21
23
  import { CHAT_SELECTOR, SESSION_STORE_KEY } from '../../common/constants';
22
24
 
23
25
  const TextArea = styled('textarea', {
@@ -77,7 +79,7 @@ export const ChatFooter = ({ onSend, children }: { onSend: (count: number) => vo
77
79
  const inputRef = useRef<HTMLTextAreaElement>(null);
78
80
  const [draftMessage, setDraftMessage] = useChatDraftMessage();
79
81
  const isMobile = useMedia(cssConfig.media.md);
80
- const { elements } = useRoomLayoutConferencingScreen();
82
+ const { elements, screenType } = useRoomLayoutConferencingScreen();
81
83
  const message_placeholder = elements?.chat?.message_placeholder || 'Send a message';
82
84
  const localPeer = useHMSStore(selectLocalPeer);
83
85
  const isOverlayChat = elements?.chat?.is_overlay;
@@ -87,18 +89,21 @@ export const ChatFooter = ({ onSend, children }: { onSend: (count: number) => vo
87
89
  const defaultSelection = useDefaultChatSelection();
88
90
  const selection = selectedPeer.name || selectedRole || defaultSelection;
89
91
  const isLocalPeerBlacklisted = useIsPeerBlacklisted({ local: true });
92
+ const { toggleAudio, toggleVideo } = useAVToggle();
93
+ const noAVPermissions = !(toggleAudio || toggleVideo);
94
+ const isMwebHLSStream = useMobileHLSStream();
95
+ const isLandscapeHLSStream = useLandscapeHLSStream();
90
96
 
91
97
  useEffect(() => {
92
98
  if (!selectedPeer.id && !selectedRole && !['Everyone', ''].includes(defaultSelection)) {
93
99
  setRoleSelector(defaultSelection);
94
100
  } else {
95
101
  // @ts-ignore
96
- if (!elements?.chat?.disable_autofocus) {
102
+ if (!(isMobile || isLandscapeHLSStream) && !elements?.chat?.disable_autofocus) {
97
103
  inputRef.current?.focus();
98
104
  }
99
105
  }
100
- // @ts-ignore
101
- }, [defaultSelection, elements?.chat?.disable_autofocus, selectedPeer, selectedRole, setRoleSelector]);
106
+ }, [defaultSelection, selectedPeer, selectedRole, setRoleSelector, isMobile, isLandscapeHLSStream, elements?.chat]);
102
107
  const sendMessage = useCallback(async () => {
103
108
  const message = inputRef?.current?.value;
104
109
  if (!message || !message.trim().length) {
@@ -143,11 +148,11 @@ export const ChatFooter = ({ onSend, children }: { onSend: (count: number) => vo
143
148
  }
144
149
 
145
150
  return (
146
- <Box>
151
+ <Box css={{ position: 'relative' }}>
147
152
  <Flex>
148
153
  <ChatSelectorContainer />
149
154
  {canDisableChat && isMobile && isOverlayChat ? (
150
- <Flex align="center" justify="end" css={{ mb: '$4' }}>
155
+ <Flex align="center" justify="end" css={{ mb: '$4' }} onClick={e => e.stopPropagation()}>
151
156
  <Popover.Root>
152
157
  <Popover.Trigger asChild>
153
158
  <IconButton css={{ border: '1px solid $border_bright' }}>
@@ -209,6 +214,7 @@ export const ChatFooter = ({ onSend, children }: { onSend: (count: number) => vo
209
214
  h: '$14',
210
215
  boxSizing: 'border-box',
211
216
  },
217
+ ...(isLandscapeHLSStream ? { minHeight: '$14', py: 0 } : {}),
212
218
  }}
213
219
  >
214
220
  {children}
@@ -223,6 +229,7 @@ export const ChatFooter = ({ onSend, children }: { onSend: (count: number) => vo
223
229
  placeholder={message_placeholder}
224
230
  ref={inputRef}
225
231
  required
232
+ autoFocus={!(isMobile || isLandscapeHLSStream)}
226
233
  onKeyPress={async event => {
227
234
  if (event.key === 'Enter') {
228
235
  if (!event.shiftKey) {
@@ -237,7 +244,7 @@ export const ChatFooter = ({ onSend, children }: { onSend: (count: number) => vo
237
244
  onCut={e => e.stopPropagation()}
238
245
  onCopy={e => e.stopPropagation()}
239
246
  />
240
- {!isMobile ? (
247
+ {!isMobile && !isLandscapeHLSStream ? (
241
248
  <EmojiPicker
242
249
  onSelect={emoji => {
243
250
  if (inputRef.current) {
@@ -260,6 +267,19 @@ export const ChatFooter = ({ onSend, children }: { onSend: (count: number) => vo
260
267
  <SendIcon />
261
268
  </BaseIconButton>
262
269
  </Flex>
270
+ {(isMwebHLSStream || isLandscapeHLSStream) && (
271
+ <>
272
+ <Flex
273
+ css={{
274
+ alignItems: 'center',
275
+ }}
276
+ gap="1"
277
+ >
278
+ {noAVPermissions ? <RaiseHand css={{ bg: '$surface_default' }} /> : null}
279
+ <MoreSettings elements={elements} screenType={screenType} />
280
+ </Flex>
281
+ </>
282
+ )}
263
283
  </Flex>
264
284
  )}
265
285
  </Box>
@@ -8,7 +8,7 @@ export const MwebChatOption = ({
8
8
  onClick,
9
9
  color = '$on_surface_high',
10
10
  }: {
11
- icon: any;
11
+ icon: React.ReactNode;
12
12
  text: string;
13
13
  onClick: () => void | Promise<void>;
14
14
  color?: string;
@@ -6,10 +6,12 @@ import {
6
6
  selectAppData,
7
7
  selectIsConnectedToRoom,
8
8
  selectRoomState,
9
+ useAVToggle,
9
10
  useHMSActions,
10
11
  useHMSStore,
11
12
  } from '@100mslive/react-sdk';
12
13
  import { Footer } from './Footer/Footer';
14
+ import { MoreSettings } from './MoreSettings/MoreSettings';
13
15
  import { HLSFailureModal } from './Notifications/HLSFailureModal';
14
16
  // @ts-ignore: No implicit Any
15
17
  import { ActivatedPIP } from './PIP/PIPComponent';
@@ -20,15 +22,19 @@ import { Box, Flex } from '../../Layout';
20
22
  import { useHMSPrebuiltContext } from '../AppContext';
21
23
  import { VideoStreamingSection } from '../layouts/VideoStreamingSection';
22
24
  // @ts-ignore: No implicit Any
25
+ import { EmojiReaction } from './EmojiReaction';
26
+ // @ts-ignore: No implicit Any
23
27
  import FullPageProgress from './FullPageProgress';
24
28
  import { Header } from './Header';
25
29
  import { PreviousRoleInMetadata } from './PreviousRoleInMetadata';
30
+ import { RaiseHand } from './RaiseHand';
26
31
  import {
27
32
  useRoomLayoutConferencingScreen,
28
33
  useRoomLayoutPreviewScreen,
29
34
  } from '../provider/roomLayoutProvider/hooks/useRoomLayoutScreen';
30
35
  // @ts-ignore: No implicit Any
31
36
  import { useAuthToken, useSetAppDataByKey } from './AppData/useUISettings';
37
+ import { useLandscapeHLSStream, useMobileHLSStream } from '../common/hooks';
32
38
  // @ts-ignore: No implicit Any
33
39
  import { APP_DATA, isAndroid, isIOS, isIPadOS } from '../common/constants';
34
40
 
@@ -47,12 +53,21 @@ export const ConferenceScreen = () => {
47
53
  const isMobileDevice = isAndroid || isIOS || isIPadOS;
48
54
  const dropdownListRef = useRef<string[]>();
49
55
  const [isHLSStarted] = useSetAppDataByKey(APP_DATA.hlsStarted);
56
+
57
+ const { toggleAudio, toggleVideo } = useAVToggle();
58
+ const noAVPermissions = !(toggleAudio || toggleVideo);
59
+ // using it in hls stream to show action button when chat is disabled
60
+ const showChat = !!screenProps.elements?.chat;
61
+ const autoRoomJoined = useRef(isPreviewScreenEnabled);
62
+ const isMobileHLSStream = useMobileHLSStream();
63
+ const isLandscapeHLSStream = useLandscapeHLSStream();
64
+ const isMwebHLSStream = isMobileHLSStream || isLandscapeHLSStream;
65
+
50
66
  const toggleControls = () => {
51
- if (dropdownListRef.current?.length === 0 && isMobileDevice) {
67
+ if (dropdownListRef.current?.length === 0 && isMobileDevice && !isMwebHLSStream) {
52
68
  setHideControls(value => !value);
53
69
  }
54
70
  };
55
- const autoRoomJoined = useRef(isPreviewScreenEnabled);
56
71
 
57
72
  useEffect(() => {
58
73
  let timeout: undefined | ReturnType<typeof setTimeout>;
@@ -105,6 +120,8 @@ export const ConferenceScreen = () => {
105
120
  return <FullPageProgress text={roomState === HMSRoomState.Connecting ? 'Joining...' : ''} />;
106
121
  }
107
122
 
123
+ const hideControlsForStreaming = isMwebHLSStream ? true : hideControls;
124
+
108
125
  return (
109
126
  <>
110
127
  {isHLSStarted ? (
@@ -113,13 +130,13 @@ export const ConferenceScreen = () => {
113
130
  </Box>
114
131
  ) : null}
115
132
  <Flex css={{ size: '100%', overflow: 'hidden' }} direction="column">
116
- {!screenProps.hideSections.includes('header') && (
133
+ {!(screenProps.hideSections.includes('header') || isMwebHLSStream) && (
117
134
  <Box
118
135
  ref={headerRef}
119
136
  css={{
120
137
  h: '$18',
121
138
  transition: 'margin 0.3s ease-in-out',
122
- marginTop: hideControls ? `-${headerRef.current?.clientHeight}px` : 'none',
139
+ marginTop: hideControlsForStreaming ? `-${headerRef.current?.clientHeight}px` : 'none',
123
140
  '@md': {
124
141
  h: '$17',
125
142
  },
@@ -151,11 +168,11 @@ export const ConferenceScreen = () => {
151
168
  <VideoStreamingSection
152
169
  screenType={screenProps.screenType}
153
170
  elements={screenProps.elements}
154
- hideControls={hideControls}
171
+ hideControls={hideControlsForStreaming}
155
172
  />
156
173
  ) : null}
157
174
  </Box>
158
- {!screenProps.hideSections.includes('footer') && screenProps.elements && (
175
+ {!screenProps.hideSections.includes('footer') && screenProps.elements && !isMwebHLSStream && (
159
176
  <Box
160
177
  ref={footerRef}
161
178
  css={{
@@ -163,7 +180,7 @@ export const ConferenceScreen = () => {
163
180
  maxHeight: '$24',
164
181
  transition: 'margin 0.3s ease-in-out',
165
182
  bg: '$background_dim',
166
- marginBottom: hideControls ? `-${footerRef.current?.clientHeight}px` : undefined,
183
+ marginBottom: hideControlsForStreaming ? `-${footerRef.current?.clientHeight}px` : undefined,
167
184
  '@md': {
168
185
  maxHeight: 'unset',
169
186
  bg: screenProps.screenType === 'hls_live_streaming' ? 'transparent' : '$background_dim',
@@ -174,6 +191,30 @@ export const ConferenceScreen = () => {
174
191
  <Footer elements={screenProps.elements} screenType={screenProps.screenType} />
175
192
  </Box>
176
193
  )}
194
+ {isMwebHLSStream && !showChat && (
195
+ <Flex
196
+ css={{
197
+ alignItems: 'center',
198
+ pr: '$4',
199
+ pb: '$4',
200
+ position: 'relative',
201
+ }}
202
+ justify="end"
203
+ gap="1"
204
+ >
205
+ {noAVPermissions ? <RaiseHand /> : null}
206
+ <MoreSettings elements={screenProps.elements} screenType={screenProps.screenType} />
207
+ <Box
208
+ css={{
209
+ position: 'absolute',
210
+ bottom: '100%',
211
+ mb: '$4',
212
+ }}
213
+ >
214
+ <EmojiReaction />
215
+ </Box>
216
+ </Flex>
217
+ )}
177
218
  <RoleChangeRequestModal />
178
219
  <HLSFailureModal />
179
220
  <ActivatedPIP />