bigbluebutton-Github/bigbluebutton-html5/imports/ui/components/app/component.jsx

352 lines
11 KiB
React
Raw Normal View History

2021-05-28 02:12:49 +08:00
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { defineMessages, injectIntl } from 'react-intl';
import ReactModal from 'react-modal';
import browserInfo from '/imports/utils/browserInfo';
2021-04-01 01:13:36 +08:00
import deviceInfo from '/imports/utils/deviceInfo';
2018-10-12 23:05:53 +08:00
import PollingContainer from '/imports/ui/components/polling/container';
import logger from '/imports/startup/client/logger';
2019-02-27 01:40:01 +08:00
import ActivityCheckContainer from '/imports/ui/components/activity-check/container';
2022-02-16 01:57:50 +08:00
import ToastContainer from '/imports/ui/components/common/toast/container';
import PadsSessionsContainer from '/imports/ui/components/pads/pads-graphql/sessions/component';
2023-07-31 22:24:25 +08:00
import WakeLockContainer from '../wake-lock/container';
import NotificationsBarContainer from '../notifications-bar/container';
2017-03-28 04:40:44 +08:00
import AudioContainer from '../audio/container';
2019-03-16 04:07:14 +08:00
import BannerBarContainer from '/imports/ui/components/banner-bar/container';
import RaiseHandNotifier from '/imports/ui/components/raisehand-notifier/container';
2024-06-17 19:54:03 +08:00
import ManyWebcamsNotifier from '/imports/ui/components/video-provider/many-users-notify/container';
2024-04-17 06:39:29 +08:00
import AudioCaptionsSpeechContainer from '/imports/ui/components/audio/audio-graphql/audio-captions/speech/component';
2020-02-26 03:29:14 +08:00
import UploaderContainer from '/imports/ui/components/presentation/presentation-uploader/container';
import ScreenReaderAlertContainer from '../screenreader-alert/container';
import ScreenReaderAlertAdapter from '../screenreader-alert/adapter';
2024-06-17 19:54:03 +08:00
import WebcamContainer from '../webcam/component';
2023-10-12 20:32:24 +08:00
import PresentationContainer from '../presentation/container';
import ScreenshareContainer from '../screenshare/container';
import ExternalVideoPlayerContainer from '../external-video-player/external-video-player-graphql/component';
2024-06-15 02:32:55 +08:00
import GenericContentMainAreaContainer from '../generic-content/generic-main-content/container';
import EmojiRainContainer from '../emoji-rain/container';
2021-10-28 00:43:51 +08:00
import Styled from './styles';
import { SMALL_VIEWPORT_BREAKPOINT } from '../layout/enums';
2021-09-24 04:46:50 +08:00
import LayoutEngine from '../layout/layout-manager/layoutEngine';
2021-05-18 04:25:07 +08:00
import NavBarContainer from '../nav-bar/container';
import SidebarNavigationContainer from '../sidebar-navigation/container';
import SidebarContentContainer from '../sidebar-content/container';
import PluginsEngineManager from '../plugins-engine/manager';
import Notifications from '../notifications/component';
2021-11-06 03:59:01 +08:00
import GlobalStyles from '/imports/ui/stylesheets/styled-components/globalStyles';
import ActionsBarContainer from '../actions-bar/container';
2022-09-03 02:18:17 +08:00
import PushLayoutEngine from '../layout/push-layout/pushLayoutEngine';
import NotesContainer from '/imports/ui/components/notes/component';
import AppService from '/imports/ui/components/app/service';
import TimeSync from './app-graphql/time-sync/component';
import PresentationUploaderToastContainer from '/imports/ui/components/presentation/presentation-toast/presentation-uploader-toast/container';
2023-12-12 00:21:00 +08:00
import BreakoutJoinConfirmationContainerGraphQL from '../breakout-join-confirmation/breakout-join-confirmation-graphql/component';
import FloatingWindowContainer from '/imports/ui/components/floating-window/container';
2024-02-24 02:14:12 +08:00
import ChatAlertContainerGraphql from '../chat/chat-graphql/alert/component';
2024-06-12 05:55:38 +08:00
import { notify } from '/imports/ui/services/notification';
2024-06-29 04:21:30 +08:00
import VoiceActivityAdapter from '../../core/adapters/voice-activity';
import LayoutObserver from '../layout/observer';
const intlMessages = defineMessages({
userListLabel: {
2017-09-23 01:51:47 +08:00
id: 'app.userList.label',
2017-04-10 23:50:03 +08:00
description: 'Aria-label for Userlist Nav',
},
chatLabel: {
2017-09-23 01:23:25 +08:00
id: 'app.chat.label',
2017-04-19 03:42:55 +08:00
description: 'Aria-label for Chat Section',
},
2017-08-11 00:05:51 +08:00
actionsBarLabel: {
id: 'app.actionsBar.label',
2017-04-19 03:42:55 +08:00
description: 'Aria-label for ActionsBar Section',
},
clearedReaction: {
id: 'app.toast.clearedReactions.label',
description: 'message for cleared reactions',
},
raisedHand: {
id: 'app.toast.setEmoji.raiseHand',
description: 'toast message for raised hand notification',
},
loweredHand: {
id: 'app.toast.setEmoji.lowerHand',
description: 'toast message for lowered hand notification',
},
away: {
id: 'app.toast.setEmoji.away',
description: 'toast message for set away notification',
},
notAway: {
id: 'app.toast.setEmoji.notAway',
description: 'toast message for remove away notification',
},
meetingMuteOn: {
id: 'app.toast.meetingMuteOn.label',
2019-06-01 02:48:41 +08:00
description: 'message used when meeting has been muted',
},
meetingMuteOff: {
id: 'app.toast.meetingMuteOff.label',
2019-06-01 02:48:41 +08:00
description: 'message used when meeting has been unmuted',
},
pollPublishedLabel: {
id: 'app.whiteboard.annotations.poll',
description: 'message displayed when a poll is published',
},
2021-09-05 06:36:48 +08:00
defaultViewLabel: {
id: 'app.title.defaultViewLabel',
description: 'view name appended to document title',
2021-09-05 06:36:48 +08:00
},
2022-01-11 13:02:24 +08:00
promotedLabel: {
id: 'app.toast.promotedLabel',
description: 'notification message when promoted',
},
demotedLabel: {
id: 'app.toast.demotedLabel',
description: 'notification message when demoted',
},
});
2016-04-29 03:02:51 +08:00
const propTypes = {
2022-04-09 03:05:29 +08:00
darkTheme: PropTypes.bool.isRequired,
};
class App extends Component {
2021-05-18 04:25:07 +08:00
constructor(props) {
super(props);
2016-09-15 01:48:50 +08:00
this.state = {
isAudioModalOpen: false,
isVideoPreviewModalOpen: false,
2023-08-30 04:00:32 +08:00
presentationFitToWidth: false,
2016-09-15 01:48:50 +08:00
};
2020-06-13 02:50:42 +08:00
this.timeOffsetInterval = null;
2020-04-27 04:18:43 +08:00
2023-08-30 04:00:32 +08:00
this.setPresentationFitToWidth = this.setPresentationFitToWidth.bind(this);
this.setAudioModalIsOpen = this.setAudioModalIsOpen.bind(this);
this.setVideoPreviewModalIsOpen = this.setVideoPreviewModalIsOpen.bind(this);
}
componentDidMount() {
const { browserName } = browserInfo;
2021-05-18 04:25:07 +08:00
const { osName } = deviceInfo;
2017-07-04 22:32:22 +08:00
ReactModal.setAppElement('#app');
const body = document.getElementsByTagName('body')[0];
if (browserName) {
body.classList.add(`browser-${browserName.split(' ').pop().toLowerCase()}`);
}
2021-04-01 01:13:36 +08:00
body.classList.add(`os-${osName.split(' ').shift().toLowerCase()}`);
2021-05-18 04:25:07 +08:00
window.ondragover = (e) => { e.preventDefault(); };
window.ondrop = (e) => { e.preventDefault(); };
logger.info({ logCode: 'app_component_componentdidmount' }, 'Client loaded successfully');
}
componentDidUpdate(prevProps) {
const {
currentUserAway,
currentUserRaiseHand,
intl,
} = this.props;
2022-04-09 03:05:29 +08:00
this.renderDarkMode();
if (prevProps.currentUserAway !== currentUserAway) {
if (currentUserAway === true) {
notify(intl.formatMessage(intlMessages.away), 'info', 'user');
} else {
notify(intl.formatMessage(intlMessages.notAway), 'info', 'clear_status');
}
}
if (prevProps.currentUserRaiseHand !== currentUserRaiseHand) {
if (currentUserRaiseHand === true) {
notify(intl.formatMessage(intlMessages.raisedHand), 'info', 'user');
} else {
notify(intl.formatMessage(intlMessages.loweredHand), 'info', 'clear_status');
}
}
}
componentWillUnmount() {
window.onbeforeunload = null;
2020-06-13 02:50:42 +08:00
if (this.timeOffsetInterval) {
clearInterval(this.timeOffsetInterval);
}
}
setPresentationFitToWidth(presentationFitToWidth) {
this.setState({ presentationFitToWidth });
}
setAudioModalIsOpen(value) {
this.setState({ isAudioModalOpen: value });
}
setVideoPreviewModalIsOpen(value) {
this.setState({ isVideoPreviewModalOpen: value });
}
renderDarkMode() {
const { darkTheme } = this.props;
AppService.setDarkTheme(darkTheme);
}
renderActionsBar() {
const {
hideActionsBar,
presentationIsOpen,
} = this.props;
if (hideActionsBar) return null;
return (
<ActionsBarContainer
presentationIsOpen={presentationIsOpen}
setPresentationFitToWidth={this.setPresentationFitToWidth}
/>
);
}
renderAudioCaptions() {
const {
audioCaptions,
captionsStyle,
} = this.props;
if (!audioCaptions) return null;
return (
<Styled.CaptionsWrapper
role="region"
style={
{
position: 'absolute',
left: captionsStyle.left,
right: captionsStyle.right,
maxWidth: captionsStyle.maxWidth,
}
}
>
{audioCaptions}
</Styled.CaptionsWrapper>
);
}
render() {
const {
2021-05-18 04:25:07 +08:00
customStyle,
customStyleUrl,
shouldShowExternalVideo,
shouldShowPresentation,
shouldShowScreenshare,
isSharedNotesPinned,
presentationIsOpen,
darkTheme,
intl,
genericMainContentId,
} = this.props;
const {
isAudioModalOpen,
isVideoPreviewModalOpen,
2023-08-17 03:24:34 +08:00
presentationFitToWidth,
} = this.state;
2016-04-29 03:02:51 +08:00
return (
2021-05-18 04:25:07 +08:00
<>
<ScreenReaderAlertAdapter />
<PluginsEngineManager />
<FloatingWindowContainer />
<TimeSync />
2022-03-11 03:33:25 +08:00
<Notifications />
<PushLayoutEngine
shouldShowScreenshare={shouldShowScreenshare}
shouldShowExternalVideo={shouldShowExternalVideo}
/>
<LayoutEngine />
<LayoutObserver />
2021-11-06 03:59:01 +08:00
<GlobalStyles />
2021-10-28 00:43:51 +08:00
<Styled.Layout
2021-08-05 19:03:24 +08:00
id="layout"
2021-08-05 12:22:07 +08:00
style={{
width: '100%',
height: '100%',
}}
>
<ActivityCheckContainer />
<ScreenReaderAlertContainer />
2021-08-05 12:22:07 +08:00
<BannerBarContainer />
<NotificationsBarContainer />
2021-08-05 12:22:07 +08:00
<SidebarNavigationContainer />
<SidebarContentContainer isSharedNotesPinned={isSharedNotesPinned} />
2021-08-05 12:22:07 +08:00
<NavBarContainer main="new" />
<WebcamContainer />
2023-12-13 04:47:29 +08:00
<ExternalVideoPlayerContainer />
2024-06-15 02:32:55 +08:00
<GenericContentMainAreaContainer
genericMainContentId={genericMainContentId}
/>
{
shouldShowPresentation
? (
<PresentationContainer
setPresentationFitToWidth={this.setPresentationFitToWidth}
fitToWidth={presentationFitToWidth}
darkTheme={darkTheme}
presentationIsOpen={presentationIsOpen}
/>
)
: null
}
2021-08-05 12:22:07 +08:00
{
shouldShowScreenshare
? (
<ScreenshareContainer />
)
: null
2021-08-05 12:22:07 +08:00
}
{isSharedNotesPinned
? (
<NotesContainer
area="media"
/>
) : null}
<AudioCaptionsSpeechContainer />
{this.renderAudioCaptions()}
<PresentationUploaderToastContainer intl={intl} />
2021-08-05 12:22:07 +08:00
<UploaderContainer />
2023-12-12 00:21:00 +08:00
<BreakoutJoinConfirmationContainerGraphQL />
<AudioContainer {...{
isAudioModalOpen,
setAudioModalIsOpen: this.setAudioModalIsOpen,
isVideoPreviewModalOpen,
setVideoPreviewModalIsOpen: this.setVideoPreviewModalIsOpen,
2024-04-17 06:39:29 +08:00
}}
/>
2021-08-05 12:22:07 +08:00
<ToastContainer rtl />
<ChatAlertContainerGraphql />
<RaiseHandNotifier />
2021-08-05 12:22:07 +08:00
<ManyWebcamsNotifier />
<PollingContainer />
<PadsSessionsContainer />
2023-07-31 22:24:25 +08:00
<WakeLockContainer />
2021-08-05 12:22:07 +08:00
{this.renderActionsBar()}
<EmojiRainContainer />
2024-06-29 04:21:30 +08:00
<VoiceActivityAdapter />
2021-08-05 12:22:07 +08:00
{customStyleUrl ? <link rel="stylesheet" type="text/css" href={customStyleUrl} /> : null}
{customStyle ? <link rel="stylesheet" type="text/css" href={`data:text/css;charset=UTF-8,${encodeURIComponent(customStyle)}`} /> : null}
2021-10-28 00:43:51 +08:00
</Styled.Layout>
2021-05-18 04:25:07 +08:00
</>
2016-04-29 03:02:51 +08:00
);
}
}
App.propTypes = propTypes;
2022-04-09 03:05:29 +08:00
export default injectIntl(App);