UNPKG

@selfcommunity/react-ui

Version:

React UI Components to integrate a Community created with SelfCommunity Platform.

153 lines (148 loc) • 10.3 kB
import { __rest } from "tslib"; import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime"; import { Box, Button, CircularProgress, Typography } from '@mui/material'; import { styled } from '@mui/material/styles'; import { useThemeProps } from '@mui/system'; import { Link, SCPreferences, SCRoutes, useSCPreferences, useSCRouting, useSCUser } from '@selfcommunity/react-core'; import { SCLiveStreamViewType } from '@selfcommunity/types'; import classNames from 'classnames'; import { PREFIX } from './constants'; import { ConnectionState, formatChatMessageLinks, LayoutContextProvider, LiveKitRoom } from '@livekit/components-react'; import { useCallback, useMemo, useState } from 'react'; import { defaultUserChoices } from '@livekit/components-core'; import { defaultVideoOptions } from '../constants'; import { FormattedMessage, useIntl } from 'react-intl'; import { VideoConference } from './VideoConference'; import { useLiveStream } from './LiveStreamProvider'; import DialogContent from '@mui/material/DialogContent'; import BaseDialog from '../../../shared/BaseDialog'; import { closeSnackbar } from 'notistack'; const classes = { root: `${PREFIX}-root`, logo: `${PREFIX}-logo`, title: `${PREFIX}-title`, content: `${PREFIX}-content`, endConferenceWrap: `${PREFIX}-end-conference-wrap`, btnBackHome: `${PREFIX}-btn-back-home`, actions: `${PREFIX}-actions`, error: `${PREFIX}-error` }; const Root = styled(Box, { name: PREFIX, slot: 'Root' })(({ theme }) => ({})); const DialogRoot = styled(BaseDialog, { name: PREFIX, slot: 'Root', overridesResolver: (props, styles) => styles.dialogRoot })(({ theme }) => ({})); const PREFERENCES = [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 */ export default function LiveStreamVideoConference(inProps) { //PROPS const props = useThemeProps({ props: inProps, name: PREFIX }); const { className, handleOnLeaveRoom, userChoices = defaultUserChoices, connectionDetails = {}, LiveKitRoomComponentProps = { /* simulateParticipants: true */ }, VideoConferenceComponentProps = {}, startConferenceEndContent, endConferenceEndContent, options = defaultVideoOptions } = props, rest = __rest(props, ["className", "handleOnLeaveRoom", "userChoices", "connectionDetails", "LiveKitRoomComponentProps", "VideoConferenceComponentProps", "startConferenceEndContent", "endConferenceEndContent", "options"]); // CONTEXT const scUserContext = useSCUser(); const scRoutingContext = useSCRouting(); const scPreferences = useSCPreferences(); const { liveStream } = useLiveStream(); // STATE const [liveActive, setLiveActive] = useState(true); const [error, setError] = useState(null); // INTL const intl = useIntl(); // PREFERENCES const preferences = useMemo(() => { const _preferences = {}; PREFERENCES.map((p) => (_preferences[p] = p in scPreferences.preferences ? scPreferences.preferences[p].value : null)); return _preferences; }, [scPreferences.preferences]); // PERMISSIONS const canUseAudio = 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 = 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 = 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 = 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 = useMemo(() => (scUserContext.user && liveStream && liveStream.settings.view === SCLiveStreamViewType.SPEAKER ? liveStream.host : null), [scUserContext, liveStream]); const hideParticipantsList = 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 = useMemo(() => { return { autoSubscribe: true }; }, []); // HANDLERS /** * Handle on leave */ const handleOnLeave = useCallback(() => { setLiveActive(false); handleOnLeaveRoom === null || handleOnLeaveRoom === void 0 ? void 0 : handleOnLeaveRoom(); }, [handleOnLeaveRoom]); /** * Handle on error */ const handleError = 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 = useCallback((error) => { console.error(error); setError(`Encountered an unexpected encryption error, check the console logs for details: ${error.message}`); setLiveActive(false); }, []); const handleBackHome = useCallback(() => { closeSnackbar(); }, [closeSnackbar]); /** * User must be authenticated */ if (!scUserContext.user || !connectionDetails) { return _jsx(CircularProgress, {}); } /** * Renders root object */ return (_jsx(Root, Object.assign({ className: classNames(classes.root, className) }, rest, { children: liveActive && !error ? (_jsx(_Fragment, { children: _jsx(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: _jsxs(LayoutContextProvider, { children: [_jsx(VideoConference, Object.assign({ chatMessageFormatter: formatChatMessageLinks }, (speakerFocused && { speakerFocused: liveStream.host }), VideoConferenceComponentProps, { disableMicrophone: !canUseAudio, disableCamera: !canUseVideo, disableChat: !canUseChat, disableShareScreen: !canUseShareScreen, hideParticipantsList: hideParticipantsList })), _jsx(ConnectionState, {})] }) })) })) : (_jsx(_Fragment, { children: error ? (_jsx(DialogRoot, Object.assign({ open: true, maxWidth: 'md', fullWidth: true }, { children: _jsx(DialogContent, { children: _jsxs(Box, Object.assign({ className: classes.endConferenceWrap }, { children: [_jsx(Link, Object.assign({ to: scRoutingContext.url(SCRoutes.HOME_ROUTE_NAME, {}), className: classes.logo }, { children: _jsx("img", { src: preferences[SCPreferences.LOGO_NAVBAR_LOGO], alt: "logo" }) })), startConferenceEndContent, error, _jsx(Button, Object.assign({ variant: "contained", color: "secondary", component: Link, to: '/', className: classes.btnBackHome }, { children: _jsx(FormattedMessage, { id: "ui.liveStreamRoom.button.backHome", defaultMessage: "ui.liveStreamRoom.button.backHome" }) })), endConferenceEndContent] })) }) }))) : liveActive === false ? (_jsx(DialogRoot, Object.assign({ open: true, maxWidth: 'md', fullWidth: true }, { children: _jsx(DialogContent, { children: _jsxs(Box, Object.assign({ className: classes.endConferenceWrap }, { children: [_jsx(Link, Object.assign({ to: scRoutingContext.url(SCRoutes.HOME_ROUTE_NAME, {}), className: classes.logo }, { children: _jsx("img", { src: preferences[SCPreferences.LOGO_NAVBAR_LOGO], alt: "logo" }) })), startConferenceEndContent, _jsx(Typography, Object.assign({ variant: "h5" }, { children: _jsx(FormattedMessage, { id: "ui.liveStreamRoom.conference.end", defaultMessage: "ui.liveStreamRoom.conference.end" }) })), _jsx(Button, Object.assign({ variant: "contained", color: "secondary", component: Link, to: '/', onClick: handleBackHome, className: classes.btnBackHome }, { children: _jsx(FormattedMessage, { id: "ui.liveStreamRoom.button.backHome", defaultMessage: "ui.liveStreamRoom.button.backHome" }) })), endConferenceEndContent] })) }) }))) : (_jsx(CircularProgress, {})) })) }))); }