@100mslive/roomkit-react 0.1.4 → 0.1.6-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 (197) hide show
  1. package/dist/{HLSView-CTAJQUU4.js → HLSView-PY2FKWX3.js} +191 -123
  2. package/dist/HLSView-PY2FKWX3.js.map +7 -0
  3. package/dist/Prebuilt/App.d.ts +3 -0
  4. package/dist/Prebuilt/AppContext.d.ts +13 -0
  5. package/dist/Prebuilt/common/PeersSorter.d.ts +21 -0
  6. package/dist/Prebuilt/components/Footer/Footer.d.ts +6 -0
  7. package/dist/Prebuilt/components/Header/Header.d.ts +2 -0
  8. package/dist/Prebuilt/components/InsetTile.d.ts +2 -0
  9. package/dist/Prebuilt/components/Leave/DesktopLeaveRoom.d.ts +7 -0
  10. package/dist/Prebuilt/components/Leave/EndSessionContent.d.ts +8 -0
  11. package/dist/Prebuilt/components/Leave/LeaveAtoms.d.ts +2196 -0
  12. package/dist/Prebuilt/components/Leave/LeaveCard.d.ts +12 -0
  13. package/dist/Prebuilt/components/Leave/LeaveRoom.d.ts +5 -0
  14. package/dist/Prebuilt/components/Leave/LeaveSessionContent.d.ts +6 -0
  15. package/dist/Prebuilt/components/Leave/MwebLeaveRoom.d.ts +7 -0
  16. package/dist/Prebuilt/components/MoreSettings/MoreSettings.d.ts +6 -0
  17. package/dist/Prebuilt/components/MoreSettings/SplitComponents/DesktopOptions.d.ts +6 -0
  18. package/dist/Prebuilt/components/Pagination.d.ts +6 -0
  19. package/dist/Prebuilt/components/Preview/PreviewForm.d.ts +10 -0
  20. package/dist/Prebuilt/components/SecondaryTiles.d.ts +3 -0
  21. package/dist/Prebuilt/components/VideoLayouts/EqualProminence.d.ts +3 -0
  22. package/dist/Prebuilt/components/VideoLayouts/Grid.d.ts +5 -0
  23. package/dist/Prebuilt/components/VideoLayouts/GridLayout.d.ts +10 -0
  24. package/dist/Prebuilt/components/VideoLayouts/ProminenceLayout.d.ts +12 -0
  25. package/dist/Prebuilt/components/VideoLayouts/RoleProminence.d.ts +3 -0
  26. package/dist/Prebuilt/components/VideoLayouts/ScreenshareLayout.d.ts +3 -0
  27. package/dist/Prebuilt/components/VideoLayouts/interface.d.ts +8 -0
  28. package/dist/Prebuilt/components/hooks/useRoleProminencePeers.d.ts +5 -0
  29. package/dist/Prebuilt/components/hooks/useTileLayout.d.ts +12 -0
  30. package/dist/Prebuilt/components/hooks/useVideoTileLayout.d.ts +11 -0
  31. package/dist/Prebuilt/layouts/SidePane.d.ts +6 -0
  32. package/dist/Prebuilt/layouts/VideoStreamingSection.d.ts +6 -0
  33. package/dist/Prebuilt/plugins/whiteboard/ToggleWhiteboard.d.ts +5 -0
  34. package/dist/Prebuilt/provider/roomLayoutProvider/hooks/useFetchRoomLayout.d.ts +1 -0
  35. package/dist/Prebuilt/provider/roomLayoutProvider/hooks/useInsetEnabled.d.ts +1 -0
  36. package/dist/Prebuilt/provider/roomLayoutProvider/hooks/useRoomLayoutScreen.d.ts +17 -0
  37. package/dist/Prebuilt/provider/roomLayoutProvider/index.d.ts +6 -1
  38. package/dist/{VirtualBackground-GGGBJYVY.js → VirtualBackground-AYDHYLIZ.js} +5 -11
  39. package/dist/VirtualBackground-AYDHYLIZ.js.map +7 -0
  40. package/dist/{chunk-TJNDX446.js → chunk-E2M2ZSOL.js} +8 -5
  41. package/dist/chunk-E2M2ZSOL.js.map +7 -0
  42. package/dist/chunk-GQD2AGWW.js +888 -0
  43. package/dist/chunk-GQD2AGWW.js.map +7 -0
  44. package/dist/{chunk-L2SX7GBO.js → chunk-RXTHJUMZ.js} +2462 -4738
  45. package/dist/chunk-RXTHJUMZ.js.map +7 -0
  46. package/dist/conference-V2XZGTKU.js +5927 -0
  47. package/dist/conference-V2XZGTKU.js.map +7 -0
  48. package/dist/index.cjs.js +9414 -15534
  49. package/dist/index.cjs.js.map +4 -4
  50. package/dist/index.js +2 -2
  51. package/dist/meta.cjs.json +2156 -3347
  52. package/dist/meta.esbuild.json +2601 -3885
  53. package/package.json +7 -7
  54. package/src/Button/Button.tsx +2 -2
  55. package/src/Prebuilt/App.tsx +49 -33
  56. package/src/Prebuilt/{AppContext.jsx → AppContext.tsx} +11 -3
  57. package/src/Prebuilt/IconButton.jsx +1 -0
  58. package/src/Prebuilt/Prebuilt.stories.tsx +1 -0
  59. package/src/Prebuilt/common/{PeersSorter.js → PeersSorter.ts} +15 -10
  60. package/src/Prebuilt/common/constants.js +3 -112
  61. package/src/Prebuilt/common/hooks.js +34 -1
  62. package/src/Prebuilt/common/utils.js +0 -8
  63. package/src/Prebuilt/components/AppData/AppData.jsx +3 -13
  64. package/src/Prebuilt/components/AppData/useUISettings.js +0 -4
  65. package/src/Prebuilt/components/AudioVideoToggle.jsx +6 -0
  66. package/src/Prebuilt/components/AuthToken.jsx +11 -42
  67. package/src/Prebuilt/components/Chat/Chat.jsx +57 -26
  68. package/src/Prebuilt/components/Chat/ChatBody.jsx +92 -32
  69. package/src/Prebuilt/components/Chat/ChatFooter.jsx +72 -48
  70. package/src/Prebuilt/components/Chat/ChatParticipantHeader.jsx +73 -0
  71. package/src/Prebuilt/components/Chat/ChatSelector.jsx +16 -17
  72. package/src/Prebuilt/components/Chat/ChatSelectorContainer.jsx +81 -0
  73. package/src/Prebuilt/components/Connection/TileConnection.jsx +30 -12
  74. package/src/Prebuilt/components/EmojiReaction.jsx +18 -17
  75. package/src/Prebuilt/components/Footer/ChatToggle.jsx +1 -7
  76. package/src/Prebuilt/components/Footer/Footer.tsx +89 -0
  77. package/src/Prebuilt/components/Footer/ParticipantList.jsx +213 -173
  78. package/src/Prebuilt/components/Footer/RoleAccordion.jsx +78 -0
  79. package/src/Prebuilt/components/HMSVideo/Controls.jsx +2 -2
  80. package/src/Prebuilt/components/HMSVideo/HLSQualitySelector.jsx +33 -10
  81. package/src/Prebuilt/components/HMSVideo/PlayButton.jsx +1 -1
  82. package/src/Prebuilt/components/HMSVideo/VideoTime.jsx +3 -3
  83. package/src/Prebuilt/components/HMSVideo/VolumeControl.jsx +38 -9
  84. package/src/Prebuilt/components/Header/{ConferencingHeader.jsx → Header.tsx} +9 -7
  85. package/src/Prebuilt/components/Header/HeaderComponents.jsx +13 -4
  86. package/src/Prebuilt/components/Header/StreamActions.jsx +33 -60
  87. package/src/Prebuilt/components/Header/index.tsx +1 -0
  88. package/src/Prebuilt/components/IconButtonWithOptions/IconButtonWithOptions.jsx +17 -3
  89. package/src/Prebuilt/components/InsetTile.tsx +122 -0
  90. package/src/Prebuilt/components/{MoreSettings/SplitComponents/DesktopLeaveRoom.jsx → Leave/DesktopLeaveRoom.tsx} +50 -18
  91. package/src/Prebuilt/components/{EndSessionContent.jsx → Leave/EndSessionContent.tsx} +19 -9
  92. package/src/Prebuilt/components/Leave/LeaveAtoms.tsx +26 -0
  93. package/src/Prebuilt/components/{LeaveCard.jsx → Leave/LeaveCard.tsx} +22 -3
  94. package/src/Prebuilt/components/Leave/LeaveRoom.tsx +63 -0
  95. package/src/Prebuilt/components/{LeaveSessionContent.jsx → Leave/LeaveSessionContent.tsx} +13 -5
  96. package/src/Prebuilt/components/{MoreSettings/SplitComponents/MwebLeaveRoom.jsx → Leave/MwebLeaveRoom.tsx} +38 -13
  97. package/src/Prebuilt/components/MetaActions.jsx +15 -23
  98. package/src/Prebuilt/components/MoreSettings/ActionTile.jsx +5 -0
  99. package/src/Prebuilt/components/MoreSettings/ChangeNameContent.jsx +12 -7
  100. package/src/Prebuilt/components/MoreSettings/ChangeNameModal.jsx +1 -1
  101. package/src/Prebuilt/components/MoreSettings/FullScreenItem.jsx +1 -4
  102. package/src/Prebuilt/components/MoreSettings/MoreSettings.tsx +27 -0
  103. package/src/Prebuilt/components/MoreSettings/SplitComponents/{DesktopOptions.jsx → DesktopOptions.tsx} +86 -75
  104. package/src/Prebuilt/components/MoreSettings/SplitComponents/MwebOptions.jsx +20 -19
  105. package/src/Prebuilt/components/Notifications/HLSFailureModal.jsx +3 -1
  106. package/src/Prebuilt/components/Notifications/Notifications.jsx +18 -11
  107. package/src/Prebuilt/components/Notifications/PeerNotifications.jsx +14 -2
  108. package/src/Prebuilt/components/Notifications/PermissionErrorModal.jsx +10 -4
  109. package/src/Prebuilt/components/PIP/PIPComponent.jsx +7 -16
  110. package/src/Prebuilt/components/PIP/PIPManager.js +1 -0
  111. package/src/Prebuilt/components/{Pagination.jsx → Pagination.tsx} +35 -6
  112. package/src/Prebuilt/components/Playlist/Playlist.jsx +1 -6
  113. package/src/Prebuilt/components/PostLeave.jsx +7 -7
  114. package/src/Prebuilt/components/Preview/PreviewContainer.jsx +5 -13
  115. package/src/Prebuilt/components/Preview/{PreviewForm.jsx → PreviewForm.tsx} +14 -4
  116. package/src/Prebuilt/components/Preview/PreviewJoin.jsx +9 -7
  117. package/src/Prebuilt/components/RaiseHand.jsx +0 -7
  118. package/src/Prebuilt/components/RoleChangeRequestModal.jsx +82 -6
  119. package/src/Prebuilt/components/ScreenshareDisplay.jsx +4 -10
  120. package/src/Prebuilt/components/ScreenshareTile.jsx +41 -33
  121. package/src/Prebuilt/components/SecondaryTiles.tsx +34 -0
  122. package/src/Prebuilt/components/Settings/LayoutSettings.jsx +2 -12
  123. package/src/Prebuilt/components/Settings/NotificationSettings.jsx +3 -9
  124. package/src/Prebuilt/components/Settings/SettingsModal.jsx +3 -9
  125. package/src/Prebuilt/components/StatsForNerds.jsx +3 -1
  126. package/src/Prebuilt/components/TileMenu/TileMenu.jsx +15 -16
  127. package/src/Prebuilt/components/TileMenu/TileMenuContent.jsx +21 -19
  128. package/src/Prebuilt/components/Toast/ToastConfig.jsx +53 -11
  129. package/src/Prebuilt/components/VideoLayouts/EqualProminence.tsx +62 -0
  130. package/src/Prebuilt/components/VideoLayouts/Grid.tsx +41 -0
  131. package/src/Prebuilt/components/VideoLayouts/GridLayout.tsx +92 -0
  132. package/src/Prebuilt/components/VideoLayouts/ProminenceLayout.tsx +60 -0
  133. package/src/Prebuilt/components/VideoLayouts/RoleProminence.tsx +56 -0
  134. package/src/Prebuilt/components/VideoLayouts/ScreenshareLayout.tsx +36 -0
  135. package/src/Prebuilt/components/VideoLayouts/interface.ts +9 -0
  136. package/src/Prebuilt/components/VideoTile.jsx +93 -43
  137. package/src/Prebuilt/components/conference.jsx +24 -20
  138. package/src/Prebuilt/components/hooks/useMetadata.jsx +7 -0
  139. package/src/Prebuilt/components/hooks/useRoleProminencePeers.tsx +38 -0
  140. package/src/Prebuilt/components/hooks/useTileLayout.tsx +121 -0
  141. package/src/Prebuilt/components/hooks/useVideoTileLayout.ts +22 -0
  142. package/src/Prebuilt/components/pdfAnnotator/pdfFileOptions.jsx +5 -72
  143. package/src/Prebuilt/components/pdfAnnotator/submitPdf.jsx +4 -45
  144. package/src/Prebuilt/components/pdfAnnotator/uploadedFile.jsx +2 -17
  145. package/src/Prebuilt/components/peerTileUtils.jsx +1 -1
  146. package/src/Prebuilt/images/empty-chat.svg +12 -0
  147. package/src/Prebuilt/layouts/EmbedView.jsx +17 -40
  148. package/src/Prebuilt/layouts/HLSView.jsx +83 -66
  149. package/src/Prebuilt/layouts/PDFView.jsx +1 -11
  150. package/src/Prebuilt/layouts/SidePane.tsx +96 -0
  151. package/src/Prebuilt/layouts/{mainView.jsx → VideoStreamingSection.tsx} +38 -47
  152. package/src/Prebuilt/layouts/WhiteboardView.jsx +10 -34
  153. package/src/Prebuilt/plugins/VirtualBackground/VirtualBackground.jsx +1 -4
  154. package/src/Prebuilt/plugins/whiteboard/{ToggleWhiteboard.jsx → ToggleWhiteboard.tsx} +5 -9
  155. package/src/Prebuilt/primitives/DialogContent.jsx +15 -11
  156. package/src/Prebuilt/provider/roomLayoutProvider/constants/index.ts +17 -2
  157. package/src/Prebuilt/provider/roomLayoutProvider/hooks/useFetchRoomLayout.ts +36 -13
  158. package/src/Prebuilt/provider/roomLayoutProvider/hooks/useInsetEnabled.ts +10 -0
  159. package/src/Prebuilt/provider/roomLayoutProvider/hooks/useRoomLayoutScreen.ts +65 -0
  160. package/src/Prebuilt/provider/roomLayoutProvider/index.tsx +17 -6
  161. package/dist/HLSView-CTAJQUU4.js.map +0 -7
  162. package/dist/PinnedTrackView-CQKONH4O.js +0 -102
  163. package/dist/PinnedTrackView-CQKONH4O.js.map +0 -7
  164. package/dist/VirtualBackground-GGGBJYVY.js.map +0 -7
  165. package/dist/chunk-I2FJWE74.js +0 -827
  166. package/dist/chunk-I2FJWE74.js.map +0 -7
  167. package/dist/chunk-L2SX7GBO.js.map +0 -7
  168. package/dist/chunk-NOKIGB6Y.js +0 -1100
  169. package/dist/chunk-NOKIGB6Y.js.map +0 -7
  170. package/dist/chunk-TJNDX446.js.map +0 -7
  171. package/dist/conference-OEO7VOJD.js +0 -8995
  172. package/dist/conference-OEO7VOJD.js.map +0 -7
  173. package/src/Prebuilt/components/Chat/ChatHeader.jsx +0 -67
  174. package/src/Prebuilt/components/EqualProminence.jsx +0 -180
  175. package/src/Prebuilt/components/FirstPersonDisplay.jsx +0 -50
  176. package/src/Prebuilt/components/Footer/Footer.jsx +0 -73
  177. package/src/Prebuilt/components/Header/Header.jsx +0 -8
  178. package/src/Prebuilt/components/Header/StreamingHeader.jsx +0 -54
  179. package/src/Prebuilt/components/LeaveRoom.jsx +0 -94
  180. package/src/Prebuilt/components/MoreSettings/MoreSettings.jsx +0 -10
  181. package/src/Prebuilt/components/Notifications/MessageNotifications.jsx +0 -25
  182. package/src/Prebuilt/components/gridView.jsx +0 -85
  183. package/src/Prebuilt/components/hooks/useFeatures.js +0 -22
  184. package/src/Prebuilt/components/hooks/useNavigation.js +0 -19
  185. package/src/Prebuilt/components/hooks/useSkipPreview.jsx +0 -20
  186. package/src/Prebuilt/components/pdfAnnotator/pdfErrorView.jsx +0 -29
  187. package/src/Prebuilt/images/Logo.svg +0 -8
  188. package/src/Prebuilt/layouts/ActiveSpeakerView.jsx +0 -34
  189. package/src/Prebuilt/layouts/InsetView.jsx +0 -260
  190. package/src/Prebuilt/layouts/PinnedTrackView.jsx +0 -59
  191. package/src/Prebuilt/layouts/SidePane.jsx +0 -52
  192. package/src/Prebuilt/layouts/mainGridView.jsx +0 -98
  193. package/src/Prebuilt/layouts/screenShareView.jsx +0 -183
  194. /package/{src/Prebuilt/components/Header/index.jsx → dist/Prebuilt/components/Header/index.d.ts} +0 -0
  195. /package/src/Prebuilt/components/{ScreenShare.jsx → ScreenShareToggle.jsx} +0 -0
  196. /package/src/{assets → Prebuilt/images}/android-perm-1.png +0 -0
  197. /package/src/{assets → Prebuilt/images}/ios-perm-0.png +0 -0
