@selfcommunity/react-ui
Version:
React UI Components to integrate a Community created with SelfCommunity Platform.
156 lines (151 loc) • 11.6 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const tslib_1 = require("tslib");
const jsx_runtime_1 = require("react/jsx-runtime");
const material_1 = require("@mui/material");
const styles_1 = require("@mui/material/styles");
const system_1 = require("@mui/system");
const react_core_1 = require("@selfcommunity/react-core");
const types_1 = require("@selfcommunity/types");
const classnames_1 = tslib_1.__importDefault(require("classnames"));
const constants_1 = require("./constants");
const components_react_1 = require("@livekit/components-react");
const react_1 = require("react");
const components_core_1 = require("@livekit/components-core");
const constants_2 = require("../constants");
const react_intl_1 = require("react-intl");
const VideoConference_1 = require("./VideoConference");
const LiveStreamProvider_1 = require("./LiveStreamProvider");
const DialogContent_1 = tslib_1.__importDefault(require("@mui/material/DialogContent"));
const BaseDialog_1 = tslib_1.__importDefault(require("../../../shared/BaseDialog"));
const notistack_1 = require("notistack");
const classes = {
root: `${constants_1.PREFIX}-root`,
logo: `${constants_1.PREFIX}-logo`,
title: `${constants_1.PREFIX}-title`,
content: `${constants_1.PREFIX}-content`,
endConferenceWrap: `${constants_1.PREFIX}-end-conference-wrap`,
btnBackHome: `${constants_1.PREFIX}-btn-back-home`,
actions: `${constants_1.PREFIX}-actions`,
error: `${constants_1.PREFIX}-error`
};
const Root = (0, styles_1.styled)(material_1.Box, {
name: constants_1.PREFIX,
slot: 'Root'
})(({ theme }) => ({}));
const DialogRoot = (0, styles_1.styled)(BaseDialog_1.default, {
name: constants_1.PREFIX,
slot: 'Root',
overridesResolver: (props, styles) => styles.dialogRoot
})(({ theme }) => ({}));
const PREFERENCES = [react_core_1.SCPreferences.LOGO_NAVBAR_LOGO];
/**
*> API documentation for the Community-JS LiveStreamVideoConference component. Learn about the available props and the CSS API.
*
#### Import
```jsx
import {LiveStreamVideoConference} from '@selfcommunity/react-ui';
```
#### Component Name
The name `LiveStreamVideoConference` can be used when providing style overrides in the theme.
#### CSS
|Rule Name|Global class|Description|
|---|---|---|
|root|.SCLiveStreamForm-root|Styles applied to the root element.|
* @param inProps
*/
function LiveStreamVideoConference(inProps) {
//PROPS
const props = (0, system_1.useThemeProps)({
props: inProps,
name: constants_1.PREFIX
});
const { className, handleOnLeaveRoom, userChoices = components_core_1.defaultUserChoices, connectionDetails = {}, LiveKitRoomComponentProps = {
/* simulateParticipants: true */
}, VideoConferenceComponentProps = {}, startConferenceEndContent, endConferenceEndContent, options = constants_2.defaultVideoOptions } = props, rest = tslib_1.__rest(props, ["className", "handleOnLeaveRoom", "userChoices", "connectionDetails", "LiveKitRoomComponentProps", "VideoConferenceComponentProps", "startConferenceEndContent", "endConferenceEndContent", "options"]);
// CONTEXT
const scUserContext = (0, react_core_1.useSCUser)();
const scRoutingContext = (0, react_core_1.useSCRouting)();
const scPreferences = (0, react_core_1.useSCPreferences)();
const { liveStream } = (0, LiveStreamProvider_1.useLiveStream)();
// STATE
const [liveActive, setLiveActive] = (0, react_1.useState)(true);
const [error, setError] = (0, react_1.useState)(null);
// INTL
const intl = (0, react_intl_1.useIntl)();
// PREFERENCES
const preferences = (0, react_1.useMemo)(() => {
const _preferences = {};
PREFERENCES.map((p) => (_preferences[p] = p in scPreferences.preferences ? scPreferences.preferences[p].value : null));
return _preferences;
}, [scPreferences.preferences]);
// PERMISSIONS
const canUseAudio = (0, react_1.useMemo)(() => { var _a; return scUserContext.user && liveStream && (liveStream.host.id === scUserContext.user.id || (liveStream && !((_a = liveStream === null || liveStream === void 0 ? void 0 : liveStream.settings) === null || _a === void 0 ? void 0 : _a.muteParticipants))); }, [scUserContext, liveStream]);
const canUseVideo = (0, react_1.useMemo)(() => { var _a; return scUserContext.user && liveStream && (liveStream.host.id === scUserContext.user.id || (liveStream && !((_a = liveStream === null || liveStream === void 0 ? void 0 : liveStream.settings) === null || _a === void 0 ? void 0 : _a.disableVideo))); }, [scUserContext, liveStream]);
const canUseChat = (0, react_1.useMemo)(() => { var _a; return scUserContext.user && liveStream && liveStream && !((_a = liveStream === null || liveStream === void 0 ? void 0 : liveStream.settings) === null || _a === void 0 ? void 0 : _a.disableChat); }, [scUserContext, liveStream]);
const canUseShareScreen = (0, react_1.useMemo)(() => { var _a; return scUserContext.user && liveStream && (liveStream.host.id === scUserContext.user.id || (liveStream && !((_a = liveStream === null || liveStream === void 0 ? void 0 : liveStream.settings) === null || _a === void 0 ? void 0 : _a.disableShareScreen))); }, [scUserContext, liveStream]);
const speakerFocused = (0, react_1.useMemo)(() => (scUserContext.user && liveStream && liveStream.settings.view === types_1.SCLiveStreamViewType.SPEAKER ? liveStream.host : null), [scUserContext, liveStream]);
const hideParticipantsList = (0, react_1.useMemo)(() => { var _a; return scUserContext.user && liveStream && ((_a = liveStream === null || liveStream === void 0 ? void 0 : liveStream.settings) === null || _a === void 0 ? void 0 : _a.hideParticipantsList) && liveStream.host.id !== scUserContext.user.id; }, [scUserContext, liveStream]);
// CONNECT OPTIONS
const connectOptions = (0, react_1.useMemo)(() => {
return {
autoSubscribe: true
};
}, []);
// HANDLERS
/**
* Handle on leave
*/
const handleOnLeave = (0, react_1.useCallback)(() => {
setLiveActive(false);
handleOnLeaveRoom === null || handleOnLeaveRoom === void 0 ? void 0 : handleOnLeaveRoom();
}, [handleOnLeaveRoom]);
/**
* Handle on error
*/
const handleError = (0, react_1.useCallback)((error) => {
console.error(error);
if (error.message === 'Permission denied') {
setError(intl.formatMessage({
id: 'ui.liveStreamRoom.connect.error.device.permission',
defaultMessage: 'ui.liveStreamRoom.connect.error.device.permission'
}));
}
else if (error.message === 'Requested device not found') {
setError(intl.formatMessage({
id: 'ui.liveStreamRoom.connect.error.device.notFound',
defaultMessage: 'ui.liveStreamRoom.connect.error.device.notFound'
}));
}
else {
console.log(`Encountered an unexpected error, check the console logs for details: ${error.message}`);
setError(intl.formatMessage({
id: 'ui.liveStreamRoom.connect.error.clientInitiatedDisconnect',
defaultMessage: 'ui.liveStreamRoom.connect.error.clientInitiatedDisconnect'
}));
}
setLiveActive(false);
}, []);
/**
* Handle encryption error
*/
const handleEncryptionError = (0, react_1.useCallback)((error) => {
console.error(error);
setError(`Encountered an unexpected encryption error, check the console logs for details: ${error.message}`);
setLiveActive(false);
}, []);
const handleBackHome = (0, react_1.useCallback)(() => {
(0, notistack_1.closeSnackbar)();
}, [notistack_1.closeSnackbar]);
/**
* User must be authenticated
*/
if (!scUserContext.user || !connectionDetails) {
return (0, jsx_runtime_1.jsx)(material_1.CircularProgress, {});
}
/**
* Renders root object
*/
return ((0, jsx_runtime_1.jsx)(Root, Object.assign({ className: (0, classnames_1.default)(classes.root, className) }, rest, { children: liveActive && !error ? ((0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, { children: (0, jsx_runtime_1.jsx)(components_react_1.LiveKitRoom, Object.assign({ connect: Boolean(liveActive), token: connectionDetails['participantToken'], serverUrl: connectionDetails['serverUrl'], connectOptions: connectOptions, video: userChoices.videoEnabled, audio: userChoices.audioEnabled, onDisconnected: handleOnLeave, onEncryptionError: handleEncryptionError, onError: handleError }, LiveKitRoomComponentProps, { children: (0, jsx_runtime_1.jsxs)(components_react_1.LayoutContextProvider, { children: [(0, jsx_runtime_1.jsx)(VideoConference_1.VideoConference, Object.assign({ chatMessageFormatter: components_react_1.formatChatMessageLinks }, (speakerFocused && { speakerFocused: liveStream.host }), VideoConferenceComponentProps, { disableMicrophone: !canUseAudio, disableCamera: !canUseVideo, disableChat: !canUseChat, disableShareScreen: !canUseShareScreen, hideParticipantsList: hideParticipantsList })), (0, jsx_runtime_1.jsx)(components_react_1.ConnectionState, {})] }) })) })) : ((0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, { children: error ? ((0, jsx_runtime_1.jsx)(DialogRoot, Object.assign({ open: true, maxWidth: 'md', fullWidth: true }, { children: (0, jsx_runtime_1.jsx)(DialogContent_1.default, { children: (0, jsx_runtime_1.jsxs)(material_1.Box, Object.assign({ className: classes.endConferenceWrap }, { children: [(0, jsx_runtime_1.jsx)(react_core_1.Link, Object.assign({ to: scRoutingContext.url(react_core_1.SCRoutes.HOME_ROUTE_NAME, {}), className: classes.logo }, { children: (0, jsx_runtime_1.jsx)("img", { src: preferences[react_core_1.SCPreferences.LOGO_NAVBAR_LOGO], alt: "logo" }) })), startConferenceEndContent, error, (0, jsx_runtime_1.jsx)(material_1.Button, Object.assign({ variant: "contained", color: "secondary", component: react_core_1.Link, to: '/', className: classes.btnBackHome }, { children: (0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.liveStreamRoom.button.backHome", defaultMessage: "ui.liveStreamRoom.button.backHome" }) })), endConferenceEndContent] })) }) }))) : liveActive === false ? ((0, jsx_runtime_1.jsx)(DialogRoot, Object.assign({ open: true, maxWidth: 'md', fullWidth: true }, { children: (0, jsx_runtime_1.jsx)(DialogContent_1.default, { children: (0, jsx_runtime_1.jsxs)(material_1.Box, Object.assign({ className: classes.endConferenceWrap }, { children: [(0, jsx_runtime_1.jsx)(react_core_1.Link, Object.assign({ to: scRoutingContext.url(react_core_1.SCRoutes.HOME_ROUTE_NAME, {}), className: classes.logo }, { children: (0, jsx_runtime_1.jsx)("img", { src: preferences[react_core_1.SCPreferences.LOGO_NAVBAR_LOGO], alt: "logo" }) })), startConferenceEndContent, (0, jsx_runtime_1.jsx)(material_1.Typography, Object.assign({ variant: "h5" }, { children: (0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.liveStreamRoom.conference.end", defaultMessage: "ui.liveStreamRoom.conference.end" }) })), (0, jsx_runtime_1.jsx)(material_1.Button, Object.assign({ variant: "contained", color: "secondary", component: react_core_1.Link, to: '/', onClick: handleBackHome, className: classes.btnBackHome }, { children: (0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.liveStreamRoom.button.backHome", defaultMessage: "ui.liveStreamRoom.button.backHome" }) })), endConferenceEndContent] })) }) }))) : ((0, jsx_runtime_1.jsx)(material_1.CircularProgress, {})) })) })));
}
exports.default = LiveStreamVideoConference;