@selfcommunity/react-ui 0.10.2-courses.116 → 0.10.2-courses.117
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.
- package/lib/cjs/components/Composer/Layer/CategoryLayer/CategoryLayer.d.ts +1 -1
- package/lib/cjs/components/Composer/Layer/CategoryLayer/CategoryLayer.js +4 -1
- package/lib/cjs/components/LiveStreamRoom/LiveStreamVideoConference/LiveStreamSettingsMenu.d.ts +1 -0
- package/lib/cjs/components/LiveStreamRoom/LiveStreamVideoConference/LiveStreamSettingsMenu.js +38 -1
- package/lib/cjs/components/LiveStreamRoom/LiveStreamVideoConference/PreJoin.js +17 -3
- package/lib/cjs/components/LiveStreamRoom/LiveStreamVideoConference/VideoConference.js +16 -2
- package/lib/esm/components/Composer/Layer/CategoryLayer/CategoryLayer.d.ts +1 -1
- package/lib/esm/components/Composer/Layer/CategoryLayer/CategoryLayer.js +4 -1
- package/lib/esm/components/LiveStreamRoom/LiveStreamVideoConference/LiveStreamSettingsMenu.d.ts +1 -0
- package/lib/esm/components/LiveStreamRoom/LiveStreamVideoConference/LiveStreamSettingsMenu.js +38 -1
- package/lib/esm/components/LiveStreamRoom/LiveStreamVideoConference/PreJoin.js +17 -3
- package/lib/esm/components/LiveStreamRoom/LiveStreamVideoConference/VideoConference.js +17 -3
- package/lib/umd/react-ui.js +1 -1
- package/package.json +8 -8
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import { BoxProps } from '@mui/material';
|
|
3
|
-
import { SCCategoryType } from '@selfcommunity/types
|
|
3
|
+
import { SCCategoryType } from '@selfcommunity/types';
|
|
4
4
|
import { ComposerLayerProps } from '../../../../types/composer';
|
|
5
5
|
export interface CategoryLayerProps extends Omit<BoxProps, 'defaultValue'>, ComposerLayerProps {
|
|
6
6
|
defaultValue: SCCategoryType[];
|
|
@@ -6,6 +6,7 @@ const react_1 = tslib_1.__importStar(require("react"));
|
|
|
6
6
|
const react_intl_1 = require("react-intl");
|
|
7
7
|
const material_1 = require("@mui/material");
|
|
8
8
|
const styles_1 = require("@mui/material/styles");
|
|
9
|
+
const react_core_1 = require("@selfcommunity/react-core");
|
|
9
10
|
const Icon_1 = tslib_1.__importDefault(require("@mui/material/Icon"));
|
|
10
11
|
const CategoryAutocomplete_1 = tslib_1.__importDefault(require("../../../CategoryAutocomplete"));
|
|
11
12
|
const DialogContent_1 = tslib_1.__importDefault(require("@mui/material/DialogContent"));
|
|
@@ -25,9 +26,11 @@ const CategoryLayer = react_1.default.forwardRef((props, ref) => {
|
|
|
25
26
|
const { className, onClose, onSave, defaultValue = [] } = props, rest = tslib_1.__rest(props, ["className", "onClose", "onSave", "defaultValue"]);
|
|
26
27
|
// STATE
|
|
27
28
|
const [value, setValue] = (0, react_1.useState)(defaultValue);
|
|
29
|
+
// CONTEXT
|
|
30
|
+
const scUserContext = (0, react_core_1.useSCUser)();
|
|
28
31
|
// HANDLERS
|
|
29
32
|
const handleSave = (0, react_1.useCallback)(() => onSave(value), [value, onSave]);
|
|
30
33
|
const handleChange = (0, react_1.useCallback)((categories) => setValue(categories), []);
|
|
31
|
-
return ((0, jsx_runtime_1.jsxs)(Root, Object.assign({ ref: ref, className: (0, classnames_1.default)(className, classes.root) }, rest, { children: [(0, jsx_runtime_1.jsxs)(material_1.DialogTitle, Object.assign({ className: classes.title }, { children: [(0, jsx_runtime_1.jsx)(material_1.IconButton, Object.assign({ onClick: onClose }, { children: (0, jsx_runtime_1.jsx)(Icon_1.default, { children: "arrow_back" }) })), (0, jsx_runtime_1.jsx)(material_1.Typography, { children: (0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.composer.layer.category.title", defaultMessage: "ui.composer.layer.category.title" }) }), (0, jsx_runtime_1.jsx)(material_1.Button, Object.assign({ size: "small", color: "secondary", variant: "contained", onClick: handleSave }, { children: (0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.composer.layer.save", defaultMessage: "ui.composer.layer.save" }) }))] })), (0, jsx_runtime_1.jsx)(DialogContent_1.default, Object.assign({ className: classes.content }, { children: (0, jsx_runtime_1.jsx)(CategoryAutocomplete_1.default, { multiple: true, onChange: handleChange, defaultValue: defaultValue, endpointQueryParams: { can_create_content: true } }) }))] })));
|
|
34
|
+
return ((0, jsx_runtime_1.jsxs)(Root, Object.assign({ ref: ref, className: (0, classnames_1.default)(className, classes.root) }, rest, { children: [(0, jsx_runtime_1.jsxs)(material_1.DialogTitle, Object.assign({ className: classes.title }, { children: [(0, jsx_runtime_1.jsx)(material_1.IconButton, Object.assign({ onClick: onClose }, { children: (0, jsx_runtime_1.jsx)(Icon_1.default, { children: "arrow_back" }) })), (0, jsx_runtime_1.jsx)(material_1.Typography, { children: (0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.composer.layer.category.title", defaultMessage: "ui.composer.layer.category.title" }) }), (0, jsx_runtime_1.jsx)(material_1.Button, Object.assign({ size: "small", color: "secondary", variant: "contained", onClick: handleSave }, { children: (0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.composer.layer.save", defaultMessage: "ui.composer.layer.save" }) }))] })), (0, jsx_runtime_1.jsx)(DialogContent_1.default, Object.assign({ className: classes.content }, { children: (0, jsx_runtime_1.jsx)(CategoryAutocomplete_1.default, Object.assign({ multiple: true, onChange: handleChange, defaultValue: defaultValue }, (!react_core_1.UserUtils.isStaff(scUserContext.user) && { endpointQueryParams: { can_create_content: true } }))) }))] })));
|
|
32
35
|
});
|
|
33
36
|
exports.default = CategoryLayer;
|
package/lib/cjs/components/LiveStreamRoom/LiveStreamVideoConference/LiveStreamSettingsMenu.d.ts
CHANGED
|
@@ -4,5 +4,6 @@ export interface LiveStreamSettingsMenuProps {
|
|
|
4
4
|
handleBlur?: (event: any) => void;
|
|
5
5
|
actionBlurDisabled?: boolean;
|
|
6
6
|
onlyContentMenu?: boolean;
|
|
7
|
+
hideRecordAction?: boolean;
|
|
7
8
|
}
|
|
8
9
|
export default function LiveStreamSettingsMenu(inProps: LiveStreamSettingsMenuProps): JSX.Element;
|
package/lib/cjs/components/LiveStreamRoom/LiveStreamVideoConference/LiveStreamSettingsMenu.js
CHANGED
|
@@ -9,6 +9,7 @@ const material_1 = require("@mui/material");
|
|
|
9
9
|
const styles_1 = require("@mui/material/styles");
|
|
10
10
|
const system_1 = require("@mui/system");
|
|
11
11
|
const classnames_1 = tslib_1.__importDefault(require("classnames"));
|
|
12
|
+
// import {useIsRecording, useMaybeLayoutContext, useRoomContext} from '@livekit/components-react';
|
|
12
13
|
const react_1 = require("react");
|
|
13
14
|
const react_intl_1 = require("react-intl");
|
|
14
15
|
const PREFIX = 'SCLiveStreamSettingsMenu';
|
|
@@ -49,15 +50,51 @@ function LiveStreamSettingsMenu(inProps) {
|
|
|
49
50
|
props: inProps,
|
|
50
51
|
name: PREFIX
|
|
51
52
|
});
|
|
52
|
-
const { className, actionBlurDisabled = false, blurEnabled = false, handleBlur, onlyContentMenu = false } = props, rest = tslib_1.__rest(props, ["className", "actionBlurDisabled", "blurEnabled", "handleBlur", "onlyContentMenu"]);
|
|
53
|
+
const { className, actionBlurDisabled = false, blurEnabled = false, handleBlur, hideRecordAction = true, onlyContentMenu = false } = props, rest = tslib_1.__rest(props, ["className", "actionBlurDisabled", "blurEnabled", "handleBlur", "hideRecordAction", "onlyContentMenu"]);
|
|
53
54
|
const [anchorEl, setAnchorEl] = React.useState(null);
|
|
54
55
|
const open = Boolean(anchorEl);
|
|
56
|
+
/*
|
|
57
|
+
// Recording: https://github.com/livekit-examples/meet/blob/main/lib/SettingsMenu.tsx
|
|
58
|
+
const room = useRoomContext();
|
|
59
|
+
const isRecording = useIsRecording();
|
|
60
|
+
const [initialRecStatus, setInitialRecStatus] = useState(isRecording);
|
|
61
|
+
const [processingRecRequest, setProcessingRecRequest] = useState(false);
|
|
62
|
+
const recordingEndpoint = process.env.NEXT_PUBLIC_LK_RECORD_ENDPOINT;
|
|
63
|
+
*/
|
|
55
64
|
const handleClick = (event) => {
|
|
56
65
|
setAnchorEl(event.currentTarget);
|
|
57
66
|
};
|
|
58
67
|
const handleClose = () => {
|
|
59
68
|
setAnchorEl(null);
|
|
60
69
|
};
|
|
70
|
+
/* useEffect(() => {
|
|
71
|
+
if (initialRecStatus !== isRecording) {
|
|
72
|
+
setProcessingRecRequest(false);
|
|
73
|
+
}
|
|
74
|
+
}, [isRecording, initialRecStatus]);
|
|
75
|
+
|
|
76
|
+
const toggleRoomRecording = async () => {
|
|
77
|
+
/* if (!recordingEndpoint) {
|
|
78
|
+
throw TypeError('No recording endpoint specified');
|
|
79
|
+
}
|
|
80
|
+
if (room.isE2EEEnabled) {
|
|
81
|
+
throw Error('Recording of encrypted meetings is currently not supported');
|
|
82
|
+
}
|
|
83
|
+
setProcessingRecRequest(true);
|
|
84
|
+
setInitialRecStatus(isRecording);
|
|
85
|
+
let response: Response;
|
|
86
|
+
if (isRecording) {
|
|
87
|
+
response = await fetch(recordingEndpoint + `/stop?roomName=${room.name}`);
|
|
88
|
+
} else {
|
|
89
|
+
response = await fetch(recordingEndpoint + `/start?roomName=${room.name}`);
|
|
90
|
+
}
|
|
91
|
+
if (response.ok) {
|
|
92
|
+
} else {
|
|
93
|
+
console.error('Error handling recording request, check server logs:', response.status, response.statusText);
|
|
94
|
+
setProcessingRecRequest(false);
|
|
95
|
+
}
|
|
96
|
+
};
|
|
97
|
+
*/
|
|
61
98
|
const MenuContent = (0, react_1.useMemo)(() => ((0, jsx_runtime_1.jsxs)(material_1.Box, { children: [(0, jsx_runtime_1.jsx)(material_1.Typography, Object.assign({ variant: "body1", component: "div" }, { children: (0, jsx_runtime_1.jsx)("b", { children: (0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.liveStreamRoom.settingsMenu.visualEffect", defaultMessage: "ui.liveStreamRoom.settingsMenu.visualEffect" }) }) })), (0, jsx_runtime_1.jsx)(material_1.FormControlLabel, { labelPlacement: "start", control: (0, jsx_runtime_1.jsx)(material_1.Switch, { checked: blurEnabled, disabled: actionBlurDisabled, onChange: handleBlur, inputProps: { 'aria-label': 'controlled' } }), label: (0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.liveStreamRoom.settingsMenu.visualEffect.blurEffect", defaultMessage: "ui.liveStreamRoom.settingsMenu.visualEffect.blurEffect" }) })] })), [blurEnabled, actionBlurDisabled, handleBlur]);
|
|
62
99
|
if (onlyContentMenu) {
|
|
63
100
|
return MenuContent;
|
|
@@ -17,6 +17,8 @@ const track_processors_1 = require("@livekit/track-processors");
|
|
|
17
17
|
const LiveStreamSettingsMenu_1 = tslib_1.__importDefault(require("./LiveStreamSettingsMenu"));
|
|
18
18
|
const utils_1 = require("@selfcommunity/utils");
|
|
19
19
|
const LiveStream_1 = require("../../../constants/LiveStream");
|
|
20
|
+
const react_intl_1 = require("react-intl");
|
|
21
|
+
const notistack_1 = require("notistack");
|
|
20
22
|
/** @alpha */
|
|
21
23
|
function usePreviewTracks(options, onError) {
|
|
22
24
|
const [tracks, setTracks] = React.useState();
|
|
@@ -175,6 +177,7 @@ function PreJoin(_a) {
|
|
|
175
177
|
preventSave: !persistUserChoices,
|
|
176
178
|
preventLoad: !persistUserChoices
|
|
177
179
|
});
|
|
180
|
+
const { enqueueSnackbar } = (0, notistack_1.useSnackbar)();
|
|
178
181
|
// Initialize device settings
|
|
179
182
|
const [audioEnabled, setAudioEnabled] = React.useState(initialUserChoices.audioEnabled && canUseAudio);
|
|
180
183
|
const [videoEnabled, setVideoEnabled] = React.useState(initialUserChoices.videoEnabled && canUseVideo);
|
|
@@ -182,7 +185,7 @@ function PreJoin(_a) {
|
|
|
182
185
|
const [videoDeviceId, setVideoDeviceId] = React.useState(initialUserChoices.videoDeviceId);
|
|
183
186
|
const [username, setUsername] = React.useState(initialUserChoices.username);
|
|
184
187
|
// Processors
|
|
185
|
-
const [blurEnabled, setBlurEnabled] = React.useState((0, utils_1.isClientSideRendering)() ?
|
|
188
|
+
const [blurEnabled, setBlurEnabled] = React.useState((0, utils_1.isClientSideRendering)() ? ((_b = window === null || window === void 0 ? void 0 : window.localStorage) === null || _b === void 0 ? void 0 : _b.getItem(LiveStream_1.CHOICE_VIDEO_BLUR_EFFECT)) === 'true' : false);
|
|
186
189
|
const [processorPending, setProcessorPending] = React.useState(false);
|
|
187
190
|
// Save user choices to persistent storage.
|
|
188
191
|
React.useEffect(() => {
|
|
@@ -240,8 +243,9 @@ function PreJoin(_a) {
|
|
|
240
243
|
}, [onValidate]);
|
|
241
244
|
const handleBlur = React.useCallback(() => {
|
|
242
245
|
var _a;
|
|
243
|
-
|
|
244
|
-
(
|
|
246
|
+
const _blur = !blurEnabled;
|
|
247
|
+
setBlurEnabled(_blur);
|
|
248
|
+
(_a = window === null || window === void 0 ? void 0 : window.localStorage) === null || _a === void 0 ? void 0 : _a.setItem(LiveStream_1.CHOICE_VIDEO_BLUR_EFFECT, _blur.toString());
|
|
245
249
|
}, [setBlurEnabled, blurEnabled]);
|
|
246
250
|
(0, react_1.useEffect)(() => {
|
|
247
251
|
const newUserChoices = {
|
|
@@ -255,6 +259,7 @@ function PreJoin(_a) {
|
|
|
255
259
|
setIsValid(handleValidation(newUserChoices));
|
|
256
260
|
}, [username, scUserContext.user, videoEnabled, handleValidation, audioEnabled, audioDeviceId, videoDeviceId]);
|
|
257
261
|
(0, react_1.useEffect)(() => {
|
|
262
|
+
var _a;
|
|
258
263
|
if (videoTrack && videoEnabled) {
|
|
259
264
|
setProcessorPending(true);
|
|
260
265
|
try {
|
|
@@ -265,6 +270,15 @@ function PreJoin(_a) {
|
|
|
265
270
|
videoTrack.stopProcessor();
|
|
266
271
|
}
|
|
267
272
|
}
|
|
273
|
+
catch (e) {
|
|
274
|
+
console.log(e);
|
|
275
|
+
setBlurEnabled(false);
|
|
276
|
+
(_a = window === null || window === void 0 ? void 0 : window.localStorage) === null || _a === void 0 ? void 0 : _a.setItem(LiveStream_1.CHOICE_VIDEO_BLUR_EFFECT, false.toString());
|
|
277
|
+
enqueueSnackbar((0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.liveStreamRoom.errorApplyVideoEffect", defaultMessage: "ui.contributionActionMenu.errorApplyVideoEffect" }), {
|
|
278
|
+
variant: 'warning',
|
|
279
|
+
autoHideDuration: 3000
|
|
280
|
+
});
|
|
281
|
+
}
|
|
268
282
|
finally {
|
|
269
283
|
setProcessorPending(false);
|
|
270
284
|
}
|
|
@@ -22,6 +22,9 @@ const LiveStreamSettingsMenu_1 = tslib_1.__importDefault(require("./LiveStreamSe
|
|
|
22
22
|
const track_processors_1 = require("@livekit/track-processors");
|
|
23
23
|
const utils_1 = require("@selfcommunity/utils");
|
|
24
24
|
const LiveStream_1 = require("../../../constants/LiveStream");
|
|
25
|
+
const Icon_1 = tslib_1.__importDefault(require("@mui/material/Icon"));
|
|
26
|
+
const notistack_1 = require("notistack");
|
|
27
|
+
const react_intl_1 = require("react-intl");
|
|
25
28
|
const PREFIX = 'SCVideoConference';
|
|
26
29
|
const classes = {
|
|
27
30
|
root: `${PREFIX}-root`
|
|
@@ -59,7 +62,7 @@ function VideoConference(inProps) {
|
|
|
59
62
|
const lastAutoFocusedScreenShareTrack = React.useRef(null);
|
|
60
63
|
// HOOKS
|
|
61
64
|
const scUserContext = (0, react_core_1.useSCUser)();
|
|
62
|
-
const [blurEnabled, setBlurEnabled] = React.useState((0, utils_1.isClientSideRendering)() ?
|
|
65
|
+
const [blurEnabled, setBlurEnabled] = React.useState((0, utils_1.isClientSideRendering)() ? ((_a = window === null || window === void 0 ? void 0 : window.localStorage) === null || _a === void 0 ? void 0 : _a.getItem(LiveStream_1.CHOICE_VIDEO_BLUR_EFFECT)) === 'true' : false);
|
|
63
66
|
const [processorPending, setProcessorPending] = React.useState(false);
|
|
64
67
|
const tracks = (0, components_react_1.useTracks)([
|
|
65
68
|
{ source: livekit_client_1.Track.Source.Camera, withPlaceholder: true },
|
|
@@ -87,6 +90,7 @@ function VideoConference(inProps) {
|
|
|
87
90
|
const focusTrack = (_b = (0, components_react_1.usePinnedTracks)(layoutContext)) === null || _b === void 0 ? void 0 : _b[0];
|
|
88
91
|
const carouselTracks = tracks.filter((track) => !(0, components_core_1.isEqualTrackRef)(track, focusTrack));
|
|
89
92
|
const { cameraTrack } = (0, components_react_1.useLocalParticipant)();
|
|
93
|
+
const { enqueueSnackbar } = (0, notistack_1.useSnackbar)();
|
|
90
94
|
(0, useLiveStreamCheck_1.useLivestreamCheck)();
|
|
91
95
|
/**
|
|
92
96
|
* widgetUpdate
|
|
@@ -166,6 +170,7 @@ function VideoConference(inProps) {
|
|
|
166
170
|
}
|
|
167
171
|
}, [tracks, participants, speakerFocused]);
|
|
168
172
|
(0, react_1.useEffect)(() => {
|
|
173
|
+
var _a;
|
|
169
174
|
const localCamTrack = cameraTrack === null || cameraTrack === void 0 ? void 0 : cameraTrack.track;
|
|
170
175
|
if (localCamTrack) {
|
|
171
176
|
setProcessorPending(true);
|
|
@@ -177,6 +182,15 @@ function VideoConference(inProps) {
|
|
|
177
182
|
localCamTrack.stopProcessor();
|
|
178
183
|
}
|
|
179
184
|
}
|
|
185
|
+
catch (e) {
|
|
186
|
+
console.log(e);
|
|
187
|
+
setBlurEnabled(false);
|
|
188
|
+
(_a = window === null || window === void 0 ? void 0 : window.localStorage) === null || _a === void 0 ? void 0 : _a.setItem(LiveStream_1.CHOICE_VIDEO_BLUR_EFFECT, false.toString());
|
|
189
|
+
enqueueSnackbar((0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.liveStreamRoom.errorApplyVideoEffect", defaultMessage: "ui.contributionActionMenu.errorApplyVideoEffect" }), {
|
|
190
|
+
variant: 'warning',
|
|
191
|
+
autoHideDuration: 3000
|
|
192
|
+
});
|
|
193
|
+
}
|
|
180
194
|
finally {
|
|
181
195
|
setProcessorPending(false);
|
|
182
196
|
}
|
|
@@ -187,6 +201,6 @@ function VideoConference(inProps) {
|
|
|
187
201
|
microphone: !disableMicrophone,
|
|
188
202
|
camera: !disableCamera,
|
|
189
203
|
screenShare: !disableShareScreen
|
|
190
|
-
}, { settings: true }) })] })), !disableChat && ((0, jsx_runtime_1.jsx)(components_react_1.Chat, { style: { display: widgetState.showChat ? 'grid' : 'none' }, messageFormatter: chatMessageFormatter, messageEncoder: chatMessageEncoder, messageDecoder: chatMessageDecoder })), (0, jsx_runtime_1.
|
|
204
|
+
}, { settings: true }) })] })), !disableChat && ((0, jsx_runtime_1.jsx)(components_react_1.Chat, { style: { display: widgetState.showChat ? 'grid' : 'none' }, messageFormatter: chatMessageFormatter, messageEncoder: chatMessageEncoder, messageDecoder: chatMessageDecoder })), (0, jsx_runtime_1.jsxs)("div", Object.assign({ className: "lk-settings-menu-modal", style: { display: widgetState.showSettings ? 'block' : 'none' } }, { children: [(0, jsx_runtime_1.jsx)(material_1.IconButton, Object.assign({ className: "lk-settings-menu-modal-icon-close", onClick: () => { var _a, _b; return (_b = layoutContext === null || layoutContext === void 0 ? void 0 : (_a = layoutContext.widget).dispatch) === null || _b === void 0 ? void 0 : _b.call(_a, { msg: 'toggle_settings' }); } }, { children: (0, jsx_runtime_1.jsx)(Icon_1.default, { children: "close" }) })), SettingsComponent ? ((0, jsx_runtime_1.jsx)(SettingsComponent, {})) : ((0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, { children: (0, jsx_runtime_1.jsx)(LiveStreamSettingsMenu_1.default, { onlyContentMenu: true, actionBlurDisabled: !cameraTrack && !disableCamera, blurEnabled: blurEnabled, handleBlur: handleBlur }) }))] }))] }))), (0, jsx_runtime_1.jsx)(components_react_1.RoomAudioRenderer, {}), (0, jsx_runtime_1.jsx)(components_react_1.ConnectionStateToast, {})] })));
|
|
191
205
|
}
|
|
192
206
|
exports.VideoConference = VideoConference;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import { BoxProps } from '@mui/material';
|
|
3
|
-
import { SCCategoryType } from '@selfcommunity/types
|
|
3
|
+
import { SCCategoryType } from '@selfcommunity/types';
|
|
4
4
|
import { ComposerLayerProps } from '../../../../types/composer';
|
|
5
5
|
export interface CategoryLayerProps extends Omit<BoxProps, 'defaultValue'>, ComposerLayerProps {
|
|
6
6
|
defaultValue: SCCategoryType[];
|
|
@@ -4,6 +4,7 @@ import React, { useCallback, useState } from 'react';
|
|
|
4
4
|
import { FormattedMessage } from 'react-intl';
|
|
5
5
|
import { Box, Button, DialogTitle, IconButton, Typography } from '@mui/material';
|
|
6
6
|
import { styled } from '@mui/material/styles';
|
|
7
|
+
import { UserUtils, useSCUser } from '@selfcommunity/react-core';
|
|
7
8
|
import Icon from '@mui/material/Icon';
|
|
8
9
|
import CategoryAutocomplete from '../../../CategoryAutocomplete';
|
|
9
10
|
import DialogContent from '@mui/material/DialogContent';
|
|
@@ -23,9 +24,11 @@ const CategoryLayer = React.forwardRef((props, ref) => {
|
|
|
23
24
|
const { className, onClose, onSave, defaultValue = [] } = props, rest = __rest(props, ["className", "onClose", "onSave", "defaultValue"]);
|
|
24
25
|
// STATE
|
|
25
26
|
const [value, setValue] = useState(defaultValue);
|
|
27
|
+
// CONTEXT
|
|
28
|
+
const scUserContext = useSCUser();
|
|
26
29
|
// HANDLERS
|
|
27
30
|
const handleSave = useCallback(() => onSave(value), [value, onSave]);
|
|
28
31
|
const handleChange = useCallback((categories) => setValue(categories), []);
|
|
29
|
-
return (_jsxs(Root, Object.assign({ ref: ref, className: classNames(className, classes.root) }, rest, { children: [_jsxs(DialogTitle, Object.assign({ className: classes.title }, { children: [_jsx(IconButton, Object.assign({ onClick: onClose }, { children: _jsx(Icon, { children: "arrow_back" }) })), _jsx(Typography, { children: _jsx(FormattedMessage, { id: "ui.composer.layer.category.title", defaultMessage: "ui.composer.layer.category.title" }) }), _jsx(Button, Object.assign({ size: "small", color: "secondary", variant: "contained", onClick: handleSave }, { children: _jsx(FormattedMessage, { id: "ui.composer.layer.save", defaultMessage: "ui.composer.layer.save" }) }))] })), _jsx(DialogContent, Object.assign({ className: classes.content }, { children: _jsx(CategoryAutocomplete, { multiple: true, onChange: handleChange, defaultValue: defaultValue, endpointQueryParams: { can_create_content: true } }) }))] })));
|
|
32
|
+
return (_jsxs(Root, Object.assign({ ref: ref, className: classNames(className, classes.root) }, rest, { children: [_jsxs(DialogTitle, Object.assign({ className: classes.title }, { children: [_jsx(IconButton, Object.assign({ onClick: onClose }, { children: _jsx(Icon, { children: "arrow_back" }) })), _jsx(Typography, { children: _jsx(FormattedMessage, { id: "ui.composer.layer.category.title", defaultMessage: "ui.composer.layer.category.title" }) }), _jsx(Button, Object.assign({ size: "small", color: "secondary", variant: "contained", onClick: handleSave }, { children: _jsx(FormattedMessage, { id: "ui.composer.layer.save", defaultMessage: "ui.composer.layer.save" }) }))] })), _jsx(DialogContent, Object.assign({ className: classes.content }, { children: _jsx(CategoryAutocomplete, Object.assign({ multiple: true, onChange: handleChange, defaultValue: defaultValue }, (!UserUtils.isStaff(scUserContext.user) && { endpointQueryParams: { can_create_content: true } }))) }))] })));
|
|
30
33
|
});
|
|
31
34
|
export default CategoryLayer;
|
package/lib/esm/components/LiveStreamRoom/LiveStreamVideoConference/LiveStreamSettingsMenu.d.ts
CHANGED
|
@@ -4,5 +4,6 @@ export interface LiveStreamSettingsMenuProps {
|
|
|
4
4
|
handleBlur?: (event: any) => void;
|
|
5
5
|
actionBlurDisabled?: boolean;
|
|
6
6
|
onlyContentMenu?: boolean;
|
|
7
|
+
hideRecordAction?: boolean;
|
|
7
8
|
}
|
|
8
9
|
export default function LiveStreamSettingsMenu(inProps: LiveStreamSettingsMenuProps): JSX.Element;
|
package/lib/esm/components/LiveStreamRoom/LiveStreamVideoConference/LiveStreamSettingsMenu.js
CHANGED
|
@@ -7,6 +7,7 @@ import { Box, FormControlLabel, Icon, Switch, Typography } from '@mui/material';
|
|
|
7
7
|
import { styled } from '@mui/material/styles';
|
|
8
8
|
import { useThemeProps } from '@mui/system';
|
|
9
9
|
import classNames from 'classnames';
|
|
10
|
+
// import {useIsRecording, useMaybeLayoutContext, useRoomContext} from '@livekit/components-react';
|
|
10
11
|
import { Fragment, useMemo } from 'react';
|
|
11
12
|
import { FormattedMessage } from 'react-intl';
|
|
12
13
|
const PREFIX = 'SCLiveStreamSettingsMenu';
|
|
@@ -47,15 +48,51 @@ export default function LiveStreamSettingsMenu(inProps) {
|
|
|
47
48
|
props: inProps,
|
|
48
49
|
name: PREFIX
|
|
49
50
|
});
|
|
50
|
-
const { className, actionBlurDisabled = false, blurEnabled = false, handleBlur, onlyContentMenu = false } = props, rest = __rest(props, ["className", "actionBlurDisabled", "blurEnabled", "handleBlur", "onlyContentMenu"]);
|
|
51
|
+
const { className, actionBlurDisabled = false, blurEnabled = false, handleBlur, hideRecordAction = true, onlyContentMenu = false } = props, rest = __rest(props, ["className", "actionBlurDisabled", "blurEnabled", "handleBlur", "hideRecordAction", "onlyContentMenu"]);
|
|
51
52
|
const [anchorEl, setAnchorEl] = React.useState(null);
|
|
52
53
|
const open = Boolean(anchorEl);
|
|
54
|
+
/*
|
|
55
|
+
// Recording: https://github.com/livekit-examples/meet/blob/main/lib/SettingsMenu.tsx
|
|
56
|
+
const room = useRoomContext();
|
|
57
|
+
const isRecording = useIsRecording();
|
|
58
|
+
const [initialRecStatus, setInitialRecStatus] = useState(isRecording);
|
|
59
|
+
const [processingRecRequest, setProcessingRecRequest] = useState(false);
|
|
60
|
+
const recordingEndpoint = process.env.NEXT_PUBLIC_LK_RECORD_ENDPOINT;
|
|
61
|
+
*/
|
|
53
62
|
const handleClick = (event) => {
|
|
54
63
|
setAnchorEl(event.currentTarget);
|
|
55
64
|
};
|
|
56
65
|
const handleClose = () => {
|
|
57
66
|
setAnchorEl(null);
|
|
58
67
|
};
|
|
68
|
+
/* useEffect(() => {
|
|
69
|
+
if (initialRecStatus !== isRecording) {
|
|
70
|
+
setProcessingRecRequest(false);
|
|
71
|
+
}
|
|
72
|
+
}, [isRecording, initialRecStatus]);
|
|
73
|
+
|
|
74
|
+
const toggleRoomRecording = async () => {
|
|
75
|
+
/* if (!recordingEndpoint) {
|
|
76
|
+
throw TypeError('No recording endpoint specified');
|
|
77
|
+
}
|
|
78
|
+
if (room.isE2EEEnabled) {
|
|
79
|
+
throw Error('Recording of encrypted meetings is currently not supported');
|
|
80
|
+
}
|
|
81
|
+
setProcessingRecRequest(true);
|
|
82
|
+
setInitialRecStatus(isRecording);
|
|
83
|
+
let response: Response;
|
|
84
|
+
if (isRecording) {
|
|
85
|
+
response = await fetch(recordingEndpoint + `/stop?roomName=${room.name}`);
|
|
86
|
+
} else {
|
|
87
|
+
response = await fetch(recordingEndpoint + `/start?roomName=${room.name}`);
|
|
88
|
+
}
|
|
89
|
+
if (response.ok) {
|
|
90
|
+
} else {
|
|
91
|
+
console.error('Error handling recording request, check server logs:', response.status, response.statusText);
|
|
92
|
+
setProcessingRecRequest(false);
|
|
93
|
+
}
|
|
94
|
+
};
|
|
95
|
+
*/
|
|
59
96
|
const MenuContent = useMemo(() => (_jsxs(Box, { children: [_jsx(Typography, Object.assign({ variant: "body1", component: "div" }, { children: _jsx("b", { children: _jsx(FormattedMessage, { id: "ui.liveStreamRoom.settingsMenu.visualEffect", defaultMessage: "ui.liveStreamRoom.settingsMenu.visualEffect" }) }) })), _jsx(FormControlLabel, { labelPlacement: "start", control: _jsx(Switch, { checked: blurEnabled, disabled: actionBlurDisabled, onChange: handleBlur, inputProps: { 'aria-label': 'controlled' } }), label: _jsx(FormattedMessage, { id: "ui.liveStreamRoom.settingsMenu.visualEffect.blurEffect", defaultMessage: "ui.liveStreamRoom.settingsMenu.visualEffect.blurEffect" }) })] })), [blurEnabled, actionBlurDisabled, handleBlur]);
|
|
60
97
|
if (onlyContentMenu) {
|
|
61
98
|
return MenuContent;
|
|
@@ -14,6 +14,8 @@ import { BackgroundBlur } from '@livekit/track-processors';
|
|
|
14
14
|
import LiveStreamSettingsMenu from './LiveStreamSettingsMenu';
|
|
15
15
|
import { isClientSideRendering } from '@selfcommunity/utils';
|
|
16
16
|
import { CHOICE_VIDEO_BLUR_EFFECT } from '../../../constants/LiveStream';
|
|
17
|
+
import { FormattedMessage } from 'react-intl';
|
|
18
|
+
import { useSnackbar } from 'notistack';
|
|
17
19
|
/** @alpha */
|
|
18
20
|
export function usePreviewTracks(options, onError) {
|
|
19
21
|
const [tracks, setTracks] = React.useState();
|
|
@@ -170,6 +172,7 @@ export function PreJoin(_a) {
|
|
|
170
172
|
preventSave: !persistUserChoices,
|
|
171
173
|
preventLoad: !persistUserChoices
|
|
172
174
|
});
|
|
175
|
+
const { enqueueSnackbar } = useSnackbar();
|
|
173
176
|
// Initialize device settings
|
|
174
177
|
const [audioEnabled, setAudioEnabled] = React.useState(initialUserChoices.audioEnabled && canUseAudio);
|
|
175
178
|
const [videoEnabled, setVideoEnabled] = React.useState(initialUserChoices.videoEnabled && canUseVideo);
|
|
@@ -177,7 +180,7 @@ export function PreJoin(_a) {
|
|
|
177
180
|
const [videoDeviceId, setVideoDeviceId] = React.useState(initialUserChoices.videoDeviceId);
|
|
178
181
|
const [username, setUsername] = React.useState(initialUserChoices.username);
|
|
179
182
|
// Processors
|
|
180
|
-
const [blurEnabled, setBlurEnabled] = React.useState(isClientSideRendering() ?
|
|
183
|
+
const [blurEnabled, setBlurEnabled] = React.useState(isClientSideRendering() ? ((_b = window === null || window === void 0 ? void 0 : window.localStorage) === null || _b === void 0 ? void 0 : _b.getItem(CHOICE_VIDEO_BLUR_EFFECT)) === 'true' : false);
|
|
181
184
|
const [processorPending, setProcessorPending] = React.useState(false);
|
|
182
185
|
// Save user choices to persistent storage.
|
|
183
186
|
React.useEffect(() => {
|
|
@@ -235,8 +238,9 @@ export function PreJoin(_a) {
|
|
|
235
238
|
}, [onValidate]);
|
|
236
239
|
const handleBlur = React.useCallback(() => {
|
|
237
240
|
var _a;
|
|
238
|
-
|
|
239
|
-
(
|
|
241
|
+
const _blur = !blurEnabled;
|
|
242
|
+
setBlurEnabled(_blur);
|
|
243
|
+
(_a = window === null || window === void 0 ? void 0 : window.localStorage) === null || _a === void 0 ? void 0 : _a.setItem(CHOICE_VIDEO_BLUR_EFFECT, _blur.toString());
|
|
240
244
|
}, [setBlurEnabled, blurEnabled]);
|
|
241
245
|
useEffect(() => {
|
|
242
246
|
const newUserChoices = {
|
|
@@ -250,6 +254,7 @@ export function PreJoin(_a) {
|
|
|
250
254
|
setIsValid(handleValidation(newUserChoices));
|
|
251
255
|
}, [username, scUserContext.user, videoEnabled, handleValidation, audioEnabled, audioDeviceId, videoDeviceId]);
|
|
252
256
|
useEffect(() => {
|
|
257
|
+
var _a;
|
|
253
258
|
if (videoTrack && videoEnabled) {
|
|
254
259
|
setProcessorPending(true);
|
|
255
260
|
try {
|
|
@@ -260,6 +265,15 @@ export function PreJoin(_a) {
|
|
|
260
265
|
videoTrack.stopProcessor();
|
|
261
266
|
}
|
|
262
267
|
}
|
|
268
|
+
catch (e) {
|
|
269
|
+
console.log(e);
|
|
270
|
+
setBlurEnabled(false);
|
|
271
|
+
(_a = window === null || window === void 0 ? void 0 : window.localStorage) === null || _a === void 0 ? void 0 : _a.setItem(CHOICE_VIDEO_BLUR_EFFECT, false.toString());
|
|
272
|
+
enqueueSnackbar(_jsx(FormattedMessage, { id: "ui.liveStreamRoom.errorApplyVideoEffect", defaultMessage: "ui.contributionActionMenu.errorApplyVideoEffect" }), {
|
|
273
|
+
variant: 'warning',
|
|
274
|
+
autoHideDuration: 3000
|
|
275
|
+
});
|
|
276
|
+
}
|
|
263
277
|
finally {
|
|
264
278
|
setProcessorPending(false);
|
|
265
279
|
}
|
|
@@ -12,13 +12,16 @@ import { FocusLayout, FocusLayoutContainer, FocusLayoutContainerNoParticipants }
|
|
|
12
12
|
import { useSCUser } from '@selfcommunity/react-core';
|
|
13
13
|
import classNames from 'classnames';
|
|
14
14
|
import { styled } from '@mui/material/styles';
|
|
15
|
-
import { Box } from '@mui/material';
|
|
15
|
+
import { Box, IconButton } from '@mui/material';
|
|
16
16
|
import { useThemeProps } from '@mui/system';
|
|
17
17
|
import NoParticipants from './NoParticipants';
|
|
18
18
|
import LiveStreamSettingsMenu from './LiveStreamSettingsMenu';
|
|
19
19
|
import { BackgroundBlur } from '@livekit/track-processors';
|
|
20
20
|
import { isClientSideRendering } from '@selfcommunity/utils';
|
|
21
21
|
import { CHOICE_VIDEO_BLUR_EFFECT } from '../../../constants/LiveStream';
|
|
22
|
+
import Icon from '@mui/material/Icon';
|
|
23
|
+
import { useSnackbar } from 'notistack';
|
|
24
|
+
import { FormattedMessage } from 'react-intl';
|
|
22
25
|
const PREFIX = 'SCVideoConference';
|
|
23
26
|
const classes = {
|
|
24
27
|
root: `${PREFIX}-root`
|
|
@@ -56,7 +59,7 @@ export function VideoConference(inProps) {
|
|
|
56
59
|
const lastAutoFocusedScreenShareTrack = React.useRef(null);
|
|
57
60
|
// HOOKS
|
|
58
61
|
const scUserContext = useSCUser();
|
|
59
|
-
const [blurEnabled, setBlurEnabled] = React.useState(isClientSideRendering() ?
|
|
62
|
+
const [blurEnabled, setBlurEnabled] = React.useState(isClientSideRendering() ? ((_a = window === null || window === void 0 ? void 0 : window.localStorage) === null || _a === void 0 ? void 0 : _a.getItem(CHOICE_VIDEO_BLUR_EFFECT)) === 'true' : false);
|
|
60
63
|
const [processorPending, setProcessorPending] = React.useState(false);
|
|
61
64
|
const tracks = useTracks([
|
|
62
65
|
{ source: Track.Source.Camera, withPlaceholder: true },
|
|
@@ -84,6 +87,7 @@ export function VideoConference(inProps) {
|
|
|
84
87
|
const focusTrack = (_b = usePinnedTracks(layoutContext)) === null || _b === void 0 ? void 0 : _b[0];
|
|
85
88
|
const carouselTracks = tracks.filter((track) => !isEqualTrackRef(track, focusTrack));
|
|
86
89
|
const { cameraTrack } = useLocalParticipant();
|
|
90
|
+
const { enqueueSnackbar } = useSnackbar();
|
|
87
91
|
useLivestreamCheck();
|
|
88
92
|
/**
|
|
89
93
|
* widgetUpdate
|
|
@@ -163,6 +167,7 @@ export function VideoConference(inProps) {
|
|
|
163
167
|
}
|
|
164
168
|
}, [tracks, participants, speakerFocused]);
|
|
165
169
|
useEffect(() => {
|
|
170
|
+
var _a;
|
|
166
171
|
const localCamTrack = cameraTrack === null || cameraTrack === void 0 ? void 0 : cameraTrack.track;
|
|
167
172
|
if (localCamTrack) {
|
|
168
173
|
setProcessorPending(true);
|
|
@@ -174,6 +179,15 @@ export function VideoConference(inProps) {
|
|
|
174
179
|
localCamTrack.stopProcessor();
|
|
175
180
|
}
|
|
176
181
|
}
|
|
182
|
+
catch (e) {
|
|
183
|
+
console.log(e);
|
|
184
|
+
setBlurEnabled(false);
|
|
185
|
+
(_a = window === null || window === void 0 ? void 0 : window.localStorage) === null || _a === void 0 ? void 0 : _a.setItem(CHOICE_VIDEO_BLUR_EFFECT, false.toString());
|
|
186
|
+
enqueueSnackbar(_jsx(FormattedMessage, { id: "ui.liveStreamRoom.errorApplyVideoEffect", defaultMessage: "ui.contributionActionMenu.errorApplyVideoEffect" }), {
|
|
187
|
+
variant: 'warning',
|
|
188
|
+
autoHideDuration: 3000
|
|
189
|
+
});
|
|
190
|
+
}
|
|
177
191
|
finally {
|
|
178
192
|
setProcessorPending(false);
|
|
179
193
|
}
|
|
@@ -184,5 +198,5 @@ export function VideoConference(inProps) {
|
|
|
184
198
|
microphone: !disableMicrophone,
|
|
185
199
|
camera: !disableCamera,
|
|
186
200
|
screenShare: !disableShareScreen
|
|
187
|
-
}, { settings: true }) })] })), !disableChat && (_jsx(Chat, { style: { display: widgetState.showChat ? 'grid' : 'none' }, messageFormatter: chatMessageFormatter, messageEncoder: chatMessageEncoder, messageDecoder: chatMessageDecoder })),
|
|
201
|
+
}, { settings: true }) })] })), !disableChat && (_jsx(Chat, { style: { display: widgetState.showChat ? 'grid' : 'none' }, messageFormatter: chatMessageFormatter, messageEncoder: chatMessageEncoder, messageDecoder: chatMessageDecoder })), _jsxs("div", Object.assign({ className: "lk-settings-menu-modal", style: { display: widgetState.showSettings ? 'block' : 'none' } }, { children: [_jsx(IconButton, Object.assign({ className: "lk-settings-menu-modal-icon-close", onClick: () => { var _a, _b; return (_b = layoutContext === null || layoutContext === void 0 ? void 0 : (_a = layoutContext.widget).dispatch) === null || _b === void 0 ? void 0 : _b.call(_a, { msg: 'toggle_settings' }); } }, { children: _jsx(Icon, { children: "close" }) })), SettingsComponent ? (_jsx(SettingsComponent, {})) : (_jsx(_Fragment, { children: _jsx(LiveStreamSettingsMenu, { onlyContentMenu: true, actionBlurDisabled: !cameraTrack && !disableCamera, blurEnabled: blurEnabled, handleBlur: handleBlur }) }))] }))] }))), _jsx(RoomAudioRenderer, {}), _jsx(ConnectionStateToast, {})] })));
|
|
188
202
|
}
|