@@ -1,14 +1,10 @@
1
- import React, { useEffect, useMemo, useState } from 'react';
2
- import { matchPath, useLocation } from 'react-router-dom';
3
- import { useSearchParam } from 'react-use';
4
- import { v4 as uuid } from 'uuid';
1
+ import React, { useEffect, useState } from 'react';
5
2
  import { useHMSActions } from '@100mslive/react-sdk';
6
3
  import { styled } from '../../Theme';
7
4
  import { useHMSPrebuiltContext } from '../AppContext';
8
5
  import { ErrorDialog } from '../primitives/DialogContent';
9
6
  import { useSetAppDataByKey, useTokenEndpoint } from './AppData/useUISettings';
10
- import getToken from '../services/tokenService';
11
- import { APP_DATA, QUERY_PARAM_AUTH_TOKEN } from '../common/constants';
7
+ import { APP_DATA } from '../common/constants';
12
8
 
13
9
  /**
14
10
  * query params exposed -
@@ -19,20 +15,12 @@ import { APP_DATA, QUERY_PARAM_AUTH_TOKEN } from '../common/constants';
19
15
  * auth_token=123 => uses the passed in token to join instead of fetching from token endpoint
20
16
  * ui_mode=activespeaker => lands in active speaker mode after joining the room
21
17
  */
