@100mslive/roomkit-react 0.1.4-alpha.1 → 0.1.4
Sign up to get free protection for your applications and to get access to all the features.
- package/dist/{HLSView-F2K5VSTS.js → HLSView-CTAJQUU4.js} +7 -11
- package/dist/{HLSView-F2K5VSTS.js.map → HLSView-CTAJQUU4.js.map} +1 -1
- package/dist/PinnedTrackView-CQKONH4O.js +102 -0
- package/dist/PinnedTrackView-CQKONH4O.js.map +7 -0
- package/dist/Popover/index.d.ts +1 -0
- package/dist/Prebuilt/App.d.ts +25 -0
- package/dist/Prebuilt/index.d.ts +1 -0
- package/dist/Prebuilt/provider/roomLayoutProvider/index.d.ts +1 -1
- package/dist/Sheet/Sheet.d.ts +3093 -0
- package/dist/Sheet/index.d.ts +1 -0
- package/dist/Theme/ThemeProvider.d.ts +4 -286
- package/dist/Theme/stitches.config.d.ts +1 -1
- package/dist/{VirtualBackground-S3XEPZ2T.js → VirtualBackground-GGGBJYVY.js} +31 -7
- package/dist/VirtualBackground-GGGBJYVY.js.map +7 -0
- package/dist/chunk-I2FJWE74.js +827 -0
- package/dist/chunk-I2FJWE74.js.map +7 -0
- package/dist/{chunk-42SWPN2C.js → chunk-L2SX7GBO.js} +3020 -2189
- package/dist/chunk-L2SX7GBO.js.map +7 -0
- package/dist/chunk-NOKIGB6Y.js +1100 -0
- package/dist/chunk-NOKIGB6Y.js.map +7 -0
- package/dist/chunk-TJNDX446.js +67 -0
- package/dist/chunk-TJNDX446.js.map +7 -0
- package/dist/{chunk-ESUJK7AT.js → conference-OEO7VOJD.js} +3136 -653
- package/dist/conference-OEO7VOJD.js.map +7 -0
- package/dist/index.cjs.js +15733 -15498
- package/dist/index.cjs.js.map +4 -4
- package/dist/index.js +4 -8
- package/dist/meta.cjs.json +3355 -3017
- package/dist/meta.esbuild.json +3534 -3329
- package/dist/utils/animations.d.ts +16 -0
- package/package.json +8 -10
- package/src/Button/Button.tsx +4 -4
- package/src/Dropdown/Dropdown.tsx +2 -2
- package/src/IconButton/IconButton.tsx +4 -2
- package/src/Pagination/StyledPagination.tsx +1 -0
- package/src/Popover/index.tsx +2 -1
- package/src/Prebuilt/{App.jsx → App.tsx} +95 -48
- package/src/Prebuilt/Prebuilt.stories.tsx +22 -8
- package/src/Prebuilt/common/constants.js +1 -2
- package/src/Prebuilt/common/hooks.js +8 -0
- package/src/Prebuilt/common/utils.js +15 -0
- package/src/Prebuilt/components/AppData/AppData.jsx +1 -2
- package/src/Prebuilt/components/AppData/useUISettings.js +0 -5
- package/src/Prebuilt/components/AudioVideoToggle.jsx +69 -26
- package/src/Prebuilt/components/AuthToken.jsx +3 -2
- package/src/Prebuilt/components/Chat/ChatSelector.jsx +1 -1
- package/src/Prebuilt/components/Connection/TileConnection.jsx +0 -1
- package/src/Prebuilt/components/EmojiReaction.jsx +23 -73
- package/src/Prebuilt/components/EndSessionContent.jsx +57 -0
- package/src/Prebuilt/components/EqualProminence.jsx +180 -0
- package/src/Prebuilt/components/ErrorBoundary.jsx +4 -10
- package/src/Prebuilt/components/Footer/EmojiCard.jsx +34 -0
- package/src/Prebuilt/components/Footer/Footer.jsx +73 -0
- package/src/Prebuilt/components/{Header → Footer}/ParticipantList.jsx +5 -5
- package/src/Prebuilt/components/Header/ConferencingHeader.jsx +27 -7
- package/src/Prebuilt/components/Header/HeaderComponents.jsx +16 -14
- package/src/Prebuilt/components/Header/StreamActions.jsx +101 -36
- package/src/Prebuilt/components/Header/StreamingHeader.jsx +1 -1
- package/src/Prebuilt/components/Header/common.jsx +164 -0
- package/src/Prebuilt/components/IconButtonWithOptions/IconButtonWithOptions.jsx +1 -2
- package/src/Prebuilt/components/LeaveCard.jsx +19 -0
- package/src/Prebuilt/components/LeaveRoom.jsx +35 -143
- package/src/Prebuilt/components/LeaveSessionContent.jsx +45 -0
- package/src/Prebuilt/components/MoreSettings/ActionTile.jsx +55 -0
- package/src/Prebuilt/components/MoreSettings/ChangeNameContent.jsx +96 -0
- package/src/Prebuilt/components/MoreSettings/ChangeNameModal.jsx +31 -54
- package/src/Prebuilt/components/MoreSettings/EmbedUrl.jsx +48 -73
- package/src/Prebuilt/components/MoreSettings/MoreSettings.jsx +5 -221
- package/src/Prebuilt/components/MoreSettings/MuteAllContent.jsx +61 -0
- package/src/Prebuilt/components/MoreSettings/MuteAllModal.jsx +32 -49
- package/src/Prebuilt/components/MoreSettings/SplitComponents/DesktopLeaveRoom.jsx +129 -0
- package/src/Prebuilt/components/MoreSettings/SplitComponents/DesktopOptions.jsx +219 -0
- package/src/Prebuilt/components/MoreSettings/SplitComponents/MwebLeaveRoom.jsx +100 -0
- package/src/Prebuilt/components/MoreSettings/SplitComponents/MwebOptions.jsx +259 -0
- package/src/Prebuilt/components/Notifications/Notifications.jsx +0 -2
- package/src/Prebuilt/components/Notifications/ReconnectNotifications.jsx +0 -4
- package/src/Prebuilt/components/PIP/PIPComponent.jsx +30 -26
- package/src/Prebuilt/components/PIP/PIPManager.js +13 -0
- package/src/Prebuilt/components/PIP/index.jsx +2 -7
- package/src/Prebuilt/components/Pagination.jsx +4 -4
- package/src/Prebuilt/components/Preview/PreviewContainer.jsx +5 -13
- package/src/Prebuilt/components/Preview/PreviewForm.jsx +9 -5
- package/src/Prebuilt/components/Preview/PreviewJoin.jsx +20 -27
- package/src/Prebuilt/components/RaiseHand.jsx +27 -0
- package/src/Prebuilt/components/ScreenShare.jsx +1 -1
- package/src/Prebuilt/components/ScreenshareDisplay.jsx +2 -2
- package/src/Prebuilt/components/ScreenshareTile.jsx +2 -2
- package/src/Prebuilt/components/Settings/DeviceSettings.jsx +2 -1
- package/src/Prebuilt/components/Settings/LayoutSettings.jsx +1 -24
- package/src/Prebuilt/components/Settings/SettingsModal.jsx +152 -17
- package/src/Prebuilt/components/ShareMenuIcon.jsx +1 -0
- package/src/Prebuilt/components/TileMenu/TileMenu.jsx +133 -0
- package/src/Prebuilt/components/TileMenu/TileMenuContent.jsx +313 -0
- package/src/Prebuilt/components/VideoList.jsx +5 -33
- package/src/Prebuilt/components/VideoTile.jsx +30 -8
- package/src/Prebuilt/components/conference.jsx +14 -1
- package/src/Prebuilt/components/init/Init.jsx +0 -27
- package/src/Prebuilt/components/init/initUtils.js +0 -23
- package/src/Prebuilt/components/pdfAnnotator/pdfFileOptions.jsx +2 -1
- package/src/Prebuilt/components/pdfAnnotator/pdfInfo.jsx +1 -1
- package/src/Prebuilt/components/pdfAnnotator/shareScreenOptions.jsx +19 -8
- package/src/Prebuilt/components/pdfAnnotator/uploadedFile.jsx +1 -0
- package/src/Prebuilt/images/pdf-share.png +0 -0
- package/src/Prebuilt/images/screen-share.png +0 -0
- package/src/Prebuilt/index.ts +1 -0
- package/src/Prebuilt/layouts/EmbedView.jsx +0 -1
- package/src/Prebuilt/layouts/InsetView.jsx +65 -24
- package/src/Prebuilt/layouts/PDFView.jsx +0 -1
- package/src/Prebuilt/layouts/SidePane.jsx +8 -7
- package/src/Prebuilt/layouts/mainView.jsx +22 -31
- package/src/Prebuilt/layouts/screenShareView.jsx +0 -2
- package/src/Prebuilt/plugins/VirtualBackground/VirtualBackground.jsx +25 -1
- package/src/Prebuilt/primitives/DialogContent.jsx +1 -1
- package/src/Prebuilt/provider/roomLayoutProvider/index.tsx +1 -1
- package/src/Sheet/Sheet.mdx +19 -0
- package/src/Sheet/Sheet.stories.tsx +103 -0
- package/src/Sheet/Sheet.tsx +118 -0
- package/src/Sheet/index.ts +1 -0
- package/src/Theme/ThemeProvider.tsx +10 -13
- package/src/Theme/base.config.ts +1 -1
- package/src/Theme/stitches.config.ts +1 -1
- package/src/TileMenu/StyledMenuTile.tsx +2 -2
- package/src/TileMenu/TileMenu.tsx +2 -0
- package/src/VideoTile/StyledVideoTile.tsx +5 -0
- package/src/utils/animations.ts +18 -0
- package/dist/ActiveSpeakerView-V6O4K3BV.js +0 -39
- package/dist/ActiveSpeakerView-V6O4K3BV.js.map +0 -7
- package/dist/PinnedTrackView-7YQG4QKC.js +0 -70
- package/dist/PinnedTrackView-7YQG4QKC.js.map +0 -7
- package/dist/VirtualBackground-S3XEPZ2T.js.map +0 -7
- package/dist/chunk-42SWPN2C.js.map +0 -7
- package/dist/chunk-4NEZLVVH.js +0 -811
- package/dist/chunk-4NEZLVVH.js.map +0 -7
- package/dist/chunk-4ZBEFSRC.js +0 -58
- package/dist/chunk-4ZBEFSRC.js.map +0 -7
- package/dist/chunk-ESUJK7AT.js.map +0 -7
- package/dist/chunk-R6PDR5WZ.js +0 -243
- package/dist/chunk-R6PDR5WZ.js.map +0 -7
- package/dist/conference-7QKOMJPP.js +0 -3697
- package/dist/conference-7QKOMJPP.js.map +0 -7
- package/dist/transcription-RJA4V6PC.js +0 -356
- package/dist/transcription-RJA4V6PC.js.map +0 -7
- package/src/Prebuilt/common/useSortedPeers.js +0 -28
- package/src/Prebuilt/components/BottomActionSheet/BottomActionSheet.jsx +0 -96
- package/src/Prebuilt/components/BottomActionSheet/BottomActionSheet.stories.tsx +0 -46
- package/src/Prebuilt/components/Footer/ConferencingFooter.jsx +0 -101
- package/src/Prebuilt/components/Footer/StreamingFooter.jsx +0 -71
- package/src/Prebuilt/components/Footer.jsx +0 -8
- package/src/Prebuilt/components/MoreSettings/ChangeSelfRole.jsx +0 -67
- package/src/Prebuilt/components/TileMenu.jsx +0 -268
- package/src/Prebuilt/index.d.ts +0 -20
- package/src/Prebuilt/index.js +0 -2
@@ -1,7 +1,9 @@
|
|
1
1
|
import React, { Fragment } from 'react';
|
2
2
|
import {
|
3
3
|
DeviceType,
|
4
|
+
HMSRoomState,
|
4
5
|
selectLocalVideoTrackID,
|
6
|
+
selectRoomState,
|
5
7
|
selectVideoTrackByID,
|
6
8
|
useAVToggle,
|
7
9
|
useDevices,
|
@@ -18,7 +20,7 @@ import { isMacOS } from '../common/constants';
|
|
18
20
|
|
19
21
|
const optionsCSS = { fontWeight: '$semiBold', color: '$on_surface_high', w: '100%', p: '$8' };
|
20
22
|
|
21
|
-
export const AudioVideoToggle = () => {
|
23
|
+
export const AudioVideoToggle = ({ hideOptions = false }) => {
|
22
24
|
const { allDevices, selectedDeviceIDs, updateDevice } = useDevices();
|
23
25
|
const { videoInput, audioInput } = allDevices;
|
24
26
|
|
@@ -64,40 +66,81 @@ export const AudioVideoToggle = () => {
|
|
64
66
|
const actions = useHMSActions();
|
65
67
|
const videoTrackId = useHMSStore(selectLocalVideoTrackID);
|
66
68
|
const localVideoTrack = useHMSStore(selectVideoTrackByID(videoTrackId));
|
69
|
+
const roomState = useHMSStore(selectRoomState);
|
67
70
|
|
68
71
|
return (
|
69
72
|
<Fragment>
|
70
73
|
{toggleAudio ? (
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
74
|
+
hideOptions ? (
|
75
|
+
<Tooltip title={`Turn ${isLocalAudioEnabled ? 'off' : 'on'} audio (${isMacOS ? '⌘' : 'ctrl'} + d)`}>
|
76
|
+
<IconButton
|
77
|
+
active={isLocalAudioEnabled}
|
78
|
+
onClick={toggleAudio}
|
79
|
+
key="toggleAudio"
|
80
|
+
data-testid="audio_btn"
|
81
|
+
className="__cancel-drag-event"
|
82
|
+
>
|
83
|
+
{!isLocalAudioEnabled ? (
|
84
|
+
<MicOffIcon data-testid="audio_off_btn" />
|
85
|
+
) : (
|
86
|
+
<MicOnIcon data-testid="audio_on_btn" />
|
87
|
+
)}
|
88
|
+
</IconButton>
|
89
|
+
</Tooltip>
|
90
|
+
) : (
|
91
|
+
<IconButtonWithOptions
|
92
|
+
options={formattedAudioInputList}
|
93
|
+
tooltipMessage={`Turn ${isLocalAudioEnabled ? 'off' : 'on'} audio (${isMacOS ? '⌘' : 'ctrl'} + d)`}
|
94
|
+
icon={
|
95
|
+
!isLocalAudioEnabled ? (
|
96
|
+
<MicOffIcon data-testid="audio_off_btn" />
|
97
|
+
) : (
|
98
|
+
<MicOnIcon data-testid="audio_on_btn" />
|
99
|
+
)
|
100
|
+
}
|
101
|
+
active={isLocalAudioEnabled}
|
102
|
+
onClick={toggleAudio}
|
103
|
+
key="toggleAudio"
|
104
|
+
/>
|
105
|
+
)
|
81
106
|
) : null}
|
82
107
|
|
83
108
|
{toggleVideo ? (
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
109
|
+
hideOptions ? (
|
110
|
+
<Tooltip title={`Turn ${isLocalVideoEnabled ? 'off' : 'on'} video (${isMacOS ? '⌘' : 'ctrl'} + e)`}>
|
111
|
+
<IconButton
|
112
|
+
key="toggleVideo"
|
113
|
+
active={isLocalVideoEnabled}
|
114
|
+
onClick={toggleVideo}
|
115
|
+
data-testid="video_btn"
|
116
|
+
className="__cancel-drag-event"
|
117
|
+
>
|
118
|
+
{!isLocalVideoEnabled ? (
|
119
|
+
<VideoOffIcon data-testid="video_off_btn" />
|
120
|
+
) : (
|
121
|
+
<VideoOnIcon data-testid="video_on_btn" />
|
122
|
+
)}
|
123
|
+
</IconButton>
|
124
|
+
</Tooltip>
|
125
|
+
) : (
|
126
|
+
<IconButtonWithOptions
|
127
|
+
options={formattedVideoInputList}
|
128
|
+
tooltipMessage={`Turn ${isLocalVideoEnabled ? 'off' : 'on'} video (${isMacOS ? '⌘' : 'ctrl'} + e)`}
|
129
|
+
icon={
|
130
|
+
!isLocalVideoEnabled ? (
|
131
|
+
<VideoOffIcon data-testid="video_off_btn" />
|
132
|
+
) : (
|
133
|
+
<VideoOnIcon data-testid="video_on_btn" />
|
134
|
+
)
|
135
|
+
}
|
136
|
+
key="toggleVideo"
|
137
|
+
active={isLocalVideoEnabled}
|
138
|
+
onClick={toggleVideo}
|
139
|
+
/>
|
140
|
+
)
|
98
141
|
) : null}
|
99
142
|
|
100
|
-
{localVideoTrack?.facingMode ? (
|
143
|
+
{localVideoTrack?.facingMode && roomState === HMSRoomState.Preview ? (
|
101
144
|
<Tooltip title="Switch Camera" key="switchCamera">
|
102
145
|
<IconButton
|
103
146
|
onClick={async () => {
|
@@ -22,7 +22,7 @@ import { APP_DATA, QUERY_PARAM_AUTH_TOKEN } from '../common/constants';
|
|
22
22
|
const AuthToken = React.memo(({ authTokenByRoomCodeEndpoint }) => {
|
23
23
|
const hmsActions = useHMSActions();
|
24
24
|
const tokenEndpoint = useTokenEndpoint();
|
25
|
-
const { showPreview, roomCode } = useHMSPrebuiltContext();
|
25
|
+
const { showPreview, roomCode, userId } = useHMSPrebuiltContext();
|
26
26
|
const location = useLocation();
|
27
27
|
const matches = useMemo(
|
28
28
|
() =>
|
@@ -46,7 +46,7 @@ const AuthToken = React.memo(({ authTokenByRoomCodeEndpoint }) => {
|
|
46
46
|
const code = !userRole && (roomCode || urlRoomCode);
|
47
47
|
|
48
48
|
const getTokenFn = code
|
49
|
-
? () => hmsActions.getAuthTokenByRoomCode({ roomCode: code }, { endpoint: authTokenByRoomCodeEndpoint })
|
49
|
+
? () => hmsActions.getAuthTokenByRoomCode({ roomCode: code, userId }, { endpoint: authTokenByRoomCodeEndpoint })
|
50
50
|
: () => getToken(tokenEndpoint, uuid(), userRole, urlRoomId);
|
51
51
|
|
52
52
|
getTokenFn()
|
@@ -66,6 +66,7 @@ const AuthToken = React.memo(({ authTokenByRoomCodeEndpoint }) => {
|
|
66
66
|
authTokenByRoomCodeEndpoint,
|
67
67
|
setAuthTokenInAppData,
|
68
68
|
roomCode,
|
69
|
+
userId,
|
69
70
|
]);
|
70
71
|
|
71
72
|
if (error.title) {
|
@@ -10,7 +10,7 @@ import {
|
|
10
10
|
} from '@100mslive/react-sdk';
|
11
11
|
import { CheckIcon } from '@100mslive/react-icons';
|
12
12
|
import { Box, Dropdown, Flex, HorizontalDivider, Text, Tooltip } from '../../../';
|
13
|
-
import { ParticipantSearch } from '../
|
13
|
+
import { ParticipantSearch } from '../Footer/ParticipantList';
|
14
14
|
import { useFilteredRoles } from '../../common/hooks';
|
15
15
|
|
16
16
|
const ChatDotIcon = () => {
|
@@ -5,44 +5,36 @@ import {
|
|
5
5
|
selectAvailableRoleNames,
|
6
6
|
selectIsConnectedToRoom,
|
7
7
|
selectLocalPeerID,
|
8
|
-
selectLocalPeerRoleName,
|
9
8
|
useCustomEvent,
|
10
9
|
useHMSActions,
|
11
10
|
useHMSStore,
|
12
11
|
useRecordingStreaming,
|
13
12
|
} from '@100mslive/react-sdk';
|
14
13
|
import { EmojiIcon } from '@100mslive/react-icons';
|
14
|
+
import { EmojiCard } from './Footer/EmojiCard';
|
15
|
+
import { ToastManager } from './Toast/ToastManager';
|
15
16
|
import { Dropdown } from '../../Dropdown';
|
16
|
-
import {
|
17
|
-
import { Text } from '../../Text';
|
18
|
-
import { styled } from '../../Theme';
|
17
|
+
import { Box } from '../../Layout';
|
19
18
|
import { Tooltip } from '../../Tooltip';
|
20
19
|
import IconButton from '../IconButton';
|
21
20
|
import { useHLSViewerRole } from './AppData/useUISettings';
|
22
21
|
import { useDropdownList } from './hooks/useDropdownList';
|
23
22
|
import { useIsFeatureEnabled } from './hooks/useFeatures';
|
24
|
-
import { EMOJI_REACTION_TYPE, FEATURE_LIST
|
23
|
+
import { EMOJI_REACTION_TYPE, FEATURE_LIST } from '../common/constants';
|
25
24
|
|
26
25
|
init({ data });
|
27
26
|
|
28
|
-
// When changing emojis in the grid, keep in mind that the payload used in sendHLSTimedMetadata has a limit of 100 characters. Using bigger emoji Ids can cause the limit to be exceeded.
|
29
|
-
const emojiReactionList = [
|
30
|
-
[{ emojiId: '+1' }, { emojiId: '-1' }, { emojiId: 'wave' }, { emojiId: 'clap' }, { emojiId: 'fire' }],
|
31
|
-
[{ emojiId: 'tada' }, { emojiId: 'heart_eyes' }, { emojiId: 'joy' }, { emojiId: 'open_mouth' }, { emojiId: 'sob' }],
|
32
|
-
];
|
33
|
-
|
34
27
|
export const EmojiReaction = () => {
|
35
28
|
const [open, setOpen] = useState(false);
|
36
|
-
const hmsActions = useHMSActions();
|
37
29
|
const isConnected = useHMSStore(selectIsConnectedToRoom);
|
30
|
+
const isFeatureEnabled = useIsFeatureEnabled(FEATURE_LIST.EMOJI_REACTION);
|
31
|
+
useDropdownList({ open: open, name: 'EmojiReaction' });
|
32
|
+
const hmsActions = useHMSActions();
|
38
33
|
const roles = useHMSStore(selectAvailableRoleNames);
|
39
|
-
const localPeerRole = useHMSStore(selectLocalPeerRoleName);
|
40
34
|
const localPeerId = useHMSStore(selectLocalPeerID);
|
41
35
|
const hlsViewerRole = useHLSViewerRole();
|
42
36
|
const { isStreamingOn } = useRecordingStreaming();
|
43
|
-
const isFeatureEnabled = useIsFeatureEnabled(FEATURE_LIST.EMOJI_REACTION);
|
44
37
|
const filteredRoles = useMemo(() => roles.filter(role => role !== hlsViewerRole), [roles, hlsViewerRole]);
|
45
|
-
useDropdownList({ open: open, name: 'EmojiReaction' });
|
46
38
|
|
47
39
|
const onEmojiEvent = useCallback(data => {
|
48
40
|
window.showFlyingEmoji(data?.emojiId, data?.senderId);
|
@@ -61,16 +53,21 @@ export const EmojiReaction = () => {
|
|
61
53
|
};
|
62
54
|
sendEvent(data, { roleNames: filteredRoles });
|
63
55
|
if (isStreamingOn) {
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
56
|
+
try {
|
57
|
+
await hmsActions.sendHLSTimedMetadata([
|
58
|
+
{
|
59
|
+
payload: JSON.stringify(data),
|
60
|
+
duration: 2,
|
61
|
+
},
|
62
|
+
]);
|
63
|
+
} catch (error) {
|
64
|
+
console.log(error);
|
65
|
+
ToastManager.addToast({ title: error.message });
|
66
|
+
}
|
70
67
|
}
|
71
68
|
};
|
72
69
|
|
73
|
-
if (!isConnected ||
|
70
|
+
if (!isConnected || !isFeatureEnabled) {
|
74
71
|
return null;
|
75
72
|
}
|
76
73
|
return (
|
@@ -79,63 +76,16 @@ export const EmojiReaction = () => {
|
|
79
76
|
<Dropdown.Trigger asChild data-testid="emoji_reaction_btn">
|
80
77
|
<IconButton>
|
81
78
|
<Tooltip title="Emoji reaction">
|
82
|
-
<
|
79
|
+
<Box>
|
80
|
+
<EmojiIcon />
|
81
|
+
</Box>
|
83
82
|
</Tooltip>
|
84
83
|
</IconButton>
|
85
84
|
</Dropdown.Trigger>
|
86
85
|
<Dropdown.Content sideOffset={5} align="center" css={{ p: '$8', bg: '$surface_default' }}>
|
87
|
-
{
|
88
|
-
<Flex key={index} justify="between" css={{ mb: '$8' }}>
|
89
|
-
{emojiLine.map(emoji => (
|
90
|
-
<EmojiContainer key={emoji.emojiId} onClick={() => sendReaction(emoji.emojiId)}>
|
91
|
-
<em-emoji id={emoji.emojiId} size="100%" set="apple"></em-emoji>
|
92
|
-
</EmojiContainer>
|
93
|
-
))}
|
94
|
-
</Flex>
|
95
|
-
))}
|
96
|
-
<div style={{ textAlign: 'center' }}>
|
97
|
-
<Text
|
98
|
-
variant="sm"
|
99
|
-
inline={true}
|
100
|
-
css={{
|
101
|
-
color: '$on_primary_medium',
|
102
|
-
}}
|
103
|
-
>
|
104
|
-
Reactions will be timed for Live Streaming viewers.{' '}
|
105
|
-
</Text>
|
106
|
-
<Text
|
107
|
-
variant="sm"
|
108
|
-
inline={true}
|
109
|
-
css={{
|
110
|
-
color: '$primary_bright',
|
111
|
-
fontWeight: '$semiBold',
|
112
|
-
}}
|
113
|
-
>
|
114
|
-
<a
|
115
|
-
href={HLS_TIMED_METADATA_DOC_URL}
|
116
|
-
target="_blank"
|
117
|
-
rel="noopener noreferrer"
|
118
|
-
style={{ color: 'inherit', textDecoration: 'none' }}
|
119
|
-
>
|
120
|
-
Learn more.
|
121
|
-
</a>
|
122
|
-
</Text>
|
123
|
-
</div>
|
86
|
+
<EmojiCard sendReaction={sendReaction} />
|
124
87
|
</Dropdown.Content>
|
125
88
|
</Dropdown.Root>
|
126
89
|
</Fragment>
|
127
90
|
);
|
128
91
|
};
|
129
|
-
|
130
|
-
const EmojiContainer = styled('span', {
|
131
|
-
position: 'relative',
|
132
|
-
cursor: 'pointer',
|
133
|
-
width: '$16',
|
134
|
-
height: '$16',
|
135
|
-
p: '$4',
|
136
|
-
'&:hover': {
|
137
|
-
p: '7px',
|
138
|
-
bg: '$surface_brighter',
|
139
|
-
borderRadius: '$1',
|
140
|
-
},
|
141
|
-
});
|
@@ -0,0 +1,57 @@
|
|
1
|
+
import React from 'react';
|
2
|
+
import { AlertTriangleIcon, CrossIcon } from '@100mslive/react-icons';
|
3
|
+
import { Button } from '../../Button';
|
4
|
+
import { Box, Flex } from '../../Layout';
|
5
|
+
import { Text } from '../../Text';
|
6
|
+
import { useShowStreamingUI } from '../common/hooks';
|
7
|
+
|
8
|
+
export const EndSessionContent = ({ setShowEndStreamAlert, stopStream, leaveRoom, isModal = false }) => {
|
9
|
+
const showStreamingUI = useShowStreamingUI();
|
10
|
+
return (
|
11
|
+
<Box>
|
12
|
+
<Flex
|
13
|
+
css={{
|
14
|
+
color: '$alert_error_default',
|
15
|
+
display: 'flex',
|
16
|
+
alignItems: 'center',
|
17
|
+
}}
|
18
|
+
>
|
19
|
+
<AlertTriangleIcon style={{ marginRight: '0.5rem' }} />
|
20
|
+
<Text variant="lg" css={{ color: 'inherit', fontWeight: '$semiBold' }}>
|
21
|
+
End {showStreamingUI ? 'Stream' : 'Session'}
|
22
|
+
</Text>
|
23
|
+
{isModal ? null : (
|
24
|
+
<Box css={{ color: '$on_surface_high', ml: 'auto' }} onClick={() => setShowEndStreamAlert(false)}>
|
25
|
+
<CrossIcon />
|
26
|
+
</Box>
|
27
|
+
)}
|
28
|
+
</Flex>
|
29
|
+
<Text variant="sm" css={{ color: '$on_surface_medium', mb: '$8', mt: '$4' }}>
|
30
|
+
The {showStreamingUI ? 'stream' : 'session'} will end for everyone. You can't undo this action.
|
31
|
+
</Text>
|
32
|
+
<Flex align="center" justify="between" css={{ w: '100%', gap: '$8' }}>
|
33
|
+
<Button
|
34
|
+
outlined
|
35
|
+
variant="standard"
|
36
|
+
css={{ w: '100%', '@md': { display: 'none' } }}
|
37
|
+
onClick={() => setShowEndStreamAlert(false)}
|
38
|
+
>
|
39
|
+
Cancel
|
40
|
+
</Button>
|
41
|
+
<Button
|
42
|
+
variant="danger"
|
43
|
+
css={{ w: '100%' }}
|
44
|
+
onClick={async () => {
|
45
|
+
await stopStream();
|
46
|
+
leaveRoom();
|
47
|
+
setShowEndStreamAlert(false);
|
48
|
+
}}
|
49
|
+
id="stopStream"
|
50
|
+
data-testid="stop_stream_btn"
|
51
|
+
>
|
52
|
+
End {showStreamingUI ? 'Stream' : 'Session'}
|
53
|
+
</Button>
|
54
|
+
</Flex>
|
55
|
+
</Box>
|
56
|
+
);
|
57
|
+
};
|
@@ -0,0 +1,180 @@
|
|
1
|
+
import React, { useEffect, useMemo, useState } from 'react';
|
2
|
+
import { useMeasure, useMedia } from 'react-use';
|
3
|
+
import {
|
4
|
+
getPeersWithTiles,
|
5
|
+
selectLocalPeer,
|
6
|
+
selectPeers,
|
7
|
+
selectRemotePeers,
|
8
|
+
selectTracksMap,
|
9
|
+
useHMSStore,
|
10
|
+
useHMSVanillaStore,
|
11
|
+
} from '@100mslive/react-sdk';
|
12
|
+
import { Box, Flex } from '../../Layout';
|
13
|
+
import { config as cssConfig } from '../../Theme';
|
14
|
+
import { InsetTile } from '../layouts/InsetView';
|
15
|
+
import { useRoomLayout } from '../provider/roomLayoutProvider';
|
16
|
+
import { Pagination } from './Pagination';
|
17
|
+
import VideoTile from './VideoTile';
|
18
|
+
import { useUISettings } from './AppData/useUISettings';
|
19
|
+
import PeersSorter from '../common/PeersSorter';
|
20
|
+
import { UI_SETTINGS } from '../common/constants';
|
21
|
+
|
22
|
+
const aspectRatioConfig = { default: [1 / 1, 4 / 3, 16 / 9], mobile: [1 / 1, 3 / 4, 9 / 16] };
|
23
|
+
|
24
|
+
export function EqualProminence() {
|
25
|
+
const layout = useRoomLayout();
|
26
|
+
const { enable_local_tile_inset: isInsetEnabled = true } =
|
27
|
+
//@ts-ignore
|
28
|
+
layout?.screens?.conferencing?.default?.elements?.video_tile_layout?.grid || {};
|
29
|
+
const peers = useHMSStore(isInsetEnabled ? selectRemotePeers : selectPeers);
|
30
|
+
const [sortedPeers, setSortedPeers] = useState(peers);
|
31
|
+
const localPeer = useHMSStore(selectLocalPeer);
|
32
|
+
const vanillaStore = useHMSVanillaStore();
|
33
|
+
const isMobile = useMedia(cssConfig.media.md);
|
34
|
+
let maxTileCount = useUISettings(UI_SETTINGS.maxTileCount);
|
35
|
+
maxTileCount = isMobile ? Math.min(maxTileCount, 6) : maxTileCount;
|
36
|
+
const [pagesWithTiles, setPagesWithTiles] = useState([]);
|
37
|
+
const [page, setPage] = useState(0);
|
38
|
+
const [ref, { width, height }] = useMeasure();
|
39
|
+
const peersSorter = useMemo(() => new PeersSorter(vanillaStore), [vanillaStore]);
|
40
|
+
const pageSize = pagesWithTiles[0]?.length;
|
41
|
+
|
42
|
+
useEffect(() => {
|
43
|
+
// currentPageIndex should not exceed pages length
|
44
|
+
if (page >= pagesWithTiles.length) {
|
45
|
+
setPage(0);
|
46
|
+
}
|
47
|
+
}, [pagesWithTiles.length, page]);
|
48
|
+
|
49
|
+
useEffect(() => {
|
50
|
+
if (width === 0 || height === 0) {
|
51
|
+
return;
|
52
|
+
}
|
53
|
+
const tracksMap = vanillaStore.getState(selectTracksMap);
|
54
|
+
const peersWithTiles = getPeersWithTiles(
|
55
|
+
sortedPeers.length === 0 ? [localPeer] : sortedPeers,
|
56
|
+
tracksMap,
|
57
|
+
() => false,
|
58
|
+
);
|
59
|
+
const noOfPages = Math.ceil(peersWithTiles.length / maxTileCount);
|
60
|
+
let remaining = peersWithTiles.length;
|
61
|
+
let sliceStart = 0;
|
62
|
+
let pagesList = [];
|
63
|
+
// split into pages
|
64
|
+
for (let i = 0; i < noOfPages; i++) {
|
65
|
+
const count = Math.min(remaining, maxTileCount);
|
66
|
+
pagesList.push(peersWithTiles.slice(sliceStart, sliceStart + count));
|
67
|
+
remaining = remaining - count;
|
68
|
+
sliceStart += count;
|
69
|
+
}
|
70
|
+
// calculate dimesions for each page
|
71
|
+
for (const page of pagesList) {
|
72
|
+
const noOfTilesInPage = page.length;
|
73
|
+
let maxCols =
|
74
|
+
noOfTilesInPage > 2 && noOfTilesInPage < 9
|
75
|
+
? Math.ceil(noOfTilesInPage / 2)
|
76
|
+
: Math.ceil(Math.sqrt(noOfTilesInPage));
|
77
|
+
if (isMobile) {
|
78
|
+
maxCols = noOfTilesInPage < 4 ? 1 : Math.min(maxCols, 2);
|
79
|
+
}
|
80
|
+
let maxRows = Math.ceil(noOfTilesInPage / maxCols);
|
81
|
+
let index = 0;
|
82
|
+
// convert the current page to a matrix(grid)
|
83
|
+
const matrix = new Array(maxRows).fill(null).map((_, i) => {
|
84
|
+
const numCols = Math.min(maxCols, noOfTilesInPage - i * maxCols);
|
85
|
+
let rowElements = [];
|
86
|
+
for (let j = 0; j < numCols; j++) {
|
87
|
+
if (index < page.length) {
|
88
|
+
rowElements.push(page[index++]);
|
89
|
+
}
|
90
|
+
}
|
91
|
+
return rowElements;
|
92
|
+
});
|
93
|
+
|
94
|
+
const maxHeight = height - (maxRows - 1) * 8;
|
95
|
+
const maxRowHeight = maxHeight / matrix.length;
|
96
|
+
const aspectRatios =
|
97
|
+
isMobile && (noOfTilesInPage === 1 || noOfTilesInPage > 3)
|
98
|
+
? aspectRatioConfig.mobile
|
99
|
+
: aspectRatioConfig.default;
|
100
|
+
// calculate height and width of each tile in a row
|
101
|
+
for (const row of matrix) {
|
102
|
+
let tileWidth = (width - (row.length - 1) * 8) / row.length;
|
103
|
+
let tileHeight = 0;
|
104
|
+
const calcHeights = aspectRatios.map(aR => tileWidth / aR);
|
105
|
+
for (const h of calcHeights) {
|
106
|
+
if (h < maxRowHeight) {
|
107
|
+
if (tileHeight < h) {
|
108
|
+
tileHeight = h;
|
109
|
+
}
|
110
|
+
}
|
111
|
+
}
|
112
|
+
|
113
|
+
// tileHeight is not calculated as it could be exceeding the max possible height
|
114
|
+
// find the max possible width instead
|
115
|
+
if (tileHeight === 0) {
|
116
|
+
tileHeight = maxRowHeight;
|
117
|
+
const calcWidths = aspectRatios.map(aR => tileHeight * aR);
|
118
|
+
tileWidth = 0;
|
119
|
+
for (const w of calcWidths) {
|
120
|
+
if (w < width) {
|
121
|
+
if (tileWidth < w) {
|
122
|
+
tileWidth = w;
|
123
|
+
}
|
124
|
+
}
|
125
|
+
}
|
126
|
+
}
|
127
|
+
for (let i = 0; i < row.length; i++) {
|
128
|
+
row[i].width = tileWidth;
|
129
|
+
row[i].height = tileHeight;
|
130
|
+
}
|
131
|
+
}
|
132
|
+
}
|
133
|
+
setPagesWithTiles(pagesList);
|
134
|
+
}, [width, height, maxTileCount, vanillaStore, sortedPeers, page, isMobile, localPeer]);
|
135
|
+
|
136
|
+
useEffect(() => {
|
137
|
+
if (page !== 0) {
|
138
|
+
return;
|
139
|
+
}
|
140
|
+
peersSorter.setPeersAndTilesPerPage({
|
141
|
+
peers,
|
142
|
+
tilesPerPage: pageSize || maxTileCount,
|
143
|
+
});
|
144
|
+
peersSorter.onUpdate(setSortedPeers);
|
145
|
+
}, [page, peersSorter, peers, pageSize, maxTileCount]);
|
146
|
+
|
147
|
+
return (
|
148
|
+
<Flex direction="column" css={{ flex: '1 1 0', h: '100%', position: 'relative', minWidth: 0 }}>
|
149
|
+
<Box
|
150
|
+
ref={ref}
|
151
|
+
css={{
|
152
|
+
flex: '1 1 0',
|
153
|
+
gap: '$4',
|
154
|
+
display: 'flex',
|
155
|
+
placeContent: 'center',
|
156
|
+
alignItems: 'center',
|
157
|
+
justifyContent: 'center',
|
158
|
+
flexFlow: 'row wrap',
|
159
|
+
minHeight: 0,
|
160
|
+
}}
|
161
|
+
>
|
162
|
+
{pagesWithTiles[page]?.map(tile => {
|
163
|
+
return (
|
164
|
+
<VideoTile
|
165
|
+
key={tile.track?.id || tile.peer?.id}
|
166
|
+
width={tile.width}
|
167
|
+
height={tile.height}
|
168
|
+
peerId={tile.peer?.id}
|
169
|
+
trackId={tile.track?.id}
|
170
|
+
rootCSS={{ padding: 0 }}
|
171
|
+
objectFit="contain"
|
172
|
+
/>
|
173
|
+
);
|
174
|
+
})}
|
175
|
+
</Box>
|
176
|
+
{pagesWithTiles.length > 1 && <Pagination page={page} onPageChange={setPage} numPages={pagesWithTiles.length} />}
|
177
|
+
{isInsetEnabled && sortedPeers.length > 0 && <InsetTile />}
|
178
|
+
</Flex>
|
179
|
+
);
|
180
|
+
}
|
@@ -1,5 +1,4 @@
|
|
1
1
|
import React, { Component } from 'react';
|
2
|
-
import { logMessage } from 'zipyai';
|
3
2
|
import { CopyIcon } from '@100mslive/react-icons';
|
4
3
|
import { Button } from '../../Button';
|
5
4
|
import { Box, Flex } from '../../Layout';
|
@@ -16,15 +15,10 @@ export class ErrorBoundary extends Component {
|
|
16
15
|
componentDidCatch(error, errorInfo) {
|
17
16
|
console.error(`react error boundary - ${error.message}`, error, errorInfo);
|
18
17
|
// Catch errors in any components below and re-render with error message
|
19
|
-
this.setState(
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
},
|
24
|
-
() => {
|
25
|
-
logMessage(`uiError - ${this.state.error} - ${JSON.stringify(this.state.errorInfo)}`);
|
26
|
-
},
|
27
|
-
);
|
18
|
+
this.setState({
|
19
|
+
error: error?.message,
|
20
|
+
errorInfo: errorInfo,
|
21
|
+
});
|
28
22
|
}
|
29
23
|
|
30
24
|
render() {
|
@@ -0,0 +1,34 @@
|
|
1
|
+
import React from 'react';
|
2
|
+
import { Flex } from '../../../Layout';
|
3
|
+
import { styled } from '../../../Theme';
|
4
|
+
|
5
|
+
// When changing emojis in the grid, keep in mind that the payload used in sendHLSTimedMetadata has a limit of 100 characters. Using bigger emoji Ids can cause the limit to be exceeded.
|
6
|
+
const emojiReactionList = [
|
7
|
+
[{ emojiId: '+1' }, { emojiId: '-1' }, { emojiId: 'wave' }, { emojiId: 'clap' }, { emojiId: 'fire' }],
|
8
|
+
[{ emojiId: 'tada' }, { emojiId: 'heart_eyes' }, { emojiId: 'joy' }, { emojiId: 'open_mouth' }, { emojiId: 'sob' }],
|
9
|
+
];
|
10
|
+
|
11
|
+
export const EmojiCard = ({ sendReaction }) => {
|
12
|
+
return emojiReactionList.map((emojiLine, index) => (
|
13
|
+
<Flex key={index} justify="between" css={{ mb: '$8' }}>
|
14
|
+
{emojiLine.map(emoji => (
|
15
|
+
<EmojiContainer key={emoji.emojiId} onClick={() => sendReaction(emoji.emojiId)}>
|
16
|
+
<em-emoji id={emoji.emojiId} size="100%" set="apple"></em-emoji>
|
17
|
+
</EmojiContainer>
|
18
|
+
))}
|
19
|
+
</Flex>
|
20
|
+
));
|
21
|
+
};
|
22
|
+
|
23
|
+
const EmojiContainer = styled('span', {
|
24
|
+
position: 'relative',
|
25
|
+
cursor: 'pointer',
|
26
|
+
width: '$16',
|
27
|
+
height: '$16',
|
28
|
+
p: '$4',
|
29
|
+
'&:hover': {
|
30
|
+
p: '7px',
|
31
|
+
bg: '$surface_brighter',
|
32
|
+
borderRadius: '$1',
|
33
|
+
},
|
34
|
+
});
|