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

Sign up to get free protection for your applications and to get access to all the features.
Files changed (105) 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-ERIM35YN.js → chunk-R2JJJQR3.js} +1539 -1173
  27. package/dist/chunk-R2JJJQR3.js.map +7 -0
  28. package/dist/index.cjs.js +2709 -1898
  29. package/dist/index.cjs.js.map +4 -4
  30. package/dist/index.js +1 -1
  31. package/dist/meta.cjs.json +777 -290
  32. package/dist/meta.esbuild.json +796 -298
  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/AuthToken.jsx +1 -1
  42. package/src/Prebuilt/components/Chat/Chat.tsx +41 -1
  43. package/src/Prebuilt/components/Chat/ChatFooter.tsx +33 -13
  44. package/src/Prebuilt/components/Chat/MwebChatOption.tsx +1 -1
  45. package/src/Prebuilt/components/ConferenceScreen.tsx +48 -7
  46. package/src/Prebuilt/components/EmojiReaction.jsx +33 -23
  47. package/src/Prebuilt/components/Footer/Footer.tsx +0 -1
  48. package/src/Prebuilt/components/Footer/RoleOptions.tsx +138 -125
  49. package/src/Prebuilt/components/HMSVideo/Controls.jsx +1 -1
  50. package/src/Prebuilt/components/HMSVideo/FullscreenButton.tsx +13 -0
  51. package/src/Prebuilt/components/HMSVideo/HLSAutoplayBlockedPrompt.tsx +72 -0
  52. package/src/Prebuilt/components/HMSVideo/HLSCaptionSelector.tsx +4 -2
  53. package/src/Prebuilt/components/HMSVideo/HLSQualitySelector.tsx +248 -0
  54. package/src/Prebuilt/components/HMSVideo/HMSVideo.jsx +17 -7
  55. package/src/Prebuilt/components/HMSVideo/MwebHLSViewTitle.tsx +84 -0
  56. package/src/Prebuilt/components/HMSVideo/PlayButton.tsx +27 -0
  57. package/src/Prebuilt/components/HMSVideo/PlayPauseButton.tsx +27 -0
  58. package/src/Prebuilt/components/HMSVideo/PlayerContext.tsx +15 -0
  59. package/src/Prebuilt/components/HMSVideo/SeekControls.tsx +22 -0
  60. package/src/Prebuilt/components/HMSVideo/VideoProgress.tsx +95 -0
  61. package/src/Prebuilt/components/HMSVideo/VideoTime.tsx +43 -0
  62. package/src/Prebuilt/components/HMSVideo/{VolumeControl.jsx → VolumeControl.tsx} +6 -4
  63. package/src/Prebuilt/components/HMSVideo/{index.js → index.ts} +6 -2
  64. package/src/Prebuilt/components/HMSVideo/{HMSVIdeoUtils.js → utils.ts} +5 -5
  65. package/src/Prebuilt/components/Header/StreamActions.tsx +1 -1
  66. package/src/Prebuilt/components/IconButtonWithOptions/IconButtonWithOptions.tsx +1 -1
  67. package/src/Prebuilt/components/Leave/DesktopLeaveRoom.tsx +50 -46
  68. package/src/Prebuilt/components/Leave/LeaveRoom.tsx +15 -4
  69. package/src/Prebuilt/components/Leave/MwebLeaveRoom.tsx +46 -27
  70. package/src/Prebuilt/components/MoreSettings/MoreSettings.tsx +3 -1
  71. package/src/Prebuilt/components/MoreSettings/SplitComponents/DesktopOptions.tsx +37 -31
  72. package/src/Prebuilt/components/MoreSettings/SplitComponents/MwebOptions.tsx +12 -8
  73. package/src/Prebuilt/components/MwebLandscapePrompt.tsx +14 -3
  74. package/src/Prebuilt/components/Notifications/HandRaisedNotifications.tsx +5 -2
  75. package/src/Prebuilt/components/Notifications/PeerNotifications.tsx +1 -1
  76. package/src/Prebuilt/components/Polls/Voting/QuestionCard.jsx +19 -8
  77. package/src/Prebuilt/components/Polls/Voting/Voting.tsx +3 -2
  78. package/src/Prebuilt/components/Polls/common/OptionInputWithDelete.tsx +1 -1
  79. package/src/Prebuilt/components/Polls/common/utils.ts +2 -2
  80. package/src/Prebuilt/components/RaiseHand.tsx +24 -0
  81. package/src/Prebuilt/components/RoomDetails/RoomDetailsPane.tsx +41 -14
  82. package/src/Prebuilt/components/SidePaneTabs.tsx +56 -48
  83. package/src/Prebuilt/components/StatsForNerds.jsx +14 -6
  84. package/src/Prebuilt/components/Streaming/Common.jsx +1 -1
  85. package/src/Prebuilt/components/TileMenu/TileMenuContent.tsx +2 -2
  86. package/src/Prebuilt/components/Toast/ToastBatcher.js +8 -1
  87. package/src/Prebuilt/components/Toast/ToastConfig.jsx +17 -0
  88. package/src/Prebuilt/components/pdfAnnotator/shareScreenOptions.jsx +2 -2
  89. package/src/Prebuilt/components/pdfAnnotator/uploadedFile.jsx +1 -1
  90. package/src/Prebuilt/layouts/HLSView.jsx +359 -178
  91. package/src/Prebuilt/layouts/SidePane.tsx +145 -59
  92. package/src/Prebuilt/layouts/VideoStreamingSection.tsx +22 -2
  93. package/src/Prebuilt/primitives/DialogContent.jsx +1 -1
  94. package/src/Prebuilt/provider/roomLayoutProvider/index.tsx +1 -1
  95. package/src/Sheet/Sheet.tsx +7 -3
  96. package/dist/HLSView-SJCF34GE.js +0 -987
  97. package/dist/HLSView-SJCF34GE.js.map +0 -7
  98. package/dist/chunk-ERIM35YN.js.map +0 -7
  99. package/src/Prebuilt/components/HMSVideo/FullscreenButton.jsx +0 -18
  100. package/src/Prebuilt/components/HMSVideo/HLSAutoplayBlockedPrompt.jsx +0 -35
  101. package/src/Prebuilt/components/HMSVideo/HLSQualitySelector.jsx +0 -127
  102. package/src/Prebuilt/components/HMSVideo/PlayButton.jsx +0 -13
  103. package/src/Prebuilt/components/HMSVideo/VideoProgress.jsx +0 -76
  104. package/src/Prebuilt/components/HMSVideo/VideoTime.jsx +0 -33
  105. 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.1",
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.1",
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.1",
88
- "@100mslive/react-icons": "0.9.8-alpha.1",
89
- "@100mslive/react-sdk": "0.9.8-alpha.1",
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": "44ec4f466226ce1135b5b72556b212b9b10dae07"
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
  );
@@ -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 />
@@ -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';