Merge branch 'master' of https://github.com/bigbluebutton/bigbluebutton into tRecord
This commit is contained in:
commit
5afba4cf67
@ -11,20 +11,19 @@ export default function clearGroupChatMsg(meetingId, chatId) {
|
|||||||
if (chatId) {
|
if (chatId) {
|
||||||
GroupChatMsg.remove({ meetingId, chatId }, () => {
|
GroupChatMsg.remove({ meetingId, chatId }, () => {
|
||||||
Logger.info(`Cleared GroupChatMsg (${meetingId}, ${chatId})`);
|
Logger.info(`Cleared GroupChatMsg (${meetingId}, ${chatId})`);
|
||||||
|
const clearMsg = {
|
||||||
|
color: '0',
|
||||||
|
timestamp: Date.now(),
|
||||||
|
correlationId: `${PUBLIC_CHAT_SYSTEM_ID}-${Date.now()}`,
|
||||||
|
sender: {
|
||||||
|
id: PUBLIC_CHAT_SYSTEM_ID,
|
||||||
|
name: '',
|
||||||
|
},
|
||||||
|
message: CHAT_CLEAR_MESSAGE,
|
||||||
|
};
|
||||||
|
|
||||||
|
return addGroupChatMsg(meetingId, PUBLIC_GROUP_CHAT_ID, clearMsg);
|
||||||
});
|
});
|
||||||
|
|
||||||
const clearMsg = {
|
|
||||||
color: '0',
|
|
||||||
timestamp: Date.now(),
|
|
||||||
correlationId: `${PUBLIC_CHAT_SYSTEM_ID}-${Date.now()}`,
|
|
||||||
sender: {
|
|
||||||
id: PUBLIC_CHAT_SYSTEM_ID,
|
|
||||||
name: '',
|
|
||||||
},
|
|
||||||
message: CHAT_CLEAR_MESSAGE,
|
|
||||||
};
|
|
||||||
|
|
||||||
return addGroupChatMsg(meetingId, PUBLIC_GROUP_CHAT_ID, clearMsg);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (meetingId) {
|
if (meetingId) {
|
||||||
|
@ -45,11 +45,16 @@ class Base extends Component {
|
|||||||
this.updateLoadingState = this.updateLoadingState.bind(this);
|
this.updateLoadingState = this.updateLoadingState.bind(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
componentWillUpdate() {
|
componentDidUpdate(prevProps) {
|
||||||
const { approved } = this.props;
|
const { ejected, approved } = this.props;
|
||||||
const { loading } = this.state;
|
const { loading } = this.state;
|
||||||
|
|
||||||
if (approved && loading) this.updateLoadingState(false);
|
if (approved && loading) this.updateLoadingState(false);
|
||||||
|
|
||||||
|
if (prevProps.ejected || ejected) {
|
||||||
|
Session.set('codeError', '403');
|
||||||
|
Session.set('isMeetingEnded', true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
updateLoadingState(loading = false) {
|
updateLoadingState(loading = false) {
|
||||||
@ -173,6 +178,7 @@ const BaseContainer = withTracker(() => {
|
|||||||
const subscriptionsReady = subscriptionsHandlers.every(handler => handler.ready());
|
const subscriptionsReady = subscriptionsHandlers.every(handler => handler.ready());
|
||||||
return {
|
return {
|
||||||
approved: Users.findOne({ userId: Auth.userID, approved: true, guest: true }),
|
approved: Users.findOne({ userId: Auth.userID, approved: true, guest: true }),
|
||||||
|
ejected: Users.findOne({ userId: Auth.userID, ejected: true }),
|
||||||
meetingEnded: Session.get('isMeetingEnded'),
|
meetingEnded: Session.get('isMeetingEnded'),
|
||||||
locale,
|
locale,
|
||||||
subscriptionsReady,
|
subscriptionsReady,
|
||||||
|
@ -15,6 +15,9 @@ import ChatAlertContainer from '../chat/alert/container';
|
|||||||
import { styles } from './styles';
|
import { styles } from './styles';
|
||||||
|
|
||||||
const MOBILE_MEDIA = 'only screen and (max-width: 40em)';
|
const MOBILE_MEDIA = 'only screen and (max-width: 40em)';
|
||||||
|
const APP_CONFIG = Meteor.settings.public.app;
|
||||||
|
const DESKTOP_FONT_SIZE = APP_CONFIG.desktopFontSize;
|
||||||
|
const MOBILE_FONT_SIZE = APP_CONFIG.mobileFontSize;
|
||||||
|
|
||||||
const intlMessages = defineMessages({
|
const intlMessages = defineMessages({
|
||||||
userListLabel: {
|
userListLabel: {
|
||||||
@ -36,7 +39,6 @@ const intlMessages = defineMessages({
|
|||||||
});
|
});
|
||||||
|
|
||||||
const propTypes = {
|
const propTypes = {
|
||||||
fontSize: PropTypes.string,
|
|
||||||
navbar: PropTypes.element,
|
navbar: PropTypes.element,
|
||||||
sidebar: PropTypes.element,
|
sidebar: PropTypes.element,
|
||||||
media: PropTypes.element,
|
media: PropTypes.element,
|
||||||
@ -49,7 +51,6 @@ const propTypes = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const defaultProps = {
|
const defaultProps = {
|
||||||
fontSize: '16px',
|
|
||||||
navbar: null,
|
navbar: null,
|
||||||
sidebar: null,
|
sidebar: null,
|
||||||
media: null,
|
media: null,
|
||||||
@ -70,13 +71,14 @@ class App extends Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
const { locale, fontSize } = this.props;
|
const { locale } = this.props;
|
||||||
|
const BROWSER_RESULTS = browser();
|
||||||
|
const isMobileBrowser = BROWSER_RESULTS.mobile || BROWSER_RESULTS.os.includes('Android');
|
||||||
|
|
||||||
Modal.setAppElement('#app');
|
Modal.setAppElement('#app');
|
||||||
document.getElementsByTagName('html')[0].lang = locale;
|
document.getElementsByTagName('html')[0].lang = locale;
|
||||||
document.getElementsByTagName('html')[0].style.fontSize = fontSize;
|
document.getElementsByTagName('html')[0].style.fontSize = isMobileBrowser ? MOBILE_FONT_SIZE : DESKTOP_FONT_SIZE;
|
||||||
|
|
||||||
const BROWSER_RESULTS = browser();
|
|
||||||
const body = document.getElementsByTagName('body')[0];
|
const body = document.getElementsByTagName('body')[0];
|
||||||
if (BROWSER_RESULTS && BROWSER_RESULTS.name) {
|
if (BROWSER_RESULTS && BROWSER_RESULTS.name) {
|
||||||
body.classList.add(`browser-${BROWSER_RESULTS.name}`);
|
body.classList.add(`browser-${BROWSER_RESULTS.name}`);
|
||||||
@ -192,14 +194,14 @@ class App extends Component {
|
|||||||
|
|
||||||
render() {
|
render() {
|
||||||
const {
|
const {
|
||||||
customStyle, customStyleUrl, micsLocked,
|
customStyle, customStyleUrl, micsLocked, openPanel,
|
||||||
} = this.props;
|
} = this.props;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<main className={styles.main}>
|
<main className={styles.main}>
|
||||||
<NotificationsBarContainer />
|
<NotificationsBarContainer />
|
||||||
<section className={styles.wrapper}>
|
<section className={styles.wrapper}>
|
||||||
<div className={styles.content}>
|
<div className={openPanel ? styles.content : styles.noPanelContent}>
|
||||||
{this.renderNavBar()}
|
{this.renderNavBar()}
|
||||||
{this.renderMedia()}
|
{this.renderMedia()}
|
||||||
{this.renderActionsBar()}
|
{this.renderActionsBar()}
|
||||||
|
@ -9,6 +9,7 @@
|
|||||||
--bars-padding: calc(var(--lg-padding-x) - .45rem); // -.45 so user-list and chat title is aligned with the presentation title
|
--bars-padding: calc(var(--lg-padding-x) - .45rem); // -.45 so user-list and chat title is aligned with the presentation title
|
||||||
--userlist-handle-width: 5px; // 5px so user-list and chat resize handle render as the same size
|
--userlist-handle-width: 5px; // 5px so user-list and chat resize handle render as the same size
|
||||||
--poll-pane-min-width: 20em;
|
--poll-pane-min-width: 20em;
|
||||||
|
--panel-margin-left: 0.1em;
|
||||||
}
|
}
|
||||||
|
|
||||||
.main {
|
.main {
|
||||||
@ -57,7 +58,7 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.content {
|
.content, .noPanelContent {
|
||||||
@extend %full-page;
|
@extend %full-page;
|
||||||
order: 3;
|
order: 3;
|
||||||
|
|
||||||
@ -89,13 +90,16 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.content{
|
||||||
|
margin-left: var(--panel-margin-left);
|
||||||
|
}
|
||||||
|
|
||||||
.userList {
|
.userList {
|
||||||
@extend %full-page;
|
@extend %full-page;
|
||||||
@extend %text-elipsis;
|
@extend %text-elipsis;
|
||||||
|
|
||||||
z-index: 2;
|
z-index: 2;
|
||||||
overflow: visible;
|
overflow: visible;
|
||||||
order: 1;
|
order: 1;
|
||||||
|
|
||||||
@include mq($small-only) {
|
@include mq($small-only) {
|
||||||
@ -177,7 +181,7 @@
|
|||||||
order: 2;
|
order: 2;
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
position: relative;
|
position: relative;
|
||||||
|
margin-left: var(--panel-margin-right);
|
||||||
@include mq($portrait) {
|
@include mq($portrait) {
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
}
|
}
|
||||||
|
@ -18,6 +18,7 @@ const PUBLIC_CHAT_ID = CHAT_CONFIG.public_id;
|
|||||||
const PUBLIC_GROUP_CHAT_ID = CHAT_CONFIG.public_group_id;
|
const PUBLIC_GROUP_CHAT_ID = CHAT_CONFIG.public_group_id;
|
||||||
const PRIVATE_CHAT_TYPE = CHAT_CONFIG.type_private;
|
const PRIVATE_CHAT_TYPE = CHAT_CONFIG.type_private;
|
||||||
const PUBLIC_CHAT_USER_ID = CHAT_CONFIG.system_userid;
|
const PUBLIC_CHAT_USER_ID = CHAT_CONFIG.system_userid;
|
||||||
|
const PUBLIC_CHAT_CLEAR = CHAT_CONFIG.system_messages_keys.chat_clear;
|
||||||
|
|
||||||
const ScrollCollection = new Mongo.Collection(null);
|
const ScrollCollection = new Mongo.Collection(null);
|
||||||
|
|
||||||
@ -248,8 +249,27 @@ const htmlDecode = (input) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Export the chat as [Hour:Min] user: message
|
// Export the chat as [Hour:Min] user: message
|
||||||
const exportChat = messageList => (
|
const exportChat = (messageList) => {
|
||||||
messageList.map((message) => {
|
const { welcomeProp } = getMeeting();
|
||||||
|
const { logTime } = getUser(Auth.userID);
|
||||||
|
const { welcomeMsg } = welcomeProp;
|
||||||
|
|
||||||
|
const clearMessage = messageList.filter(message => message.message === PUBLIC_CHAT_CLEAR);
|
||||||
|
|
||||||
|
const hasClearMessage = clearMessage.length;
|
||||||
|
|
||||||
|
if (!hasClearMessage || (hasClearMessage && clearMessage[0].timestamp < logTime)) {
|
||||||
|
messageList.push({
|
||||||
|
timestamp: logTime,
|
||||||
|
message: welcomeMsg,
|
||||||
|
type: SYSTEM_CHAT_TYPE,
|
||||||
|
sender: PUBLIC_CHAT_USER_ID,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
messageList.sort((a, b) => a.timestamp - b.timestamp);
|
||||||
|
|
||||||
|
return messageList.map((message) => {
|
||||||
const date = new Date(message.timestamp);
|
const date = new Date(message.timestamp);
|
||||||
const hour = date.getHours().toString().padStart(2, 0);
|
const hour = date.getHours().toString().padStart(2, 0);
|
||||||
const min = date.getMinutes().toString().padStart(2, 0);
|
const min = date.getMinutes().toString().padStart(2, 0);
|
||||||
@ -259,8 +279,8 @@ const exportChat = messageList => (
|
|||||||
}
|
}
|
||||||
const userName = message.sender === PUBLIC_CHAT_USER_ID ? '' : `${getUser(message.sender).name} :`;
|
const userName = message.sender === PUBLIC_CHAT_USER_ID ? '' : `${getUser(message.sender).name} :`;
|
||||||
return `${hourMin} ${userName} ${htmlDecode(message.message)}`;
|
return `${hourMin} ${userName} ${htmlDecode(message.message)}`;
|
||||||
}).join('\n')
|
}).join('\n');
|
||||||
);
|
};
|
||||||
|
|
||||||
const setNotified = (chatType, item) => {
|
const setNotified = (chatType, item) => {
|
||||||
const notified = Storage.getItem('notified');
|
const notified = Storage.getItem('notified');
|
||||||
|
@ -7,7 +7,6 @@ import { notify } from '/imports/ui/services/notification';
|
|||||||
import VideoService from '/imports/ui/components/video-provider/service';
|
import VideoService from '/imports/ui/components/video-provider/service';
|
||||||
import getFromUserSettings from '/imports/ui/services/users-settings';
|
import getFromUserSettings from '/imports/ui/services/users-settings';
|
||||||
import { withModalMounter } from '/imports/ui/components/modal/service';
|
import { withModalMounter } from '/imports/ui/components/modal/service';
|
||||||
import VideoPreviewContainer from '/imports/ui/components/video-preview/container';
|
|
||||||
import Media from './component';
|
import Media from './component';
|
||||||
import MediaService, { getSwapLayout } from './service';
|
import MediaService, { getSwapLayout } from './service';
|
||||||
import PresentationPodsContainer from '../presentation-pod/container';
|
import PresentationPodsContainer from '../presentation-pod/container';
|
||||||
@ -80,8 +79,9 @@ class MediaContainer extends Component {
|
|||||||
|
|
||||||
const chromeErrorElement = (
|
const chromeErrorElement = (
|
||||||
<div>
|
<div>
|
||||||
{intl.formatMessage(intlMessages.chromeExtensionError)}{' '}
|
{intl.formatMessage(intlMessages.chromeExtensionError)}
|
||||||
<a href={CHROME_EXTENSION_LINK} target="_blank">
|
{' '}
|
||||||
|
<a href={CHROME_EXTENSION_LINK} target="_blank" rel="noopener noreferrer">
|
||||||
{intl.formatMessage(intlMessages.chromeExtensionErrorLink)}
|
{intl.formatMessage(intlMessages.chromeExtensionErrorLink)}
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
@ -99,7 +99,7 @@ class MediaContainer extends Component {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default withModalMounter(withTracker(({ mountModal }) => {
|
export default withModalMounter(withTracker(() => {
|
||||||
const { dataSaving } = Settings;
|
const { dataSaving } = Settings;
|
||||||
const { viewParticipantsWebcams, viewScreenshare } = dataSaving;
|
const { viewParticipantsWebcams, viewScreenshare } = dataSaving;
|
||||||
|
|
||||||
@ -118,7 +118,7 @@ export default withModalMounter(withTracker(({ mountModal }) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const usersVideo = VideoService.getAllUsersVideo();
|
const usersVideo = VideoService.getAllUsersVideo();
|
||||||
if (MediaService.shouldShowOverlay() && usersVideo.length) {
|
if (MediaService.shouldShowOverlay() && usersVideo.length && viewParticipantsWebcams) {
|
||||||
data.floatingOverlay = usersVideo.length < 2;
|
data.floatingOverlay = usersVideo.length < 2;
|
||||||
data.hideOverlay = usersVideo.length === 0;
|
data.hideOverlay = usersVideo.length === 0;
|
||||||
}
|
}
|
||||||
|
@ -1,10 +1,12 @@
|
|||||||
import React, { Component } from 'react';
|
import React, { Component } from 'react';
|
||||||
import Modal from '/imports/ui/components/modal/fullscreen/component';
|
import Modal from '/imports/ui/components/modal/fullscreen/component';
|
||||||
import { Tab, Tabs, TabList, TabPanel } from 'react-tabs';
|
import {
|
||||||
|
Tab, Tabs, TabList, TabPanel,
|
||||||
|
} from 'react-tabs';
|
||||||
import { defineMessages, injectIntl, intlShape } from 'react-intl';
|
import { defineMessages, injectIntl, intlShape } from 'react-intl';
|
||||||
import ClosedCaptions from '/imports/ui/components/settings/submenus/closed-captions/component';
|
import ClosedCaptions from '/imports/ui/components/settings/submenus/closed-captions/component';
|
||||||
import DataSaving from '/imports/ui/components/settings/submenus/data-saving/component';
|
import DataSaving from '/imports/ui/components/settings/submenus/data-saving/component';
|
||||||
import Application from '/imports/ui/components/settings/submenus/application/container';
|
import Application from '/imports/ui/components/settings/submenus/application/component';
|
||||||
import _ from 'lodash';
|
import _ from 'lodash';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
|
|
||||||
@ -61,20 +63,43 @@ const intlMessages = defineMessages({
|
|||||||
|
|
||||||
const propTypes = {
|
const propTypes = {
|
||||||
intl: intlShape.isRequired,
|
intl: intlShape.isRequired,
|
||||||
dataSaving: PropTypes.object.isRequired,
|
dataSaving: PropTypes.shape({
|
||||||
application: PropTypes.object.isRequired,
|
viewParticipantsWebcams: PropTypes.bool,
|
||||||
cc: PropTypes.object.isRequired,
|
viewScreenshare: PropTypes.bool,
|
||||||
participants: PropTypes.object.isRequired,
|
}).isRequired,
|
||||||
|
application: PropTypes.shape({
|
||||||
|
chatAudioAlerts: PropTypes.bool,
|
||||||
|
chatPushAlerts: PropTypes.bool,
|
||||||
|
fallbackLocale: PropTypes.string,
|
||||||
|
fontSize: PropTypes.string,
|
||||||
|
locale: PropTypes.string,
|
||||||
|
}).isRequired,
|
||||||
|
cc: PropTypes.shape({
|
||||||
|
backgroundColor: PropTypes.string,
|
||||||
|
enabled: PropTypes.bool,
|
||||||
|
fontColor: PropTypes.string,
|
||||||
|
fontFamily: PropTypes.string,
|
||||||
|
fontSize: PropTypes.string,
|
||||||
|
takeOwnership: PropTypes.bool,
|
||||||
|
}).isRequired,
|
||||||
|
participants: PropTypes.shape({
|
||||||
|
layout: PropTypes.bool,
|
||||||
|
lockAll: PropTypes.bool,
|
||||||
|
microphone: PropTypes.bool,
|
||||||
|
muteAll: PropTypes.bool,
|
||||||
|
privateChat: PropTypes.bool,
|
||||||
|
publicChat: PropTypes.bool,
|
||||||
|
}).isRequired,
|
||||||
updateSettings: PropTypes.func.isRequired,
|
updateSettings: PropTypes.func.isRequired,
|
||||||
availableLocales: PropTypes.object.isRequired,
|
availableLocales: PropTypes.objectOf(PropTypes.array).isRequired,
|
||||||
mountModal: PropTypes.func.isRequired,
|
mountModal: PropTypes.func.isRequired,
|
||||||
locales: PropTypes.array.isRequired,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class Settings extends Component {
|
class Settings extends Component {
|
||||||
static setHtmlFontSize(size) {
|
static setHtmlFontSize(size) {
|
||||||
document.getElementsByTagName('html')[0].style.fontSize = size;
|
document.getElementsByTagName('html')[0].style.fontSize = size;
|
||||||
}
|
}
|
||||||
|
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
|
|
||||||
@ -104,7 +129,8 @@ class Settings extends Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
componentWillMount() {
|
componentWillMount() {
|
||||||
this.props.availableLocales.then((locales) => {
|
const { availableLocales } = this.props;
|
||||||
|
availableLocales.then((locales) => {
|
||||||
this.setState({ availableLocales: locales });
|
this.setState({ availableLocales: locales });
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -123,12 +149,17 @@ class Settings extends Component {
|
|||||||
|
|
||||||
renderModalContent() {
|
renderModalContent() {
|
||||||
const { intl } = this.props;
|
const { intl } = this.props;
|
||||||
|
const {
|
||||||
|
selectedTab,
|
||||||
|
availableLocales,
|
||||||
|
current,
|
||||||
|
locales,
|
||||||
|
} = this.state;
|
||||||
return (
|
return (
|
||||||
<Tabs
|
<Tabs
|
||||||
className={styles.tabs}
|
className={styles.tabs}
|
||||||
onSelect={this.handleSelectTab}
|
onSelect={this.handleSelectTab}
|
||||||
selectedIndex={this.state.selectedTab}
|
selectedIndex={selectedTab}
|
||||||
role="presentation"
|
role="presentation"
|
||||||
selectedTabPanelClassName={styles.selectedTab}
|
selectedTabPanelClassName={styles.selectedTab}
|
||||||
>
|
>
|
||||||
@ -170,9 +201,9 @@ class Settings extends Component {
|
|||||||
</TabList>
|
</TabList>
|
||||||
<TabPanel className={styles.tabPanel}>
|
<TabPanel className={styles.tabPanel}>
|
||||||
<Application
|
<Application
|
||||||
availableLocales={this.state.availableLocales}
|
availableLocales={availableLocales}
|
||||||
handleUpdateSettings={this.handleUpdateSettings}
|
handleUpdateSettings={this.handleUpdateSettings}
|
||||||
settings={this.state.current.application}
|
settings={current.application}
|
||||||
/>
|
/>
|
||||||
</TabPanel>
|
</TabPanel>
|
||||||
{/* <TabPanel className={styles.tabPanel}> */}
|
{/* <TabPanel className={styles.tabPanel}> */}
|
||||||
@ -183,14 +214,14 @@ class Settings extends Component {
|
|||||||
{/* </TabPanel> */}
|
{/* </TabPanel> */}
|
||||||
<TabPanel className={styles.tabPanel}>
|
<TabPanel className={styles.tabPanel}>
|
||||||
<ClosedCaptions
|
<ClosedCaptions
|
||||||
settings={this.state.current.cc}
|
settings={current.cc}
|
||||||
handleUpdateSettings={this.handleUpdateSettings}
|
handleUpdateSettings={this.handleUpdateSettings}
|
||||||
locales={this.props.locales}
|
locales={locales}
|
||||||
/>
|
/>
|
||||||
</TabPanel>
|
</TabPanel>
|
||||||
<TabPanel className={styles.tabPanel}>
|
<TabPanel className={styles.tabPanel}>
|
||||||
<DataSaving
|
<DataSaving
|
||||||
settings={this.state.current.dataSaving}
|
settings={current.dataSaving}
|
||||||
handleUpdateSettings={this.handleUpdateSettings}
|
handleUpdateSettings={this.handleUpdateSettings}
|
||||||
/>
|
/>
|
||||||
</TabPanel>
|
</TabPanel>
|
||||||
@ -205,18 +236,22 @@ class Settings extends Component {
|
|||||||
</Tabs>
|
</Tabs>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const {
|
const {
|
||||||
intl,
|
intl,
|
||||||
mountModal,
|
mountModal,
|
||||||
} = this.props;
|
} = this.props;
|
||||||
|
const {
|
||||||
|
current,
|
||||||
|
saved,
|
||||||
|
} = this.state;
|
||||||
return (
|
return (
|
||||||
<Modal
|
<Modal
|
||||||
title={intl.formatMessage(intlMessages.SettingsLabel)}
|
title={intl.formatMessage(intlMessages.SettingsLabel)}
|
||||||
confirm={{
|
confirm={{
|
||||||
callback: () => {
|
callback: () => {
|
||||||
this.updateSettings(this.state.current);
|
this.updateSettings(current);
|
||||||
// router.push(location.pathname); // TODO 4767
|
// router.push(location.pathname); // TODO 4767
|
||||||
/* We need to use mountModal(null) here to prevent submenu state updates,
|
/* We need to use mountModal(null) here to prevent submenu state updates,
|
||||||
* from re-opening the modal.
|
* from re-opening the modal.
|
||||||
@ -228,7 +263,7 @@ class Settings extends Component {
|
|||||||
}}
|
}}
|
||||||
dismiss={{
|
dismiss={{
|
||||||
callback: () => {
|
callback: () => {
|
||||||
Settings.setHtmlFontSize(this.state.saved.application.fontSize);
|
Settings.setHtmlFontSize(saved.application.fontSize);
|
||||||
mountModal(null);
|
mountModal(null);
|
||||||
},
|
},
|
||||||
label: intl.formatMessage(intlMessages.CancelLabel),
|
label: intl.formatMessage(intlMessages.CancelLabel),
|
||||||
|
@ -1,13 +1,12 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import Button from '/imports/ui/components/button/component';
|
|
||||||
import cx from 'classnames';
|
import cx from 'classnames';
|
||||||
|
import Button from '/imports/ui/components/button/component';
|
||||||
import Toggle from '/imports/ui/components/switch/component';
|
import Toggle from '/imports/ui/components/switch/component';
|
||||||
import { defineMessages, injectIntl } from 'react-intl';
|
import { defineMessages, injectIntl } from 'react-intl';
|
||||||
import BaseMenu from '../base/component';
|
import BaseMenu from '../base/component';
|
||||||
import { styles } from '../styles';
|
import { styles } from '../styles';
|
||||||
|
|
||||||
const MIN_FONTSIZE = 0;
|
const MIN_FONTSIZE = 0;
|
||||||
const MAX_FONTSIZE = 4;
|
|
||||||
|
|
||||||
const intlMessages = defineMessages({
|
const intlMessages = defineMessages({
|
||||||
applicationSectionTitle: {
|
applicationSectionTitle: {
|
||||||
@ -61,6 +60,10 @@ const intlMessages = defineMessages({
|
|||||||
});
|
});
|
||||||
|
|
||||||
class ApplicationMenu extends BaseMenu {
|
class ApplicationMenu extends BaseMenu {
|
||||||
|
static setHtmlFontSize(size) {
|
||||||
|
document.getElementsByTagName('html')[0].style.fontSize = size;
|
||||||
|
}
|
||||||
|
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
|
|
||||||
@ -69,41 +72,66 @@ class ApplicationMenu extends BaseMenu {
|
|||||||
settings: props.settings,
|
settings: props.settings,
|
||||||
isLargestFontSize: false,
|
isLargestFontSize: false,
|
||||||
isSmallestFontSize: false,
|
isSmallestFontSize: false,
|
||||||
|
fontSizes: [
|
||||||
|
'12px',
|
||||||
|
'14px',
|
||||||
|
'16px',
|
||||||
|
'18px',
|
||||||
|
'20px',
|
||||||
|
],
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
componentDidMount() {
|
||||||
|
this.setInitialFontSize();
|
||||||
|
}
|
||||||
|
|
||||||
|
setInitialFontSize() {
|
||||||
|
const { fontSizes } = this.state;
|
||||||
|
const clientFont = document.getElementsByTagName('html')[0].style.fontSize;
|
||||||
|
const hasFont = fontSizes.includes(clientFont);
|
||||||
|
if (!hasFont) {
|
||||||
|
fontSizes.push(clientFont);
|
||||||
|
fontSizes.sort();
|
||||||
|
}
|
||||||
|
const fontIndex = fontSizes.indexOf(clientFont);
|
||||||
|
this.changeFontSize(clientFont);
|
||||||
|
this.setState({
|
||||||
|
isSmallestFontSize: fontIndex <= MIN_FONTSIZE,
|
||||||
|
isLargestFontSize: fontIndex >= (fontSizes.length - 1),
|
||||||
|
fontSizes,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
handleUpdateFontSize(size) {
|
handleUpdateFontSize(size) {
|
||||||
const obj = this.state;
|
const obj = this.state;
|
||||||
obj.settings.fontSize = size;
|
obj.settings.fontSize = size;
|
||||||
this.handleUpdateSettings(this.state.settingsName, obj.settings);
|
this.handleUpdateSettings(this.state.settingsName, obj.settings);
|
||||||
}
|
}
|
||||||
|
|
||||||
setHtmlFontSize(size) {
|
|
||||||
document.getElementsByTagName('html')[0].style.fontSize = size;
|
|
||||||
}
|
|
||||||
|
|
||||||
changeFontSize(size) {
|
changeFontSize(size) {
|
||||||
const obj = this.state;
|
const obj = this.state;
|
||||||
obj.settings.fontSize = size;
|
obj.settings.fontSize = size;
|
||||||
this.setState(obj, () => {
|
this.setState(obj, () => {
|
||||||
this.setHtmlFontSize(this.state.settings.fontSize);
|
ApplicationMenu.setHtmlFontSize(this.state.settings.fontSize);
|
||||||
this.handleUpdateFontSize(this.state.settings.fontSize);
|
this.handleUpdateFontSize(this.state.settings.fontSize);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
handleIncreaseFontSize() {
|
handleIncreaseFontSize() {
|
||||||
const currentFontSize = this.state.settings.fontSize;
|
const currentFontSize = this.state.settings.fontSize;
|
||||||
const availableFontSizes = this.props.fontSizes;
|
const availableFontSizes = this.state.fontSizes;
|
||||||
const canIncreaseFontSize = availableFontSizes.indexOf(currentFontSize) < MAX_FONTSIZE;
|
const maxFontSize = availableFontSizes.length - 1;
|
||||||
const fs = canIncreaseFontSize ? availableFontSizes.indexOf(currentFontSize) + 1 : MAX_FONTSIZE;
|
const canIncreaseFontSize = availableFontSizes.indexOf(currentFontSize) < maxFontSize;
|
||||||
|
const fs = canIncreaseFontSize ? availableFontSizes.indexOf(currentFontSize) + 1 : maxFontSize;
|
||||||
this.changeFontSize(availableFontSizes[fs]);
|
this.changeFontSize(availableFontSizes[fs]);
|
||||||
if (fs === MAX_FONTSIZE) this.setState({ isLargestFontSize: true });
|
if (fs === maxFontSize) this.setState({ isLargestFontSize: true });
|
||||||
this.setState({ isSmallestFontSize: false });
|
this.setState({ isSmallestFontSize: false });
|
||||||
}
|
}
|
||||||
|
|
||||||
handleDecreaseFontSize() {
|
handleDecreaseFontSize() {
|
||||||
const currentFontSize = this.state.settings.fontSize;
|
const currentFontSize = this.state.settings.fontSize;
|
||||||
const availableFontSizes = this.props.fontSizes;
|
const availableFontSizes = this.state.fontSizes;
|
||||||
const canDecreaseFontSize = availableFontSizes.indexOf(currentFontSize) > MIN_FONTSIZE;
|
const canDecreaseFontSize = availableFontSizes.indexOf(currentFontSize) > MIN_FONTSIZE;
|
||||||
const fs = canDecreaseFontSize ? availableFontSizes.indexOf(currentFontSize) - 1 : MIN_FONTSIZE;
|
const fs = canDecreaseFontSize ? availableFontSizes.indexOf(currentFontSize) - 1 : MIN_FONTSIZE;
|
||||||
this.changeFontSize(availableFontSizes[fs]);
|
this.changeFontSize(availableFontSizes[fs]);
|
||||||
|
@ -1,20 +0,0 @@
|
|||||||
import React from 'react';
|
|
||||||
import { withTracker } from 'meteor/react-meteor-data';
|
|
||||||
import Application from './component';
|
|
||||||
|
|
||||||
|
|
||||||
const ApplicationContainer = ({ children, ...props }) => (
|
|
||||||
<Application {...props}>
|
|
||||||
{children}
|
|
||||||
</Application>
|
|
||||||
);
|
|
||||||
|
|
||||||
export default withTracker(() => ({
|
|
||||||
fontSizes: [
|
|
||||||
'12px',
|
|
||||||
'14px',
|
|
||||||
'16px',
|
|
||||||
'18px',
|
|
||||||
'20px',
|
|
||||||
],
|
|
||||||
}))(ApplicationContainer);
|
|
@ -1,7 +1,7 @@
|
|||||||
public:
|
public:
|
||||||
app:
|
app:
|
||||||
mobileFont: 16
|
mobileFontSize: 16px
|
||||||
desktopFont: 14
|
desktopFontSize: 14px
|
||||||
audioChatNotification: false
|
audioChatNotification: false
|
||||||
autoJoin: true
|
autoJoin: true
|
||||||
showParticipantsOnLogin: true
|
showParticipantsOnLogin: true
|
||||||
@ -20,7 +20,6 @@ public:
|
|||||||
application:
|
application:
|
||||||
chatAudioAlerts: false
|
chatAudioAlerts: false
|
||||||
chatPushAlerts: false
|
chatPushAlerts: false
|
||||||
fontSize: 16px
|
|
||||||
fallbackLocale: en
|
fallbackLocale: en
|
||||||
audio:
|
audio:
|
||||||
inputDeviceId: undefined
|
inputDeviceId: undefined
|
||||||
|
@ -431,7 +431,7 @@
|
|||||||
"app.sfu.noAvailableCodec2203": "Error 2203: Server could not find an appropriate codec",
|
"app.sfu.noAvailableCodec2203": "Error 2203: Server could not find an appropriate codec",
|
||||||
"app.meeting.endNotification.ok.label": "OK",
|
"app.meeting.endNotification.ok.label": "OK",
|
||||||
"app.whiteboard.toolbar.tools": "Tools",
|
"app.whiteboard.toolbar.tools": "Tools",
|
||||||
"app.whiteboard.toolbar.tools.hand": "Hand",
|
"app.whiteboard.toolbar.tools.hand": "Pan",
|
||||||
"app.whiteboard.toolbar.tools.pencil": "Pencil",
|
"app.whiteboard.toolbar.tools.pencil": "Pencil",
|
||||||
"app.whiteboard.toolbar.tools.rectangle": "Rectangle",
|
"app.whiteboard.toolbar.tools.rectangle": "Rectangle",
|
||||||
"app.whiteboard.toolbar.tools.triangle": "Triangle",
|
"app.whiteboard.toolbar.tools.triangle": "Triangle",
|
||||||
@ -456,8 +456,8 @@
|
|||||||
"app.whiteboard.toolbar.color.silver": "Silver",
|
"app.whiteboard.toolbar.color.silver": "Silver",
|
||||||
"app.whiteboard.toolbar.undo": "Undo annotation",
|
"app.whiteboard.toolbar.undo": "Undo annotation",
|
||||||
"app.whiteboard.toolbar.clear": "Clear all annotations",
|
"app.whiteboard.toolbar.clear": "Clear all annotations",
|
||||||
"app.whiteboard.toolbar.multiUserOn": "Turn multi-user mode on",
|
"app.whiteboard.toolbar.multiUserOn": "Turn multi-user whiteboard on",
|
||||||
"app.whiteboard.toolbar.multiUserOff": "Turn multi-user mode off",
|
"app.whiteboard.toolbar.multiUserOff": "Turn multi-user whiteboard off",
|
||||||
"app.whiteboard.toolbar.fontSize": "Font Size List",
|
"app.whiteboard.toolbar.fontSize": "Font Size List",
|
||||||
"app.feedback.title": "You have logged out of the conference",
|
"app.feedback.title": "You have logged out of the conference",
|
||||||
"app.feedback.subtitle": "We'd love to hear about your experience with BigBlueButton (optional)",
|
"app.feedback.subtitle": "We'd love to hear about your experience with BigBlueButton (optional)",
|
||||||
|
Loading…
Reference in New Issue
Block a user