Merge branch 'remove-react-router' of https://github.com/antobinary/bigbluebutton into post-router-style-fix
This commit is contained in:
commit
14066b4280
@ -23,3 +23,4 @@ shell-server@0.3.0
|
||||
http@1.3.0
|
||||
dynamic-import@0.2.0
|
||||
rocketchat:streamer
|
||||
session
|
||||
|
@ -2,18 +2,33 @@
|
||||
import React from 'react';
|
||||
import { Meteor } from 'meteor/meteor';
|
||||
import { render } from 'react-dom';
|
||||
import renderRoutes from '/imports/startup/client/routes';
|
||||
import logger from '/imports/startup/client/logger';
|
||||
import LoadingScreen from '/imports/ui/components/loading-screen/component';
|
||||
import { joinRouteHandler, authenticatedRouteHandler } from '/imports/startup/client/auth';
|
||||
import Base from '/imports/startup/client/base';
|
||||
import { Session } from 'meteor/session';
|
||||
|
||||
Meteor.startup(() => {
|
||||
render(renderRoutes(), document.getElementById('app'));
|
||||
render(<LoadingScreen />, document.getElementById('app'));
|
||||
|
||||
// Logs all uncaught exceptions to the client logger
|
||||
window.addEventListener('error', (e) => {
|
||||
const stack = e.error.stack;
|
||||
const { stack } = e.error;
|
||||
let message = e.error.toString();
|
||||
|
||||
// Checks if stack includes the message, if not add the two together.
|
||||
(stack.includes(message)) ? message = stack : message += `\n${stack}`;
|
||||
logger.error(message);
|
||||
});
|
||||
|
||||
// TODO make this a Promise
|
||||
joinRouteHandler((value, error) => {
|
||||
authenticatedRouteHandler((valueInner, errorInner) => {
|
||||
// set defaults
|
||||
Session.set('isChatOpen', false);
|
||||
Session.set('idChatOpen', '');
|
||||
Session.set('isMeetingEnded', false);
|
||||
render(<Base />, document.getElementById('app'));
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@ -28,7 +28,7 @@ export default class Acl {
|
||||
authToken,
|
||||
validated: true,
|
||||
connectionStatus: 'online',
|
||||
// TODO: We cant check for approved until we move subscription login out of <Base />
|
||||
// TODO: We cant check for approved until we move subscription login out of <Base /> // TODO 4767
|
||||
// approved: true,
|
||||
});
|
||||
|
||||
|
@ -4,17 +4,21 @@ import { setCustomLogoUrl } from '/imports/ui/components/user-list/service';
|
||||
import { log, makeCall } from '/imports/ui/services/api';
|
||||
import deviceInfo from '/imports/utils/deviceInfo';
|
||||
import logger from '/imports/startup/client/logger';
|
||||
import { Session } from 'meteor/session';
|
||||
|
||||
// disconnected and trying to open a new connection
|
||||
const STATUS_CONNECTING = 'connecting';
|
||||
const METADATA_KEY = 'metadata';
|
||||
|
||||
export function joinRouteHandler(nextState, replace, callback) {
|
||||
const { sessionToken } = nextState.location.query;
|
||||
export function joinRouteHandler(callback) {
|
||||
const urlParams = new URLSearchParams(window.location.search);
|
||||
const sessionToken = urlParams.get('sessionToken');
|
||||
console.log('joinRouteHandler_2', sessionToken);
|
||||
|
||||
if (!nextState || !sessionToken) {
|
||||
replace({ pathname: '/error/404' });
|
||||
callback();
|
||||
if (!sessionToken) {
|
||||
Session.set('hasError', true);
|
||||
Session.set('codeError', '404');
|
||||
callback('failed - no sessionToken');
|
||||
}
|
||||
|
||||
// Old credentials stored in memory were being used when joining a new meeting
|
||||
@ -31,67 +35,70 @@ export function joinRouteHandler(nextState, replace, callback) {
|
||||
externUserID, fullname, confname, customdata,
|
||||
} = response;
|
||||
|
||||
console.log({ returncode });
|
||||
if (returncode === 'FAILED') {
|
||||
replace({ pathname: '/error/404' });
|
||||
callback();
|
||||
Session.set('hasError', true);
|
||||
Session.set('codeError', '404');
|
||||
callback('failed unhappily');
|
||||
} else {
|
||||
setCustomLogoUrl(customLogoURL);
|
||||
|
||||
let metakeys = 0;
|
||||
if (metadata) {
|
||||
metakeys = metadata.length
|
||||
? metadata.reduce((acc, meta) => {
|
||||
const key = Object.keys(meta).shift();
|
||||
|
||||
const handledHTML5Parameters = [
|
||||
'html5autoswaplayout', 'html5autosharewebcam', 'html5hidepresentation',
|
||||
];
|
||||
if (handledHTML5Parameters.indexOf(key) === -1) {
|
||||
return acc;
|
||||
}
|
||||
|
||||
/* this reducer transforms array of objects in a single object and
|
||||
forces the metadata a be boolean value */
|
||||
let value = meta[key];
|
||||
try {
|
||||
value = JSON.parse(meta[key]);
|
||||
} catch (e) {
|
||||
log('error', `Caught: ${e.message}`);
|
||||
}
|
||||
return { ...acc, [key]: value };
|
||||
}, {}) : {};
|
||||
}
|
||||
|
||||
if (customdata.length) {
|
||||
makeCall('addUserSettings', meetingID, internalUserID, customdata);
|
||||
}
|
||||
|
||||
SessionStorage.setItem(METADATA_KEY, metakeys);
|
||||
|
||||
Auth.set(
|
||||
meetingID, internalUserID, authToken, logoutUrl,
|
||||
sessionToken, fullname, externUserID, confname,
|
||||
);
|
||||
|
||||
Session.set('isUserListOpen', deviceInfo.type().isPhone);
|
||||
const userInfo = window.navigator;
|
||||
|
||||
// Browser information is sent once on startup
|
||||
// Sent here instead of Meteor.startup, as the
|
||||
// user might not be validated by then, thus user's data
|
||||
// would not be sent with this information
|
||||
const clientInfo = {
|
||||
language: userInfo.language,
|
||||
userAgent: userInfo.userAgent,
|
||||
screenSize: { width: window.screen.width, height: window.screen.height },
|
||||
windowSize: { width: window.innerWidth, height: window.innerHeight },
|
||||
bbbVersion: Meteor.settings.public.app.bbbServerVersion,
|
||||
location: window.location.href,
|
||||
};
|
||||
|
||||
logger.info(clientInfo);
|
||||
|
||||
callback('all is cool'); // TODO 4767
|
||||
}
|
||||
|
||||
setCustomLogoUrl(customLogoURL);
|
||||
|
||||
const metakeys = metadata.length
|
||||
? metadata.reduce((acc, meta) => {
|
||||
const key = Object.keys(meta).shift();
|
||||
|
||||
const handledHTML5Parameters = [
|
||||
'html5autoswaplayout', 'html5autosharewebcam', 'html5hidepresentation',
|
||||
];
|
||||
if (handledHTML5Parameters.indexOf(key) === -1) {
|
||||
return acc;
|
||||
}
|
||||
|
||||
/* this reducer transforms array of objects in a single object and
|
||||
forces the metadata a be boolean value */
|
||||
let value = meta[key];
|
||||
try {
|
||||
value = JSON.parse(meta[key]);
|
||||
} catch (e) {
|
||||
log('error', `Caught: ${e.message}`);
|
||||
}
|
||||
return { ...acc, [key]: value };
|
||||
}, {}) : {};
|
||||
|
||||
if (customdata.length) {
|
||||
makeCall('addUserSettings', meetingID, internalUserID, customdata);
|
||||
}
|
||||
|
||||
SessionStorage.setItem(METADATA_KEY, metakeys);
|
||||
|
||||
Auth.set(
|
||||
meetingID, internalUserID, authToken, logoutUrl,
|
||||
sessionToken, fullname, externUserID, confname,
|
||||
);
|
||||
|
||||
const path = deviceInfo.type().isPhone ? '/' : '/users';
|
||||
const userInfo = window.navigator;
|
||||
|
||||
// Browser information is sent once on startup
|
||||
// Sent here instead of Meteor.startup, as the
|
||||
// user might not be validiated by then, thus user's data
|
||||
// would not be sent with this information
|
||||
const clientInfo = {
|
||||
language: userInfo.language,
|
||||
userAgent: userInfo.userAgent,
|
||||
screenSize: { width: window.screen.width, height: window.screen.height },
|
||||
windowSize: { width: window.innerWidth, height: window.innerHeight },
|
||||
bbbVersion: Meteor.settings.public.app.bbbServerVersion,
|
||||
location: window.location.href,
|
||||
};
|
||||
|
||||
replace({ pathname: path });
|
||||
|
||||
logger.info(clientInfo);
|
||||
|
||||
return callback();
|
||||
});
|
||||
}
|
||||
|
||||
@ -138,7 +145,7 @@ function _addReconnectObservable() {
|
||||
});
|
||||
}
|
||||
|
||||
export function authenticatedRouteHandler(nextState, replace, callback) {
|
||||
export function authenticatedRouteHandler(callback) {
|
||||
if (Auth.loggedIn) {
|
||||
callback();
|
||||
}
|
||||
@ -149,7 +156,8 @@ export function authenticatedRouteHandler(nextState, replace, callback) {
|
||||
.then(callback)
|
||||
.catch((reason) => {
|
||||
log('error', reason);
|
||||
replace({ pathname: `/error/${reason.error}` });
|
||||
Session.set('hasError', true);
|
||||
Session.set('codeError', reason.error);
|
||||
callback();
|
||||
});
|
||||
}
|
||||
|
@ -1,6 +1,5 @@
|
||||
import React, { Component } from 'react';
|
||||
import { withTracker } from 'meteor/react-meteor-data';
|
||||
import { withRouter } from 'react-router';
|
||||
import PropTypes from 'prop-types';
|
||||
import Auth from '/imports/ui/services/auth';
|
||||
import AppContainer from '/imports/ui/components/app/container';
|
||||
@ -14,6 +13,7 @@ import Users from '/imports/api/users';
|
||||
import Annotations from '/imports/api/annotations';
|
||||
import AnnotationsLocal from '/imports/ui/components/whiteboard/service';
|
||||
import GroupChat from '/imports/api/group-chat';
|
||||
import { Session } from 'meteor/session';
|
||||
import IntlStartup from './intl';
|
||||
|
||||
const CHAT_CONFIG = Meteor.settings.public.chat;
|
||||
@ -21,20 +21,16 @@ const PUBLIC_GROUP_CHAT_ID = CHAT_CONFIG.public_group_id;
|
||||
const PUBLIC_CHAT_TYPE = CHAT_CONFIG.type_public;
|
||||
|
||||
const propTypes = {
|
||||
error: PropTypes.object,
|
||||
errorCode: PropTypes.number,
|
||||
subscriptionsReady: PropTypes.bool.isRequired,
|
||||
locale: PropTypes.string,
|
||||
endedCode: PropTypes.string,
|
||||
approved: PropTypes.bool,
|
||||
meetingEnded: PropTypes.bool,
|
||||
};
|
||||
|
||||
const defaultProps = {
|
||||
error: undefined,
|
||||
errorCode: undefined,
|
||||
locale: undefined,
|
||||
endedCode: undefined,
|
||||
approved: undefined,
|
||||
meetingEnded: false,
|
||||
};
|
||||
|
||||
class Base extends Component {
|
||||
@ -43,11 +39,9 @@ class Base extends Component {
|
||||
|
||||
this.state = {
|
||||
loading: false,
|
||||
error: props.error || null,
|
||||
};
|
||||
|
||||
this.updateLoadingState = this.updateLoadingState.bind(this);
|
||||
this.updateErrorState = this.updateErrorState.bind(this);
|
||||
}
|
||||
|
||||
componentWillUpdate() {
|
||||
@ -63,29 +57,23 @@ class Base extends Component {
|
||||
});
|
||||
}
|
||||
|
||||
updateErrorState(error = null) {
|
||||
this.setState({
|
||||
error,
|
||||
});
|
||||
}
|
||||
|
||||
renderByState() {
|
||||
const { updateLoadingState, updateErrorState } = this;
|
||||
const stateControls = { updateLoadingState, updateErrorState };
|
||||
const { updateLoadingState } = this;
|
||||
const stateControls = { updateLoadingState };
|
||||
|
||||
const { loading, error } = this.state;
|
||||
const { loading } = this.state;
|
||||
|
||||
const { subscriptionsReady, errorCode } = this.props;
|
||||
const { endedCode } = this.props.params;
|
||||
const codeError = Session.get('codeError');
|
||||
const { subscriptionsReady, meetingEnded } = this.props;
|
||||
|
||||
if (endedCode) {
|
||||
if (meetingEnded) {
|
||||
AudioManager.exitAudio();
|
||||
return (<MeetingEnded code={endedCode} />);
|
||||
return (<MeetingEnded code={Session.get('codeError')} />);
|
||||
}
|
||||
|
||||
if (error || errorCode) {
|
||||
logger.error(`User could not log in HTML5, hit ${errorCode}`);
|
||||
return (<ErrorScreen code={errorCode}>{error}</ErrorScreen>);
|
||||
if (codeError) {
|
||||
logger.error(`User could not log in HTML5, hit ${codeError}`);
|
||||
return (<ErrorScreen code={codeError} />);
|
||||
}
|
||||
|
||||
if (loading || !subscriptionsReady) {
|
||||
@ -101,9 +89,9 @@ class Base extends Component {
|
||||
}
|
||||
|
||||
render() {
|
||||
const { updateLoadingState, updateErrorState } = this;
|
||||
const { updateLoadingState } = this;
|
||||
const { locale } = this.props;
|
||||
const stateControls = { updateLoadingState, updateErrorState };
|
||||
const stateControls = { updateLoadingState };
|
||||
|
||||
return (
|
||||
<IntlStartup locale={locale} baseControls={stateControls}>
|
||||
@ -122,9 +110,7 @@ const SUBSCRIPTIONS_NAME = [
|
||||
'group-chat', 'presentation-pods', 'users-settings',
|
||||
];
|
||||
|
||||
const BaseContainer = withRouter(withTracker(({ params, router }) => {
|
||||
if (params.errorCode) return params;
|
||||
|
||||
const BaseContainer = withTracker(() => {
|
||||
const { locale } = Settings.application;
|
||||
const { credentials, loggedIn } = Auth;
|
||||
const { meetingId, requesterUserId } = credentials;
|
||||
@ -139,7 +125,8 @@ const BaseContainer = withRouter(withTracker(({ params, router }) => {
|
||||
const subscriptionErrorHandler = {
|
||||
onError: (error) => {
|
||||
logger.error(error);
|
||||
return router.push('/logout');
|
||||
Session.set('isMeetingEnded', true);
|
||||
Session.set('codeError', error.error);
|
||||
},
|
||||
};
|
||||
|
||||
@ -179,11 +166,12 @@ const BaseContainer = withRouter(withTracker(({ params, router }) => {
|
||||
const subscriptionsReady = subscriptionsHandlers.every(handler => handler.ready());
|
||||
return {
|
||||
approved: Users.findOne({ userId: Auth.userID, approved: true, guest: true }),
|
||||
meetingEnded: Session.get('isMeetingEnded'),
|
||||
locale,
|
||||
subscriptionsReady,
|
||||
annotationsHandler,
|
||||
groupChatMessageHandler,
|
||||
};
|
||||
})(Base));
|
||||
})(Base);
|
||||
|
||||
export default BaseContainer;
|
||||
|
@ -1,57 +0,0 @@
|
||||
import React from 'react';
|
||||
import { Router, Route, Redirect, IndexRoute, useRouterHistory } from 'react-router';
|
||||
import { createHistory } from 'history';
|
||||
|
||||
import LoadingScreen from '/imports/ui/components/loading-screen/component';
|
||||
import ChatContainer from '/imports/ui/components/chat/container';
|
||||
import UserListContainer from '/imports/ui/components/user-list/container';
|
||||
import { joinRouteHandler, logoutRouteHandler, authenticatedRouteHandler } from './auth';
|
||||
import Base from './base';
|
||||
|
||||
const browserHistory = useRouterHistory(createHistory)({
|
||||
basename: Meteor.settings.public.app.basename,
|
||||
});
|
||||
|
||||
const disconnect = () => {
|
||||
Meteor.disconnect();
|
||||
};
|
||||
|
||||
const renderRoutes = () => (
|
||||
<Router history={browserHistory} >
|
||||
<Route path="/logout" onEnter={logoutRouteHandler} />
|
||||
<Route
|
||||
path="/join"
|
||||
component={LoadingScreen}
|
||||
onEnter={joinRouteHandler}
|
||||
/>
|
||||
<Route path="/" component={Base} onEnter={authenticatedRouteHandler} >
|
||||
<IndexRoute components={{}} />
|
||||
<Route name="users" path="users" components={{ userList: UserListContainer }} />
|
||||
<Route
|
||||
name="chat"
|
||||
path="users/chat/:chatID"
|
||||
components={{
|
||||
userList: UserListContainer,
|
||||
chat: ChatContainer,
|
||||
}}
|
||||
/>
|
||||
<Redirect from="users/chat" to="/users/chat/public" />
|
||||
</Route>
|
||||
<Route
|
||||
name="meeting-ended"
|
||||
path="/ended/:endedCode"
|
||||
component={Base}
|
||||
onEnter={disconnect}
|
||||
onLeave={logoutRouteHandler}
|
||||
/>
|
||||
<Route
|
||||
name="error"
|
||||
path="/error/:errorCode"
|
||||
component={Base}
|
||||
onEnter={disconnect}
|
||||
/>
|
||||
<Redirect from="*" to="/error/404" />
|
||||
</Router>
|
||||
);
|
||||
|
||||
export default renderRoutes;
|
@ -12,6 +12,8 @@ import NotificationsBarContainer from '../notifications-bar/container';
|
||||
import AudioContainer from '../audio/container';
|
||||
import ChatAlertContainer from '../chat/alert/container';
|
||||
import { styles } from './styles';
|
||||
import UserListContainer from '../user-list/container';
|
||||
import ChatContainer from '../chat/container';
|
||||
|
||||
const MOBILE_MEDIA = 'only screen and (max-width: 40em)';
|
||||
const USERLIST_COMPACT_WIDTH = 50;
|
||||
@ -42,7 +44,7 @@ const propTypes = {
|
||||
media: PropTypes.element,
|
||||
actionsbar: PropTypes.element,
|
||||
closedCaption: PropTypes.element,
|
||||
userList: PropTypes.element,
|
||||
userListIsOpen: PropTypes.bool.isRequired,
|
||||
chat: PropTypes.element,
|
||||
locale: PropTypes.string,
|
||||
intl: intlShape.isRequired,
|
||||
@ -55,7 +57,6 @@ const defaultProps = {
|
||||
media: null,
|
||||
actionsbar: null,
|
||||
closedCaption: null,
|
||||
userList: null,
|
||||
chat: null,
|
||||
locale: 'en',
|
||||
};
|
||||
@ -64,6 +65,8 @@ class App extends Component {
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
console.log('1');
|
||||
|
||||
this.state = {
|
||||
compactUserList: false,
|
||||
enableResize: !window.matchMedia(MOBILE_MEDIA).matches,
|
||||
@ -141,31 +144,33 @@ class App extends Component {
|
||||
}
|
||||
|
||||
renderUserList() {
|
||||
const { intl, chatIsOpen } = this.props;
|
||||
let { userList } = this.props;
|
||||
const {
|
||||
intl, chatIsOpen, userListIsOpen,
|
||||
} = this.props;
|
||||
|
||||
const { compactUserList } = this.state;
|
||||
|
||||
if (!userList) return null;
|
||||
if (!userListIsOpen) return null;
|
||||
|
||||
const userListStyle = {};
|
||||
userListStyle[styles.compact] = compactUserList;
|
||||
userList = React.cloneElement(userList, {
|
||||
compact: compactUserList,
|
||||
});
|
||||
// userList = React.cloneElement(userList, {
|
||||
// compact: compactUserList, // TODO 4767
|
||||
// });
|
||||
|
||||
return (
|
||||
<div
|
||||
className={cx(styles.userList, userListStyle)}
|
||||
aria-label={intl.formatMessage(intlMessages.userListLabel)}
|
||||
aria-hidden={chatIsOpen}
|
||||
aria-hidden={chatIsOpen /* TODO 4767 -- Why is this not `userListIsOpen` */}
|
||||
>
|
||||
{userList}
|
||||
<UserListContainer />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
renderUserListResizable() {
|
||||
const { userList } = this.props;
|
||||
const { userListIsOpen } = this.props;
|
||||
|
||||
// Variables for resizing user-list.
|
||||
const USERLIST_MIN_WIDTH_PX = 100;
|
||||
@ -175,7 +180,7 @@ class App extends Component {
|
||||
// decide whether using pixel or percentage unit as a default width for userList
|
||||
const USERLIST_DEFAULT_WIDTH = (window.innerWidth * (USERLIST_DEFAULT_WIDTH_RELATIVE / 100.0)) < USERLIST_MAX_WIDTH_PX ? `${USERLIST_DEFAULT_WIDTH_RELATIVE}%` : USERLIST_MAX_WIDTH_PX;
|
||||
|
||||
if (!userList) return null;
|
||||
if (!userListIsOpen) return null;
|
||||
|
||||
const resizableEnableOptions = {
|
||||
top: false,
|
||||
@ -209,29 +214,29 @@ class App extends Component {
|
||||
}
|
||||
|
||||
renderChat() {
|
||||
const { chat, intl } = this.props;
|
||||
const { intl, chatIsOpen } = this.props;
|
||||
|
||||
if (!chat) return null;
|
||||
if (!chatIsOpen) return null;
|
||||
|
||||
return (
|
||||
<section
|
||||
className={styles.chat}
|
||||
aria-label={intl.formatMessage(intlMessages.chatLabel)}
|
||||
>
|
||||
{chat}
|
||||
<ChatContainer />
|
||||
</section>
|
||||
);
|
||||
}
|
||||
|
||||
renderChatResizable() {
|
||||
const { chat } = this.props;
|
||||
const { chatIsOpen } = this.props;
|
||||
|
||||
// Variables for resizing chat.
|
||||
const CHAT_MIN_WIDTH = '10%';
|
||||
const CHAT_MAX_WIDTH = '25%';
|
||||
const CHAT_DEFAULT_WIDTH = '15%';
|
||||
|
||||
if (!chat) return null;
|
||||
if (!chatIsOpen) return null;
|
||||
|
||||
const resizableEnableOptions = {
|
||||
top: false,
|
||||
@ -260,7 +265,7 @@ class App extends Component {
|
||||
|
||||
renderMedia() {
|
||||
const {
|
||||
media, intl, chatIsOpen, userlistIsOpen,
|
||||
media, intl, chatIsOpen, userListIsOpen,
|
||||
} = this.props;
|
||||
|
||||
if (!media) return null;
|
||||
@ -269,7 +274,7 @@ class App extends Component {
|
||||
<section
|
||||
className={styles.media}
|
||||
aria-label={intl.formatMessage(intlMessages.mediaLabel)}
|
||||
aria-hidden={userlistIsOpen || chatIsOpen}
|
||||
aria-hidden={userListIsOpen || chatIsOpen}
|
||||
>
|
||||
{media}
|
||||
{this.renderClosedCaption()}
|
||||
@ -279,7 +284,7 @@ class App extends Component {
|
||||
|
||||
renderActionsBar() {
|
||||
const {
|
||||
actionsbar, intl, userlistIsOpen, chatIsOpen,
|
||||
actionsbar, intl, userListIsOpen, chatIsOpen,
|
||||
} = this.props;
|
||||
|
||||
if (!actionsbar) return null;
|
||||
@ -288,7 +293,7 @@ class App extends Component {
|
||||
<section
|
||||
className={styles.actionsbar}
|
||||
aria-label={intl.formatMessage(intlMessages.actionsBarLabel)}
|
||||
aria-hidden={userlistIsOpen || chatIsOpen}
|
||||
aria-hidden={userListIsOpen || chatIsOpen}
|
||||
>
|
||||
{actionsbar}
|
||||
</section>
|
||||
@ -296,7 +301,7 @@ class App extends Component {
|
||||
}
|
||||
|
||||
render() {
|
||||
const { params, userlistIsOpen } = this.props;
|
||||
const { params, userListIsOpen } = this.props;
|
||||
const { enableResize } = this.state;
|
||||
|
||||
return (
|
||||
@ -309,14 +314,14 @@ class App extends Component {
|
||||
{this.renderActionsBar()}
|
||||
</div>
|
||||
{enableResize ? this.renderUserListResizable() : this.renderUserList()}
|
||||
{userlistIsOpen && enableResize ? <div className={styles.userlistPad} /> : null}
|
||||
{userListIsOpen && enableResize ? <div className={styles.userlistPad} /> : null}
|
||||
{enableResize ? this.renderChatResizable() : this.renderChat()}
|
||||
{this.renderSidebar()}
|
||||
</section>
|
||||
<ModalContainer />
|
||||
<AudioContainer />
|
||||
<ToastContainer />
|
||||
<ChatAlertContainer currentChatID={params.chatID} />
|
||||
{/* <ChatAlertContainer currentChatID={params.chatID} /> TODO 4767 */}
|
||||
</main>
|
||||
);
|
||||
}
|
||||
|
@ -1,6 +1,5 @@
|
||||
import React, { cloneElement } from 'react';
|
||||
import React from 'react';
|
||||
import { withTracker } from 'meteor/react-meteor-data';
|
||||
import { withRouter } from 'react-router';
|
||||
import { defineMessages, injectIntl } from 'react-intl';
|
||||
import PropTypes from 'prop-types';
|
||||
import Auth from '/imports/ui/services/auth';
|
||||
@ -28,7 +27,6 @@ const propTypes = {
|
||||
navbar: PropTypes.node,
|
||||
actionsbar: PropTypes.node,
|
||||
media: PropTypes.node,
|
||||
location: PropTypes.shape({}).isRequired,
|
||||
};
|
||||
|
||||
const defaultProps = {
|
||||
@ -45,7 +43,6 @@ const intlMessages = defineMessages({
|
||||
});
|
||||
|
||||
const AppContainer = (props) => {
|
||||
// inject location on the navbar container
|
||||
const {
|
||||
navbar,
|
||||
actionsbar,
|
||||
@ -53,11 +50,9 @@ const AppContainer = (props) => {
|
||||
...otherProps
|
||||
} = props;
|
||||
|
||||
const navbarWithLocation = cloneElement(navbar, { location: props.location });
|
||||
|
||||
return (
|
||||
<App
|
||||
navbar={navbarWithLocation}
|
||||
navbar={navbar}
|
||||
actionsbar={actionsbar}
|
||||
media={media}
|
||||
{...otherProps}
|
||||
@ -66,7 +61,7 @@ const AppContainer = (props) => {
|
||||
};
|
||||
|
||||
|
||||
export default withRouter(injectIntl(withModalMounter(withTracker(({ router, intl, baseControls }) => {
|
||||
export default injectIntl(withModalMounter(withTracker(({ intl, baseControls }) => {
|
||||
const currentUser = Users.findOne({ userId: Auth.userID });
|
||||
const isMeetingBreakout = meetingIsBreakout();
|
||||
|
||||
@ -82,7 +77,8 @@ export default withRouter(injectIntl(withModalMounter(withTracker(({ router, int
|
||||
const hasNewConnection = 'connectionId' in fields && (fields.connectionId !== Meteor.connection._lastSessionId);
|
||||
|
||||
if (fields.ejected || hasNewConnection) {
|
||||
router.push(`/ended/${403}`);
|
||||
Session.set('codeError', '403');
|
||||
Session.set('isMeetingEnded', true);
|
||||
}
|
||||
},
|
||||
});
|
||||
@ -93,7 +89,8 @@ export default withRouter(injectIntl(withModalMounter(withTracker(({ router, int
|
||||
if (isMeetingBreakout) {
|
||||
Auth.clearCredentials().then(window.close);
|
||||
} else {
|
||||
router.push(`/ended/${410}`);
|
||||
Session.set('codeError', '410');
|
||||
Session.set('isMeetingEnded', true);
|
||||
}
|
||||
},
|
||||
});
|
||||
@ -108,10 +105,10 @@ export default withRouter(injectIntl(withModalMounter(withTracker(({ router, int
|
||||
return {
|
||||
closedCaption: getCaptionsStatus() ? <ClosedCaptionsContainer /> : null,
|
||||
fontSize: getFontSize(),
|
||||
userlistIsOpen: window.location.pathname.includes('users'),
|
||||
chatIsOpen: window.location.pathname.includes('chat'),
|
||||
userListIsOpen: Boolean(Session.get('isUserListOpen')),
|
||||
chatIsOpen: Boolean(Session.get('isChatOpen')),
|
||||
};
|
||||
})(AppContainer))));
|
||||
})(AppContainer)));
|
||||
|
||||
AppContainer.defaultProps = defaultProps;
|
||||
AppContainer.propTypes = propTypes;
|
||||
|
@ -2,7 +2,6 @@ import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import _ from 'lodash';
|
||||
import injectNotify from '/imports/ui/components/toast/inject-notify/component';
|
||||
import { Link } from 'react-router';
|
||||
import { styles } from '../../styles.scss';
|
||||
|
||||
const ALERT_INTERVAL = 2000; // 2 seconds
|
||||
@ -15,11 +14,11 @@ const propTypes = {
|
||||
|
||||
class ChatPushAlert extends React.Component {
|
||||
static link(message, chatId) {
|
||||
return (
|
||||
<Link className={styles.link} to={`/users/chat/${chatId}`}>
|
||||
{message}
|
||||
</Link>
|
||||
);
|
||||
// return (
|
||||
// {/*<Link className={styles.link} to={`/users/chat/${chatId}`}>*/}
|
||||
// {/*{message}*/}
|
||||
// {/*</Link> // TODO 4767 */}
|
||||
// );
|
||||
}
|
||||
|
||||
constructor(props) {
|
||||
|
@ -1,9 +1,9 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { Link } from 'react-router';
|
||||
import { defineMessages, injectIntl } from 'react-intl';
|
||||
import injectWbResizeEvent from '/imports/ui/components/presentation/resize-wrapper/component';
|
||||
import Button from '/imports/ui/components/button/component';
|
||||
import { Session } from 'meteor/session';
|
||||
import { styles } from './styles';
|
||||
import MessageForm from './message-form/component';
|
||||
import MessageList from './message-list/component';
|
||||
@ -54,33 +54,33 @@ const Chat = (props) => {
|
||||
data-test="chatTitle"
|
||||
className={styles.title}
|
||||
>
|
||||
<Link
|
||||
to="/users"
|
||||
role="button"
|
||||
<Button
|
||||
onClick={() => {
|
||||
Session.set('isChatOpen', false);
|
||||
alert('A');
|
||||
}}
|
||||
aria-label={intl.formatMessage(intlMessages.hideChatLabel, { 0: title })}
|
||||
accessKey={HIDE_CHAT_AK}
|
||||
>
|
||||
<Icon iconName="left_arrow" /> {title}
|
||||
</Link>
|
||||
label={title}
|
||||
icon="left_arrow"
|
||||
/>
|
||||
</div>
|
||||
{
|
||||
chatID !== 'public' ?
|
||||
<Link
|
||||
to="/users"
|
||||
role="button"
|
||||
tabIndex={-1}
|
||||
>
|
||||
<Button
|
||||
className={styles.closeBtn}
|
||||
icon="close"
|
||||
size="md"
|
||||
hideLabel
|
||||
onClick={() => actions.handleClosePrivateChat(chatID)}
|
||||
aria-label={intl.formatMessage(intlMessages.closeChatLabel, { 0: title })}
|
||||
label={intl.formatMessage(intlMessages.closeChatLabel, { 0: title })}
|
||||
accessKey={CLOSE_CHAT_AK}
|
||||
/>
|
||||
</Link> :
|
||||
<Button
|
||||
className={styles.closeBtn}
|
||||
icon="close"
|
||||
size="md"
|
||||
hideLabel
|
||||
onClick={() => {
|
||||
actions.handleClosePrivateChat(chatID);
|
||||
Session.set('idChatOpen', '');
|
||||
}}
|
||||
aria-label={intl.formatMessage(intlMessages.closeChatLabel, { 0: title })}
|
||||
label={intl.formatMessage(intlMessages.closeChatLabel, { 0: title })}
|
||||
accessKey={CLOSE_CHAT_AK}
|
||||
/>
|
||||
:
|
||||
<ChatDropdown />
|
||||
}
|
||||
</header>
|
||||
|
@ -1,6 +1,7 @@
|
||||
import React, { Component } from 'react';
|
||||
import { defineMessages, injectIntl } from 'react-intl';
|
||||
import { withTracker } from 'meteor/react-meteor-data';
|
||||
import { Session } from 'meteor/session';
|
||||
import Chat from './component';
|
||||
import ChatService from './service';
|
||||
|
||||
@ -30,7 +31,7 @@ const intlMessages = defineMessages({
|
||||
class ChatContainer extends Component {
|
||||
componentDidMount() {
|
||||
// in case of reopening a chat, need to make sure it's removed from closed list
|
||||
ChatService.removeFromClosedChatsSession(this.props.chatID);
|
||||
ChatService.removeFromClosedChatsSession(this.props.chatID); // TODO 4767
|
||||
}
|
||||
render() {
|
||||
return (
|
||||
@ -41,9 +42,8 @@ class ChatContainer extends Component {
|
||||
}
|
||||
}
|
||||
|
||||
export default injectIntl(withTracker(({ params, intl }) => {
|
||||
const chatID = params.chatID || PUBLIC_CHAT_KEY;
|
||||
|
||||
export default injectIntl(withTracker(({ intl }) => {
|
||||
const chatID = Session.get('idChatOpen') || PUBLIC_CHAT_KEY;
|
||||
let messages = [];
|
||||
let isChatLocked = ChatService.isChatLocked(chatID);
|
||||
let title = intl.formatMessage(intlMessages.titlePublic);
|
||||
|
@ -39,7 +39,7 @@ class MessageList extends Component {
|
||||
const { scrollArea } = this;
|
||||
|
||||
this.setState({
|
||||
scrollArea: this.scrollArea
|
||||
scrollArea: this.scrollArea,
|
||||
});
|
||||
|
||||
this.scrollTo(this.props.scrollPosition);
|
||||
@ -60,7 +60,7 @@ class MessageList extends Component {
|
||||
partnerIsLoggedOut,
|
||||
} = this.props;
|
||||
|
||||
if(!this.state.scrollArea && nextState.scrollArea) return true;
|
||||
if (!this.state.scrollArea && nextState.scrollArea) return true;
|
||||
|
||||
const switchingCorrespondent = chatId !== nextProps.chatId;
|
||||
const hasNewUnreadMessages = hasUnreadMessages !== nextProps.hasUnreadMessages;
|
||||
@ -164,14 +164,16 @@ class MessageList extends Component {
|
||||
}
|
||||
|
||||
render() {
|
||||
const { messages, intl } = this.props;
|
||||
const {
|
||||
messages, intl, id, lastReadMessageTime, handleReadMessage,
|
||||
} = this.props;
|
||||
const isEmpty = messages.length === 0;
|
||||
return (
|
||||
<div className={styles.messageListWrapper}>
|
||||
<div
|
||||
role="log"
|
||||
ref={(ref) => { if (ref != null) { this.scrollArea = ref; } }}
|
||||
id={this.props.id}
|
||||
id={id}
|
||||
className={styles.messageList}
|
||||
aria-live="polite"
|
||||
aria-atomic="false"
|
||||
@ -180,14 +182,14 @@ class MessageList extends Component {
|
||||
>
|
||||
{messages.map(message => (
|
||||
<MessageListItem
|
||||
handleReadMessage={this.props.handleReadMessage}
|
||||
handleReadMessage={handleReadMessage}
|
||||
className={styles.messageListItem}
|
||||
key={message.id}
|
||||
messages={message.content}
|
||||
user={message.sender}
|
||||
time={message.time}
|
||||
chatAreaId={this.props.id}
|
||||
lastReadMessageTime={this.props.lastReadMessageTime}
|
||||
chatAreaId={id}
|
||||
lastReadMessageTime={lastReadMessageTime}
|
||||
scrollArea={this.state.scrollArea}
|
||||
/>
|
||||
))}
|
||||
|
@ -11,7 +11,7 @@ const propTypes = {
|
||||
/* We should recheck this proptype, sometimes we need to create an container and send to dropdown,
|
||||
but with this */
|
||||
// proptype, is not possible.
|
||||
children: PropTypes.arrayOf((propValue, key, componentName, location, propFullName) => {
|
||||
children: PropTypes.arrayOf((propValue, key, componentName, location, propFullName) => { // TODO 4767
|
||||
if (propValue[key].type !== ListItem &&
|
||||
propValue[key].type !== ListSeparator &&
|
||||
propValue[key].type !== ListTitle) {
|
||||
|
@ -2,7 +2,6 @@ import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { defineMessages, injectIntl } from 'react-intl';
|
||||
import Button from '/imports/ui/components/button/component';
|
||||
import { withRouter } from 'react-router';
|
||||
import { styles } from './styles';
|
||||
|
||||
const intlMessages = defineMessages({
|
||||
@ -37,7 +36,9 @@ const defaultProps = {
|
||||
class ErrorScreen extends React.PureComponent {
|
||||
render() {
|
||||
const {
|
||||
intl, code, children, router,
|
||||
intl,
|
||||
code,
|
||||
children,
|
||||
} = this.props;
|
||||
|
||||
let formatedMessage = intl.formatMessage(intlMessages[defaultProps.code]);
|
||||
@ -60,7 +61,7 @@ class ErrorScreen extends React.PureComponent {
|
||||
<div className={styles.content}>
|
||||
<Button
|
||||
size="sm"
|
||||
onClick={() => router.push('/logout/')}
|
||||
onClick={() => Session.set('isMeetingEnded', true)}
|
||||
label={intl.formatMessage(intlMessages.leave)}
|
||||
/>
|
||||
</div>
|
||||
@ -69,7 +70,7 @@ class ErrorScreen extends React.PureComponent {
|
||||
}
|
||||
}
|
||||
|
||||
export default withRouter(injectIntl(ErrorScreen));
|
||||
export default injectIntl(ErrorScreen);
|
||||
|
||||
ErrorScreen.propTypes = propTypes;
|
||||
ErrorScreen.defaultProps = defaultProps;
|
||||
|
@ -7,6 +7,7 @@ import { styles } from './styles';
|
||||
|
||||
const propTypes = {
|
||||
handleEndMeeting: PropTypes.func.isRequired,
|
||||
confirmLeaving: PropTypes.func.isRequired,
|
||||
intl: PropTypes.shape({
|
||||
formatMessage: PropTypes.func.isRequired,
|
||||
}).isRequired,
|
||||
@ -55,15 +56,14 @@ const intlMessages = defineMessages({
|
||||
|
||||
const LeaveConfirmation = ({
|
||||
intl,
|
||||
router,
|
||||
handleEndMeeting,
|
||||
showEndMeeting,
|
||||
showFeedback,
|
||||
confirmLeaving,
|
||||
}) => (
|
||||
<Modal
|
||||
title={intl.formatMessage(intlMessages.title)}
|
||||
confirm={{
|
||||
callback: showFeedback,
|
||||
callback: confirmLeaving,
|
||||
label: intl.formatMessage(intlMessages.confirmLabel),
|
||||
description: intl.formatMessage(intlMessages.confirmDesc),
|
||||
}}
|
||||
@ -79,7 +79,7 @@ const LeaveConfirmation = ({
|
||||
className={styles.endMeeting}
|
||||
label={intl.formatMessage(intlMessages.endMeetingLabel)}
|
||||
onClick={handleEndMeeting}
|
||||
aria-describedby={'modalEndMeetingDesc'}
|
||||
aria-describedby="modalEndMeetingDesc"
|
||||
/> : null
|
||||
}
|
||||
<div id="modalEndMeetingDesc" hidden>{intl.formatMessage(intlMessages.endMeetingDesc)}</div>
|
||||
|
@ -1,8 +1,8 @@
|
||||
import React from 'react';
|
||||
import { meetingIsBreakout } from '/imports/ui/components/app/service';
|
||||
import { withTracker } from 'meteor/react-meteor-data';
|
||||
import { withRouter } from 'react-router';
|
||||
import getFromUserSettings from '/imports/ui/services/users-settings';
|
||||
import { Session } from 'meteor/session';
|
||||
|
||||
import LogoutConfirmation from './component';
|
||||
import {
|
||||
isModerator,
|
||||
@ -13,14 +13,15 @@ const LogoutConfirmationContainer = props => (
|
||||
<LogoutConfirmation {...props} />
|
||||
);
|
||||
|
||||
export default withRouter(withTracker(({ router }) => {
|
||||
const APP_CONFIG = Meteor.settings.public.app;
|
||||
const shouldShowFeedback = !meetingIsBreakout() && getFromUserSettings('askForFeedbackOnLogout', APP_CONFIG.askForFeedbackOnLogout);
|
||||
const showFeedback = shouldShowFeedback ? () => router.push('/ended/430') : () => router.push('/logout');
|
||||
export default withTracker(() => {
|
||||
const confirmLeaving = () => {
|
||||
Session.set('isMeetingEnded', true);
|
||||
Session.set('codeError', '430');
|
||||
};
|
||||
|
||||
return {
|
||||
showEndMeeting: !meetingIsBreakout() && isModerator(),
|
||||
handleEndMeeting: endMeeting,
|
||||
showFeedback,
|
||||
confirmLeaving,
|
||||
};
|
||||
})(LogoutConfirmationContainer));
|
||||
})(LogoutConfirmationContainer);
|
||||
|
@ -1,10 +1,10 @@
|
||||
import React from 'react';
|
||||
import { withRouter } from 'react-router';
|
||||
import PropTypes from 'prop-types';
|
||||
import { defineMessages, injectIntl } from 'react-intl';
|
||||
import Auth from '/imports/ui/services/auth';
|
||||
import Button from '/imports/ui/components/button/component';
|
||||
import getFromUserSettings from '/imports/ui/services/users-settings';
|
||||
import { logoutRouteHandler } from '/imports/startup/client/auth';
|
||||
import Rating from './rating/component';
|
||||
import { styles } from './styles';
|
||||
|
||||
@ -64,9 +64,6 @@ const propTypes = {
|
||||
formatMessage: PropTypes.func.isRequired,
|
||||
}).isRequired,
|
||||
code: PropTypes.string.isRequired,
|
||||
router: PropTypes.shape({
|
||||
push: PropTypes.func.isRequired,
|
||||
}).isRequired,
|
||||
};
|
||||
|
||||
class MeetingEnded extends React.PureComponent {
|
||||
@ -96,12 +93,8 @@ class MeetingEnded extends React.PureComponent {
|
||||
selected,
|
||||
} = this.state;
|
||||
|
||||
const {
|
||||
router,
|
||||
} = this.props;
|
||||
|
||||
if (selected <= 0) {
|
||||
router.push('/logout');
|
||||
logoutRouteHandler();
|
||||
return;
|
||||
}
|
||||
|
||||
@ -122,7 +115,9 @@ class MeetingEnded extends React.PureComponent {
|
||||
};
|
||||
|
||||
fetch(url, options)
|
||||
.finally(() => router.push('/logout'));
|
||||
.finally(() => {
|
||||
logoutRouteHandler();
|
||||
});
|
||||
}
|
||||
|
||||
render() {
|
||||
@ -173,4 +168,4 @@ class MeetingEnded extends React.PureComponent {
|
||||
|
||||
MeetingEnded.propTypes = propTypes;
|
||||
|
||||
export default injectIntl(withRouter(MeetingEnded));
|
||||
export default injectIntl(MeetingEnded);
|
||||
|
@ -1,7 +1,7 @@
|
||||
import React from 'react';
|
||||
import { Meteor } from 'meteor/meteor';
|
||||
import { withTracker } from 'meteor/react-meteor-data';
|
||||
import { withRouter } from 'react-router';
|
||||
import { Session } from 'meteor/session';
|
||||
import Meetings from '/imports/api/meetings';
|
||||
import Auth from '/imports/ui/services/auth';
|
||||
import { meetingIsBreakout } from '/imports/ui/components/app/service';
|
||||
@ -20,7 +20,7 @@ const NavBarContainer = ({ children, ...props }) => (
|
||||
</NavBar>
|
||||
);
|
||||
|
||||
export default withRouter(withTracker(({ location, router }) => {
|
||||
export default withTracker(() => {
|
||||
const CLIENT_TITLE = getFromUserSettings('clientTitle', PUBLIC_CONFIG.app.clientTitle);
|
||||
|
||||
let meetingTitle;
|
||||
@ -54,7 +54,7 @@ export default withRouter(withTracker(({ location, router }) => {
|
||||
const breakouts = Service.getBreakouts();
|
||||
const currentUserId = Auth.userID;
|
||||
|
||||
const isExpanded = location.pathname.indexOf('/users') !== -1;
|
||||
const isExpanded = Boolean(Session.get('isUserListOpen'));
|
||||
|
||||
return {
|
||||
isExpanded,
|
||||
@ -66,11 +66,7 @@ export default withRouter(withTracker(({ location, router }) => {
|
||||
isBreakoutRoom: meetingIsBreakout(),
|
||||
beingRecorded: meetingRecorded,
|
||||
toggleUserList: () => {
|
||||
if (location.pathname.indexOf('/users') !== -1) {
|
||||
router.push('/');
|
||||
} else {
|
||||
router.push('/users');
|
||||
}
|
||||
Session.set('isUserListOpen', !isExpanded);
|
||||
},
|
||||
};
|
||||
})(NavBarContainer));
|
||||
})(NavBarContainer);
|
||||
|
@ -208,8 +208,6 @@ class Settings extends Component {
|
||||
render() {
|
||||
const {
|
||||
intl,
|
||||
router,
|
||||
location,
|
||||
mountModal,
|
||||
} = this.props;
|
||||
|
||||
@ -219,7 +217,7 @@ class Settings extends Component {
|
||||
confirm={{
|
||||
callback: () => {
|
||||
this.updateSettings(this.state.current);
|
||||
router.push(location.pathname);
|
||||
// router.push(location.pathname); // TODO 4767
|
||||
/* We need to use mountModal(null) here to prevent submenu state updates,
|
||||
* from re-opening the modal.
|
||||
*/
|
||||
|
@ -1,6 +1,5 @@
|
||||
import React from 'react';
|
||||
import { withTracker } from 'meteor/react-meteor-data';
|
||||
import { withRouter } from 'react-router';
|
||||
import SettingsService from '/imports/ui/services/settings';
|
||||
import Settings from './component';
|
||||
|
||||
@ -15,7 +14,7 @@ const SettingsContainer = props => (
|
||||
<Settings {...props} />
|
||||
);
|
||||
|
||||
export default withRouter(withTracker(() => ({
|
||||
export default withTracker(() => ({
|
||||
audio: SettingsService.audio,
|
||||
dataSaving: SettingsService.dataSaving,
|
||||
application: SettingsService.application,
|
||||
@ -25,4 +24,4 @@ export default withRouter(withTracker(() => ({
|
||||
locales: getClosedCaptionLocales(),
|
||||
availableLocales: getAvailableLocales(),
|
||||
isModerator: getUserRoles() === 'MODERATOR',
|
||||
}))(SettingsContainer));
|
||||
}))(SettingsContainer);
|
||||
|
@ -1,12 +1,12 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { withRouter, Link } from 'react-router';
|
||||
import cx from 'classnames';
|
||||
import { defineMessages, injectIntl } from 'react-intl';
|
||||
import { styles } from './styles';
|
||||
import ChatAvatar from './chat-avatar/component';
|
||||
import ChatIcon from './chat-icon/component';
|
||||
import ChatUnreadCounter from './chat-unread-messages/component';
|
||||
import Button from '../../button/component';
|
||||
|
||||
const intlMessages = defineMessages({
|
||||
titlePublic: {
|
||||
@ -23,10 +23,6 @@ const intlMessages = defineMessages({
|
||||
},
|
||||
});
|
||||
|
||||
const CHAT_CONFIG = Meteor.settings.public.chat;
|
||||
const PRIVATE_CHAT_PATH = CHAT_CONFIG.path_route;
|
||||
const CLOSED_CHAT_PATH = 'users/';
|
||||
|
||||
const SHORTCUTS_CONFIG = Meteor.settings.public.app.shortcuts;
|
||||
const TOGGLE_CHAT_PUB_AK = SHORTCUTS_CONFIG.togglePublicChat.accesskey;
|
||||
|
||||
@ -57,25 +53,28 @@ const ChatListItem = (props) => {
|
||||
intl,
|
||||
tabIndex,
|
||||
isPublicChat,
|
||||
location,
|
||||
} = props;
|
||||
|
||||
let linkPath = [PRIVATE_CHAT_PATH, chat.id].join('');
|
||||
linkPath = location.pathname.includes(linkPath) ? CLOSED_CHAT_PATH : linkPath;
|
||||
const isCurrentChat = chat.id === openChat;
|
||||
const linkClasses = {};
|
||||
linkClasses[styles.active] = isCurrentChat;
|
||||
|
||||
return (
|
||||
<Link
|
||||
data-test="publicChatLink"
|
||||
to={linkPath}
|
||||
<Button
|
||||
className={cx(styles.chatListItem, linkClasses)}
|
||||
role="button"
|
||||
aria-expanded={isCurrentChat}
|
||||
tabIndex={tabIndex}
|
||||
accessKey={isPublicChat(chat) ? TOGGLE_CHAT_PUB_AK : null}
|
||||
color="primary"
|
||||
onClick={() => {
|
||||
Session.set('isChatOpen', true);
|
||||
Session.set('idChatOpen', chat.id);
|
||||
}}
|
||||
id="chat-toggle-button"
|
||||
// label={"~"}
|
||||
label={isPublicChat(chat) ? intl.formatMessage(intlMessages.titlePublic) : chat.name}
|
||||
>
|
||||
|
||||
<div className={styles.chatListItemLink}>
|
||||
<div className={styles.chatIcon}>
|
||||
{chat.icon ?
|
||||
@ -90,7 +89,8 @@ const ChatListItem = (props) => {
|
||||
<div className={styles.chatName}>
|
||||
{!compact ?
|
||||
<span className={styles.chatNameMain}>
|
||||
{isPublicChat(chat) ? intl.formatMessage(intlMessages.titlePublic) : chat.name}
|
||||
{isPublicChat(chat) ?
|
||||
intl.formatMessage(intlMessages.titlePublic) : chat.name}
|
||||
</span> : null}
|
||||
</div>
|
||||
{(chat.unreadCounter > 0) ?
|
||||
@ -99,11 +99,11 @@ const ChatListItem = (props) => {
|
||||
/>
|
||||
: null}
|
||||
</div>
|
||||
</Link>
|
||||
</Button>
|
||||
);
|
||||
};
|
||||
|
||||
ChatListItem.propTypes = propTypes;
|
||||
ChatListItem.defaultProps = defaultProps;
|
||||
|
||||
export default withRouter(injectIntl(ChatListItem));
|
||||
export default injectIntl(ChatListItem);
|
||||
|
@ -1,7 +1,6 @@
|
||||
import React, { Component } from 'react';
|
||||
import { injectIntl } from 'react-intl';
|
||||
import PropTypes from 'prop-types';
|
||||
import { withRouter } from 'react-router';
|
||||
import injectWbResizeEvent from '/imports/ui/components/presentation/resize-wrapper/component';
|
||||
import { styles } from './styles';
|
||||
import CustomLogo from './custom-logo/component';
|
||||
@ -40,10 +39,6 @@ const defaultProps = {
|
||||
};
|
||||
|
||||
class UserList extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
}
|
||||
|
||||
render() {
|
||||
const {
|
||||
intl,
|
||||
@ -113,4 +108,4 @@ class UserList extends Component {
|
||||
UserList.propTypes = propTypes;
|
||||
UserList.defaultProps = defaultProps;
|
||||
|
||||
export default withRouter(injectWbResizeEvent(injectIntl(UserList)));
|
||||
export default injectWbResizeEvent(injectIntl(UserList));
|
||||
|
@ -258,7 +258,7 @@ const getOpenChats = (chatID) => {
|
||||
|
||||
const isVoiceOnlyUser = userId => userId.toString().startsWith('v_');
|
||||
|
||||
const getAvailableActions = (currentUser, user, router, isBreakoutRoom) => {
|
||||
const getAvailableActions = (currentUser, user, isBreakoutRoom) => {
|
||||
const isDialInUser = isVoiceOnlyUser(user.id) || user.isPhoneUser;
|
||||
|
||||
const hasAuthority = currentUser.isModerator || user.isCurrent;
|
||||
|
@ -1,6 +1,5 @@
|
||||
import React, { Component } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { withRouter } from 'react-router';
|
||||
import { injectIntl } from 'react-intl';
|
||||
import UserDropdown from './user-dropdown/component';
|
||||
|
||||
@ -21,7 +20,6 @@ const propTypes = {
|
||||
intl: PropTypes.shape({
|
||||
formatMessage: PropTypes.func.isRequired,
|
||||
}).isRequired,
|
||||
router: PropTypes.shape({}).isRequired,
|
||||
isBreakoutRoom: PropTypes.bool,
|
||||
getAvailableActions: PropTypes.func.isRequired,
|
||||
meeting: PropTypes.shape({}).isRequired,
|
||||
@ -50,7 +48,6 @@ class UserListItem extends Component {
|
||||
changeRole,
|
||||
setEmojiStatus,
|
||||
currentUser,
|
||||
router,
|
||||
isBreakoutRoom,
|
||||
getAvailableActions,
|
||||
handleEmojiChange,
|
||||
@ -73,7 +70,6 @@ class UserListItem extends Component {
|
||||
changeRole,
|
||||
setEmojiStatus,
|
||||
currentUser,
|
||||
router,
|
||||
isBreakoutRoom,
|
||||
getAvailableActions,
|
||||
handleEmojiChange,
|
||||
@ -89,4 +85,4 @@ class UserListItem extends Component {
|
||||
UserListItem.propTypes = propTypes;
|
||||
UserListItem.defaultProps = defaultProps;
|
||||
|
||||
export default withRouter(injectIntl(UserListItem));
|
||||
export default injectIntl(UserListItem);
|
||||
|
@ -14,6 +14,7 @@ import _ from 'lodash';
|
||||
import { styles } from './styles';
|
||||
import UserName from './../user-name/component';
|
||||
import UserIcons from './../user-icons/component';
|
||||
import { Session } from 'meteor/session';
|
||||
|
||||
const messages = defineMessages({
|
||||
presenter: {
|
||||
@ -169,7 +170,6 @@ class UserDropdown extends Component {
|
||||
intl,
|
||||
currentUser,
|
||||
user,
|
||||
router,
|
||||
isBreakoutRoom,
|
||||
getAvailableActions,
|
||||
handleEmojiChange,
|
||||
@ -181,7 +181,7 @@ class UserDropdown extends Component {
|
||||
changeRole,
|
||||
} = this.props;
|
||||
|
||||
const actionPermissions = getAvailableActions(currentUser, user, router, isBreakoutRoom);
|
||||
const actionPermissions = getAvailableActions(currentUser, user, isBreakoutRoom);
|
||||
const actions = [];
|
||||
|
||||
const {
|
||||
@ -233,7 +233,10 @@ class UserDropdown extends Component {
|
||||
actions.push(this.makeDropdownItem(
|
||||
'openChat',
|
||||
intl.formatMessage(messages.ChatLabel),
|
||||
() => this.onActionsHide(router.push(`/users/chat/${user.id}`)),
|
||||
() => {
|
||||
Session.set('idChatOpen', user.id);
|
||||
console.error(`__ idChatOpen: ${Session.get('idChatOpen')}`);
|
||||
},
|
||||
'chat',
|
||||
));
|
||||
}
|
||||
|
@ -50,13 +50,13 @@ export function log(type = 'error', message, ...args) {
|
||||
screenSize: { width: window.screen.width, height: window.screen.height },
|
||||
windowSize: { width: window.innerWidth, height: window.innerHeight },
|
||||
bbbVersion: Meteor.settings.public.app.bbbServerVersion,
|
||||
location: window.location.href,
|
||||
location: window.location.href, // TODO 4767
|
||||
};
|
||||
const logContents = { ...args };
|
||||
const topic = logContents[0] ? logContents[0].topic : null;
|
||||
|
||||
const messageOrStack = message.stack || message.message || JSON.stringify(message);
|
||||
console.debug(`CLIENT LOG (${topic ? type.toUpperCase() + '.' + topic : type.toUpperCase()}): `, messageOrStack, ...args);
|
||||
console.debug(`CLIENT LOG (${topic ? `${type.toUpperCase()}.${topic}` : type.toUpperCase()}): `, messageOrStack, ...args);
|
||||
|
||||
Meteor.call('logClient', type, messageOrStack, {
|
||||
clientInfo,
|
||||
|
29
bigbluebutton-html5/package-lock.json
generated
29
bigbluebutton-html5/package-lock.json
generated
@ -755,16 +755,6 @@
|
||||
"readable-stream": "2.3.6"
|
||||
}
|
||||
},
|
||||
"create-react-class": {
|
||||
"version": "15.6.2",
|
||||
"resolved": "https://registry.npmjs.org/create-react-class/-/create-react-class-15.6.2.tgz",
|
||||
"integrity": "sha1-zx7RXxKq1/FO9fLf4F5sQvke8Co=",
|
||||
"requires": {
|
||||
"fbjs": "0.8.16",
|
||||
"loose-envify": "1.3.1",
|
||||
"object-assign": "4.1.1"
|
||||
}
|
||||
},
|
||||
"cross-spawn": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-3.0.1.tgz",
|
||||
@ -1911,11 +1901,6 @@
|
||||
"warning": "3.0.0"
|
||||
}
|
||||
},
|
||||
"hoist-non-react-statics": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-1.2.0.tgz",
|
||||
"integrity": "sha1-qkSM8JhtVcxAdzsXF0t90GbLfPs="
|
||||
},
|
||||
"hosted-git-info": {
|
||||
"version": "2.7.1",
|
||||
"resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.7.1.tgz",
|
||||
@ -4646,20 +4631,6 @@
|
||||
"react-dom": "16.0.1"
|
||||
}
|
||||
},
|
||||
"react-router": {
|
||||
"version": "3.0.5",
|
||||
"resolved": "https://registry.npmjs.org/react-router/-/react-router-3.0.5.tgz",
|
||||
"integrity": "sha1-w7eHN1gEWou8lWKu9P9LyMznwTY=",
|
||||
"requires": {
|
||||
"create-react-class": "15.6.2",
|
||||
"history": "3.3.0",
|
||||
"hoist-non-react-statics": "1.2.0",
|
||||
"invariant": "2.2.2",
|
||||
"loose-envify": "1.3.1",
|
||||
"prop-types": "15.6.2",
|
||||
"warning": "3.0.0"
|
||||
}
|
||||
},
|
||||
"react-tabs": {
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmjs.org/react-tabs/-/react-tabs-2.1.1.tgz",
|
||||
|
@ -58,7 +58,6 @@
|
||||
"react-intl": "~2.4.0",
|
||||
"react-modal": "~3.0.4",
|
||||
"react-render-in-browser": "^1.0.0",
|
||||
"react-router": "~3.0.2",
|
||||
"react-tabs": "~2.1.0",
|
||||
"react-toastify": "~2.1.2",
|
||||
"react-toggle": "~4.0.2",
|
||||
|
402
bigbluebutton-html5/private/config/settings-development.json
Executable file
402
bigbluebutton-html5/private/config/settings-development.json
Executable file
@ -0,0 +1,402 @@
|
||||
{
|
||||
"public": {
|
||||
|
||||
"app": {
|
||||
"mobileFont": 16,
|
||||
"desktopFont": 14,
|
||||
"audioChatNotification": false,
|
||||
"autoJoin": true,
|
||||
"listenOnlyMode": true,
|
||||
"forceListenOnly": false,
|
||||
"skipCheck": false,
|
||||
"clientTitle": "BigBlueButton",
|
||||
"appName": "BigBlueButton HTML5 Client",
|
||||
"bbbServerVersion": "2.0-rc",
|
||||
"copyright": "©2018 BigBlueButton Inc.",
|
||||
"html5ClientBuild": "HTML5_CLIENT_VERSION",
|
||||
"lockOnJoin": true,
|
||||
"basename": "/html5client",
|
||||
"askForFeedbackOnLogout": false,
|
||||
"defaultSettings": {
|
||||
"application": {
|
||||
"chatAudioAlerts": false,
|
||||
"chatPushAlerts": false,
|
||||
"fontSize": "16px",
|
||||
"fallbackLocale": "en"
|
||||
},
|
||||
"audio": {
|
||||
"inputDeviceId": "undefined",
|
||||
"outputDeviceId": "undefined"
|
||||
},
|
||||
"dataSaving": {
|
||||
"viewParticipantsWebcams": true,
|
||||
"viewScreenshare": true
|
||||
},
|
||||
"cc": {
|
||||
"backgroundColor": "#FFFFFF",
|
||||
"fontColor": "#000000",
|
||||
"enabled": false,
|
||||
"fontFamily": "Calibri",
|
||||
"fontSize": "16px",
|
||||
"takeOwnership": false
|
||||
},
|
||||
"participants": {
|
||||
"muteAll": false,
|
||||
"lockAll": false,
|
||||
"microphone": false,
|
||||
"publicChat": false,
|
||||
"privateChat": false,
|
||||
"layout": false
|
||||
}
|
||||
},
|
||||
"shortcuts": {
|
||||
"openOptions": {"accesskey": "O", "descId": "openOptions"},
|
||||
"toggleUserList": {"accesskey": "U", "descId": "toggleUserList"},
|
||||
"toggleMute": {"accesskey": "M", "descId": "toggleMute"},
|
||||
"joinAudio": {"accesskey": "J", "descId": "joinAudio"},
|
||||
"leaveAudio": {"accesskey": "L", "descId": "leaveAudio"},
|
||||
"togglePublicChat": {"accesskey": "P", "descId": "togglePublicChat"},
|
||||
"hidePrivateChat": {"accesskey": "H", "descId": "hidePrivateChat"},
|
||||
"closePrivateChat": {"accesskey": "G", "descId": "closePrivateChat"},
|
||||
"openActions": {"accesskey": "A", "descId": "openActions"},
|
||||
"openStatus": {"accesskey": "S", "descId": "openStatus"}
|
||||
},
|
||||
"branding": {
|
||||
"displayBrandingArea": false
|
||||
},
|
||||
"allowHTML5Moderator": true,
|
||||
"allowModeratorToUnmuteAudio": true,
|
||||
"httpsConnection": false,
|
||||
"connectionTimeout": 60000,
|
||||
"showHelpButton": true
|
||||
},
|
||||
|
||||
"kurento": {
|
||||
"wsUrl": "HOST",
|
||||
"chromeDefaultExtensionKey": "akgoaoikmbmhcopjgakkcepdgdgkjfbc",
|
||||
"chromeDefaultExtensionLink": "https://chrome.google.com/webstore/detail/bigbluebutton-screenshare/akgoaoikmbmhcopjgakkcepdgdgkjfbc",
|
||||
"chromeExtensionKey": "KEY",
|
||||
"chromeExtensionLink": "LINK",
|
||||
"chromeScreenshareSources": ["window", "screen"],
|
||||
"firefoxScreenshareSource": "window",
|
||||
"cameraConstraints": {
|
||||
"width": {
|
||||
"max": 640
|
||||
},
|
||||
"height": {
|
||||
"max": 480
|
||||
}
|
||||
},
|
||||
"enableScreensharing": false,
|
||||
"enableVideo": false,
|
||||
"enableVideoStats": false,
|
||||
"enableListenOnly": false
|
||||
},
|
||||
|
||||
"acl": {
|
||||
"viewer": {
|
||||
"subscriptions": [
|
||||
"users",
|
||||
"cursor",
|
||||
"screenshare",
|
||||
"meetings",
|
||||
"polls",
|
||||
"chat",
|
||||
"presentations",
|
||||
"annotations",
|
||||
"slides",
|
||||
"captions",
|
||||
"breakouts",
|
||||
"voiceUsers",
|
||||
"whiteboard-multi-user",
|
||||
"presentation-pods",
|
||||
"group-chat",
|
||||
"group-chat-msg",
|
||||
"users-settings"
|
||||
],
|
||||
"methods": [
|
||||
"listenOnlyToggle",
|
||||
"userLogout",
|
||||
"setEmojiStatus",
|
||||
"toggleSelfVoice",
|
||||
"publishVote",
|
||||
"sendChat",
|
||||
"createGroupChat",
|
||||
"destroyGroupChat",
|
||||
"sendGroupChatMsg"
|
||||
]
|
||||
},
|
||||
"moderator": {
|
||||
"methods": [
|
||||
"assignPresenter",
|
||||
"removeUser",
|
||||
"muteUser",
|
||||
"unmuteUser",
|
||||
"endMeeting",
|
||||
"toggleVoice",
|
||||
"clearPublicChatHistory",
|
||||
"changeRole",
|
||||
"ejectUserFromVoice",
|
||||
"toggleRecording"
|
||||
]
|
||||
},
|
||||
"presenter": {
|
||||
"methods": [
|
||||
"assignPresenter",
|
||||
"switchSlide",
|
||||
"modifyWhiteboardAccess",
|
||||
"undoAnnotation",
|
||||
"clearWhiteboard",
|
||||
"moveCursor",
|
||||
"sendAnnotation",
|
||||
"removePresentation",
|
||||
"setPresentation",
|
||||
"zoomSlide",
|
||||
"requestPresentationUploadToken"
|
||||
]
|
||||
}
|
||||
},
|
||||
|
||||
"chat": {
|
||||
"min_message_length": 1,
|
||||
"max_message_length": 5000,
|
||||
"grouping_messages_window": 10000,
|
||||
"type_system": "SYSTEM_MESSAGE",
|
||||
"type_public": "PUBLIC_ACCESS",
|
||||
"type_private": "PRIVATE_ACCESS",
|
||||
"system_userid": "SYSTEM_MESSAGE",
|
||||
"system_username": "SYSTEM_MESSAGE",
|
||||
"public_id": "public",
|
||||
"public_group_id": "MAIN-PUBLIC-GROUP-CHAT",
|
||||
"public_userid": "public_chat_userid",
|
||||
"public_username": "public_chat_username",
|
||||
"storage_key": "UNREAD_CHATS",
|
||||
"system_messages_keys": {
|
||||
"chat_clear": "PUBLIC_CHAT_CLEAR"
|
||||
}
|
||||
},
|
||||
|
||||
"media": {
|
||||
"WebRTCHangupRetryInterval": 2000,
|
||||
"vertoServerAddress": "HOST",
|
||||
"freeswitchProfilePassword": "1234",
|
||||
"vertoPort": "8082",
|
||||
"useSIPAudio": true,
|
||||
"stunTurnServersFetchAddress": "/bigbluebutton/api/stuns",
|
||||
"mediaTag": "#remote-media",
|
||||
"callTransferTimeout": 5000,
|
||||
"callHangupTimeout": 2000,
|
||||
"callHangupMaximumRetries": 10,
|
||||
"echoTestNumber": "9196"
|
||||
},
|
||||
|
||||
"presentation": {
|
||||
"defaultPresentationFile": "default.pdf",
|
||||
"uploadEndpoint": "/bigbluebutton/presentation/upload",
|
||||
"uploadSizeMin": 0,
|
||||
"uploadSizeMax": 50000000,
|
||||
"uploadValidMimeTypes": [
|
||||
"application/vnd.ms-excel",
|
||||
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
|
||||
"application/msword",
|
||||
"application/vnd.openxmlformats-officedocument.wordprocessingml.document",
|
||||
"application/vnd.ms-powerpoint",
|
||||
"application/vnd.openxmlformats-officedocument.presentationml.presentation",
|
||||
"application/vnd.oasis.opendocument.text",
|
||||
"application/rtf",
|
||||
"text/plain",
|
||||
"application/vnd.oasis.opendocument.spreadsheet",
|
||||
"application/vnd.oasis.opendocument.presentation",
|
||||
"application/vnd.oasis.opendocument.text",
|
||||
"application/vnd.oasis.opendocument.graphics",
|
||||
"application/vnd.oasis.opendocument.chart",
|
||||
"application/vnd.oasis.opendocument.image",
|
||||
"application/pdf",
|
||||
"image/jpeg",
|
||||
"image/png"
|
||||
]
|
||||
},
|
||||
|
||||
"user": {
|
||||
"role_moderator": "MODERATOR",
|
||||
"role_viewer": "VIEWER",
|
||||
"role_presenter": "PRESENTER"
|
||||
},
|
||||
|
||||
"whiteboard": {
|
||||
"annotations": {
|
||||
"status": {
|
||||
"start": "DRAW_START",
|
||||
"update": "DRAW_UPDATE",
|
||||
"end": "DRAW_END"
|
||||
}
|
||||
},
|
||||
"toolbar": {
|
||||
"colors": [
|
||||
{
|
||||
"label": "black",
|
||||
"value": "#000000"
|
||||
},
|
||||
{
|
||||
"label": "white",
|
||||
"value": "#ffffff"
|
||||
},
|
||||
{
|
||||
"label": "red",
|
||||
"value": "#ff0000"
|
||||
},
|
||||
{
|
||||
"label": "orange",
|
||||
"value": "#ff8800"
|
||||
},
|
||||
{
|
||||
"label": "eletricLime",
|
||||
"value": "#ccff00"
|
||||
},
|
||||
{
|
||||
"label": "Lime",
|
||||
"value": "#00ff00"
|
||||
},
|
||||
{
|
||||
"label": "Cyan",
|
||||
"value": "#00ffff"
|
||||
},
|
||||
{
|
||||
"label": "dodgerBlue",
|
||||
"value": "#0088ff"
|
||||
},
|
||||
{
|
||||
"label": "blue",
|
||||
"value": "#0000ff"
|
||||
},
|
||||
{
|
||||
"label": "violet",
|
||||
"value": "#8800ff"
|
||||
},
|
||||
{
|
||||
"label": "magenta",
|
||||
"value": "#ff00ff"
|
||||
},
|
||||
{
|
||||
"label": "silver",
|
||||
"value": "#c0c0c0"
|
||||
}
|
||||
],
|
||||
"thickness": [
|
||||
{
|
||||
"value": 14
|
||||
},
|
||||
{
|
||||
"value": 12
|
||||
},
|
||||
{
|
||||
"value": 10
|
||||
},
|
||||
{
|
||||
"value": 8
|
||||
},
|
||||
{
|
||||
"value": 6
|
||||
},
|
||||
{
|
||||
"value": 4
|
||||
},
|
||||
{
|
||||
"value": 2
|
||||
},
|
||||
{
|
||||
"value": 1
|
||||
}
|
||||
],
|
||||
"font_sizes": [
|
||||
{
|
||||
"value": 36
|
||||
},
|
||||
{
|
||||
"value": 32
|
||||
},
|
||||
{
|
||||
"value": 28
|
||||
},
|
||||
{
|
||||
"value": 24
|
||||
},
|
||||
{
|
||||
"value": 20
|
||||
},
|
||||
{
|
||||
"value": 16
|
||||
}
|
||||
],
|
||||
"tools": [
|
||||
{
|
||||
"icon": "text_tool",
|
||||
"value": "text"
|
||||
},
|
||||
{
|
||||
"icon": "line_tool",
|
||||
"value": "line"
|
||||
},
|
||||
{
|
||||
"icon": "circle_tool",
|
||||
"value": "ellipse"
|
||||
},
|
||||
{
|
||||
"icon": "triangle_tool",
|
||||
"value": "triangle"
|
||||
},
|
||||
{
|
||||
"icon": "rectangle_tool",
|
||||
"value": "rectangle"
|
||||
},
|
||||
{
|
||||
"icon": "pen_tool",
|
||||
"value": "pencil"
|
||||
},
|
||||
{
|
||||
"icon": "hand",
|
||||
"value": "hand"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"clientLog": {
|
||||
"server": { "enabled": true, "level": "info" },
|
||||
"console": { "enabled": true, "level": "debug" },
|
||||
"external": { "enabled": true, "level": "info", "url": "https://LOG_HOST/html5Log", "method": "POST" }
|
||||
}
|
||||
},
|
||||
|
||||
"private": {
|
||||
|
||||
"app": {
|
||||
"captionsChunkLength": 1000,
|
||||
"pencilChunkLength": 100
|
||||
},
|
||||
|
||||
"redis": {
|
||||
"host": "127.0.0.1",
|
||||
"post": "6379",
|
||||
"timeout": 5000,
|
||||
"debug": true,
|
||||
"channels": {
|
||||
"toAkkaApps": "to-akka-apps-redis-channel"
|
||||
},
|
||||
"subscribeTo": [
|
||||
"to-html5-redis-channel",
|
||||
"from-akka-apps-*"
|
||||
],
|
||||
"async": [
|
||||
"from-akka-apps-wb-redis-channel"
|
||||
],
|
||||
"ignored": [
|
||||
"CheckAlivePongSysMsg",
|
||||
"DoLatencyTracerMsg"
|
||||
]
|
||||
},
|
||||
|
||||
"serverLog": {
|
||||
"level": "info"
|
||||
}
|
||||
}
|
||||
}
|
402
bigbluebutton-html5/private/config/settings-production.json
Executable file
402
bigbluebutton-html5/private/config/settings-production.json
Executable file
@ -0,0 +1,402 @@
|
||||
{
|
||||
"public": {
|
||||
|
||||
"app": {
|
||||
"mobileFont": 16,
|
||||
"desktopFont": 14,
|
||||
"audioChatNotification": false,
|
||||
"autoJoin": true,
|
||||
"listenOnlyMode": true,
|
||||
"forceListenOnly": false,
|
||||
"skipCheck": false,
|
||||
"clientTitle": "BigBlueButton",
|
||||
"appName": "BigBlueButton HTML5 Client",
|
||||
"bbbServerVersion": "2.0-rc",
|
||||
"copyright": "©2018 BigBlueButton Inc.",
|
||||
"html5ClientBuild": "HTML5_CLIENT_VERSION",
|
||||
"lockOnJoin": true,
|
||||
"basename": "/html5client",
|
||||
"askForFeedbackOnLogout": false,
|
||||
"defaultSettings": {
|
||||
"application": {
|
||||
"chatAudioAlerts": false,
|
||||
"chatPushAlerts": false,
|
||||
"fontSize": "16px",
|
||||
"fallbackLocale": "en"
|
||||
},
|
||||
"audio": {
|
||||
"inputDeviceId": "undefined",
|
||||
"outputDeviceId": "undefined"
|
||||
},
|
||||
"dataSaving": {
|
||||
"viewParticipantsWebcams": true,
|
||||
"viewScreenshare": true
|
||||
},
|
||||
"cc": {
|
||||
"backgroundColor": "#FFFFFF",
|
||||
"fontColor": "#000000",
|
||||
"enabled": false,
|
||||
"fontFamily": "Calibri",
|
||||
"fontSize": "16px",
|
||||
"takeOwnership": false
|
||||
},
|
||||
"participants": {
|
||||
"muteAll": false,
|
||||
"lockAll": false,
|
||||
"microphone": false,
|
||||
"publicChat": false,
|
||||
"privateChat": false,
|
||||
"layout": false
|
||||
}
|
||||
},
|
||||
"shortcuts": {
|
||||
"openOptions": {"accesskey": "O", "descId": "openOptions"},
|
||||
"toggleUserList": {"accesskey": "U", "descId": "toggleUserList"},
|
||||
"toggleMute": {"accesskey": "M", "descId": "toggleMute"},
|
||||
"joinAudio": {"accesskey": "J", "descId": "joinAudio"},
|
||||
"leaveAudio": {"accesskey": "L", "descId": "leaveAudio"},
|
||||
"togglePublicChat": {"accesskey": "P", "descId": "togglePublicChat"},
|
||||
"hidePrivateChat": {"accesskey": "H", "descId": "hidePrivateChat"},
|
||||
"closePrivateChat": {"accesskey": "G", "descId": "closePrivateChat"},
|
||||
"openActions": {"accesskey": "A", "descId": "openActions"},
|
||||
"openStatus": {"accesskey": "S", "descId": "openStatus"}
|
||||
},
|
||||
"branding": {
|
||||
"displayBrandingArea": false
|
||||
},
|
||||
"allowHTML5Moderator": true,
|
||||
"allowModeratorToUnmuteAudio": true,
|
||||
"httpsConnection": true,
|
||||
"connectionTimeout": 10000,
|
||||
"showHelpButton": true
|
||||
},
|
||||
|
||||
"kurento": {
|
||||
"wsUrl": "HOST",
|
||||
"chromeDefaultExtensionKey": "akgoaoikmbmhcopjgakkcepdgdgkjfbc",
|
||||
"chromeDefaultExtensionLink": "https://chrome.google.com/webstore/detail/bigbluebutton-screenshare/akgoaoikmbmhcopjgakkcepdgdgkjfbc",
|
||||
"chromeExtensionKey": "KEY",
|
||||
"chromeExtensionLink": "LINK",
|
||||
"chromeScreenshareSources": ["window", "screen"],
|
||||
"firefoxScreenshareSource": "window",
|
||||
"cameraConstraints": {
|
||||
"width": {
|
||||
"max": 640
|
||||
},
|
||||
"height": {
|
||||
"max": 480
|
||||
}
|
||||
},
|
||||
"enableScreensharing": false,
|
||||
"enableVideo": false,
|
||||
"enableVideoStats": false,
|
||||
"enableListenOnly": false
|
||||
},
|
||||
|
||||
"acl": {
|
||||
"viewer": {
|
||||
"subscriptions": [
|
||||
"users",
|
||||
"cursor",
|
||||
"screenshare",
|
||||
"meetings",
|
||||
"polls",
|
||||
"chat",
|
||||
"presentations",
|
||||
"annotations",
|
||||
"slides",
|
||||
"captions",
|
||||
"breakouts",
|
||||
"voiceUsers",
|
||||
"whiteboard-multi-user",
|
||||
"presentation-pods",
|
||||
"group-chat",
|
||||
"group-chat-msg",
|
||||
"users-settings"
|
||||
],
|
||||
"methods": [
|
||||
"listenOnlyToggle",
|
||||
"userLogout",
|
||||
"setEmojiStatus",
|
||||
"toggleSelfVoice",
|
||||
"publishVote",
|
||||
"sendChat",
|
||||
"createGroupChat",
|
||||
"destroyGroupChat",
|
||||
"sendGroupChatMsg"
|
||||
]
|
||||
},
|
||||
"moderator": {
|
||||
"methods": [
|
||||
"assignPresenter",
|
||||
"removeUser",
|
||||
"muteUser",
|
||||
"unmuteUser",
|
||||
"endMeeting",
|
||||
"toggleVoice",
|
||||
"clearPublicChatHistory",
|
||||
"changeRole",
|
||||
"ejectUserFromVoice",
|
||||
"toggleRecording"
|
||||
]
|
||||
},
|
||||
"presenter": {
|
||||
"methods": [
|
||||
"assignPresenter",
|
||||
"switchSlide",
|
||||
"modifyWhiteboardAccess",
|
||||
"undoAnnotation",
|
||||
"clearWhiteboard",
|
||||
"moveCursor",
|
||||
"sendAnnotation",
|
||||
"removePresentation",
|
||||
"setPresentation",
|
||||
"zoomSlide",
|
||||
"requestPresentationUploadToken"
|
||||
]
|
||||
}
|
||||
},
|
||||
|
||||
"chat": {
|
||||
"min_message_length": 1,
|
||||
"max_message_length": 5000,
|
||||
"grouping_messages_window": 10000,
|
||||
"type_system": "SYSTEM_MESSAGE",
|
||||
"type_public": "PUBLIC_ACCESS",
|
||||
"type_private": "PRIVATE_ACCESS",
|
||||
"system_userid": "SYSTEM_MESSAGE",
|
||||
"system_username": "SYSTEM_MESSAGE",
|
||||
"public_id": "public",
|
||||
"public_group_id": "MAIN-PUBLIC-GROUP-CHAT",
|
||||
"public_userid": "public_chat_userid",
|
||||
"public_username": "public_chat_username",
|
||||
"storage_key": "UNREAD_CHATS",
|
||||
"system_messages_keys": {
|
||||
"chat_clear": "PUBLIC_CHAT_CLEAR"
|
||||
}
|
||||
},
|
||||
|
||||
"media": {
|
||||
"WebRTCHangupRetryInterval": 2000,
|
||||
"vertoServerAddress": "HOST",
|
||||
"freeswitchProfilePassword": "1234",
|
||||
"vertoPort": "8082",
|
||||
"useSIPAudio": true,
|
||||
"stunTurnServersFetchAddress": "/bigbluebutton/api/stuns",
|
||||
"mediaTag": "#remote-media",
|
||||
"callTransferTimeout": 5000,
|
||||
"callHangupTimeout": 2000,
|
||||
"callHangupMaximumRetries": 10,
|
||||
"echoTestNumber": "9196"
|
||||
},
|
||||
|
||||
"presentation": {
|
||||
"defaultPresentationFile": "default.pdf",
|
||||
"uploadEndpoint": "/bigbluebutton/presentation/upload",
|
||||
"uploadSizeMin": 0,
|
||||
"uploadSizeMax": 50000000,
|
||||
"uploadValidMimeTypes": [
|
||||
"application/vnd.ms-excel",
|
||||
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
|
||||
"application/msword",
|
||||
"application/vnd.openxmlformats-officedocument.wordprocessingml.document",
|
||||
"application/vnd.ms-powerpoint",
|
||||
"application/vnd.openxmlformats-officedocument.presentationml.presentation",
|
||||
"application/vnd.oasis.opendocument.text",
|
||||
"application/rtf",
|
||||
"text/plain",
|
||||
"application/vnd.oasis.opendocument.spreadsheet",
|
||||
"application/vnd.oasis.opendocument.presentation",
|
||||
"application/vnd.oasis.opendocument.text",
|
||||
"application/vnd.oasis.opendocument.graphics",
|
||||
"application/vnd.oasis.opendocument.chart",
|
||||
"application/vnd.oasis.opendocument.image",
|
||||
"application/pdf",
|
||||
"image/jpeg",
|
||||
"image/png"
|
||||
]
|
||||
},
|
||||
|
||||
"user": {
|
||||
"role_moderator": "MODERATOR",
|
||||
"role_viewer": "VIEWER",
|
||||
"role_presenter": "PRESENTER"
|
||||
},
|
||||
|
||||
"whiteboard": {
|
||||
"annotations": {
|
||||
"status": {
|
||||
"start": "DRAW_START",
|
||||
"update": "DRAW_UPDATE",
|
||||
"end": "DRAW_END"
|
||||
}
|
||||
},
|
||||
"toolbar": {
|
||||
"colors": [
|
||||
{
|
||||
"label": "black",
|
||||
"value": "#000000"
|
||||
},
|
||||
{
|
||||
"label": "white",
|
||||
"value": "#ffffff"
|
||||
},
|
||||
{
|
||||
"label": "red",
|
||||
"value": "#ff0000"
|
||||
},
|
||||
{
|
||||
"label": "orange",
|
||||
"value": "#ff8800"
|
||||
},
|
||||
{
|
||||
"label": "eletricLime",
|
||||
"value": "#ccff00"
|
||||
},
|
||||
{
|
||||
"label": "Lime",
|
||||
"value": "#00ff00"
|
||||
},
|
||||
{
|
||||
"label": "Cyan",
|
||||
"value": "#00ffff"
|
||||
},
|
||||
{
|
||||
"label": "dodgerBlue",
|
||||
"value": "#0088ff"
|
||||
},
|
||||
{
|
||||
"label": "blue",
|
||||
"value": "#0000ff"
|
||||
},
|
||||
{
|
||||
"label": "violet",
|
||||
"value": "#8800ff"
|
||||
},
|
||||
{
|
||||
"label": "magenta",
|
||||
"value": "#ff00ff"
|
||||
},
|
||||
{
|
||||
"label": "silver",
|
||||
"value": "#c0c0c0"
|
||||
}
|
||||
],
|
||||
"thickness": [
|
||||
{
|
||||
"value": 14
|
||||
},
|
||||
{
|
||||
"value": 12
|
||||
},
|
||||
{
|
||||
"value": 10
|
||||
},
|
||||
{
|
||||
"value": 8
|
||||
},
|
||||
{
|
||||
"value": 6
|
||||
},
|
||||
{
|
||||
"value": 4
|
||||
},
|
||||
{
|
||||
"value": 2
|
||||
},
|
||||
{
|
||||
"value": 1
|
||||
}
|
||||
],
|
||||
"font_sizes": [
|
||||
{
|
||||
"value": 36
|
||||
},
|
||||
{
|
||||
"value": 32
|
||||
},
|
||||
{
|
||||
"value": 28
|
||||
},
|
||||
{
|
||||
"value": 24
|
||||
},
|
||||
{
|
||||
"value": 20
|
||||
},
|
||||
{
|
||||
"value": 16
|
||||
}
|
||||
],
|
||||
"tools": [
|
||||
{
|
||||
"icon": "text_tool",
|
||||
"value": "text"
|
||||
},
|
||||
{
|
||||
"icon": "line_tool",
|
||||
"value": "line"
|
||||
},
|
||||
{
|
||||
"icon": "circle_tool",
|
||||
"value": "ellipse"
|
||||
},
|
||||
{
|
||||
"icon": "triangle_tool",
|
||||
"value": "triangle"
|
||||
},
|
||||
{
|
||||
"icon": "rectangle_tool",
|
||||
"value": "rectangle"
|
||||
},
|
||||
{
|
||||
"icon": "pen_tool",
|
||||
"value": "pencil"
|
||||
},
|
||||
{
|
||||
"icon": "hand",
|
||||
"value": "hand"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"clientLog": {
|
||||
"server": { "enabled": true, "level": "info" },
|
||||
"console": { "enabled": false, "level": "debug" },
|
||||
"external": { "enabled": false, "level": "info", "url": "https://LOG_HOST/html5Log", "method": "POST" }
|
||||
}
|
||||
},
|
||||
|
||||
"private": {
|
||||
|
||||
"app": {
|
||||
"captionsChunkLength": 1000,
|
||||
"pencilChunkLength": 100
|
||||
},
|
||||
|
||||
"redis": {
|
||||
"host": "127.0.0.1",
|
||||
"post": "6379",
|
||||
"timeout": 5000,
|
||||
"debug": true,
|
||||
"channels": {
|
||||
"toAkkaApps": "to-akka-apps-redis-channel"
|
||||
},
|
||||
"subscribeTo": [
|
||||
"to-html5-redis-channel",
|
||||
"from-akka-apps-*"
|
||||
],
|
||||
"async": [
|
||||
"from-akka-apps-wb-redis-channel"
|
||||
],
|
||||
"ignored": [
|
||||
"CheckAlivePongSysMsg",
|
||||
"DoLatencyTracerMsg"
|
||||
]
|
||||
},
|
||||
|
||||
"serverLog": {
|
||||
"level": "info"
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user