22
- const AuthToken = React.memo(({ authTokenByRoomCodeEndpoint }) => {
18
+ const AuthToken = React.memo(({ authTokenByRoomCodeEndpoint, defaultAuthToken }) => {
23
19
  const hmsActions = useHMSActions();
24
20
  const tokenEndpoint = useTokenEndpoint();
25
- const { showPreview, roomCode, userId } = useHMSPrebuiltContext();
26
- const location = useLocation();
27
- const matches = useMemo(
28
- () =>
29
- matchPath(`${showPreview ? 'preview' : 'meeting'}/:roomId/:role`, location.pathname) ||
30
- matchPath(`${showPreview ? 'preview' : 'meeting'}/:roomCode/`, location.pathname),
31
- [location, showPreview],
32
- );
33
- const { roomCode: urlRoomCode, roomId: urlRoomId, role: userRole } = matches?.params || {};
21
+ const { roomCode, userId } = useHMSPrebuiltContext();
34
22
  const [error, setError] = useState({ title: '', body: '' });
35
- let authToken = useSearchParam(QUERY_PARAM_AUTH_TOKEN);
23
+ let authToken = defaultAuthToken;
36
24
  const [, setAuthTokenInAppData] = useSetAppDataByKey(APP_DATA.authToken);
37
25
 
38
26
  useEffect(() => {
@@ -40,34 +28,15 @@ const AuthToken = React.memo(({ authTokenByRoomCodeEndpoint }) => {
40
28
  setAuthTokenInAppData(authToken);
41
29
  return;
42
30
  }
43
- if (!tokenEndpoint && !urlRoomId && !roomCode && !urlRoomCode) {
31
+ if (!tokenEndpoint && !roomCode) {
44
32
  return;
45
33
  }
46
- const code = !userRole && (roomCode || urlRoomCode);
47
34
 
48
- const getTokenFn = code
49
- ? () => hmsActions.getAuthTokenByRoomCode({ roomCode: code, userId }, { endpoint: authTokenByRoomCodeEndpoint })
50
- : () => getToken(tokenEndpoint, uuid(), userRole, urlRoomId);
51
-
52
- getTokenFn()
53
- .then(token => {
54
- setAuthTokenInAppData(token);
55
- })
56
- .catch(error => {
57
- setError(convertError(error));
58
- });
59
- }, [
60
- hmsActions,
61
- tokenEndpoint,
62
- urlRoomId,
63
- urlRoomCode,
64
- userRole,
65
- authToken,
66
- authTokenByRoomCodeEndpoint,
67
- setAuthTokenInAppData,
68
- roomCode,
69
- userId,
70
- ]);
35
+ hmsActions
36
+ .getAuthTokenByRoomCode({ roomCode, userId }, { endpoint: authTokenByRoomCodeEndpoint })
37
+ .then(token => setAuthTokenInAppData(token))
38
+ .catch(error => setError(convertError(error)));
39
+ }, [hmsActions, tokenEndpoint, authToken, authTokenByRoomCodeEndpoint, setAuthTokenInAppData, roomCode, userId]);
71
40
 
72
41
  if (error.title) {
73
42
  return <ErrorDialog title={error.title}>{error.body}</ErrorDialog>;
@@ -1,4 +1,5 @@
1
1
  import React, { useCallback, useEffect, useRef, useState } from 'react';
2
+ import { useMedia } from 'react-use';
2
3
  import {
3
4
  HMSNotificationTypes,
4
5
  selectHMSMessagesCount,
@@ -13,31 +14,36 @@ import { ChevronDownIcon, CrossIcon, PinIcon } from '@100mslive/react-icons';
13
14
  import { Button } from '../../../Button';
14
15
  import { Box, Flex } from '../../../Layout';
15
16
  import { Text } from '../../../Text';
16
- import IconButton from '../../IconButton';
17
+ import { config as cssConfig } from '../../../Theme';
17
18
  import { AnnotisedMessage, ChatBody } from './ChatBody';
18
19
  import { ChatFooter } from './ChatFooter';
19
- import { ChatHeader } from './ChatHeader';
20
+ import { ChatParticipantHeader } from './ChatParticipantHeader';
20
21
  import { useSetSubscribedChatSelector } from '../AppData/useUISettings';
21
22
  import { useSetPinnedMessage } from '../hooks/useSetPinnedMessage';
22
23
  import { useUnreadCount } from './useUnreadCount';
23
24
  import { CHAT_SELECTOR, SESSION_STORE_KEY } from '../../common/constants';
24
25
 
26
+ const PINNED_MESSAGE_LENGTH = 80;
27
+
25
28
  const PinnedMessage = ({ clearPinnedMessage }) => {
26
29
  const permissions = useHMSStore(selectPermissions);
27
30
  const pinnedMessage = useHMSStore(selectSessionStore(SESSION_STORE_KEY.PINNED_MESSAGE));
31
+ const formattedPinnedMessage =
32
+ pinnedMessage?.length && pinnedMessage.length > PINNED_MESSAGE_LENGTH
33
+ ? `${pinnedMessage.slice(0, PINNED_MESSAGE_LENGTH)}...`
34
+ : pinnedMessage;
28
35
 
29
36
  return pinnedMessage ? (
30
37
  <Flex
31
- css={{ p: '$8', color: '$on_surface_medium', bg: '$surface_bright', r: '$1' }}
38
+ title={pinnedMessage}
39
+ css={{ p: '$4', color: '$on_surface_medium', bg: '$surface_default', r: '$1', gap: '$4', mb: '$8', mt: '$8' }}
32
40
  align="center"
33
41
  justify="between"
34
42
  >
35
- <Box>
36
- <PinIcon />
37
- </Box>
43
+ <PinIcon />
44
+
38
45
  <Box
39
46
  css={{
40
- ml: '$8',
41
47
  color: '$on_surface_medium',
42
48
  w: '100%',
43
49
  maxHeight: '$18',
@@ -45,19 +51,22 @@ const PinnedMessage = ({ clearPinnedMessage }) => {
45
51
  }}
46
52
  >
47
53
  <Text variant="sm">
48
- <AnnotisedMessage message={pinnedMessage} />
54
+ <AnnotisedMessage message={formattedPinnedMessage} />
49
55
  </Text>
50
56
  </Box>
51
57
  {permissions.removeOthers && (
52
- <IconButton onClick={() => clearPinnedMessage()}>
58
+ <Flex
59
+ onClick={() => clearPinnedMessage()}
60
+ css={{ cursor: 'pointer', color: '$on_surface_medium', '&:hover': { color: '$on_surface_high' } }}
61
+ >
53
62
  <CrossIcon />
54
- </IconButton>
63
+ </Flex>
55
64
  )}
56
65
  </Flex>
57
66
  ) : null;
58
67
  };
59
68
 
60
- export const Chat = () => {
69
+ export const Chat = ({ screenType }) => {
61
70
  const notification = useHMSNotifications(HMSNotificationTypes.PEER_LEFT);
62
71
  const [peerSelector, setPeerSelector] = useSetSubscribedChatSelector(CHAT_SELECTOR.PEER_ID);
63
72
  const [roleSelector, setRoleSelector] = useSetSubscribedChatSelector(CHAT_SELECTOR.ROLE);
@@ -83,6 +92,7 @@ export const Chat = () => {
83
92
  }, [notification, peerSelector, setPeerSelector]);
84
93
 
85
94
  const storeMessageSelector = selectHMSMessagesCount;
95
+ const isMobile = useMedia(cssConfig.media.md);
86
96
 
87
97
  const messagesCount = useHMSStore(storeMessageSelector) || 0;
88
98
  const scrollToBottom = useCallback(
@@ -99,10 +109,26 @@ export const Chat = () => {
99
109
  );
100
110
 
101
111
  return (
102
- <Flex direction="column" css={{ size: '100%' }}>
103
- <ChatHeader
104
- selectorOpen={isSelectorOpen}
112
+ <Flex direction="column" css={{ size: '100%', gap: '$4' }}>
113
+ {!isMobile ? (
114
+ <>
115
+ <ChatParticipantHeader selectorOpen={isSelectorOpen} onToggle={() => setSelectorOpen(value => !value)} />
116
+ <PinnedMessage clearPinnedMessage={setPinnedMessage} />
117
+ </>
118
+ ) : null}
119
+
120
+ <ChatBody
121
+ role={chatOptions.role}
122
+ peerId={chatOptions.peerId}
123
+ ref={listRef}
124
+ scrollToBottom={scrollToBottom}
125
+ screenType={screenType}
126
+ />
127
+ <ChatFooter
128
+ role={chatOptions.role}
129
+ onSend={() => scrollToBottom(1)}
105
130
  selection={chatOptions.selection}
131
+ screenType={screenType}
106
132
  onSelect={({ role, peerId, selection }) => {
107
133
  setChatOptions({
108
134
  role,
@@ -112,16 +138,8 @@ export const Chat = () => {
112
138
  setPeerSelector(peerId);
113
139
  setRoleSelector(role);
114
140
  }}
115
- role={chatOptions.role}
116
141
  peerId={chatOptions.peerId}
117
- onToggle={() => {
118
- setSelectorOpen(value => !value);
119
- }}
120
- />
121
- <PinnedMessage clearPinnedMessage={setPinnedMessage} />
122
-
123
- <ChatBody role={chatOptions.role} peerId={chatOptions.peerId} ref={listRef} scrollToBottom={scrollToBottom} />
124
- <ChatFooter role={chatOptions.role} peerId={chatOptions.peerId} onSend={() => scrollToBottom(1)}>
142
+ >
125
143
  {!isSelectorOpen && (
126
144
  <NewMessageIndicator role={chatOptions.role} peerId={chatOptions.peerId} scrollToBottom={scrollToBottom} />
127
145
  )}
@@ -146,13 +164,26 @@ const NewMessageIndicator = ({ role, peerId, scrollToBottom }) => {
146
164
  }}
147
165
  >
148
166
  <Button
167
+ variant="standard"
149
168
  onClick={() => {
150
169
  scrollToBottom(unreadCount);
151
170
  }}
152
- css={{ p: '$2 $4', '& > svg': { ml: '$4' } }}
171
+ icon
172
+ css={{
173
+ p: '$4',
174
+ pl: '$8',
175
+ pr: '$6',
176
+ '& > svg': { ml: '$4' },
177
+ borderRadius: '$round',
178
+ position: 'relative',
179
+ bottom: '$16',
180
+ fontSize: '$xs',
181
+ fontWeight: '$semiBold',
182
+ c: '$on_secondary_high',
183
+ }}
153
184
  >
154
- New Messages
155
- <ChevronDownIcon width={16} height={16} />
185
+ New {unreadCount === 1 ? 'message' : 'messages'}
186
+ <ChevronDownIcon />
156
187
  </Button>
157
188
  </Flex>
158
189
  );
@@ -1,5 +1,6 @@
1
- import React, { Fragment, useCallback, useEffect, useLayoutEffect, useRef, useState } from 'react';
1
+ import React, { Fragment, useCallback, useEffect, useLayoutEffect, useMemo, useRef, useState } from 'react';
2
2
  import { useInView } from 'react-intersection-observer';
3
+ import { useMedia } from 'react-use';
3
4
  import AutoSizer from 'react-virtualized-auto-sizer';
4
5
  import { VariableSizeList } from 'react-window';
5
6
  import {
@@ -13,13 +14,15 @@ import {
13
14
  useHMSActions,
14
15
  useHMSStore,
15
16
  } from '@100mslive/react-sdk';
16
- import { HorizontalMenuIcon, PinIcon } from '@100mslive/react-icons';
17
+ import { CopyIcon, PinIcon, VerticalMenuIcon } from '@100mslive/react-icons';
17
18
  import { Dropdown } from '../../../Dropdown';
18
19
  import { IconButton } from '../../../IconButton';
19
20
  import { Box, Flex } from '../../../Layout';
20
21
  import { Text } from '../../../Text';
21
- import { styled } from '../../../Theme';
22
+ import { config as cssConfig, styled } from '../../../Theme';
22
23
  import { Tooltip } from '../../../Tooltip';
24
+ import emptyChat from '../../images/empty-chat.svg';
25
+ import { ToastManager } from '../Toast/ToastManager';
23
26
  import { useSetPinnedMessage } from '../hooks/useSetPinnedMessage';
24
27
 
25
28
  const formatTime = date => {
@@ -46,7 +49,7 @@ const MessageTypeContainer = ({ left, right }) => {
46
49
  ml: 'auto',
47
50
  mr: '$4',
48
51
  p: '$2 $4',
49
- border: '1px solid $on_surface_low',
52
+ border: '1px solid $border_bright',
50
53
  r: '$0',
51
54
  }}
52
55
  >
@@ -55,9 +58,9 @@ const MessageTypeContainer = ({ left, right }) => {
55
58
  {left}
56
59
  </SenderName>
57
60
  )}
58
- {left && right && <Box css={{ borderLeft: '1px solid $on_surface_low', mx: '$4', h: '$8' }} />}
61
+ {left && right && <Box css={{ borderLeft: '1px solid $border_bright', mx: '$4', h: '$8' }} />}
59
62
  {right && (
60
- <SenderName as="span" variant="tiny">
63
+ <SenderName as="span" variant="tiny" css={{ textTransform: 'uppercase' }}>
61
64
  {right}
62
65
  </SenderName>
63
66
  )}
@@ -123,16 +126,19 @@ const getMessageType = ({ roles, receiver }) => {
123
126
  }
124
127
  return receiver ? 'private' : '';
125
128
  };
126
-
127
- const ChatActions = ({ onPin }) => {
129
+ const ChatActions = ({ onPin, showPinAction, messageContent }) => {
128
130
  const [open, setOpen] = useState(false);
131
+ const isMobile = useMedia(cssConfig.media.md);
132
+ if (!isMobile && !showPinAction) {
133
+ return null;
134
+ }
129
135
 
130
136
  return (
131
137
  <Dropdown.Root open={open} onOpenChange={setOpen}>
132
- <Dropdown.Trigger asChild>
138
+ <Dropdown.Trigger className="chat_actions" css={{ opacity: open ? 1 : 0, '@md': { opacity: 1 } }} asChild>
133
139
  <IconButton>
134
140
  <Tooltip title="More options">
135
- <HorizontalMenuIcon />
141
+ <VerticalMenuIcon />
136
142
  </Tooltip>
137
143
  </IconButton>
138
144
  </Dropdown.Trigger>
@@ -140,7 +146,7 @@ const ChatActions = ({ onPin }) => {
140
146
  <Dropdown.Content
141
147
  sideOffset={5}
142
148
  align="end"
143
- css={{ width: '$48', backgroundColor: '$surface_bright', py: '$0' }}
149
+ css={{ width: '$48', backgroundColor: '$surface_bright', py: '$0', border: '1px solid $border_bright' }}
144
150
  >
145
151
  <Dropdown.Item data-testid="pin_message_btn" onClick={onPin}>
146
152
  <PinIcon />
@@ -148,6 +154,30 @@ const ChatActions = ({ onPin }) => {
148
154
  Pin Message
149
155
  </Text>
150
156
  </Dropdown.Item>
157
+ {isMobile && showPinAction ? <Dropdown.ItemSeparator css={{ my: 0 }} /> : null}
158
+ {isMobile ? (
159
+ <Dropdown.Item
160
+ data-testid="copy_message_btn"
161
+ onClick={() => {
162
+ try {
163
+ navigator?.clipboard.writeText(messageContent);
164
+ ToastManager.addToast({
165
+ title: 'Message copied successfully',
166
+ });
167
+ } catch (e) {
168
+ console.log(e);
169
+ ToastManager.addToast({
170
+ title: 'Could not copy message',
171
+ });
172
+ }
173
+ }}
174
+ >
175
+ <CopyIcon />
176
+ <Text variant="sm" css={{ ml: '$4' }}>
177
+ Copy Message
178
+ </Text>
179
+ </Dropdown.Item>
180
+ ) : null}
151
181
  </Dropdown.Content>
152
182
  </Dropdown.Portal>
153
183
  </Dropdown.Root>
@@ -160,6 +190,8 @@ const SenderName = styled(Text, {
160
190
  whiteSpace: 'nowrap',
161
191
  maxWidth: '24ch',
162
192
  minWidth: 0,
193
+ color: '$on_surface_high',
194
+ fontWeight: '$semiBold',
163
195
  });
164
196
 
165
197
  const ChatMessage = React.memo(({ index, style = {}, message, setRowHeight, onPin }) => {
@@ -170,6 +202,7 @@ const ChatMessage = React.memo(({ index, style = {}, message, setRowHeight, onPi
170
202
  setRowHeight(index, rowRef.current.clientHeight);
171
203
  }
172
204
  }, [index, setRowHeight]);
205
+ const isMobile = useMedia(cssConfig.media.md);
173
206
 
174
207
  const hmsActions = useHMSActions();
175
208
  const localPeerId = useHMSStore(selectLocalPeerID);
@@ -188,13 +221,19 @@ const ChatMessage = React.memo(({ index, style = {}, message, setRowHeight, onPi
188
221
  }, [message.read, hmsActions, inView, message.id]);
189
222
 
190
223
  return (
191
- <Box ref={ref} as="div" css={{ mb: '$10', pr: '$10' }} style={style}>
224
+ <Box
225
+ ref={ref}
226
+ as="div"
227
+ css={{ mb: '$10', pr: '$10', mt: '$8', '&:hover .chat_actions': { opacity: 1 } }}
228
+ style={style}
229
+ >
192
230
  <Flex
193
231
  ref={rowRef}
194
232
  align="center"
195
233
  css={{
196
234
  flexWrap: 'wrap',
197
- bg: messageType ? '$surface_bright' : undefined,
235
+ // Theme independent color, token should not be used for transparent chat
236
+ bg: messageType ? (isMobile ? 'rgba(0, 0, 0, 0.64)' : '$surface_default') : undefined,
198
237
  r: messageType ? '$1' : undefined,
199
238
  px: messageType ? '$4' : '$2',
200
239
  py: messageType ? '$4' : 0,
@@ -214,32 +253,40 @@ const ChatMessage = React.memo(({ index, style = {}, message, setRowHeight, onPi
214
253
  }}
215
254
  as="div"
216
255
  >
217
- <Flex align="center">
256
+ <Flex align="baseline">
218
257
  {message.senderName === 'You' || !message.senderName ? (
219
- <SenderName as="span">{message.senderName || 'Anonymous'}</SenderName>
258
+ <SenderName as="span" variant="sm">
259
+ {message.senderName || 'Anonymous'}
260
+ </SenderName>
220
261
  ) : (
221
262
  <Tooltip title={message.senderName} side="top" align="start">
222
- <SenderName as="span">{message.senderName}</SenderName>
263
+ <SenderName as="span" variant="sm">
264
+ {message.senderName}
265
+ </SenderName>
223
266
  </Tooltip>
224
267
  )}
225
- <Text
226
- as="span"
227
- variant="sm"
228
- css={{
229
- ml: '$4',
230
- color: '$on_primary_medium',
231
- flexShrink: 0,
232
- }}
233
- >
234
- {formatTime(message.time)}
235
- </Text>
268
+ {!isMobile ? (
269
+ <Text
270
+ as="span"
271
+ variant="xs"
272
+ css={{
273
+ ml: '$4',
274
+ color: '$on_primary_medium',
275
+ flexShrink: 0,
276
+ }}
277
+ >
278
+ {formatTime(message.time)}
279
+ </Text>
280
+ ) : null}
236
281
  </Flex>
237
282
  <MessageType
238
283
  hasCurrentUserSent={message.sender === localPeerId}
239
284
  receiver={message.recipientPeer}
240
285
  roles={message.recipientRoles}
241
286
  />
242
- {showPinAction && <ChatActions onPin={onPin} />}
287
+ {!isMobile ? (
288
+ <ChatActions onPin={onPin} showPinAction={showPinAction} messageContent={message.message} />
289
+ ) : null}
243
290
  </Text>
244
291
  <Text
245
292
  variant="body2"
@@ -345,21 +392,34 @@ export const ChatBody = React.forwardRef(({ role, peerId, scrollToBottom }, list
345
392
  : peerId
346
393
  ? selectMessagesByPeerID(peerId)
347
394
  : selectHMSMessages;
348
- const messages = useHMSStore(storeMessageSelector) || [];
395
+ let messages = useHMSStore(storeMessageSelector);
396
+ messages = useMemo(() => messages?.filter(message => message.type === 'chat') || [], [messages]);
397
+ const isMobile = useMedia(cssConfig.media.md);
349
398
 
350
- if (messages.length === 0) {
399
+ if (messages.length === 0 && !isMobile) {
351
400
  return (
352
401
  <Flex
353
402
  css={{
354
403
  width: '100%',
355
- height: '100%',
404
+ flex: '1 1 0',
356
405
  textAlign: 'center',
357
406
  px: '$4',
358
407
  }}
359
408
  align="center"
360
409
  justify="center"
361
410
  >
362
- <Text>There are no messages here</Text>
411
+ <Box>
412
+ <img src={emptyChat} alt="Empty Chat" height={132} width={185} style={{ margin: '0 auto' }} />
413
+ <Text variant="h5" css={{ mt: '$8', c: '$on_surface_high' }}>
414
+ Start a conversation
415
+ </Text>
416
+ <Text
417
+ variant="sm"
418
+ css={{ mt: '$4', maxWidth: '80%', textAlign: 'center', mx: 'auto', c: '$on_surface_medium' }}
419
+ >
420
+ There are no messages here yet. Start a conversation by sending a message.
421
+ </Text>
422
+ </Box>
363
423
  </Flex>
364
424
  );
365
425
  }
@@ -1,10 +1,12 @@
1
1
  import React, { useCallback, useEffect, useRef, useState } from 'react';
2
+ import { useMedia } from 'react-use';
2
3
  import data from '@emoji-mart/data';
3
4
  import Picker from '@emoji-mart/react';
4
5
  import { useHMSActions } from '@100mslive/react-sdk';
5
6
  import { EmojiIcon, SendIcon } from '@100mslive/react-icons';
6
- import { Box, Flex, IconButton, Popover, styled } from '../../../';
7
+ import { Box, config as cssConfig, Flex, IconButton as BaseIconButton, Popover, styled } from '../../../';
7
8
  import { ToastManager } from '../Toast/ToastManager';
9
+ // import { ChatSelectorContainer } from './ChatSelectorContainer';
8
10
  import { useChatDraftMessage } from '../AppData/useChatState';
9
11
  import { useEmojiPickerStyles } from './useEmojiPickerStyles';
10
12
 
@@ -32,9 +34,9 @@ function EmojiPicker({ onSelect }) {
32
34
  return (
33
35
  <Popover.Root open={showEmoji} onOpenChange={setShowEmoji}>
34
36
  <Popover.Trigger asChild css={{ appearance: 'none' }}>
35
- <IconButton as="div">
37
+ <BaseIconButton as="div">
36
38
  <EmojiIcon />
37
- </IconButton>
39
+ </BaseIconButton>
38
40
  </Popover.Trigger>
39
41
  <Popover.Portal>
40
42
  <Popover.Content
@@ -60,10 +62,11 @@ function EmojiPicker({ onSelect }) {
60
62
  );
61
63
  }
62
64
 
63
- export const ChatFooter = ({ role, peerId, onSend, children }) => {
65
+ export const ChatFooter = ({ role, peerId, onSend, children /* onSelect, selection, screenType */ }) => {
64
66
  const hmsActions = useHMSActions();
65
67
  const inputRef = useRef(null);
66
68
  const [draftMessage, setDraftMessage] = useChatDraftMessage();
69
+ const isMobile = useMedia(cssConfig.media.md);
67
70
 
68
71
  const sendMessage = useCallback(async () => {
69
72
  const message = inputRef.current.value;
@@ -102,49 +105,70 @@ export const ChatFooter = ({ role, peerId, onSend, children }) => {
102
105
  }, [setDraftMessage]);
103
106
 
104
107
  return (
105
- <Flex
106
- align="center"
107
- css={{
108
- bg: '$surface_bright',
109
- minHeight: '$16',
110
- maxHeight: '$24',
111
- position: 'relative',
112
- py: '$6',
113
- pl: '$8',
114
- r: '$1',
115
- }}
116
- >
117
- {children}
118
- <TextArea
119
- placeholder="Write something here"
120
- ref={inputRef}
121
- autoFocus
122
- onKeyPress={async event => {
123
- if (event.key === 'Enter') {
124
- if (!event.shiftKey) {
125
- event.preventDefault();
126
- await sendMessage();
127
- }
128
- }
129
- }}
130
- autoComplete="off"
131
- aria-autocomplete="none"
132
- onPaste={e => e.stopPropagation()}
133
- onCut={e => e.stopPropagation()}
134
- onCopy={e => e.stopPropagation()}
135
- />
136
- <EmojiPicker
137
- onSelect={emoji => {
138
- inputRef.current.value += ` ${emoji.native} `;
139
- }}
140
- />
141
- <IconButton
142
- onClick={sendMessage}
143
- css={{ ml: 'auto', height: 'max-content', mr: '$4' }}
144
- data-testid="send_msg_btn"
145
- >
146
- <SendIcon />
147
- </IconButton>
148
- </Flex>
108
+ <>
109
+ {/* {screenType !== 'hls_live_streaming' ? (
110
+ <ChatSelectorContainer onSelect={onSelect} role={role} peerId={peerId} selection={selection} />
111
+ ) : null} */}
112
+ <Flex align="center" css={{ gap: '$4', w: '100%' }}>
113
+ <Flex
114
+ align="center"
115
+ css={{
116
+ bg: isMobile ? '$surface_dim' : '$surface_default',
117
+ minHeight: '$16',
118
+ maxHeight: '$24',
119
+ position: 'relative',
120
+ py: '$6',
121
+ pl: '$8',
122
+ flexGrow: 1,
123
+ r: '$1',
124
+ '@md': {
125
+ minHeight: 'unset',
126
+ h: '$14',
127
+ boxSizing: 'border-box',
128
+ },
129
+ }}
130
+ >
131
+ {children}
132
+ <TextArea
133
+ placeholder="Send a message...."
134
+ ref={inputRef}
135
+ autoFocus
136
+ onKeyPress={async event => {
137
+ if (event.key === 'Enter') {
138
+ if (!event.shiftKey) {
139
+ event.preventDefault();
140
+ await sendMessage();
141
+ }
142
+ }
143
+ }}
144
+ autoComplete="off"
145
+ aria-autocomplete="none"
146
+ onPaste={e => e.stopPropagation()}
147
+ onCut={e => e.stopPropagation()}
148
+ onCopy={e => e.stopPropagation()}
149
+ />
150
+ {!isMobile ? (
151
+ <EmojiPicker
152
+ onSelect={emoji => {
153
+ inputRef.current.value += ` ${emoji.native} `;
154
+ }}
155
+ />
156
+ ) : null}
157
+ <BaseIconButton
158
+ onClick={sendMessage}
159
+ css={{
160
+ ml: 'auto',
161
+ height: 'max-content',
162
+ mr: '$4',
163
+ color: '$on_surface_low',
164
+ '&:hover': { c: '$on_surface_high' },
165
+ }}
166
+ data-testid="send_msg_btn"
167
+ >
168
+ <SendIcon />
169
+ </BaseIconButton>
170
+ </Flex>
171
+ </Flex>
172
+ </>
149
173
  );
150
174
  };