diff --git a/bigbluebutton-html5/.meteor/.finished-upgraders b/bigbluebutton-html5/.meteor/.finished-upgraders index 910574ce2df99023d64240d2865fcd83e3e400e4..4538749ab812db7df6cff962d3b43de5108a1ebb 100644 --- a/bigbluebutton-html5/.meteor/.finished-upgraders +++ b/bigbluebutton-html5/.meteor/.finished-upgraders @@ -15,3 +15,4 @@ notices-for-facebook-graph-api-2 1.4.1-add-shell-server-package 1.4.3-split-account-service-packages 1.5-add-dynamic-import-package +1.7-split-underscore-from-meteor-base diff --git a/bigbluebutton-html5/.meteor/packages b/bigbluebutton-html5/.meteor/packages index a0f2677c4c0edd35479d857cb77bcf15a282cd30..f23ddee2e79c68345ddeb08c1aa84fa7ae92fdfd 100644 --- a/bigbluebutton-html5/.meteor/packages +++ b/bigbluebutton-html5/.meteor/packages @@ -3,24 +3,28 @@ # 'meteor add' and 'meteor remove' will edit this file for you, # but you can also edit it by hand. -standard-app-packages@1.0.9 -arunoda:npm@0.2.6 -amplify -blaze@2.1.8 -francocatena:status -mizzao:timesync -clinical:nightwatch -cfs:power-queue -cfs:reactive-list -cfs:micro-queue -reactive-var@1.0.11 -ecmascript@0.9.0 +meteor-base +mobile-experience +mongo +reactive-var + +standard-minifier-css +standard-minifier-js +es5-shim +ecmascript +shell-server + +static-html react-meteor-data -standard-minifier-css@1.3.5 -standard-minifier-js@2.2.0 -nathantreid:css-modules -shell-server@0.3.0 -http@1.3.0 -dynamic-import@0.2.0 -rocketchat:streamer +http session +tracker +check +jquery + +nathantreid:css-modules@=3.1.4 +rocketchat:streamer +cfs:power-queue +cfs:micro-queue +cfs:reactive-list +stevezhu:lodash diff --git a/bigbluebutton-html5/.meteor/release b/bigbluebutton-html5/.meteor/release index 56a7a07fee76d4cf2cf564cfb7a2c134ea8f74cc..2299ae70d95537b4a520d309fe34c4324b1d3eb5 100644 --- a/bigbluebutton-html5/.meteor/release +++ b/bigbluebutton-html5/.meteor/release @@ -1 +1 @@ -METEOR@1.6.0.1 +METEOR@1.8.0.1 diff --git a/bigbluebutton-html5/.meteor/versions b/bigbluebutton-html5/.meteor/versions index 71c85b26db682da4c483714055a63bff219324d4..5b0d886693cfe6a7b19cf02aeee58470d43729fb 100644 --- a/bigbluebutton-html5/.meteor/versions +++ b/bigbluebutton-html5/.meteor/versions @@ -1,94 +1,82 @@ -aldeed:simple-schema@1.5.3 allow-deny@1.1.0 -amplify@1.0.0 -arunoda:npm@0.2.6 -autoupdate@1.3.12 -babel-compiler@6.24.7 -babel-runtime@1.1.1 -base64@1.0.10 -binary-heap@1.0.10 -blaze@2.3.2 +autoupdate@1.5.0 +babel-compiler@7.2.3 +babel-runtime@1.3.0 +base64@1.0.11 +binary-heap@1.0.11 blaze-tools@1.0.10 -boilerplate-generator@1.3.1 -caching-compiler@1.1.9 -caching-html-compiler@1.1.2 -callback-hook@1.0.10 -cfs:http-methods@0.0.32 +boilerplate-generator@1.6.0 +caching-compiler@1.2.1 +caching-html-compiler@1.1.3 +callback-hook@1.1.0 cfs:micro-queue@0.0.6 cfs:power-queue@0.9.11 cfs:reactive-list@0.0.9 cfs:reactive-property@0.0.4 -check@1.2.5 -clinical:nightwatch@2.0.1 -coffeescript@1.12.7_3 -coffeescript-compiler@1.12.7_3 +check@1.3.1 ddp@1.4.0 -ddp-client@2.2.0 -ddp-common@1.3.0 -ddp-server@2.1.1 +ddp-client@2.3.3 +ddp-common@1.4.0 +ddp-server@2.2.0 deps@1.0.12 -diff-sequence@1.0.7 -dynamic-import@0.2.1 -ecmascript@0.9.0 -ecmascript-runtime@0.5.0 -ecmascript-runtime-client@0.5.0 -ecmascript-runtime-server@0.5.0 +diff-sequence@1.1.1 +dynamic-import@0.5.0 +ecmascript@0.12.3 +ecmascript-runtime@0.7.0 +ecmascript-runtime-client@0.8.0 +ecmascript-runtime-server@0.7.1 ejson@1.1.0 -fastclick@1.0.13 -francocatena:status@1.5.3 +es5-shim@4.8.0 +fetch@0.1.0 geojson-utils@1.0.10 +hot-code-push@1.0.4 html-tools@1.0.11 htmljs@1.0.11 -http@1.3.0 -id-map@1.0.9 -jquery@1.11.10 +http@1.4.2 +id-map@1.1.0 +inter-process-messaging@0.1.0 +jquery@1.11.11 launch-screen@1.1.1 livedata@1.0.18 -logging@1.1.19 -mdg:validation-error@0.5.1 -meteor@1.8.2 -meteor-platform@1.2.6 -meteorspark:util@0.2.0 -minifier-css@1.2.16 -minifier-js@2.2.2 -minimongo@1.4.3 -mizzao:timesync@0.5.0 +logging@1.1.20 +meteor@1.9.2 +meteor-base@1.4.0 +minifier-css@1.4.1 +minifier-js@2.4.0 +minimongo@1.4.5 +mobile-experience@1.0.5 mobile-status-bar@1.0.14 -modules@0.11.2 -modules-runtime@0.9.1 -mongo@1.3.1 +modern-browsers@0.1.3 +modules@0.13.0 +modules-runtime@0.10.3 +mongo@1.6.0 +mongo-decimal@0.1.0 mongo-dev-server@1.1.0 -mongo-id@1.0.6 -nathantreid:css-modules@2.8.0 -npm-mongo@2.2.33 -observe-sequence@1.0.16 -ordered-dict@1.0.9 -promise@0.10.0 -raix:eventemitter@0.1.3 -random@1.0.10 -react-meteor-data@0.2.15 -reactive-dict@1.2.0 +mongo-id@1.0.7 +nathantreid:css-modules@3.1.4 +npm-mongo@3.1.1 +ordered-dict@1.1.0 +promise@0.11.1 +random@1.1.0 +react-meteor-data@0.2.16 +reactive-dict@1.2.1 reactive-var@1.0.11 -reload@1.1.11 -retry@1.0.9 -rocketchat:streamer@0.6.2 -routepolicy@1.0.12 -session@1.1.7 -shell-server@0.3.1 -spacebars@1.0.15 +reload@1.2.0 +retry@1.1.0 +rocketchat:streamer@1.0.1 +routepolicy@1.1.0 +session@1.2.0 +shell-server@0.4.0 +socket-stream-client@0.2.2 spacebars-compiler@1.1.3 -standard-app-packages@1.0.9 -standard-minifier-css@1.3.5 -standard-minifier-js@2.2.3 -tap:i18n@1.8.2 -templating@1.3.2 -templating-compiler@1.3.3 -templating-runtime@1.3.2 +standard-minifier-css@1.5.2 +standard-minifier-js@2.4.0 +static-html@1.2.2 +stevezhu:lodash@4.17.2 templating-tools@1.1.2 -tmeasday:check-npm-versions@0.3.1 -tracker@1.1.3 -ui@1.0.13 +tmeasday:check-npm-versions@0.3.2 +tracker@1.2.0 underscore@1.0.10 -url@1.1.0 -webapp@1.4.0 +url@1.2.0 +webapp@1.7.1 webapp-hashing@1.0.9 diff --git a/bigbluebutton-html5/imports/startup/client/base.jsx b/bigbluebutton-html5/imports/startup/client/base.jsx index 9a2368a96c21bebc634281f06e867fe1065ea1d8..4428471e9d3bafb1363607e4d010cd155f0ae3c4 100755 --- a/bigbluebutton-html5/imports/startup/client/base.jsx +++ b/bigbluebutton-html5/imports/startup/client/base.jsx @@ -131,8 +131,7 @@ const BaseContainer = withTracker(() => { }, }; - const subscriptionsHandlers = SUBSCRIPTIONS_NAME.map(name => - Meteor.subscribe(name, credentials, subscriptionErrorHandler)); + const subscriptionsHandlers = SUBSCRIPTIONS_NAME.map(name => Meteor.subscribe(name, credentials, subscriptionErrorHandler)); const chats = GroupChat.find({ $or: [ diff --git a/bigbluebutton-html5/imports/startup/client/intl.jsx b/bigbluebutton-html5/imports/startup/client/intl.jsx index 3602f33a625a184b04068b8f11fbb8c8d49c2d0f..9ce3417c36a7704b78f501fd5b67e1007e13ce72 100644 --- a/bigbluebutton-html5/imports/startup/client/intl.jsx +++ b/bigbluebutton-html5/imports/startup/client/intl.jsx @@ -27,6 +27,7 @@ class IntlStartup extends Component { this.fetchLocalizedMessages = this.fetchLocalizedMessages.bind(this); } + componentWillMount() { this.fetchLocalizedMessages(this.props.locale); } @@ -69,7 +70,7 @@ class IntlStartup extends Component { render() { return this.state.fetching ? <LoadingScreen /> : ( - <IntlProvider locale={this.state.normalizedLocale} messages={this.state.messages}> + <IntlProvider locale={DEFAULT_LANGUAGE} messages={this.state.messages}> {this.props.children} </IntlProvider> ); diff --git a/bigbluebutton-html5/imports/startup/server/logger.js b/bigbluebutton-html5/imports/startup/server/logger.js index e9eacdd43fe8fdf5ad7697befcedc016ad245d80..a394ae512f7451b60debca41b6e0aa2e2dfba33b 100644 --- a/bigbluebutton-html5/imports/startup/server/logger.js +++ b/bigbluebutton-html5/imports/startup/server/logger.js @@ -1,19 +1,12 @@ import { Meteor } from 'meteor/meteor'; -import Winston from 'winston'; +import { createLogger, format, transports } from 'winston'; -const Logger = new Winston.Logger(); - -Logger.configure({ - levels: { - error: 0, warn: 1, info: 2, verbose: 3, debug: 4, - }, - colors: { - error: 'red', - warn: 'yellow', - info: 'green', - verbose: 'cyan', - debug: 'magenta', - }, +const Logger = createLogger({ + format: format.combine( + format.colorize({ level: true }), + format.splat(), + format.simple(), + ), }); Meteor.startup(() => { @@ -21,7 +14,7 @@ Meteor.startup(() => { const { level } = LOG_CONFIG; // console logging - Logger.add(Winston.transports.Console, { + Logger.add(new transports.Console(), { prettyPrint: false, humanReadableUnhandledException: true, colorize: true, diff --git a/bigbluebutton-html5/imports/ui/components/actions-bar/actions-dropdown/component.jsx b/bigbluebutton-html5/imports/ui/components/actions-bar/actions-dropdown/component.jsx index e6c404d6d07fa71b618445def68ea8033eb0ff82..0676065f445719c327c30932904a8d029895d2da 100755 --- a/bigbluebutton-html5/imports/ui/components/actions-bar/actions-dropdown/component.jsx +++ b/bigbluebutton-html5/imports/ui/components/actions-bar/actions-dropdown/component.jsx @@ -1,3 +1,4 @@ +import _ from 'lodash'; import React, { Component } from 'react'; import PropTypes from 'prop-types'; import { defineMessages, injectIntl, intlShape } from 'react-intl'; @@ -91,8 +92,8 @@ class ActionsDropdown extends Component { } componentDidMount() { - if (Meteor.settings.public.allowOutsideCommands.toggleRecording || - getFromUserSettings('outsideToggleRecording', false)) { + if (Meteor.settings.public.allowOutsideCommands.toggleRecording + || getFromUserSettings('outsideToggleRecording', false)) { ActionBarService.connectRecordingObserver(); window.addEventListener('message', ActionBarService.processOutsideToggleRecording); } @@ -121,44 +122,52 @@ class ActionsDropdown extends Component { } = this.props; return _.compact([ - (isUserPresenter ? - <DropdownListItem - icon="user" - label={intl.formatMessage(intlMessages.pollBtnLabel)} - description={intl.formatMessage(intlMessages.pollBtnDesc)} - key={this.pollId} - onClick={() => togglePollMenu()} - /> + (isUserPresenter + ? ( + <DropdownListItem + icon="user" + label={intl.formatMessage(intlMessages.pollBtnLabel)} + description={intl.formatMessage(intlMessages.pollBtnDesc)} + key={this.pollId} + onClick={() => togglePollMenu()} + /> + ) : null), - (isUserPresenter ? - <DropdownListItem - data-test="uploadPresentation" - icon="presentation" - label={intl.formatMessage(intlMessages.presentationLabel)} - description={intl.formatMessage(intlMessages.presentationDesc)} - key={this.presentationItemId} - onClick={this.handlePresentationClick} - /> + (isUserPresenter + ? ( + <DropdownListItem + data-test="uploadPresentation" + icon="presentation" + label={intl.formatMessage(intlMessages.presentationLabel)} + description={intl.formatMessage(intlMessages.presentationDesc)} + key={this.presentationItemId} + onClick={this.handlePresentationClick} + /> + ) : null), - (record && isUserModerator && allowStartStopRecording ? - <DropdownListItem - icon="record" - label={intl.formatMessage(isRecording ? - intlMessages.stopRecording : intlMessages.startRecording)} - description={intl.formatMessage(isRecording ? - intlMessages.stopRecording : intlMessages.startRecording)} - key={this.recordId} - onClick={toggleRecording} - /> + (record && isUserModerator && allowStartStopRecording + ? ( + <DropdownListItem + icon="record" + label={intl.formatMessage(isRecording + ? intlMessages.stopRecording : intlMessages.startRecording)} + description={intl.formatMessage(isRecording + ? intlMessages.stopRecording : intlMessages.startRecording)} + key={this.recordId} + onClick={toggleRecording} + /> + ) : null), - (isUserModerator && !meetingIsBreakout && !hasBreakoutRoom ? - <DropdownListItem - icon="rooms" - label={intl.formatMessage(intlMessages.createBreakoutRoom)} - description={intl.formatMessage(intlMessages.createBreakoutRoomDesc)} - key={this.createBreakoutRoomId} - onClick={this.handleCreateBreakoutRoomClick} - /> + (isUserModerator && !meetingIsBreakout && !hasBreakoutRoom + ? ( + <DropdownListItem + icon="rooms" + label={intl.formatMessage(intlMessages.createBreakoutRoom)} + description={intl.formatMessage(intlMessages.createBreakoutRoomDesc)} + key={this.createBreakoutRoomId} + onClick={this.handleCreateBreakoutRoomClick} + /> + ) : null), ]); } @@ -166,6 +175,7 @@ class ActionsDropdown extends Component { handlePresentationClick() { this.props.mountModal(<PresentationUploaderContainer />); } + handleCreateBreakoutRoomClick() { const { createBreakoutRoom, @@ -195,7 +205,7 @@ class ActionsDropdown extends Component { if ((!isUserPresenter && !isUserModerator) || availableActions.length === 0) return null; return ( - <Dropdown ref={(ref) => { this._dropdown = ref; }} > + <Dropdown ref={(ref) => { this._dropdown = ref; }}> <DropdownTrigger tabIndex={0} accessKey={OPEN_ACTIONS_AK}> <Button hideLabel diff --git a/bigbluebutton-html5/imports/ui/components/app/component.jsx b/bigbluebutton-html5/imports/ui/components/app/component.jsx index b43d5e864bf4e14f5deafe13ed04493246d5bfcf..6a1fb08bfb6a87821561bccd81e37800477e43e6 100755 --- a/bigbluebutton-html5/imports/ui/components/app/component.jsx +++ b/bigbluebutton-html5/imports/ui/components/app/component.jsx @@ -228,7 +228,6 @@ class App extends Component { minWidth={USERLIST_MIN_WIDTH_PX} maxWidth={USERLIST_MAX_WIDTH_PX} ref={(node) => { this.resizableUserList = node; }} - className={styles.resizableUserList} enable={resizableEnableOptions} onResize={(e, direction, ref) => { const { compactUserList } = this.state; @@ -284,7 +283,6 @@ class App extends Component { minWidth={CHAT_MIN_WIDTH} maxWidth={CHAT_MAX_WIDTH} ref={(node) => { this.resizableChat = node; }} - className={styles.resizableChat} enable={resizableEnableOptions} > {this.renderChat()} diff --git a/bigbluebutton-html5/imports/ui/components/audio/audio-controls/container.jsx b/bigbluebutton-html5/imports/ui/components/audio/audio-controls/container.jsx index f3e82d48c4417be646f65688d200e2bceed217c8..11cf83edb83fdbec7114f39fc599dbf03d27d205 100644 --- a/bigbluebutton-html5/imports/ui/components/audio/audio-controls/container.jsx +++ b/bigbluebutton-html5/imports/ui/components/audio/audio-controls/container.jsx @@ -35,22 +35,21 @@ const processToggleMuteFromOutside = (e) => { } }; -export default withModalMounter(withTracker(({ mountModal }) => - ({ - processToggleMuteFromOutside: arg => processToggleMuteFromOutside(arg), - mute: Service.isConnected() && !Service.isListenOnly() && !Service.isEchoTest(), - unmute: Service.isConnected() && !Service.isListenOnly() && Service.isMuted(), - join: Service.isConnected() && !Service.isEchoTest(), - disable: Service.isConnecting() || Service.isHangingUp(), - glow: Service.isTalking() && !Service.isMuted(), - handleToggleMuteMicrophone: () => Service.toggleMuteMicrophone(), - handleJoinAudio: () => { - const meeting = Meetings.findOne({ meetingId: Auth.meetingID }); - const currentUser = Users.findOne({ userId: Auth.userID }); - const currentUserIsLocked = mapUser(currentUser).isLocked; - const micsLocked = (currentUserIsLocked && meeting.lockSettingsProp.disableMic); +export default withModalMounter(withTracker(({ mountModal }) => ({ + processToggleMuteFromOutside: arg => processToggleMuteFromOutside(arg), + mute: Service.isConnected() && !Service.isListenOnly() && !Service.isEchoTest(), + unmute: Service.isConnected() && !Service.isListenOnly() && Service.isMuted(), + join: Service.isConnected() && !Service.isEchoTest(), + disable: Service.isConnecting() || Service.isHangingUp(), + glow: Service.isTalking() && !Service.isMuted(), + handleToggleMuteMicrophone: () => Service.toggleMuteMicrophone(), + handleJoinAudio: () => { + const meeting = Meetings.findOne({ meetingId: Auth.meetingID }); + const currentUser = Users.findOne({ userId: Auth.userID }); + const currentUserIsLocked = mapUser(currentUser).isLocked; + const micsLocked = (currentUserIsLocked && meeting.lockSettingsProp.disableMic); - return micsLocked ? Service.joinListenOnly() : mountModal(<AudioModalContainer />); - }, - handleLeaveAudio: () => Service.exitAudio(), - }))(AudioControlsContainer)); + return micsLocked ? Service.joinListenOnly() : mountModal(<AudioModalContainer />); + }, + handleLeaveAudio: () => Service.exitAudio(), +}))(AudioControlsContainer)); diff --git a/bigbluebutton-html5/imports/ui/components/authenticated-handler/component.jsx b/bigbluebutton-html5/imports/ui/components/authenticated-handler/component.jsx index 552080bb162b1b5a107df1d7ec83600e03a34544..d1ae21cd5479ffc2566c4e2665643761833c98aa 100644 --- a/bigbluebutton-html5/imports/ui/components/authenticated-handler/component.jsx +++ b/bigbluebutton-html5/imports/ui/components/authenticated-handler/component.jsx @@ -11,6 +11,7 @@ class AuthenticatedHandler extends Component { Session.set('hasError', true); if (codeError) Session.set('codeError', codeError); } + static shouldAuthenticate(status, lastStatus) { return lastStatus != null && lastStatus === STATUS_CONNECTING && status.connected; } @@ -31,6 +32,7 @@ class AuthenticatedHandler extends Component { } }); } + static async authenticatedRouteHandler(callback) { if (Auth.loggedIn) { callback(); @@ -51,6 +53,7 @@ class AuthenticatedHandler extends Component { setReason(error); } } + constructor(props) { super(props); this.changeState = this.changeState.bind(this); diff --git a/bigbluebutton-html5/imports/ui/components/button/component.jsx b/bigbluebutton-html5/imports/ui/components/button/component.jsx index 9f1d9aa7cae017295579182963ca103c1a048630..5f1a5b62747ca72ea77dbb569ad222cf0e1b8d1c 100644 --- a/bigbluebutton-html5/imports/ui/components/button/component.jsx +++ b/bigbluebutton-html5/imports/ui/components/button/component.jsx @@ -91,11 +91,9 @@ export default class Button extends BaseButton { const { size, color, - disabled, ghost, circle, block, - iconRight, } = this.props; const propClassNames = {}; @@ -106,8 +104,6 @@ export default class Button extends BaseButton { propClassNames[styles.ghost] = ghost; propClassNames[styles.circle] = circle; propClassNames[styles.block] = block; - propClassNames[styles.iconRight] = iconRight; - propClassNames[styles.disabled] = disabled; return propClassNames; } @@ -207,7 +203,7 @@ export default class Button extends BaseButton { if (iconName) { return (<Icon className={styles.icon} iconName={iconName} />); - } else if (customIcon) { + } if (customIcon) { return customIcon; } diff --git a/bigbluebutton-html5/imports/ui/components/chat/chat-dropdown/component.jsx b/bigbluebutton-html5/imports/ui/components/chat/chat-dropdown/component.jsx index a559339bf11f863545d8db935da82e64cafa58e9..48433e1782a5cb6c800d9e63c335245b65f567cc 100644 --- a/bigbluebutton-html5/imports/ui/components/chat/chat-dropdown/component.jsx +++ b/bigbluebutton-html5/imports/ui/components/chat/chat-dropdown/component.jsx @@ -11,7 +11,7 @@ import DropdownListItem from '/imports/ui/components/dropdown/list/item/componen import Auth from '/imports/ui/services/auth'; import Button from '/imports/ui/components/button/component'; -import ChatService from './../service'; +import ChatService from '../service'; import { styles } from './styles'; const intlMessages = defineMessages({ diff --git a/bigbluebutton-html5/imports/ui/components/chat/message-list/component.jsx b/bigbluebutton-html5/imports/ui/components/chat/message-list/component.jsx index 04dff92add6f08f587cc18068197663acbf3fef2..4bdea69c8078f2fe39122f75387f4e0ff9ea391b 100644 --- a/bigbluebutton-html5/imports/ui/components/chat/message-list/component.jsx +++ b/bigbluebutton-html5/imports/ui/components/chat/message-list/component.jsx @@ -89,9 +89,9 @@ class MessageList extends Component { // Compare with <1 to account for the chance scrollArea.scrollTop is a float // value in some browsers. - this.shouldScrollBottom = position === scrollArea.scrollHeight || - (scrollArea.scrollHeight - position < 1) || - nextProps.scrollPosition === null; + this.shouldScrollBottom = position === scrollArea.scrollHeight + || (scrollArea.scrollHeight - position < 1) + || nextProps.scrollPosition === null; } componentDidUpdate(prevProps) { @@ -183,7 +183,6 @@ class MessageList extends Component { {messages.map(message => ( <MessageListItem handleReadMessage={handleReadMessage} - className={styles.messageListItem} key={message.id} messages={message.content} user={message.sender} diff --git a/bigbluebutton-html5/imports/ui/components/checkbox/component.jsx b/bigbluebutton-html5/imports/ui/components/checkbox/component.jsx index c290664a4350031dab77ad6576b0a1055c3aa48f..c2a1084ca9fd6f119f67e82b2c322f43af23b575 100644 --- a/bigbluebutton-html5/imports/ui/components/checkbox/component.jsx +++ b/bigbluebutton-html5/imports/ui/components/checkbox/component.jsx @@ -47,7 +47,7 @@ export default class Checkbox extends Component { return ( <div className={cx({ [styles.disabled]: !!disabled, - }, styles.container, className)} + }, className)} > <input type="checkbox" @@ -59,9 +59,9 @@ export default class Checkbox extends Component { disabled={disabled} /> <div role="presentation" onClick={this.handleChange}> - { checked ? - <Icon iconName="check" className={cx(styles.icon, styles.checked)} /> : - <Icon iconName="circle" className={styles.icon} /> + { checked + ? <Icon iconName="check" className={cx(styles.icon, styles.checked)} /> + : <Icon iconName="circle" className={styles.icon} /> } </div> <div id={ariaLabelledBy} hidden>{ariaLabel}</div> diff --git a/bigbluebutton-html5/imports/ui/components/closed-captions/service.js b/bigbluebutton-html5/imports/ui/components/closed-captions/service.js index 7a4c9fe37ab7b3f7a799d10b601eb8bb3fa3e088..da2e0e10fc1d2a79b821cb80bd1aa5c927ce9f26 100644 --- a/bigbluebutton-html5/imports/ui/components/closed-captions/service.js +++ b/bigbluebutton-html5/imports/ui/components/closed-captions/service.js @@ -1,6 +1,7 @@ import Captions from '/imports/api/captions'; import Auth from '/imports/ui/services/auth'; import Settings from '/imports/ui/services/settings'; +import _ from 'lodash'; const getCCData = () => { const meetingID = Auth.meetingID; diff --git a/bigbluebutton-html5/imports/ui/components/error-screen/component.jsx b/bigbluebutton-html5/imports/ui/components/error-screen/component.jsx index 297ee48d84444c471f344c70296ae62d1131c216..53c405e37f03e61f6904917edfd67f127578eb63 100644 --- a/bigbluebutton-html5/imports/ui/components/error-screen/component.jsx +++ b/bigbluebutton-html5/imports/ui/components/error-screen/component.jsx @@ -55,16 +55,16 @@ class ErrorScreen extends React.PureComponent { return ( <div className={styles.background}> - <h1 className={styles.code}> + <h1> {code} </h1> <h1 className={styles.message}> {formatedMessage} </h1> - <div className={styles.content}> + <div> {children} </div> - <div className={styles.content}> + <div> <Button size="sm" onClick={logoutRouteHandler} diff --git a/bigbluebutton-html5/imports/ui/components/join-handler/component.jsx b/bigbluebutton-html5/imports/ui/components/join-handler/component.jsx index 02b969b4cb5b2ea7762d03567d644f691b9809b3..353f27bd8b673295c971c266da8d511297009967 100644 --- a/bigbluebutton-html5/imports/ui/components/join-handler/component.jsx +++ b/bigbluebutton-html5/imports/ui/components/join-handler/component.jsx @@ -13,6 +13,7 @@ class JoinHandler extends Component { Session.set('hasError', true); if (codeError) Session.set('codeError', codeError); } + constructor(props) { super(props); this.fetchToken = this.fetchToken.bind(this); @@ -120,9 +121,9 @@ class JoinHandler extends Component { render() { const { children } = this.props; const { joined } = this.state; - return joined ? - children : - (<LoadingScreen />); + return joined + ? children + : (<LoadingScreen />); } } diff --git a/bigbluebutton-html5/imports/ui/components/loading-screen/component.jsx b/bigbluebutton-html5/imports/ui/components/loading-screen/component.jsx index dcb56c35ccc03f59a35e9298dcc47d013d78a8f4..c54e954a3943eb4a45b281f19da6f36a15751bc6 100644 --- a/bigbluebutton-html5/imports/ui/components/loading-screen/component.jsx +++ b/bigbluebutton-html5/imports/ui/components/loading-screen/component.jsx @@ -6,7 +6,7 @@ const LoadingScreen = ({ children }) => ( <div className={styles.spinner}> <div className={styles.bounce1} /> <div className={styles.bounce2} /> - <div className={styles.bounce3} /> + <div /> </div> <div className={styles.message}> {children} diff --git a/bigbluebutton-html5/imports/ui/components/media/component.jsx b/bigbluebutton-html5/imports/ui/components/media/component.jsx index c011bfe293071798ccd5c8046a7f4eb73d4cf723..2e5faf840e1ca19d4ebca0807b8cffd7397c2b07 100644 --- a/bigbluebutton-html5/imports/ui/components/media/component.jsx +++ b/bigbluebutton-html5/imports/ui/components/media/component.jsx @@ -29,7 +29,6 @@ export default class Media extends Component { const contentClassName = cx({ [styles.content]: true, - [styles.hasOverlay]: !hideOverlay, }); const overlayClassName = cx({ diff --git a/bigbluebutton-html5/imports/ui/components/nav-bar/component.jsx b/bigbluebutton-html5/imports/ui/components/nav-bar/component.jsx index b133c4354553fb962a051a967ac6d9e864904a98..38625dc6e115e05c4ca3feaef2f09ef2c7bd6e20 100755 --- a/bigbluebutton-html5/imports/ui/components/nav-bar/component.jsx +++ b/bigbluebutton-html5/imports/ui/components/nav-bar/component.jsx @@ -59,14 +59,12 @@ const defaultProps = { shortcuts: '', }; -const openBreakoutJoinConfirmation = (breakout, breakoutName, mountModal) => - mountModal(<BreakoutJoinConfirmation - breakout={breakout} - breakoutName={breakoutName} - />); +const openBreakoutJoinConfirmation = (breakout, breakoutName, mountModal) => mountModal(<BreakoutJoinConfirmation + breakout={breakout} + breakoutName={breakoutName} +/>); -const closeBreakoutJoinConfirmation = mountModal => - mountModal(null); +const closeBreakoutJoinConfirmation = mountModal => mountModal(null); class NavBar extends PureComponent { constructor(props) { @@ -145,7 +143,9 @@ class NavBar extends PureComponent { <Dropdown isOpen={this.state.isActionsOpen}> <DropdownTrigger> <h1 className={cx(styles.presentationTitle, styles.dropdownBreakout)}> - {presentationTitle} <Icon iconName="down-arrow" /> + {presentationTitle} + {' '} + <Icon iconName="down-arrow" /> </h1> </DropdownTrigger> <DropdownContent @@ -168,7 +168,6 @@ class NavBar extends PureComponent { return ( <DropdownListItem - className={styles.actionsHeader} key={_.uniqueId('action-header')} label={breakoutName} onClick={openBreakoutJoinConfirmation.bind(this, breakout, breakoutName, mountModal)} @@ -213,9 +212,9 @@ class NavBar extends PureComponent { </div> <div className={styles.center}> {this.renderPresentationTitle()} - {beingRecorded.record ? - <span className={styles.presentationTitleSeparator}>|</span> - : null} + {beingRecorded.record + ? <span className={styles.presentationTitleSeparator}>|</span> + : null} <RecordingIndicator {...beingRecorded} title={intl.formatMessage(intlMessages[recordingMessage])} diff --git a/bigbluebutton-html5/imports/ui/components/nav-bar/settings-dropdown/component.jsx b/bigbluebutton-html5/imports/ui/components/nav-bar/settings-dropdown/component.jsx index 5b263c094f0d5be24a75e12ef8481963243fe723..bc3a659924e371a0a1b6573e98d835404dd34431 100755 --- a/bigbluebutton-html5/imports/ui/components/nav-bar/settings-dropdown/component.jsx +++ b/bigbluebutton-html5/imports/ui/components/nav-bar/settings-dropdown/component.jsx @@ -1,6 +1,5 @@ import React, { PureComponent } from 'react'; import { defineMessages, injectIntl } from 'react-intl'; -import cx from 'classnames'; import _ from 'lodash'; import { withModalMounter } from '/imports/ui/components/modal/service'; import LogoutConfirmationContainer from '/imports/ui/components/logout-confirmation/container'; @@ -191,13 +190,15 @@ class SettingsDropdown extends PureComponent { alterMenu(props) { const { fullscreenLabel, fullscreenDesc, fullscreenIcon } = this.checkFullscreen(props); - const newFullScreenButton = (<DropdownListItem - key={_.uniqueId('list-item-')} - icon={fullscreenIcon} - label={fullscreenLabel} - description={fullscreenDesc} - onClick={this.props.handleToggleFullscreen} - />); + const newFullScreenButton = ( + <DropdownListItem + key={_.uniqueId('list-item-')} + icon={fullscreenIcon} + label={fullscreenLabel} + description={fullscreenDesc} + onClick={this.props.handleToggleFullscreen} + /> + ); this.menuItems = this.menuItems.slice(1); this.menuItems.unshift(newFullScreenButton); } @@ -222,7 +223,7 @@ class SettingsDropdown extends PureComponent { ghost circle hideLabel - className={cx(styles.btn, styles.btnSettings)} + className={styles.btn} // FIXME: Without onClick react proptypes keep warning // even after the DropdownTrigger inject an onClick handler diff --git a/bigbluebutton-html5/imports/ui/components/presentation/component.jsx b/bigbluebutton-html5/imports/ui/components/presentation/component.jsx index b84102136b591d6735a0f178ffe696b1b10fd112..889ba8f50d13bf20fe40ac0e8f0ffc3fb916c72a 100644 --- a/bigbluebutton-html5/imports/ui/components/presentation/component.jsx +++ b/bigbluebutton-html5/imports/ui/components/presentation/component.jsx @@ -135,6 +135,7 @@ export default class PresentationArea extends Component { height: adjustedHeight, }; } + zoomChanger(zoom) { let newZoom = zoom; const isDifferent = newZoom !== this.state.zoom; @@ -146,6 +147,7 @@ export default class PresentationArea extends Component { } if (isDifferent) this.setState({ zoom: newZoom }); } + pointUpdate(pointX, pointY) { this.setState({ delta: { @@ -154,11 +156,13 @@ export default class PresentationArea extends Component { }, }); } + touchUpdate(bool) { this.setState({ touchZoom: bool, }); } + fitToWidthHandler() { this.setState({ fitToWidth: !this.state.fitToWidth, @@ -168,8 +172,8 @@ export default class PresentationArea extends Component { // renders the whole presentation area renderPresentationArea() { // sometimes tomcat publishes the slide url, but the actual file is not accessible (why?) - if (!this.props.currentSlide || - !this.props.currentSlide.calculatedData) { + if (!this.props.currentSlide + || !this.props.currentSlide.calculatedData) { return null; } // to control the size of the svg wrapper manually @@ -328,8 +332,8 @@ export default class PresentationArea extends Component { } renderWhiteboardToolbar() { - if (!this.props.currentSlide || - !this.props.currentSlide.calculatedData) { + if (!this.props.currentSlide + || !this.props.currentSlide.calculatedData) { return null; } @@ -353,11 +357,11 @@ export default class PresentationArea extends Component { ref={(ref) => { this.refWhiteboardArea = ref; }} className={styles.whiteboardSizeAvailable} /> - {this.state.showSlide ? - this.renderPresentationArea() + {this.state.showSlide + ? this.renderPresentationArea() : null } - {this.props.userIsPresenter || this.props.multiUser ? - this.renderWhiteboardToolbar() + {this.props.userIsPresenter || this.props.multiUser + ? this.renderWhiteboardToolbar() : null } </div> {this.renderPresentationToolbar()} diff --git a/bigbluebutton-html5/imports/ui/components/presentation/presentation-toolbar/zoom-tool/holdButton/component.jsx b/bigbluebutton-html5/imports/ui/components/presentation/presentation-toolbar/zoom-tool/holdButton/component.jsx index dea39ebaaa3c481f4117eb0006b8716eee9b994a..7619456b140bc597ceff786ec093e0f1bb357079 100644 --- a/bigbluebutton-html5/imports/ui/components/presentation/presentation-toolbar/zoom-tool/holdButton/component.jsx +++ b/bigbluebutton-html5/imports/ui/components/presentation/presentation-toolbar/zoom-tool/holdButton/component.jsx @@ -80,15 +80,15 @@ class HoldDownButton extends Component { render() { const { - key, + uniqueKey, className, children, } = this.props; - + return ( <span role="button" - key={key} + key={uniqueKey} onClick={this.onClick} onMouseDown={this.mouseDownHandler} onMouseUp={this.mouseUpHandler} @@ -107,12 +107,12 @@ const defaultProps = { exec: () => {}, minBound: null, maxBound: Infinity, - key: _.uniqueId('holdButton-'), + uniqueKey: _.uniqueId('holdButton-'), value: 0, }; const propTypes = { - key: PropTypes.string, + uniqueKey: PropTypes.string, exec: PropTypes.func.isRequired, minBound: PropTypes.number, maxBound: PropTypes.number, diff --git a/bigbluebutton-html5/imports/ui/components/presentation/presentation-uploader/component.jsx b/bigbluebutton-html5/imports/ui/components/presentation/presentation-uploader/component.jsx index 01309c44d15bdf3adb442d8fbe9f5f2b950fedb5..cd768057c610b66f7944445d5fed5837bdda578a 100755 --- a/bigbluebutton-html5/imports/ui/components/presentation/presentation-uploader/component.jsx +++ b/bigbluebutton-html5/imports/ui/components/presentation/presentation-uploader/component.jsx @@ -145,12 +145,11 @@ class PresentationUploader extends Component { return fileIndex === -1 ? false : { presentations: update(presentations, { [fileIndex]: { - $apply: file => - update(file, { - [key]: { - [operation]: value, - }, - }), + $apply: file => update(file, { + [key]: { + [operation]: value, + }, + }), }, }), }; @@ -383,8 +382,7 @@ class PresentationUploader extends Component { }); } - const conversionStatusMessage = - intlMessages[item.conversion.status] || intlMessages.genericConversionStatus; + const conversionStatusMessage = intlMessages[item.conversion.status] || intlMessages.genericConversionStatus; return intl.formatMessage(conversionStatusMessage); } @@ -419,13 +417,15 @@ class PresentationUploader extends Component { <Icon iconName="file" /> </td> { - isActualCurrent ? - <th className={styles.tableItemCurrent}> - <span className={styles.currentLabel}> - {this.props.intl.formatMessage(intlMessages.current)} - </span> - </th> - : null + isActualCurrent + ? ( + <th className={styles.tableItemCurrent}> + <span className={styles.currentLabel}> + {this.props.intl.formatMessage(intlMessages.current)} + </span> + </th> + ) + : null } <th className={styles.tableItemName} colSpan={!isActualCurrent ? 2 : 0}> <span>{item.filename}</span> @@ -479,12 +479,13 @@ class PresentationUploader extends Component { accept={fileValidMimeTypes.join()} minSize={fileSizeMin} maxSize={fileSizeMax} - disablePreview + disablepreview="true" onDrop={this.handleFiledrop} > <Icon className={styles.dropzoneIcon} iconName="upload" /> <p className={styles.dropzoneMessage}> - {intl.formatMessage(intlMessages.dropzoneLabel)} + {intl.formatMessage(intlMessages.dropzoneLabel)} + <span className={styles.dropzoneLink}> {intl.formatMessage(intlMessages.browseFilesLabel)} </span> diff --git a/bigbluebutton-html5/imports/ui/components/settings/submenus/application/component.jsx b/bigbluebutton-html5/imports/ui/components/settings/submenus/application/component.jsx index cbd75e98268a1b093451823559d97b2102a84837..c8f0d191cd43e6c44d767a0506eca1c015b08416 100644 --- a/bigbluebutton-html5/imports/ui/components/settings/submenus/application/component.jsx +++ b/bigbluebutton-html5/imports/ui/components/settings/submenus/application/component.jsx @@ -122,8 +122,8 @@ class ApplicationMenu extends BaseMenu { const { isLargestFontSize, isSmallestFontSize } = this.state; return ( - <div className={styles.tabContent}> - <div className={styles.header}> + <div> + <div> <h3 className={styles.title}> {intl.formatMessage(intlMessages.applicationSectionTitle)} </h3> diff --git a/bigbluebutton-html5/imports/ui/components/settings/submenus/closed-captions/component.jsx b/bigbluebutton-html5/imports/ui/components/settings/submenus/closed-captions/component.jsx index faaec2072d02fbe0a445c42ca06831edeee63474..12f4f34be11a35682c57dba80f741c3160fb8a82 100644 --- a/bigbluebutton-html5/imports/ui/components/settings/submenus/closed-captions/component.jsx +++ b/bigbluebutton-html5/imports/ui/components/settings/submenus/closed-captions/component.jsx @@ -1,11 +1,11 @@ import React from 'react'; -import { styles } from '../styles'; import cx from 'classnames'; -import BaseMenu from '../base/component'; import Toggle from '/imports/ui/components/switch/component'; import Checkbox from '/imports/ui/components/checkbox/component'; import { GithubPicker } from 'react-color'; import { defineMessages, injectIntl } from 'react-intl'; +import BaseMenu from '../base/component'; +import { styles } from '../styles'; // an array of font-families const FONT_FAMILIES = ['Arial', 'Calibri', 'Time New Roman', 'Sans-serif']; @@ -131,8 +131,8 @@ class ClosedCaptionsMenu extends BaseMenu { } = this.props; return ( - <div className={styles.tabContent}> - <div className={styles.header}> + <div> + <div> <h3 className={styles.title}>{intl.formatMessage(intlMessages.closedCaptionsLabel)}</h3> </div> <div className={styles.form}> @@ -145,7 +145,7 @@ class ClosedCaptionsMenu extends BaseMenu { </div> </div> <div className={styles.col}> - <div className={cx(styles.formElement, styles.pullContentRight)} > + <div className={cx(styles.formElement, styles.pullContentRight)}> <Toggle icons={false} defaultChecked={this.state.settings.enabled} @@ -156,223 +156,234 @@ class ClosedCaptionsMenu extends BaseMenu { </div> </div> </div> - { this.state.settings.enabled ? - <div> - { isModerator ? + { this.state.settings.enabled + ? ( + <div> + { isModerator + ? ( + <div className={cx(styles.row, styles.spacedLeft)}> + <div className={styles.col}> + <div className={styles.formElement}> + <label className={styles.label}> + {intl.formatMessage(intlMessages.takeOwnershipLabel)} + </label> + </div> + </div> + <div className={styles.col}> + <div className={cx(styles.formElement, styles.pullContentRight)}> + <Checkbox + onChange={() => this.handleToggle('takeOwnership')} + checked={this.state.settings.takeOwnership} + ariaLabelledBy="takeOwnership" + ariaLabel={intl.formatMessage(intlMessages.takeOwnershipLabel)} + /> + </div> + </div> + </div> + ) + : null } <div className={cx(styles.row, styles.spacedLeft)}> <div className={styles.col}> <div className={styles.formElement}> <label className={styles.label}> - {intl.formatMessage(intlMessages.takeOwnershipLabel)} + {intl.formatMessage(intlMessages.languageLabel)} </label> </div> </div> <div className={styles.col}> - <div className={cx(styles.formElement, styles.pullContentRight)}> - <Checkbox - onChange={() => this.handleToggle('takeOwnership')} - checked={this.state.settings.takeOwnership} - ariaLabelledBy="takeOwnership" - ariaLabel={intl.formatMessage(intlMessages.takeOwnershipLabel)} - /> - </div> - </div> - </div> - : null } - <div className={cx(styles.row, styles.spacedLeft)}> - <div className={styles.col}> - <div className={styles.formElement}> - <label className={styles.label}> - {intl.formatMessage(intlMessages.languageLabel)} + <label + className={cx(styles.formElement, styles.pullContentRight)} + aria-label={intl.formatMessage(intlMessages.languageLabel)} + > + <select + defaultValue={locales ? locales.indexOf(this.state.settings.locale) : -1} + className={styles.select} + onChange={this.handleSelectChange.bind(this, 'locale', this.props.locales)} + > + <option> + { this.props.locales + && this.props.locales.length + ? intl.formatMessage(intlMessages.localeOptionLabel) + : intl.formatMessage(intlMessages.noLocaleOptionLabel) } + </option> + {this.props.locales ? this.props.locales.map((locale, index) => ( + <option key={index} value={index}> + {locale} + </option> + )) : null } + </select> </label> </div> </div> - <div className={styles.col}> - <label - className={cx(styles.formElement, styles.pullContentRight)} - aria-label={intl.formatMessage(intlMessages.languageLabel)} - > - <select - defaultValue={locales ? locales.indexOf(this.state.settings.locale) : -1} - className={styles.select} - onChange={this.handleSelectChange.bind(this, 'locale', this.props.locales)} - > - <option> - { this.props.locales && - this.props.locales.length ? - intl.formatMessage(intlMessages.localeOptionLabel) : - intl.formatMessage(intlMessages.noLocaleOptionLabel) } - </option> - {this.props.locales ? this.props.locales.map((locale, index) => - (<option key={index} value={index}> - {locale} - </option>)) : null } - </select> - </label> - </div> - </div> - <div className={cx(styles.row, styles.spacedLeft)}> - <div className={styles.col}> - <div className={styles.formElement}> - <label className={styles.label}> - {intl.formatMessage(intlMessages.fontFamilyLabel)} - </label> + <div className={cx(styles.row, styles.spacedLeft)}> + <div className={styles.col}> + <div className={styles.formElement}> + <label className={styles.label}> + {intl.formatMessage(intlMessages.fontFamilyLabel)} + </label> + </div> </div> - </div> - <div className={styles.col}> - <label - className={cx(styles.formElement, styles.pullContentRight)} - aria-label={intl.formatMessage(intlMessages.fontFamilyLabel)} - > - <select - defaultValue={FONT_FAMILIES.indexOf(this.state.settings.fontFamily)} - onChange={this.handleSelectChange.bind(this, 'fontFamily', FONT_FAMILIES)} - className={styles.select} + <div className={styles.col}> + <label + className={cx(styles.formElement, styles.pullContentRight)} + aria-label={intl.formatMessage(intlMessages.fontFamilyLabel)} > - <option value="-1" disabled> - {intl.formatMessage(intlMessages.fontFamilyOptionLabel)} - </option> - { - FONT_FAMILIES.map((family, index) => - (<option key={index} value={index}> + <select + defaultValue={FONT_FAMILIES.indexOf(this.state.settings.fontFamily)} + onChange={this.handleSelectChange.bind(this, 'fontFamily', FONT_FAMILIES)} + className={styles.select} + > + <option value="-1" disabled> + {intl.formatMessage(intlMessages.fontFamilyOptionLabel)} + </option> + { + FONT_FAMILIES.map((family, index) => ( + <option key={index} value={index}> {family} - </option>)) + </option> + )) } - </select> - </label> - </div> - </div> - - <div className={cx(styles.row, styles.spacedLeft)}> - <div className={styles.col}> - <div className={styles.formElement}> - <label className={styles.label}> - {intl.formatMessage(intlMessages.fontSizeLabel)} + </select> </label> </div> </div> - <div className={styles.col}> - <label - className={cx(styles.formElement, styles.pullContentRight)} - aria-label={intl.formatMessage(intlMessages.fontSizeLabel)} - > - <select - defaultValue={FONT_SIZES.indexOf(this.state.settings.fontSize)} - onChange={this.handleSelectChange.bind(this, 'fontSize', FONT_SIZES)} - className={styles.select} + + <div className={cx(styles.row, styles.spacedLeft)}> + <div className={styles.col}> + <div className={styles.formElement}> + <label className={styles.label}> + {intl.formatMessage(intlMessages.fontSizeLabel)} + </label> + </div> + </div> + <div className={styles.col}> + <label + className={cx(styles.formElement, styles.pullContentRight)} + aria-label={intl.formatMessage(intlMessages.fontSizeLabel)} > - <option value="-1" disabled> - {intl.formatMessage(intlMessages.fontSizeOptionLabel)} - </option> - { - FONT_SIZES.map((size, index) => - (<option key={index} value={index}> + <select + defaultValue={FONT_SIZES.indexOf(this.state.settings.fontSize)} + onChange={this.handleSelectChange.bind(this, 'fontSize', FONT_SIZES)} + className={styles.select} + > + <option value="-1" disabled> + {intl.formatMessage(intlMessages.fontSizeOptionLabel)} + </option> + { + FONT_SIZES.map((size, index) => ( + <option key={index} value={index}> {size} - </option>)) + </option> + )) } - </select> - </label> - </div> - </div> - - <div className={cx(styles.row, styles.spacedLeft)}> - <div className={styles.col}> - <div className={styles.formElement}> - <label className={styles.label}> - {intl.formatMessage(intlMessages.backgroundColorLabel)} + </select> </label> </div> </div> - <div className={styles.col}> - <div - className={cx(styles.formElement, styles.pullContentRight)} - aria-label={intl.formatMessage(intlMessages.backgroundColorLabel)} - > + + <div className={cx(styles.row, styles.spacedLeft)}> + <div className={styles.col}> + <div className={styles.formElement}> + <label className={styles.label}> + {intl.formatMessage(intlMessages.backgroundColorLabel)} + </label> + </div> + </div> + <div className={styles.col}> <div - tabIndex="0" - className={styles.swatch} - onClick={ - this.handleColorPickerClick.bind(this, 'displayBackgroundColorPicker') - } + className={cx(styles.formElement, styles.pullContentRight)} + aria-label={intl.formatMessage(intlMessages.backgroundColorLabel)} > <div - className={styles.swatchInner} - style={{ background: this.state.settings.backgroundColor }} - /> - </div> - { this.state.displayBackgroundColorPicker ? - <div className={styles.colorPickerPopover}> + tabIndex="0" + className={styles.swatch} + onClick={ + this.handleColorPickerClick.bind(this, 'displayBackgroundColorPicker') + } + > <div - className={styles.colorPickerOverlay} - onClick={this.handleCloseColorPicker.bind(this)} - /> - <GithubPicker - onChange={this.handleColorChange.bind(this, 'backgroundColor')} - color={this.state.settings.backgroundColor} - colors={COLORS} - width="140px" - triangle="top-right" + className={styles.swatchInner} + style={{ background: this.state.settings.backgroundColor }} /> </div> - : null } + { this.state.displayBackgroundColorPicker + ? ( + <div className={styles.colorPickerPopover}> + <div + className={styles.colorPickerOverlay} + onClick={this.handleCloseColorPicker.bind(this)} + /> + <GithubPicker + onChange={this.handleColorChange.bind(this, 'backgroundColor')} + color={this.state.settings.backgroundColor} + colors={COLORS} + width="140px" + triangle="top-right" + /> + </div> + ) + : null } + </div> </div> </div> - </div> - <div className={cx(styles.row, styles.spacedLeft)}> - <div className={styles.col}> - <div className={styles.formElement}> - <label className={styles.label}> - {intl.formatMessage(intlMessages.fontColorLabel)} - </label> + <div className={cx(styles.row, styles.spacedLeft)}> + <div className={styles.col}> + <div className={styles.formElement}> + <label className={styles.label}> + {intl.formatMessage(intlMessages.fontColorLabel)} + </label> + </div> </div> - </div> - <div className={styles.col}> - <div - className={cx(styles.formElement, styles.pullContentRight)} - aria-label={intl.formatMessage(intlMessages.fontColorLabel)} - > + <div className={styles.col}> <div - tabIndex="0" - className={styles.swatch} - onClick={this.handleColorPickerClick.bind(this, 'displayFontColorPicker')} + className={cx(styles.formElement, styles.pullContentRight)} + aria-label={intl.formatMessage(intlMessages.fontColorLabel)} > <div - className={styles.swatchInner} - style={{ background: this.state.settings.fontColor }} - /> - </div> - { this.state.displayFontColorPicker ? - <div className={styles.colorPickerPopover}> + tabIndex="0" + className={styles.swatch} + onClick={this.handleColorPickerClick.bind(this, 'displayFontColorPicker')} + > <div - className={styles.colorPickerOverlay} - onClick={this.handleCloseColorPicker.bind(this)} - /> - <GithubPicker - onChange={this.handleColorChange.bind(this, 'fontColor')} - color={this.state.settings.fontColor} - colors={COLORS} - width="140px" - triangle="top-right" + className={styles.swatchInner} + style={{ background: this.state.settings.fontColor }} /> </div> - : null } + { this.state.displayFontColorPicker + ? ( + <div className={styles.colorPickerPopover}> + <div + className={styles.colorPickerOverlay} + onClick={this.handleCloseColorPicker.bind(this)} + /> + <GithubPicker + onChange={this.handleColorChange.bind(this, 'fontColor')} + color={this.state.settings.fontColor} + colors={COLORS} + width="140px" + triangle="top-right" + /> + </div> + ) + : null } + </div> </div> </div> - </div> - <div - className={cx(styles.ccPreviewBox, styles.spacedLeft)} - role="presentation" - style={{ background: this.state.settings.backgroundColor }} - > - <span style={this.getPreviewStyle()}> + <div + className={cx(styles.ccPreviewBox, styles.spacedLeft)} + role="presentation" + style={{ background: this.state.settings.backgroundColor }} + > + <span style={this.getPreviewStyle()}> Etiam porta sem malesuada magna mollis euis-mod. Donec ullamcorper nulla non metus auctor fringilla. - </span> + </span> + </div> </div> - </div> - : null } + ) + : null } </div> </div> ); diff --git a/bigbluebutton-html5/imports/ui/components/settings/submenus/data-saving/component.jsx b/bigbluebutton-html5/imports/ui/components/settings/submenus/data-saving/component.jsx index ef1de1585e81a1c4921fcb5850c1a1f015fa4768..a7b1446c1eff566db4e20de8bf4c4aedd0ac414a 100644 --- a/bigbluebutton-html5/imports/ui/components/settings/submenus/data-saving/component.jsx +++ b/bigbluebutton-html5/imports/ui/components/settings/submenus/data-saving/component.jsx @@ -33,14 +33,15 @@ class DataSaving extends BaseMenu { settings: props.settings, }; } + render() { const { intl } = this.props; const { viewParticipantsWebcams, viewScreenshare } = this.state.settings; return ( - <div className={styles.tabContent}> - <div className={styles.header}> + <div> + <div> <h3 className={styles.title}>{intl.formatMessage(intlMessages.dataSavingLabel)}</h3> <p className={styles.subtitle}>{intl.formatMessage(intlMessages.dataSavingDesc)}</p> </div> diff --git a/bigbluebutton-html5/imports/ui/components/tooltip/component.jsx b/bigbluebutton-html5/imports/ui/components/tooltip/component.jsx index 2b20c0193d069e15624def5f95a2dec199fdc9e1..981fde80ad20205d98f4544069290d52f27acc68 100755 --- a/bigbluebutton-html5/imports/ui/components/tooltip/component.jsx +++ b/bigbluebutton-html5/imports/ui/components/tooltip/component.jsx @@ -18,12 +18,12 @@ const defaultProps = { }; class Tooltip extends Component { - static wait(show, event) { + static wait(tip, event) { const tooltipTarget = event.target; const expandedEl = tooltipTarget.parentElement.querySelector('[aria-expanded="true"]'); const isTarget = expandedEl === tooltipTarget; if (expandedEl && !isTarget) return; - show(); + tip.show(); } constructor(props) { @@ -34,17 +34,18 @@ class Tooltip extends Component { this.onHide = this.onHide.bind(this); this.handleEscapeHide = this.handleEscapeHide.bind(this); this.delay = [150, 50]; - this.dynamicTitle = true; } componentDidMount() { const { position, + title, } = this.props; const options = { - position, - dynamicTitle: this.dynamicTitle, + placement: position, + performance: true, + content: title, delay: this.delay, onShow: this.onShow, onHide: this.onHide, @@ -53,6 +54,7 @@ class Tooltip extends Component { }; this.tooltip = Tippy(`#${this.tippySelectorId}`, options); } + onShow() { document.addEventListener('keyup', this.handleEscapeHide); } diff --git a/bigbluebutton-html5/imports/ui/components/user-list/chat-list-item/chat-icon/component.jsx b/bigbluebutton-html5/imports/ui/components/user-list/chat-list-item/chat-icon/component.jsx index 0dc1867befbd1b47d59493a1106ca2472edabdb5..0fcfa8908cd6ac4eab4c3061ee2c670e786cc25e 100644 --- a/bigbluebutton-html5/imports/ui/components/user-list/chat-list-item/chat-icon/component.jsx +++ b/bigbluebutton-html5/imports/ui/components/user-list/chat-list-item/chat-icon/component.jsx @@ -12,7 +12,7 @@ const defaultProps = { const ChatIcon = props => ( <div className={styles.chatThumbnail}> - <Icon iconName={props.icon} className={styles.actionIcon} /> + <Icon iconName={props.icon} /> </div> ); diff --git a/bigbluebutton-html5/imports/ui/components/user-list/chat-list-item/component.jsx b/bigbluebutton-html5/imports/ui/components/user-list/chat-list-item/component.jsx index d2d272315a1d7c56007af1d77e5d9d08e3b09634..b4cb9c1a48c6d9404a01bd66c1d4cf2ae2b283e6 100644 --- a/bigbluebutton-html5/imports/ui/components/user-list/chat-list-item/component.jsx +++ b/bigbluebutton-html5/imports/ui/components/user-list/chat-list-item/component.jsx @@ -88,26 +88,31 @@ const ChatListItem = (props) => { <div className={styles.chatListItemLink}> <div className={styles.chatIcon}> - {chat.icon ? - <ChatIcon icon={chat.icon} /> - : - <ChatAvatar - isModerator={chat.isModerator} - color={chat.color} - name={chat.name.toLowerCase().slice(0, 2)} - />} + {chat.icon + ? <ChatIcon icon={chat.icon} /> + : ( + <ChatAvatar + isModerator={chat.isModerator} + color={chat.color} + name={chat.name.toLowerCase().slice(0, 2)} + /> + )} </div> <div className={styles.chatName}> - {!compact ? - <span className={styles.chatNameMain}> - {isPublicChat(chat) ? - intl.formatMessage(intlMessages.titlePublic) : chat.name} - </span> : null} + {!compact + ? ( + <span className={styles.chatNameMain}> + {isPublicChat(chat) + ? intl.formatMessage(intlMessages.titlePublic) : chat.name} + </span> + ) : null} </div> - {(chat.unreadCounter > 0) ? - <ChatUnreadCounter - counter={chat.unreadCounter} - /> + {(chat.unreadCounter > 0) + ? ( + <ChatUnreadCounter + counter={chat.unreadCounter} + /> + ) : null} </div> </div> diff --git a/bigbluebutton-html5/imports/ui/components/user-list/user-list-content/user-participants/user-list-item/user-dropdown/component.jsx b/bigbluebutton-html5/imports/ui/components/user-list/user-list-content/user-participants/user-list-item/user-dropdown/component.jsx index d7b40c50617cde2fb707e905ec26803015b42dbf..7fbcb87020aae5906e12d3eb94e1c2c1fcbc2032 100755 --- a/bigbluebutton-html5/imports/ui/components/user-list/user-list-content/user-participants/user-list-item/user-dropdown/component.jsx +++ b/bigbluebutton-html5/imports/ui/components/user-list/user-list-content/user-participants/user-list-item/user-dropdown/component.jsx @@ -13,8 +13,8 @@ import DropdownListSeparator from '/imports/ui/components/dropdown/list/separato import _ from 'lodash'; import { Session } from 'meteor/session'; import { styles } from './styles'; -import UserName from './../user-name/component'; -import UserIcons from './../user-icons/component'; +import UserName from '../user-name/component'; +import UserIcons from '../user-icons/component'; const messages = defineMessages({ presenter: { @@ -371,15 +371,13 @@ class UserDropdown extends PureComponent { dropdownVisible: true, }; - const isDropdownVisible = - UserDropdown.checkIfDropdownIsVisible( - dropdownContent.offsetTop, - dropdownContent.offsetHeight, - ); + const isDropdownVisible = UserDropdown.checkIfDropdownIsVisible( + dropdownContent.offsetTop, + dropdownContent.offsetHeight, + ); if (!isDropdownVisible) { - const offsetPageTop = - ((dropdownTrigger.offsetTop + dropdownTrigger.offsetHeight) - scrollContainer.scrollTop); + const offsetPageTop = ((dropdownTrigger.offsetTop + dropdownTrigger.offsetHeight) - scrollContainer.scrollTop); nextState.dropdownOffset = window.innerHeight - offsetPageTop; nextState.dropdownDirection = 'bottom'; @@ -409,9 +407,9 @@ class UserDropdown extends PureComponent { const { clientType } = user; const isVoiceOnly = clientType === 'dial-in-user'; - const iconUser = user.emoji.status !== 'none' ? - (<Icon iconName={normalizeEmojiName(user.emoji.status)} />) : - user.name.toLowerCase().slice(0, 2); + const iconUser = user.emoji.status !== 'none' + ? (<Icon iconName={normalizeEmojiName(user.emoji.status)} />) + : user.name.toLowerCase().slice(0, 2); const iconVoiceOnlyUser = (<Icon iconName="speak_louder" />); @@ -450,7 +448,6 @@ class UserDropdown extends PureComponent { const userItemContentsStyle = {}; - userItemContentsStyle[styles.userItemContentsCompact] = compact; userItemContentsStyle[styles.dropdown] = true; userItemContentsStyle[styles.userListItem] = !this.state.isActionsOpen; userItemContentsStyle[styles.usertListItemWithMenu] = this.state.isActionsOpen; @@ -473,7 +470,7 @@ class UserDropdown extends PureComponent { const contents = ( <div - data-test={user.isCurrent ? "userListItemCurrent" : null} + data-test={user.isCurrent ? 'userListItemCurrent' : null} className={!actions.length ? styles.userListItem : null} > <div className={styles.userItemContents}> diff --git a/bigbluebutton-html5/imports/ui/components/whiteboard/annotation-factory/component.jsx b/bigbluebutton-html5/imports/ui/components/whiteboard/annotation-factory/component.jsx index d41fc85bf98fde286c604a6b3059f98dbdf3bf73..a32564ac3d571eb1149ea1c55964a619058ac0c4 100755 --- a/bigbluebutton-html5/imports/ui/components/whiteboard/annotation-factory/component.jsx +++ b/bigbluebutton-html5/imports/ui/components/whiteboard/annotation-factory/component.jsx @@ -68,11 +68,12 @@ export default class AnnotationFactory extends Component { render() { const { annotationsInfo } = this.props; + return ( <g> - {annotationsInfo ? - annotationsInfo.map(annotationInfo => this.renderAnnotation(annotationInfo)) - : null } + {annotationsInfo + ? annotationsInfo.map(annotationInfo => this.renderAnnotation(annotationInfo)) + : null } </g> ); } diff --git a/bigbluebutton-html5/imports/ui/components/whiteboard/whiteboard-toolbar/component.jsx b/bigbluebutton-html5/imports/ui/components/whiteboard/whiteboard-toolbar/component.jsx index 2204712ff4110546679dec582008aca200fa9863..a34fca67d22aa53e10fac398ed5e1be7f75bbb10 100755 --- a/bigbluebutton-html5/imports/ui/components/whiteboard/whiteboard-toolbar/component.jsx +++ b/bigbluebutton-html5/imports/ui/components/whiteboard/whiteboard-toolbar/component.jsx @@ -213,8 +213,8 @@ class WhiteboardToolbar extends Component { } else if (this.state.thicknessSelected.value !== prevState.thicknessSelected.value) { this.thicknessListIconRadius.beginElement(); // 3rd case - } else if (this.state.annotationSelected.value !== 'text' && - prevState.annotationSelected.value === 'text') { + } else if (this.state.annotationSelected.value !== 'text' + && prevState.annotationSelected.value === 'text') { this.thicknessListIconRadius.beginElement(); this.thicknessListIconColor.beginElement(); } @@ -339,17 +339,19 @@ class WhiteboardToolbar extends Component { onBlur={this.closeSubMenu} className={cx(styles.toolbarButton, this.state.currentSubmenuOpen === 'annotationList' ? styles.toolbarActive : null)} > - {this.state.currentSubmenuOpen === 'annotationList' && annotations.length > 1 ? - <ToolbarSubmenu - type="annotations" - customIcon={false} - label="Annotations" - onItemClick={this.handleAnnotationChange} - objectsToRender={annotations} - objectSelected={this.state.annotationSelected} - handleMouseEnter={this.handleMouseEnter} - handleMouseLeave={this.handleMouseLeave} - /> + {this.state.currentSubmenuOpen === 'annotationList' && annotations.length > 1 + ? ( + <ToolbarSubmenu + type="annotations" + customIcon={false} + label="Annotations" + onItemClick={this.handleAnnotationChange} + objectsToRender={annotations} + objectSelected={this.state.annotationSelected} + handleMouseEnter={this.handleMouseEnter} + handleMouseLeave={this.handleMouseLeave} + /> + ) : null} </ToolbarMenuItem> ); @@ -367,17 +369,19 @@ class WhiteboardToolbar extends Component { onBlur={this.closeSubMenu} className={cx(styles.toolbarButton, this.state.currentSubmenuOpen === 'fontSizeList' ? styles.toolbarActive : null)} > - {this.state.currentSubmenuOpen === 'fontSizeList' ? - <ToolbarSubmenu - type="font-size" - customIcon - label="Font Size" - onItemClick={this.handleFontSizeChange} - objectsToRender={this.props.fontSizes} - objectSelected={this.state.fontSizeSelected} - handleMouseEnter={this.handleMouseEnter} - handleMouseLeave={this.handleMouseLeave} - /> + {this.state.currentSubmenuOpen === 'fontSizeList' + ? ( + <ToolbarSubmenu + type="font-size" + customIcon + label="Font Size" + onItemClick={this.handleFontSizeChange} + objectsToRender={this.props.fontSizes} + objectSelected={this.state.fontSizeSelected} + handleMouseEnter={this.handleMouseEnter} + handleMouseLeave={this.handleMouseLeave} + /> + ) : null} </ToolbarMenuItem> ); @@ -405,8 +409,8 @@ class WhiteboardToolbar extends Component { return ( <ToolbarMenuItem disabled={isDisabled} - label={isDisabled ? - intl.formatMessage(intlMessages.toolbarLineThicknessDisabled) + label={isDisabled + ? intl.formatMessage(intlMessages.toolbarLineThicknessDisabled) : intl.formatMessage(intlMessages.toolbarLineThickness)} onItemClick={this.displaySubMenu} objectToReturn="thicknessList" @@ -414,17 +418,19 @@ class WhiteboardToolbar extends Component { className={cx(styles.toolbarButton, this.state.currentSubmenuOpen === 'thicknessList' ? styles.toolbarActive : null)} customIcon={this.renderThicknessItemIcon()} > - {this.state.currentSubmenuOpen === 'thicknessList' ? - <ToolbarSubmenu - type="thickness" - customIcon - label="Thickness" - onItemClick={this.handleThicknessChange} - objectsToRender={this.props.thicknessRadiuses} - objectSelected={this.state.thicknessSelected} - handleMouseEnter={this.handleMouseEnter} - handleMouseLeave={this.handleMouseLeave} - /> + {this.state.currentSubmenuOpen === 'thicknessList' + ? ( + <ToolbarSubmenu + type="thickness" + customIcon + label="Thickness" + onItemClick={this.handleThicknessChange} + objectsToRender={this.props.thicknessRadiuses} + objectSelected={this.state.thicknessSelected} + handleMouseEnter={this.handleMouseEnter} + handleMouseLeave={this.handleMouseLeave} + /> + ) : null} </ToolbarMenuItem> ); @@ -485,8 +491,8 @@ class WhiteboardToolbar extends Component { return ( <ToolbarMenuItem disabled={isDisabled} - label={isDisabled ? - intl.formatMessage(intlMessages.toolbarLineColorDisabled) + label={isDisabled + ? intl.formatMessage(intlMessages.toolbarLineColorDisabled) : intl.formatMessage(intlMessages.toolbarLineColor)} onItemClick={this.displaySubMenu} objectToReturn="colorList" @@ -494,17 +500,19 @@ class WhiteboardToolbar extends Component { className={cx(styles.toolbarButton, this.state.currentSubmenuOpen === 'colorList' ? styles.toolbarActive : null)} customIcon={this.renderColorItemIcon()} > - {this.state.currentSubmenuOpen === 'colorList' ? - <ToolbarSubmenu - type="color" - customIcon - label="Color" - onItemClick={this.handleColorChange} - objectsToRender={this.props.colors} - objectSelected={this.state.colorSelected} - handleMouseEnter={this.handleMouseEnter} - handleMouseLeave={this.handleMouseLeave} - /> + {this.state.currentSubmenuOpen === 'colorList' + ? ( + <ToolbarSubmenu + type="color" + customIcon + label="Color" + onItemClick={this.handleColorChange} + objectsToRender={this.props.colors} + objectSelected={this.state.colorSelected} + handleMouseEnter={this.handleMouseEnter} + handleMouseLeave={this.handleMouseLeave} + /> + ) : null} </ToolbarMenuItem> ); @@ -551,7 +559,7 @@ class WhiteboardToolbar extends Component { label={intl.formatMessage(intlMessages.toolbarUndoAnnotation)} icon="undo" onItemClick={this.handleUndo} - className={cx(styles.toolbarButton, styles.notActive)} + className={styles.toolbarButton} /> ); } @@ -564,7 +572,7 @@ class WhiteboardToolbar extends Component { label={intl.formatMessage(intlMessages.toolbarClearAnnotations)} icon="delete" onItemClick={this.handleClearAll} - className={cx(styles.toolbarButton, styles.notActive)} + className={styles.toolbarButton} /> ); } @@ -574,13 +582,13 @@ class WhiteboardToolbar extends Component { return ( <ToolbarMenuItem - label={multiUser ? - intl.formatMessage(intlMessages.toolbarMultiUserOff) - : intl.formatMessage(intlMessages.toolbarMultiUserOn) + label={multiUser + ? intl.formatMessage(intlMessages.toolbarMultiUserOff) + : intl.formatMessage(intlMessages.toolbarMultiUserOn) } icon={multiUser ? 'multi_whiteboard' : 'whiteboard'} onItemClick={this.handleSwitchWhiteboardMode} - className={cx(styles.toolbarButton, styles.notActive)} + className={styles.toolbarButton} /> ); } diff --git a/bigbluebutton-html5/imports/ui/components/whiteboard/whiteboard-toolbar/toolbar-submenu/component.jsx b/bigbluebutton-html5/imports/ui/components/whiteboard/whiteboard-toolbar/toolbar-submenu/component.jsx index 138079f833cd5e57082d9f2f014a98c53480c88f..7639507a73d884e7e95024620bfc11cf42b21dce 100755 --- a/bigbluebutton-html5/imports/ui/components/whiteboard/whiteboard-toolbar/toolbar-submenu/component.jsx +++ b/bigbluebutton-html5/imports/ui/components/whiteboard/whiteboard-toolbar/toolbar-submenu/component.jsx @@ -93,13 +93,13 @@ class ToolbarSubmenu extends Component { <rect x="20%" y="20%" width="60%" height="60%" fill={obj.value} /> </svg> ); - } else if (type === 'thickness') { + } if (type === 'thickness') { return ( <svg className={styles.customSvgIcon}> <circle cx="50%" cy="50%" r={obj.value} /> </svg> ); - } else if (type === 'font-size') { + } if (type === 'font-size') { return ( <p className={styles.textThickness} style={{ fontSize: obj.value }}> Aa @@ -111,18 +111,19 @@ class ToolbarSubmenu extends Component { } static getWrapperClassNames(type) { - if (type === 'color') { - return cx(styles.colorList, styles.toolbarList); - } else if (type === 'thickness') { - return cx(styles.thicknessList, styles.toolbarList); - } else if (type === 'font-size') { + if (type === 'font-size') { return cx(styles.fontSizeList, styles.toolbarList); - } else if (type === 'annotations') { - return cx(styles.annotationList, styles.toolbarList); + } if ( + type === 'annotations' + || type === 'thickness' + || type === 'color' + ) { + return styles.toolbarList; } return null; } + constructor() { super(); @@ -183,21 +184,20 @@ class ToolbarSubmenu extends Component { onMouseLeave={this.handleMouseLeave} className={ToolbarSubmenu.getWrapperClassNames(type)} > - {objectsToRender ? objectsToRender.map(obj => - ( - <ToolbarSubmenuItem - label={this.formatSubmenuLabel(type, obj)} - icon={!customIcon ? obj.icon : null} - customIcon={customIcon ? ToolbarSubmenu.getCustomIcon(type, obj) : null} - onItemClick={this.onItemClick} - objectToReturn={obj} - className={cx( - styles.toolbarListButton, - objectSelected.value === obj.value ? styles.selectedListButton : '', - )} - key={obj.value} - /> - )) : null} + {objectsToRender ? objectsToRender.map(obj => ( + <ToolbarSubmenuItem + label={this.formatSubmenuLabel(type, obj)} + icon={!customIcon ? obj.icon : null} + customIcon={customIcon ? ToolbarSubmenu.getCustomIcon(type, obj) : null} + onItemClick={this.onItemClick} + objectToReturn={obj} + className={cx( + styles.toolbarListButton, + objectSelected.value === obj.value ? styles.selectedListButton : '', + )} + key={obj.value} + /> + )) : null} </div> ); } diff --git a/bigbluebutton-html5/package-lock.json b/bigbluebutton-html5/package-lock.json old mode 100755 new mode 100644 index e32ce747914cbd4229ef8411e6dc9d82817fe07c..e4aa799c43bf6918bfc857f04a61847a3a244218 --- a/bigbluebutton-html5/package-lock.json +++ b/bigbluebutton-html5/package-lock.json @@ -9625,4 +9625,4 @@ } } } -} \ No newline at end of file +} diff --git a/bigbluebutton-html5/package.json b/bigbluebutton-html5/package.json index 8fb7745030d0edf1325b79ef2223aebead2771b2..f7eb4818d2237c99053d8594516bb1a0be2eb0be 100755 --- a/bigbluebutton-html5/package.json +++ b/bigbluebutton-html5/package.json @@ -10,11 +10,9 @@ "start:prod": "meteor reset && ROOT_URL=http://127.0.0.1/html5client NODE_ENV=production meteor --production", "start:dev": "ROOT_URL=http://127.0.0.1/html5client NODE_ENV=development meteor", "test": "jest", - "lint": "eslint . --ext .jsx,.js", - "precommit": "lint-staged" + "lint": "eslint . --ext .jsx,.js" }, "lint-staged": { - "gitDir": "../", "linters": { "*.{js,jsx}": [ "eslint --fix", @@ -28,65 +26,68 @@ "but Meteor 1.6.0.1 doesn't see it there for some reason", "need to investigate" ], - "@browser-bunyan/server-stream": "^1.3.0", - "autoprefixer": "~7.1.6", + "@babel/runtime": "^7.2.0", + "@browser-bunyan/server-stream": "^1.5.0", + "autoprefixer": "~9.3.1", "babel-plugin-react-remove-properties": "~0.2.5", "babel-runtime": "~6.26.0", - "browser-bunyan": "^1.4.0", + "browser-bunyan": "^1.5.0", "browser-detect": "^0.2.28", "classnames": "^2.2.6", - "clipboard": "~1.7.1", - "core-js": "^2.5.7", - "eventemitter2": "~4.1.2", - "flat": "~4.0.0", - "history": "~3.3.0", - "immutability-helper": "~2.4.0", + "clipboard": "^2.0.4", + "core-js": "^2.6.0", + "eventemitter2": "~5.0.1", + "fibers": "^3.1.1", + "flat": "~4.1.0", + "history": "~4.7.2", + "immutability-helper": "~2.8.1", "langmap": "0.0.16", - "lodash": "~4.17.10", + "lodash": "^4.17.11", "makeup-screenreader-trap": "0.0.5", - "meteor-node-stubs": "^0.3.3", - "node-sass": "^4.9.3", - "postcss-nested": "2.1.2", - "probe-image-size": "~3.1.0", + "meteor-node-stubs": "^0.4.1", + "node-sass": "^4.10.0", + "postcss-nested": "4.1.0", + "probe-image-size": "~4.0.0", "prop-types": "^15.6.2", - "re-resizable": "^4.8.1", - "react": "~16.0.0", - "react-autosize-textarea": "~0.4.9", + "re-resizable": "^4.10.0", + "react": "^16.6.3", + "react-autosize-textarea": "^5.0.1", "react-color": "~2.14.1", - "react-dom": "^16.0.1", - "react-dropzone": "^4.2.13", - "react-intl": "~2.4.0", - "react-modal": "~3.0.4", + "react-dom": "^16.6.3", + "react-dropzone": "^7.0.1", + "react-intl": "~2.7.2", + "react-modal": "~3.6.1", "react-render-in-browser": "^1.0.0", - "react-tabs": "~2.1.0", - "react-toastify": "~2.1.2", + "react-tabs": "~2.3.0", + "react-toastify": "^4.4.3", "react-toggle": "~4.0.2", - "react-transition-group": "~2.2.1", - "reconnecting-websocket": "~v3.2.2", + "react-transition-group": "~2.5.0", + "reconnecting-websocket": "~v4.1.10", "redis": "~2.8.0", "string-hash": "~1.1.3", - "tippy.js": "~2.0.2", - "winston": "^2.4.4", - "yaml": "^1.0.0" + "tippy.js": "^3.1.3", + "winston": "^3.1.0", + "yaml": "^1.0.3" }, "devDependencies": { - "axios": "^0.18.0", - "dotenv": "^6.1.0", - "eslint": "~4.9.0", - "eslint-config-airbnb": "~16.1.0", - "eslint-config-airbnb-base": "~12.1.0", - "eslint-plugin-import": "~2.8.0", - "eslint-plugin-jsx-a11y": "~6.0.2", - "eslint-plugin-react": "~7.4.0", - "husky": "~0.14.3", - "jest": "^23.6.0", - "lint-staged": "~4.3.0", - "postcss-modules-extract-imports": "1.1.0", + "chai": "~4.2.0", + "eslint": "~5.8.0", + "eslint-config-airbnb": "~17.1.0", + "eslint-config-airbnb-base": "~13.1.0", + "eslint-plugin-import": "~2.14.0", + "eslint-plugin-jsx-a11y": "~6.1.2", + "eslint-plugin-react": "~7.11.1", + "husky": "^1.1.4", + "lint-staged": "^8.0.5", + "postcss-modules-extract-imports": "2.0.0", "postcss-modules-local-by-default": "1.2.0", "postcss-modules-scope": "1.1.0", "postcss-modules-values": "1.3.0", - "puppeteer": "^1.10.0", - "sha1": "^1.1.1" + "wdio-junit-reporter": "~0.4.4", + "wdio-spec-reporter": "^0.1.5", + "wdio-visual-regression-service": "~0.9.0", + "webdriver-manager": "~12.1.0", + "webdriverio": "^4.14.1" }, "cssModules": { "cssClassNamingConvention": { @@ -103,13 +104,13 @@ "autoprefixer": {} } }, - "jest": { - "modulePathIgnorePatterns": [ - "/tests/webdriverio" - ] - }, "repository": { "type": "git", "url": "https://github.com/bigbluebutton/bigbluebutton.git" + }, + "husky": { + "hooks": { + "pre-commit": "lint-staged" + } } } diff --git a/bigbluebutton-html5/tests/puppeteer/chat/clear.js b/bigbluebutton-html5/tests/puppeteer/chat/clear.js index 3f24e44d3def71b83026e8cde0753ad64af80f73..9d2a633b15fe64429aa9c8fc1261bc94fc49f800 100644 --- a/bigbluebutton-html5/tests/puppeteer/chat/clear.js +++ b/bigbluebutton-html5/tests/puppeteer/chat/clear.js @@ -28,9 +28,8 @@ class Clear extends Page { // [] const after = await util.getTestElements(this); - const response = - before[0].message == e.message && - after.length == 0; + const response = before[0].message == e.message + && after.length == 0; return response; } diff --git a/bigbluebutton-html5/tests/puppeteer/chat/send.js b/bigbluebutton-html5/tests/puppeteer/chat/send.js index 2cddc25ea8f572fa260d96289650bb7d429fb249..d77f85f6b4f410157f3f0769d84bbebdf9be27bc 100644 --- a/bigbluebutton-html5/tests/puppeteer/chat/send.js +++ b/bigbluebutton-html5/tests/puppeteer/chat/send.js @@ -24,9 +24,8 @@ class Send extends Page { // [{ "name": "User1\nXX:XX XM", "message": "Hello world!" }] const chat1 = await util.getTestElements(this); - const response = - chat0.length == 0 && - chat1[0].message == e.message; + const response = chat0.length == 0 + && chat1[0].message == e.message; return response; } diff --git a/bigbluebutton-html5/tests/puppeteer/chat/util.js b/bigbluebutton-html5/tests/puppeteer/chat/util.js index bb47d4b7fcc97e927ead894c63fd8a225b289e72..de47f6a8438892f7552519f7f7ba60fb096dc605 100644 --- a/bigbluebutton-html5/tests/puppeteer/chat/util.js +++ b/bigbluebutton-html5/tests/puppeteer/chat/util.js @@ -4,7 +4,7 @@ const ce = require('../core/elements'); async function openChat(test) { // TODO: Check this if it's open before click await test.click(ce.userList); - await test.click(e.chatButton,true); + await test.click(e.chatButton, true); await test.waitForSelector(e.chatBox); await test.waitForSelector(e.chatMessages); } diff --git a/bigbluebutton-html5/tests/puppeteer/core/helper.js b/bigbluebutton-html5/tests/puppeteer/core/helper.js index 74863cbbfa811c6329b5de674eb2da9c7306b674..27a73e76a152faa8191ef90e702b2a762f2e6c8a 100644 --- a/bigbluebutton-html5/tests/puppeteer/core/helper.js +++ b/bigbluebutton-html5/tests/puppeteer/core/helper.js @@ -19,8 +19,8 @@ async function createMeeting(params) { const meetingID = `random-${getRandomInt(1000000, 10000000).toString()}`; const mp = params.moderatorPW; const ap = params.attendeePW; - const query = `name=${meetingID}&meetingID=${meetingID}&attendeePW=${ap}&moderatorPW=${mp}&joinViaHtml5=true` + - `&record=false&allowStartStopRecording=true&autoStartRecording=false&welcome=${params.welcome}`; + const query = `name=${meetingID}&meetingID=${meetingID}&attendeePW=${ap}&moderatorPW=${mp}&joinViaHtml5=true` + + `&record=false&allowStartStopRecording=true&autoStartRecording=false&welcome=${params.welcome}`; const apicall = `create${query}${params.secret}`; const checksum = sha1(apicall); const url = `${params.server}/create?${query}&checksum=${checksum}`; diff --git a/bigbluebutton-html5/tests/puppeteer/core/page.js b/bigbluebutton-html5/tests/puppeteer/core/page.js index 33de54762bbb8c9167e68b829bfabd56ef8137cb..8c1b15c922c627132e7457ec57c33bcea50d8e54 100644 --- a/bigbluebutton-html5/tests/puppeteer/core/page.js +++ b/bigbluebutton-html5/tests/puppeteer/core/page.js @@ -12,7 +12,7 @@ class Page { } getParentDir(dir) { - let tmp = dir.split('/'); + const tmp = dir.split('/'); tmp.pop(); return tmp.join('/'); } @@ -22,7 +22,7 @@ class Page { this.browser = await puppeteer.launch(args); this.page = await this.browser.newPage(); - await this.setDownloadBehavior(this.parentDir + '/downloads'); + await this.setDownloadBehavior(`${this.parentDir}/downloads`); this.meetingId = await helper.createMeeting(params); const joinURL = helper.getJoinURL(this.meetingId, params, true); @@ -33,7 +33,7 @@ class Page { } async setDownloadBehavior(downloadPath) { - const downloadBehavior = { behavior: 'allow', downloadPath: downloadPath }; + const downloadBehavior = { behavior: 'allow', downloadPath }; await this.page._client.send('Page.setDownloadBehavior', downloadBehavior); } @@ -113,9 +113,9 @@ class Page { async screenshot(relief = false) { if (relief) await helper.sleep(1000); - const filename = this.name + '-' + this.screenshotIndex + '.png'; - const path = this.parentDir + '/screenshots/' + filename; - await this.page.screenshot({ path: path }); + const filename = `${this.name}-${this.screenshotIndex}.png`; + const path = `${this.parentDir}/screenshots/${filename}`; + await this.page.screenshot({ path }); this.screenshotIndex++; } diff --git a/bigbluebutton-html5/tests/puppeteer/presentation/slide.js b/bigbluebutton-html5/tests/puppeteer/presentation/slide.js index be7a758e67277cfd9db9a488b7dab126cdc83ecd..1d6ebd9824d25d139a9fe583e489f1e3a9c68d07 100644 --- a/bigbluebutton-html5/tests/puppeteer/presentation/slide.js +++ b/bigbluebutton-html5/tests/puppeteer/presentation/slide.js @@ -32,7 +32,7 @@ class Slide extends Page { console.log(svg2); // TODO: Check test - return true + return true; } async getTestElements() { diff --git a/bigbluebutton-html5/tests/puppeteer/presentation/upload.js b/bigbluebutton-html5/tests/puppeteer/presentation/upload.js index 8df006e2d6f615f0224e6a87fe4192621623caba..b7b6da600c17029eb2634be11b12fe0ad7ea2725 100644 --- a/bigbluebutton-html5/tests/puppeteer/presentation/upload.js +++ b/bigbluebutton-html5/tests/puppeteer/presentation/upload.js @@ -23,7 +23,7 @@ class Upload extends Page { await this.click(e.start); console.log('\nWaiting for the new presentation to upload...'); - //await this.elementRemoved(e.start); + // await this.elementRemoved(e.start); await this.page.waitFor(10000); console.log('\nPresentation uploaded!'); @@ -38,7 +38,7 @@ class Upload extends Page { console.log(slides1.svg); // TODO: Check test - return true + return true; } async getTestElements() { diff --git a/bigbluebutton-html5/tests/puppeteer/whiteboard/draw.js b/bigbluebutton-html5/tests/puppeteer/whiteboard/draw.js index d1f33932dbbd5326d76f765756a6831e7e628e3b..53609625bc222f4b2d8417cea70b40009e40a144 100644 --- a/bigbluebutton-html5/tests/puppeteer/whiteboard/draw.js +++ b/bigbluebutton-html5/tests/puppeteer/whiteboard/draw.js @@ -29,7 +29,7 @@ class Draw extends Page { console.log(shapes1); // TODO: Check test - return true + return true; } async getTestElements() {