Merge pull request #6346 from KDSBrowne/html5-packages-upgrade

HTML5 packages upgrade
This commit is contained in:
Anton Georgiev 2018-12-13 14:43:47 -05:00 committed by GitHub
commit d80d78589f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
45 changed files with 636 additions and 615 deletions

View File

@ -15,3 +15,4 @@ notices-for-facebook-graph-api-2
1.4.1-add-shell-server-package 1.4.1-add-shell-server-package
1.4.3-split-account-service-packages 1.4.3-split-account-service-packages
1.5-add-dynamic-import-package 1.5-add-dynamic-import-package
1.7-split-underscore-from-meteor-base

View File

@ -3,24 +3,28 @@
# 'meteor add' and 'meteor remove' will edit this file for you, # 'meteor add' and 'meteor remove' will edit this file for you,
# but you can also edit it by hand. # but you can also edit it by hand.
standard-app-packages@1.0.9 meteor-base
arunoda:npm@0.2.6 mobile-experience
amplify mongo
blaze@2.1.8 reactive-var
francocatena:status
mizzao:timesync standard-minifier-css
clinical:nightwatch standard-minifier-js
cfs:power-queue es5-shim
cfs:reactive-list ecmascript
cfs:micro-queue shell-server
reactive-var@1.0.11
ecmascript@0.9.0 static-html
react-meteor-data react-meteor-data
standard-minifier-css@1.3.5 http
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
session session
tracker
check
jquery
nathantreid:css-modules@=3.1.4
rocketchat:streamer
cfs:power-queue
cfs:micro-queue
cfs:reactive-list
stevezhu:lodash

View File

@ -1 +1 @@
METEOR@1.6.0.1 METEOR@1.8.0.1

View File

@ -1,94 +1,82 @@
aldeed:simple-schema@1.5.3
allow-deny@1.1.0 allow-deny@1.1.0
amplify@1.0.0 autoupdate@1.5.0
arunoda:npm@0.2.6 babel-compiler@7.2.3
autoupdate@1.3.12 babel-runtime@1.3.0
babel-compiler@6.24.7 base64@1.0.11
babel-runtime@1.1.1 binary-heap@1.0.11
base64@1.0.10
binary-heap@1.0.10
blaze@2.3.2
blaze-tools@1.0.10 blaze-tools@1.0.10
boilerplate-generator@1.3.1 boilerplate-generator@1.6.0
caching-compiler@1.1.9 caching-compiler@1.2.1
caching-html-compiler@1.1.2 caching-html-compiler@1.1.3
callback-hook@1.0.10 callback-hook@1.1.0
cfs:http-methods@0.0.32
cfs:micro-queue@0.0.6 cfs:micro-queue@0.0.6
cfs:power-queue@0.9.11 cfs:power-queue@0.9.11
cfs:reactive-list@0.0.9 cfs:reactive-list@0.0.9
cfs:reactive-property@0.0.4 cfs:reactive-property@0.0.4
check@1.2.5 check@1.3.1
clinical:nightwatch@2.0.1
coffeescript@1.12.7_3
coffeescript-compiler@1.12.7_3
ddp@1.4.0 ddp@1.4.0
ddp-client@2.2.0 ddp-client@2.3.3
ddp-common@1.3.0 ddp-common@1.4.0
ddp-server@2.1.1 ddp-server@2.2.0
deps@1.0.12 deps@1.0.12
diff-sequence@1.0.7 diff-sequence@1.1.1
dynamic-import@0.2.1 dynamic-import@0.5.0
ecmascript@0.9.0 ecmascript@0.12.3
ecmascript-runtime@0.5.0 ecmascript-runtime@0.7.0
ecmascript-runtime-client@0.5.0 ecmascript-runtime-client@0.8.0
ecmascript-runtime-server@0.5.0 ecmascript-runtime-server@0.7.1
ejson@1.1.0 ejson@1.1.0
fastclick@1.0.13 es5-shim@4.8.0
francocatena:status@1.5.3 fetch@0.1.0
geojson-utils@1.0.10 geojson-utils@1.0.10
hot-code-push@1.0.4
html-tools@1.0.11 html-tools@1.0.11
htmljs@1.0.11 htmljs@1.0.11
http@1.3.0 http@1.4.2
id-map@1.0.9 id-map@1.1.0
jquery@1.11.10 inter-process-messaging@0.1.0
jquery@1.11.11
launch-screen@1.1.1 launch-screen@1.1.1
livedata@1.0.18 livedata@1.0.18
logging@1.1.19 logging@1.1.20
mdg:validation-error@0.5.1 meteor@1.9.2
meteor@1.8.2 meteor-base@1.4.0
meteor-platform@1.2.6 minifier-css@1.4.1
meteorspark:util@0.2.0 minifier-js@2.4.0
minifier-css@1.2.16 minimongo@1.4.5
minifier-js@2.2.2 mobile-experience@1.0.5
minimongo@1.4.3
mizzao:timesync@0.5.0
mobile-status-bar@1.0.14 mobile-status-bar@1.0.14
modules@0.11.2 modern-browsers@0.1.3
modules-runtime@0.9.1 modules@0.13.0
mongo@1.3.1 modules-runtime@0.10.3
mongo@1.6.0
mongo-decimal@0.1.0
mongo-dev-server@1.1.0 mongo-dev-server@1.1.0
mongo-id@1.0.6 mongo-id@1.0.7
nathantreid:css-modules@2.8.0 nathantreid:css-modules@3.1.4
npm-mongo@2.2.33 npm-mongo@3.1.1
observe-sequence@1.0.16 ordered-dict@1.1.0
ordered-dict@1.0.9 promise@0.11.1
promise@0.10.0 random@1.1.0
raix:eventemitter@0.1.3 react-meteor-data@0.2.16
random@1.0.10 reactive-dict@1.2.1
react-meteor-data@0.2.15
reactive-dict@1.2.0
reactive-var@1.0.11 reactive-var@1.0.11
reload@1.1.11 reload@1.2.0
retry@1.0.9 retry@1.1.0
rocketchat:streamer@0.6.2 rocketchat:streamer@1.0.1
routepolicy@1.0.12 routepolicy@1.1.0
session@1.1.7 session@1.2.0
shell-server@0.3.1 shell-server@0.4.0
spacebars@1.0.15 socket-stream-client@0.2.2
spacebars-compiler@1.1.3 spacebars-compiler@1.1.3
standard-app-packages@1.0.9 standard-minifier-css@1.5.2
standard-minifier-css@1.3.5 standard-minifier-js@2.4.0
standard-minifier-js@2.2.3 static-html@1.2.2
tap:i18n@1.8.2 stevezhu:lodash@4.17.2
templating@1.3.2
templating-compiler@1.3.3
templating-runtime@1.3.2
templating-tools@1.1.2 templating-tools@1.1.2
tmeasday:check-npm-versions@0.3.1 tmeasday:check-npm-versions@0.3.2
tracker@1.1.3 tracker@1.2.0
ui@1.0.13
underscore@1.0.10 underscore@1.0.10
url@1.1.0 url@1.2.0
webapp@1.4.0 webapp@1.7.1
webapp-hashing@1.0.9 webapp-hashing@1.0.9

View File

@ -131,8 +131,7 @@ const BaseContainer = withTracker(() => {
}, },
}; };
const subscriptionsHandlers = SUBSCRIPTIONS_NAME.map(name => const subscriptionsHandlers = SUBSCRIPTIONS_NAME.map(name => Meteor.subscribe(name, credentials, subscriptionErrorHandler));
Meteor.subscribe(name, credentials, subscriptionErrorHandler));
const chats = GroupChat.find({ const chats = GroupChat.find({
$or: [ $or: [

View File

@ -27,6 +27,7 @@ class IntlStartup extends Component {
this.fetchLocalizedMessages = this.fetchLocalizedMessages.bind(this); this.fetchLocalizedMessages = this.fetchLocalizedMessages.bind(this);
} }
componentWillMount() { componentWillMount() {
this.fetchLocalizedMessages(this.props.locale); this.fetchLocalizedMessages(this.props.locale);
} }
@ -69,7 +70,7 @@ class IntlStartup extends Component {
render() { render() {
return this.state.fetching ? <LoadingScreen /> : ( 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} {this.props.children}
</IntlProvider> </IntlProvider>
); );

View File

@ -1,19 +1,12 @@
import { Meteor } from 'meteor/meteor'; import { Meteor } from 'meteor/meteor';
import Winston from 'winston'; import { createLogger, format, transports } from 'winston';
const Logger = new Winston.Logger(); const Logger = createLogger({
format: format.combine(
Logger.configure({ format.colorize({ level: true }),
levels: { format.splat(),
error: 0, warn: 1, info: 2, verbose: 3, debug: 4, format.simple(),
}, ),
colors: {
error: 'red',
warn: 'yellow',
info: 'green',
verbose: 'cyan',
debug: 'magenta',
},
}); });
Meteor.startup(() => { Meteor.startup(() => {
@ -21,7 +14,7 @@ Meteor.startup(() => {
const { level } = LOG_CONFIG; const { level } = LOG_CONFIG;
// console logging // console logging
Logger.add(Winston.transports.Console, { Logger.add(new transports.Console(), {
prettyPrint: false, prettyPrint: false,
humanReadableUnhandledException: true, humanReadableUnhandledException: true,
colorize: true, colorize: true,

View File

@ -1,3 +1,4 @@
import _ from 'lodash';
import React, { Component } from 'react'; import React, { Component } from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import { defineMessages, injectIntl, intlShape } from 'react-intl'; import { defineMessages, injectIntl, intlShape } from 'react-intl';
@ -91,8 +92,8 @@ class ActionsDropdown extends Component {
} }
componentDidMount() { componentDidMount() {
if (Meteor.settings.public.allowOutsideCommands.toggleRecording || if (Meteor.settings.public.allowOutsideCommands.toggleRecording
getFromUserSettings('outsideToggleRecording', false)) { || getFromUserSettings('outsideToggleRecording', false)) {
ActionBarService.connectRecordingObserver(); ActionBarService.connectRecordingObserver();
window.addEventListener('message', ActionBarService.processOutsideToggleRecording); window.addEventListener('message', ActionBarService.processOutsideToggleRecording);
} }
@ -121,44 +122,52 @@ class ActionsDropdown extends Component {
} = this.props; } = this.props;
return _.compact([ return _.compact([
(isUserPresenter ? (isUserPresenter
<DropdownListItem ? (
icon="user" <DropdownListItem
label={intl.formatMessage(intlMessages.pollBtnLabel)} icon="user"
description={intl.formatMessage(intlMessages.pollBtnDesc)} label={intl.formatMessage(intlMessages.pollBtnLabel)}
key={this.pollId} description={intl.formatMessage(intlMessages.pollBtnDesc)}
onClick={() => togglePollMenu()} key={this.pollId}
/> onClick={() => togglePollMenu()}
/>
)
: null), : null),
(isUserPresenter ? (isUserPresenter
<DropdownListItem ? (
data-test="uploadPresentation" <DropdownListItem
icon="presentation" data-test="uploadPresentation"
label={intl.formatMessage(intlMessages.presentationLabel)} icon="presentation"
description={intl.formatMessage(intlMessages.presentationDesc)} label={intl.formatMessage(intlMessages.presentationLabel)}
key={this.presentationItemId} description={intl.formatMessage(intlMessages.presentationDesc)}
onClick={this.handlePresentationClick} key={this.presentationItemId}
/> onClick={this.handlePresentationClick}
/>
)
: null), : null),
(record && isUserModerator && allowStartStopRecording ? (record && isUserModerator && allowStartStopRecording
<DropdownListItem ? (
icon="record" <DropdownListItem
label={intl.formatMessage(isRecording ? icon="record"
intlMessages.stopRecording : intlMessages.startRecording)} label={intl.formatMessage(isRecording
description={intl.formatMessage(isRecording ? ? intlMessages.stopRecording : intlMessages.startRecording)}
intlMessages.stopRecording : intlMessages.startRecording)} description={intl.formatMessage(isRecording
key={this.recordId} ? intlMessages.stopRecording : intlMessages.startRecording)}
onClick={toggleRecording} key={this.recordId}
/> onClick={toggleRecording}
/>
)
: null), : null),
(isUserModerator && !meetingIsBreakout && !hasBreakoutRoom ? (isUserModerator && !meetingIsBreakout && !hasBreakoutRoom
<DropdownListItem ? (
icon="rooms" <DropdownListItem
label={intl.formatMessage(intlMessages.createBreakoutRoom)} icon="rooms"
description={intl.formatMessage(intlMessages.createBreakoutRoomDesc)} label={intl.formatMessage(intlMessages.createBreakoutRoom)}
key={this.createBreakoutRoomId} description={intl.formatMessage(intlMessages.createBreakoutRoomDesc)}
onClick={this.handleCreateBreakoutRoomClick} key={this.createBreakoutRoomId}
/> onClick={this.handleCreateBreakoutRoomClick}
/>
)
: null), : null),
]); ]);
} }
@ -166,6 +175,7 @@ class ActionsDropdown extends Component {
handlePresentationClick() { handlePresentationClick() {
this.props.mountModal(<PresentationUploaderContainer />); this.props.mountModal(<PresentationUploaderContainer />);
} }
handleCreateBreakoutRoomClick() { handleCreateBreakoutRoomClick() {
const { const {
createBreakoutRoom, createBreakoutRoom,
@ -195,7 +205,7 @@ class ActionsDropdown extends Component {
if ((!isUserPresenter && !isUserModerator) || availableActions.length === 0) return null; if ((!isUserPresenter && !isUserModerator) || availableActions.length === 0) return null;
return ( return (
<Dropdown ref={(ref) => { this._dropdown = ref; }} > <Dropdown ref={(ref) => { this._dropdown = ref; }}>
<DropdownTrigger tabIndex={0} accessKey={OPEN_ACTIONS_AK}> <DropdownTrigger tabIndex={0} accessKey={OPEN_ACTIONS_AK}>
<Button <Button
hideLabel hideLabel

View File

@ -228,7 +228,6 @@ class App extends Component {
minWidth={USERLIST_MIN_WIDTH_PX} minWidth={USERLIST_MIN_WIDTH_PX}
maxWidth={USERLIST_MAX_WIDTH_PX} maxWidth={USERLIST_MAX_WIDTH_PX}
ref={(node) => { this.resizableUserList = node; }} ref={(node) => { this.resizableUserList = node; }}
className={styles.resizableUserList}
enable={resizableEnableOptions} enable={resizableEnableOptions}
onResize={(e, direction, ref) => { onResize={(e, direction, ref) => {
const { compactUserList } = this.state; const { compactUserList } = this.state;
@ -284,7 +283,6 @@ class App extends Component {
minWidth={CHAT_MIN_WIDTH} minWidth={CHAT_MIN_WIDTH}
maxWidth={CHAT_MAX_WIDTH} maxWidth={CHAT_MAX_WIDTH}
ref={(node) => { this.resizableChat = node; }} ref={(node) => { this.resizableChat = node; }}
className={styles.resizableChat}
enable={resizableEnableOptions} enable={resizableEnableOptions}
> >
{this.renderChat()} {this.renderChat()}

View File

@ -35,22 +35,21 @@ const processToggleMuteFromOutside = (e) => {
} }
}; };
export default withModalMounter(withTracker(({ mountModal }) => export default withModalMounter(withTracker(({ mountModal }) => ({
({ processToggleMuteFromOutside: arg => processToggleMuteFromOutside(arg),
processToggleMuteFromOutside: arg => processToggleMuteFromOutside(arg), mute: Service.isConnected() && !Service.isListenOnly() && !Service.isEchoTest(),
mute: Service.isConnected() && !Service.isListenOnly() && !Service.isEchoTest(), unmute: Service.isConnected() && !Service.isListenOnly() && Service.isMuted(),
unmute: Service.isConnected() && !Service.isListenOnly() && Service.isMuted(), join: Service.isConnected() && !Service.isEchoTest(),
join: Service.isConnected() && !Service.isEchoTest(), disable: Service.isConnecting() || Service.isHangingUp(),
disable: Service.isConnecting() || Service.isHangingUp(), glow: Service.isTalking() && !Service.isMuted(),
glow: Service.isTalking() && !Service.isMuted(), handleToggleMuteMicrophone: () => Service.toggleMuteMicrophone(),
handleToggleMuteMicrophone: () => Service.toggleMuteMicrophone(), handleJoinAudio: () => {
handleJoinAudio: () => { const meeting = Meetings.findOne({ meetingId: Auth.meetingID });
const meeting = Meetings.findOne({ meetingId: Auth.meetingID }); const currentUser = Users.findOne({ userId: Auth.userID });
const currentUser = Users.findOne({ userId: Auth.userID }); const currentUserIsLocked = mapUser(currentUser).isLocked;
const currentUserIsLocked = mapUser(currentUser).isLocked; const micsLocked = (currentUserIsLocked && meeting.lockSettingsProp.disableMic);
const micsLocked = (currentUserIsLocked && meeting.lockSettingsProp.disableMic);
return micsLocked ? Service.joinListenOnly() : mountModal(<AudioModalContainer />); return micsLocked ? Service.joinListenOnly() : mountModal(<AudioModalContainer />);
}, },
handleLeaveAudio: () => Service.exitAudio(), handleLeaveAudio: () => Service.exitAudio(),
}))(AudioControlsContainer)); }))(AudioControlsContainer));

View File

@ -11,6 +11,7 @@ class AuthenticatedHandler extends Component {
Session.set('hasError', true); Session.set('hasError', true);
if (codeError) Session.set('codeError', codeError); if (codeError) Session.set('codeError', codeError);
} }
static shouldAuthenticate(status, lastStatus) { static shouldAuthenticate(status, lastStatus) {
return lastStatus != null && lastStatus === STATUS_CONNECTING && status.connected; return lastStatus != null && lastStatus === STATUS_CONNECTING && status.connected;
} }
@ -31,6 +32,7 @@ class AuthenticatedHandler extends Component {
} }
}); });
} }
static async authenticatedRouteHandler(callback) { static async authenticatedRouteHandler(callback) {
if (Auth.loggedIn) { if (Auth.loggedIn) {
callback(); callback();
@ -51,6 +53,7 @@ class AuthenticatedHandler extends Component {
setReason(error); setReason(error);
} }
} }
constructor(props) { constructor(props) {
super(props); super(props);
this.changeState = this.changeState.bind(this); this.changeState = this.changeState.bind(this);

View File

@ -91,11 +91,9 @@ export default class Button extends BaseButton {
const { const {
size, size,
color, color,
disabled,
ghost, ghost,
circle, circle,
block, block,
iconRight,
} = this.props; } = this.props;
const propClassNames = {}; const propClassNames = {};
@ -106,8 +104,6 @@ export default class Button extends BaseButton {
propClassNames[styles.ghost] = ghost; propClassNames[styles.ghost] = ghost;
propClassNames[styles.circle] = circle; propClassNames[styles.circle] = circle;
propClassNames[styles.block] = block; propClassNames[styles.block] = block;
propClassNames[styles.iconRight] = iconRight;
propClassNames[styles.disabled] = disabled;
return propClassNames; return propClassNames;
} }
@ -207,7 +203,7 @@ export default class Button extends BaseButton {
if (iconName) { if (iconName) {
return (<Icon className={styles.icon} iconName={iconName} />); return (<Icon className={styles.icon} iconName={iconName} />);
} else if (customIcon) { } if (customIcon) {
return customIcon; return customIcon;
} }

View File

@ -11,7 +11,7 @@ import DropdownListItem from '/imports/ui/components/dropdown/list/item/componen
import Auth from '/imports/ui/services/auth'; import Auth from '/imports/ui/services/auth';
import Button from '/imports/ui/components/button/component'; import Button from '/imports/ui/components/button/component';
import ChatService from './../service'; import ChatService from '../service';
import { styles } from './styles'; import { styles } from './styles';
const intlMessages = defineMessages({ const intlMessages = defineMessages({

View File

@ -89,9 +89,9 @@ class MessageList extends Component {
// Compare with <1 to account for the chance scrollArea.scrollTop is a float // Compare with <1 to account for the chance scrollArea.scrollTop is a float
// value in some browsers. // value in some browsers.
this.shouldScrollBottom = position === scrollArea.scrollHeight || this.shouldScrollBottom = position === scrollArea.scrollHeight
(scrollArea.scrollHeight - position < 1) || || (scrollArea.scrollHeight - position < 1)
nextProps.scrollPosition === null; || nextProps.scrollPosition === null;
} }
componentDidUpdate(prevProps) { componentDidUpdate(prevProps) {
@ -183,7 +183,6 @@ class MessageList extends Component {
{messages.map(message => ( {messages.map(message => (
<MessageListItem <MessageListItem
handleReadMessage={handleReadMessage} handleReadMessage={handleReadMessage}
className={styles.messageListItem}
key={message.id} key={message.id}
messages={message.content} messages={message.content}
user={message.sender} user={message.sender}

View File

@ -47,7 +47,7 @@ export default class Checkbox extends Component {
return ( return (
<div className={cx({ <div className={cx({
[styles.disabled]: !!disabled, [styles.disabled]: !!disabled,
}, styles.container, className)} }, className)}
> >
<input <input
type="checkbox" type="checkbox"
@ -59,9 +59,9 @@ export default class Checkbox extends Component {
disabled={disabled} disabled={disabled}
/> />
<div role="presentation" onClick={this.handleChange}> <div role="presentation" onClick={this.handleChange}>
{ checked ? { checked
<Icon iconName="check" className={cx(styles.icon, styles.checked)} /> : ? <Icon iconName="check" className={cx(styles.icon, styles.checked)} />
<Icon iconName="circle" className={styles.icon} /> : <Icon iconName="circle" className={styles.icon} />
} }
</div> </div>
<div id={ariaLabelledBy} hidden>{ariaLabel}</div> <div id={ariaLabelledBy} hidden>{ariaLabel}</div>

View File

@ -1,6 +1,7 @@
import Captions from '/imports/api/captions'; import Captions from '/imports/api/captions';
import Auth from '/imports/ui/services/auth'; import Auth from '/imports/ui/services/auth';
import Settings from '/imports/ui/services/settings'; import Settings from '/imports/ui/services/settings';
import _ from 'lodash';
const getCCData = () => { const getCCData = () => {
const meetingID = Auth.meetingID; const meetingID = Auth.meetingID;

View File

@ -55,16 +55,16 @@ class ErrorScreen extends React.PureComponent {
return ( return (
<div className={styles.background}> <div className={styles.background}>
<h1 className={styles.code}> <h1>
{code} {code}
</h1> </h1>
<h1 className={styles.message}> <h1 className={styles.message}>
{formatedMessage} {formatedMessage}
</h1> </h1>
<div className={styles.content}> <div>
{children} {children}
</div> </div>
<div className={styles.content}> <div>
<Button <Button
size="sm" size="sm"
onClick={logoutRouteHandler} onClick={logoutRouteHandler}

View File

@ -13,6 +13,7 @@ class JoinHandler extends Component {
Session.set('hasError', true); Session.set('hasError', true);
if (codeError) Session.set('codeError', codeError); if (codeError) Session.set('codeError', codeError);
} }
constructor(props) { constructor(props) {
super(props); super(props);
this.fetchToken = this.fetchToken.bind(this); this.fetchToken = this.fetchToken.bind(this);
@ -120,9 +121,9 @@ class JoinHandler extends Component {
render() { render() {
const { children } = this.props; const { children } = this.props;
const { joined } = this.state; const { joined } = this.state;
return joined ? return joined
children : ? children
(<LoadingScreen />); : (<LoadingScreen />);
} }
} }

View File

@ -6,7 +6,7 @@ const LoadingScreen = ({ children }) => (
<div className={styles.spinner}> <div className={styles.spinner}>
<div className={styles.bounce1} /> <div className={styles.bounce1} />
<div className={styles.bounce2} /> <div className={styles.bounce2} />
<div className={styles.bounce3} /> <div />
</div> </div>
<div className={styles.message}> <div className={styles.message}>
{children} {children}

View File

@ -29,7 +29,6 @@ export default class Media extends Component {
const contentClassName = cx({ const contentClassName = cx({
[styles.content]: true, [styles.content]: true,
[styles.hasOverlay]: !hideOverlay,
}); });
const overlayClassName = cx({ const overlayClassName = cx({

View File

@ -59,14 +59,12 @@ const defaultProps = {
shortcuts: '', shortcuts: '',
}; };
const openBreakoutJoinConfirmation = (breakout, breakoutName, mountModal) => const openBreakoutJoinConfirmation = (breakout, breakoutName, mountModal) => mountModal(<BreakoutJoinConfirmation
mountModal(<BreakoutJoinConfirmation breakout={breakout}
breakout={breakout} breakoutName={breakoutName}
breakoutName={breakoutName} />);
/>);
const closeBreakoutJoinConfirmation = mountModal => const closeBreakoutJoinConfirmation = mountModal => mountModal(null);
mountModal(null);
class NavBar extends PureComponent { class NavBar extends PureComponent {
constructor(props) { constructor(props) {
@ -145,7 +143,9 @@ class NavBar extends PureComponent {
<Dropdown isOpen={this.state.isActionsOpen}> <Dropdown isOpen={this.state.isActionsOpen}>
<DropdownTrigger> <DropdownTrigger>
<h1 className={cx(styles.presentationTitle, styles.dropdownBreakout)}> <h1 className={cx(styles.presentationTitle, styles.dropdownBreakout)}>
{presentationTitle} <Icon iconName="down-arrow" /> {presentationTitle}
{' '}
<Icon iconName="down-arrow" />
</h1> </h1>
</DropdownTrigger> </DropdownTrigger>
<DropdownContent <DropdownContent
@ -168,7 +168,6 @@ class NavBar extends PureComponent {
return ( return (
<DropdownListItem <DropdownListItem
className={styles.actionsHeader}
key={_.uniqueId('action-header')} key={_.uniqueId('action-header')}
label={breakoutName} label={breakoutName}
onClick={openBreakoutJoinConfirmation.bind(this, breakout, breakoutName, mountModal)} onClick={openBreakoutJoinConfirmation.bind(this, breakout, breakoutName, mountModal)}
@ -213,9 +212,9 @@ class NavBar extends PureComponent {
</div> </div>
<div className={styles.center}> <div className={styles.center}>
{this.renderPresentationTitle()} {this.renderPresentationTitle()}
{beingRecorded.record ? {beingRecorded.record
<span className={styles.presentationTitleSeparator}>|</span> ? <span className={styles.presentationTitleSeparator}>|</span>
: null} : null}
<RecordingIndicator <RecordingIndicator
{...beingRecorded} {...beingRecorded}
title={intl.formatMessage(intlMessages[recordingMessage])} title={intl.formatMessage(intlMessages[recordingMessage])}

View File

@ -1,6 +1,5 @@
import React, { PureComponent } from 'react'; import React, { PureComponent } from 'react';
import { defineMessages, injectIntl } from 'react-intl'; import { defineMessages, injectIntl } from 'react-intl';
import cx from 'classnames';
import _ from 'lodash'; import _ from 'lodash';
import { withModalMounter } from '/imports/ui/components/modal/service'; import { withModalMounter } from '/imports/ui/components/modal/service';
import LogoutConfirmationContainer from '/imports/ui/components/logout-confirmation/container'; import LogoutConfirmationContainer from '/imports/ui/components/logout-confirmation/container';
@ -191,13 +190,15 @@ class SettingsDropdown extends PureComponent {
alterMenu(props) { alterMenu(props) {
const { fullscreenLabel, fullscreenDesc, fullscreenIcon } = this.checkFullscreen(props); const { fullscreenLabel, fullscreenDesc, fullscreenIcon } = this.checkFullscreen(props);
const newFullScreenButton = (<DropdownListItem const newFullScreenButton = (
key={_.uniqueId('list-item-')} <DropdownListItem
icon={fullscreenIcon} key={_.uniqueId('list-item-')}
label={fullscreenLabel} icon={fullscreenIcon}
description={fullscreenDesc} label={fullscreenLabel}
onClick={this.props.handleToggleFullscreen} description={fullscreenDesc}
/>); onClick={this.props.handleToggleFullscreen}
/>
);
this.menuItems = this.menuItems.slice(1); this.menuItems = this.menuItems.slice(1);
this.menuItems.unshift(newFullScreenButton); this.menuItems.unshift(newFullScreenButton);
} }
@ -222,7 +223,7 @@ class SettingsDropdown extends PureComponent {
ghost ghost
circle circle
hideLabel hideLabel
className={cx(styles.btn, styles.btnSettings)} className={styles.btn}
// FIXME: Without onClick react proptypes keep warning // FIXME: Without onClick react proptypes keep warning
// even after the DropdownTrigger inject an onClick handler // even after the DropdownTrigger inject an onClick handler

View File

@ -135,6 +135,7 @@ export default class PresentationArea extends Component {
height: adjustedHeight, height: adjustedHeight,
}; };
} }
zoomChanger(zoom) { zoomChanger(zoom) {
let newZoom = zoom; let newZoom = zoom;
const isDifferent = newZoom !== this.state.zoom; const isDifferent = newZoom !== this.state.zoom;
@ -146,6 +147,7 @@ export default class PresentationArea extends Component {
} }
if (isDifferent) this.setState({ zoom: newZoom }); if (isDifferent) this.setState({ zoom: newZoom });
} }
pointUpdate(pointX, pointY) { pointUpdate(pointX, pointY) {
this.setState({ this.setState({
delta: { delta: {
@ -154,11 +156,13 @@ export default class PresentationArea extends Component {
}, },
}); });
} }
touchUpdate(bool) { touchUpdate(bool) {
this.setState({ this.setState({
touchZoom: bool, touchZoom: bool,
}); });
} }
fitToWidthHandler() { fitToWidthHandler() {
this.setState({ this.setState({
fitToWidth: !this.state.fitToWidth, fitToWidth: !this.state.fitToWidth,
@ -168,8 +172,8 @@ export default class PresentationArea extends Component {
// renders the whole presentation area // renders the whole presentation area
renderPresentationArea() { renderPresentationArea() {
// sometimes tomcat publishes the slide url, but the actual file is not accessible (why?) // sometimes tomcat publishes the slide url, but the actual file is not accessible (why?)
if (!this.props.currentSlide || if (!this.props.currentSlide
!this.props.currentSlide.calculatedData) { || !this.props.currentSlide.calculatedData) {
return null; return null;
} }
// to control the size of the svg wrapper manually // to control the size of the svg wrapper manually
@ -328,8 +332,8 @@ export default class PresentationArea extends Component {
} }
renderWhiteboardToolbar() { renderWhiteboardToolbar() {
if (!this.props.currentSlide || if (!this.props.currentSlide
!this.props.currentSlide.calculatedData) { || !this.props.currentSlide.calculatedData) {
return null; return null;
} }
@ -353,11 +357,11 @@ export default class PresentationArea extends Component {
ref={(ref) => { this.refWhiteboardArea = ref; }} ref={(ref) => { this.refWhiteboardArea = ref; }}
className={styles.whiteboardSizeAvailable} className={styles.whiteboardSizeAvailable}
/> />
{this.state.showSlide ? {this.state.showSlide
this.renderPresentationArea() ? this.renderPresentationArea()
: null } : null }
{this.props.userIsPresenter || this.props.multiUser ? {this.props.userIsPresenter || this.props.multiUser
this.renderWhiteboardToolbar() ? this.renderWhiteboardToolbar()
: null } : null }
</div> </div>
{this.renderPresentationToolbar()} {this.renderPresentationToolbar()}

View File

@ -80,7 +80,7 @@ class HoldDownButton extends Component {
render() { render() {
const { const {
key, uniqueKey,
className, className,
children, children,
} = this.props; } = this.props;
@ -88,7 +88,7 @@ class HoldDownButton extends Component {
return ( return (
<span <span
role="button" role="button"
key={key} key={uniqueKey}
onClick={this.onClick} onClick={this.onClick}
onMouseDown={this.mouseDownHandler} onMouseDown={this.mouseDownHandler}
onMouseUp={this.mouseUpHandler} onMouseUp={this.mouseUpHandler}
@ -107,12 +107,12 @@ const defaultProps = {
exec: () => {}, exec: () => {},
minBound: null, minBound: null,
maxBound: Infinity, maxBound: Infinity,
key: _.uniqueId('holdButton-'), uniqueKey: _.uniqueId('holdButton-'),
value: 0, value: 0,
}; };
const propTypes = { const propTypes = {
key: PropTypes.string, uniqueKey: PropTypes.string,
exec: PropTypes.func.isRequired, exec: PropTypes.func.isRequired,
minBound: PropTypes.number, minBound: PropTypes.number,
maxBound: PropTypes.number, maxBound: PropTypes.number,

View File

@ -145,12 +145,11 @@ class PresentationUploader extends Component {
return fileIndex === -1 ? false : { return fileIndex === -1 ? false : {
presentations: update(presentations, { presentations: update(presentations, {
[fileIndex]: { [fileIndex]: {
$apply: file => $apply: file => update(file, {
update(file, { [key]: {
[key]: { [operation]: value,
[operation]: value, },
}, }),
}),
}, },
}), }),
}; };
@ -383,8 +382,7 @@ class PresentationUploader extends Component {
}); });
} }
const conversionStatusMessage = const conversionStatusMessage = intlMessages[item.conversion.status] || intlMessages.genericConversionStatus;
intlMessages[item.conversion.status] || intlMessages.genericConversionStatus;
return intl.formatMessage(conversionStatusMessage); return intl.formatMessage(conversionStatusMessage);
} }
@ -419,13 +417,15 @@ class PresentationUploader extends Component {
<Icon iconName="file" /> <Icon iconName="file" />
</td> </td>
{ {
isActualCurrent ? isActualCurrent
<th className={styles.tableItemCurrent}> ? (
<span className={styles.currentLabel}> <th className={styles.tableItemCurrent}>
{this.props.intl.formatMessage(intlMessages.current)} <span className={styles.currentLabel}>
</span> {this.props.intl.formatMessage(intlMessages.current)}
</th> </span>
: null </th>
)
: null
} }
<th className={styles.tableItemName} colSpan={!isActualCurrent ? 2 : 0}> <th className={styles.tableItemName} colSpan={!isActualCurrent ? 2 : 0}>
<span>{item.filename}</span> <span>{item.filename}</span>
@ -479,12 +479,13 @@ class PresentationUploader extends Component {
accept={fileValidMimeTypes.join()} accept={fileValidMimeTypes.join()}
minSize={fileSizeMin} minSize={fileSizeMin}
maxSize={fileSizeMax} maxSize={fileSizeMax}
disablePreview disablepreview="true"
onDrop={this.handleFiledrop} onDrop={this.handleFiledrop}
> >
<Icon className={styles.dropzoneIcon} iconName="upload" /> <Icon className={styles.dropzoneIcon} iconName="upload" />
<p className={styles.dropzoneMessage}> <p className={styles.dropzoneMessage}>
{intl.formatMessage(intlMessages.dropzoneLabel)}&nbsp; {intl.formatMessage(intlMessages.dropzoneLabel)}
&nbsp;
<span className={styles.dropzoneLink}> <span className={styles.dropzoneLink}>
{intl.formatMessage(intlMessages.browseFilesLabel)} {intl.formatMessage(intlMessages.browseFilesLabel)}
</span> </span>

View File

@ -122,8 +122,8 @@ class ApplicationMenu extends BaseMenu {
const { isLargestFontSize, isSmallestFontSize } = this.state; const { isLargestFontSize, isSmallestFontSize } = this.state;
return ( return (
<div className={styles.tabContent}> <div>
<div className={styles.header}> <div>
<h3 className={styles.title}> <h3 className={styles.title}>
{intl.formatMessage(intlMessages.applicationSectionTitle)} {intl.formatMessage(intlMessages.applicationSectionTitle)}
</h3> </h3>

View File

@ -1,11 +1,11 @@
import React from 'react'; import React from 'react';
import { styles } from '../styles';
import cx from 'classnames'; import cx from 'classnames';
import BaseMenu from '../base/component';
import Toggle from '/imports/ui/components/switch/component'; import Toggle from '/imports/ui/components/switch/component';
import Checkbox from '/imports/ui/components/checkbox/component'; import Checkbox from '/imports/ui/components/checkbox/component';
import { GithubPicker } from 'react-color'; import { GithubPicker } from 'react-color';
import { defineMessages, injectIntl } from 'react-intl'; import { defineMessages, injectIntl } from 'react-intl';
import BaseMenu from '../base/component';
import { styles } from '../styles';
// an array of font-families // an array of font-families
const FONT_FAMILIES = ['Arial', 'Calibri', 'Time New Roman', 'Sans-serif']; const FONT_FAMILIES = ['Arial', 'Calibri', 'Time New Roman', 'Sans-serif'];
@ -131,8 +131,8 @@ class ClosedCaptionsMenu extends BaseMenu {
} = this.props; } = this.props;
return ( return (
<div className={styles.tabContent}> <div>
<div className={styles.header}> <div>
<h3 className={styles.title}>{intl.formatMessage(intlMessages.closedCaptionsLabel)}</h3> <h3 className={styles.title}>{intl.formatMessage(intlMessages.closedCaptionsLabel)}</h3>
</div> </div>
<div className={styles.form}> <div className={styles.form}>
@ -145,7 +145,7 @@ class ClosedCaptionsMenu extends BaseMenu {
</div> </div>
</div> </div>
<div className={styles.col}> <div className={styles.col}>
<div className={cx(styles.formElement, styles.pullContentRight)} > <div className={cx(styles.formElement, styles.pullContentRight)}>
<Toggle <Toggle
icons={false} icons={false}
defaultChecked={this.state.settings.enabled} defaultChecked={this.state.settings.enabled}
@ -156,223 +156,234 @@ class ClosedCaptionsMenu extends BaseMenu {
</div> </div>
</div> </div>
</div> </div>
{ this.state.settings.enabled ? { this.state.settings.enabled
<div> ? (
{ isModerator ? <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={cx(styles.row, styles.spacedLeft)}>
<div className={styles.col}> <div className={styles.col}>
<div className={styles.formElement}> <div className={styles.formElement}>
<label className={styles.label}> <label className={styles.label}>
{intl.formatMessage(intlMessages.takeOwnershipLabel)} {intl.formatMessage(intlMessages.languageLabel)}
</label> </label>
</div> </div>
</div> </div>
<div className={styles.col}> <div className={styles.col}>
<div className={cx(styles.formElement, styles.pullContentRight)}> <label
<Checkbox className={cx(styles.formElement, styles.pullContentRight)}
onChange={() => this.handleToggle('takeOwnership')} aria-label={intl.formatMessage(intlMessages.languageLabel)}
checked={this.state.settings.takeOwnership} >
ariaLabelledBy="takeOwnership" <select
ariaLabel={intl.formatMessage(intlMessages.takeOwnershipLabel)} 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> </div>
</div> </div>
</div> <div className={styles.col}>
: null } <label
<div className={cx(styles.row, styles.spacedLeft)}> className={cx(styles.formElement, styles.pullContentRight)}
<div className={styles.col}> aria-label={intl.formatMessage(intlMessages.fontFamilyLabel)}
<div className={styles.formElement}>
<label className={styles.label}>
{intl.formatMessage(intlMessages.languageLabel)}
</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> <select
{ this.props.locales && defaultValue={FONT_FAMILIES.indexOf(this.state.settings.fontFamily)}
this.props.locales.length ? onChange={this.handleSelectChange.bind(this, 'fontFamily', FONT_FAMILIES)}
intl.formatMessage(intlMessages.localeOptionLabel) : className={styles.select}
intl.formatMessage(intlMessages.noLocaleOptionLabel) } >
</option> <option value="-1" disabled>
{this.props.locales ? this.props.locales.map((locale, index) => {intl.formatMessage(intlMessages.fontFamilyOptionLabel)}
(<option key={index} value={index}> </option>
{locale} {
</option>)) : null } FONT_FAMILIES.map((family, index) => (
</select> <option key={index} value={index}>
</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>
</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}
>
<option value="-1" disabled>
{intl.formatMessage(intlMessages.fontFamilyOptionLabel)}
</option>
{
FONT_FAMILIES.map((family, index) =>
(<option key={index} value={index}>
{family} {family}
</option>)) </option>
))
} }
</select> </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)}
</label> </label>
</div> </div>
</div> </div>
<div className={styles.col}>
<label <div className={cx(styles.row, styles.spacedLeft)}>
className={cx(styles.formElement, styles.pullContentRight)} <div className={styles.col}>
aria-label={intl.formatMessage(intlMessages.fontSizeLabel)} <div className={styles.formElement}>
> <label className={styles.label}>
<select {intl.formatMessage(intlMessages.fontSizeLabel)}
defaultValue={FONT_SIZES.indexOf(this.state.settings.fontSize)} </label>
onChange={this.handleSelectChange.bind(this, 'fontSize', FONT_SIZES)} </div>
className={styles.select} </div>
<div className={styles.col}>
<label
className={cx(styles.formElement, styles.pullContentRight)}
aria-label={intl.formatMessage(intlMessages.fontSizeLabel)}
> >
<option value="-1" disabled> <select
{intl.formatMessage(intlMessages.fontSizeOptionLabel)} defaultValue={FONT_SIZES.indexOf(this.state.settings.fontSize)}
</option> onChange={this.handleSelectChange.bind(this, 'fontSize', FONT_SIZES)}
{ className={styles.select}
FONT_SIZES.map((size, index) => >
(<option key={index} value={index}> <option value="-1" disabled>
{intl.formatMessage(intlMessages.fontSizeOptionLabel)}
</option>
{
FONT_SIZES.map((size, index) => (
<option key={index} value={index}>
{size} {size}
</option>)) </option>
))
} }
</select> </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)}
</label> </label>
</div> </div>
</div> </div>
<div className={styles.col}>
<div <div className={cx(styles.row, styles.spacedLeft)}>
className={cx(styles.formElement, styles.pullContentRight)} <div className={styles.col}>
aria-label={intl.formatMessage(intlMessages.backgroundColorLabel)} <div className={styles.formElement}>
> <label className={styles.label}>
{intl.formatMessage(intlMessages.backgroundColorLabel)}
</label>
</div>
</div>
<div className={styles.col}>
<div <div
tabIndex="0" className={cx(styles.formElement, styles.pullContentRight)}
className={styles.swatch} aria-label={intl.formatMessage(intlMessages.backgroundColorLabel)}
onClick={ >
<div
tabIndex="0"
className={styles.swatch}
onClick={
this.handleColorPickerClick.bind(this, 'displayBackgroundColorPicker') this.handleColorPickerClick.bind(this, 'displayBackgroundColorPicker')
} }
> >
<div
className={styles.swatchInner}
style={{ background: this.state.settings.backgroundColor }}
/>
</div>
{ this.state.displayBackgroundColorPicker ?
<div className={styles.colorPickerPopover}>
<div <div
className={styles.colorPickerOverlay} className={styles.swatchInner}
onClick={this.handleCloseColorPicker.bind(this)} style={{ background: this.state.settings.backgroundColor }}
/>
<GithubPicker
onChange={this.handleColorChange.bind(this, 'backgroundColor')}
color={this.state.settings.backgroundColor}
colors={COLORS}
width="140px"
triangle="top-right"
/> />
</div> </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>
</div>
<div className={cx(styles.row, styles.spacedLeft)}> <div className={cx(styles.row, styles.spacedLeft)}>
<div className={styles.col}> <div className={styles.col}>
<div className={styles.formElement}> <div className={styles.formElement}>
<label className={styles.label}> <label className={styles.label}>
{intl.formatMessage(intlMessages.fontColorLabel)} {intl.formatMessage(intlMessages.fontColorLabel)}
</label> </label>
</div>
</div> </div>
</div> <div className={styles.col}>
<div className={styles.col}>
<div
className={cx(styles.formElement, styles.pullContentRight)}
aria-label={intl.formatMessage(intlMessages.fontColorLabel)}
>
<div <div
tabIndex="0" className={cx(styles.formElement, styles.pullContentRight)}
className={styles.swatch} aria-label={intl.formatMessage(intlMessages.fontColorLabel)}
onClick={this.handleColorPickerClick.bind(this, 'displayFontColorPicker')}
> >
<div <div
className={styles.swatchInner} tabIndex="0"
style={{ background: this.state.settings.fontColor }} className={styles.swatch}
/> onClick={this.handleColorPickerClick.bind(this, 'displayFontColorPicker')}
</div> >
{ this.state.displayFontColorPicker ?
<div className={styles.colorPickerPopover}>
<div <div
className={styles.colorPickerOverlay} className={styles.swatchInner}
onClick={this.handleCloseColorPicker.bind(this)} style={{ background: this.state.settings.fontColor }}
/>
<GithubPicker
onChange={this.handleColorChange.bind(this, 'fontColor')}
color={this.state.settings.fontColor}
colors={COLORS}
width="140px"
triangle="top-right"
/> />
</div> </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>
</div> <div
<div className={cx(styles.ccPreviewBox, styles.spacedLeft)}
className={cx(styles.ccPreviewBox, styles.spacedLeft)} role="presentation"
role="presentation" style={{ background: this.state.settings.backgroundColor }}
style={{ background: this.state.settings.backgroundColor }} >
> <span style={this.getPreviewStyle()}>
<span style={this.getPreviewStyle()}>
Etiam porta sem malesuada magna mollis euis-mod. Etiam porta sem malesuada magna mollis euis-mod.
Donec ullamcorper nulla non metus auctor fringilla. Donec ullamcorper nulla non metus auctor fringilla.
</span> </span>
</div>
</div> </div>
</div> )
: null } : null }
</div> </div>
</div> </div>
); );

View File

@ -33,14 +33,15 @@ class DataSaving extends BaseMenu {
settings: props.settings, settings: props.settings,
}; };
} }
render() { render() {
const { intl } = this.props; const { intl } = this.props;
const { viewParticipantsWebcams, viewScreenshare } = this.state.settings; const { viewParticipantsWebcams, viewScreenshare } = this.state.settings;
return ( return (
<div className={styles.tabContent}> <div>
<div className={styles.header}> <div>
<h3 className={styles.title}>{intl.formatMessage(intlMessages.dataSavingLabel)}</h3> <h3 className={styles.title}>{intl.formatMessage(intlMessages.dataSavingLabel)}</h3>
<p className={styles.subtitle}>{intl.formatMessage(intlMessages.dataSavingDesc)}</p> <p className={styles.subtitle}>{intl.formatMessage(intlMessages.dataSavingDesc)}</p>
</div> </div>

View File

@ -18,12 +18,12 @@ const defaultProps = {
}; };
class Tooltip extends Component { class Tooltip extends Component {
static wait(show, event) { static wait(tip, event) {
const tooltipTarget = event.target; const tooltipTarget = event.target;
const expandedEl = tooltipTarget.parentElement.querySelector('[aria-expanded="true"]'); const expandedEl = tooltipTarget.parentElement.querySelector('[aria-expanded="true"]');
const isTarget = expandedEl === tooltipTarget; const isTarget = expandedEl === tooltipTarget;
if (expandedEl && !isTarget) return; if (expandedEl && !isTarget) return;
show(); tip.show();
} }
constructor(props) { constructor(props) {
@ -34,17 +34,18 @@ class Tooltip extends Component {
this.onHide = this.onHide.bind(this); this.onHide = this.onHide.bind(this);
this.handleEscapeHide = this.handleEscapeHide.bind(this); this.handleEscapeHide = this.handleEscapeHide.bind(this);
this.delay = [150, 50]; this.delay = [150, 50];
this.dynamicTitle = true;
} }
componentDidMount() { componentDidMount() {
const { const {
position, position,
title,
} = this.props; } = this.props;
const options = { const options = {
position, placement: position,
dynamicTitle: this.dynamicTitle, performance: true,
content: title,
delay: this.delay, delay: this.delay,
onShow: this.onShow, onShow: this.onShow,
onHide: this.onHide, onHide: this.onHide,
@ -53,6 +54,7 @@ class Tooltip extends Component {
}; };
this.tooltip = Tippy(`#${this.tippySelectorId}`, options); this.tooltip = Tippy(`#${this.tippySelectorId}`, options);
} }
onShow() { onShow() {
document.addEventListener('keyup', this.handleEscapeHide); document.addEventListener('keyup', this.handleEscapeHide);
} }

View File

@ -12,7 +12,7 @@ const defaultProps = {
const ChatIcon = props => ( const ChatIcon = props => (
<div className={styles.chatThumbnail}> <div className={styles.chatThumbnail}>
<Icon iconName={props.icon} className={styles.actionIcon} /> <Icon iconName={props.icon} />
</div> </div>
); );

View File

@ -88,26 +88,31 @@ const ChatListItem = (props) => {
<div className={styles.chatListItemLink}> <div className={styles.chatListItemLink}>
<div className={styles.chatIcon}> <div className={styles.chatIcon}>
{chat.icon ? {chat.icon
<ChatIcon icon={chat.icon} /> ? <ChatIcon icon={chat.icon} />
: : (
<ChatAvatar <ChatAvatar
isModerator={chat.isModerator} isModerator={chat.isModerator}
color={chat.color} color={chat.color}
name={chat.name.toLowerCase().slice(0, 2)} name={chat.name.toLowerCase().slice(0, 2)}
/>} />
)}
</div> </div>
<div className={styles.chatName}> <div className={styles.chatName}>
{!compact ? {!compact
<span className={styles.chatNameMain}> ? (
{isPublicChat(chat) ? <span className={styles.chatNameMain}>
intl.formatMessage(intlMessages.titlePublic) : chat.name} {isPublicChat(chat)
</span> : null} ? intl.formatMessage(intlMessages.titlePublic) : chat.name}
</span>
) : null}
</div> </div>
{(chat.unreadCounter > 0) ? {(chat.unreadCounter > 0)
<ChatUnreadCounter ? (
counter={chat.unreadCounter} <ChatUnreadCounter
/> counter={chat.unreadCounter}
/>
)
: null} : null}
</div> </div>
</div> </div>

View File

@ -13,8 +13,8 @@ import DropdownListSeparator from '/imports/ui/components/dropdown/list/separato
import _ from 'lodash'; import _ from 'lodash';
import { Session } from 'meteor/session'; import { Session } from 'meteor/session';
import { styles } from './styles'; import { styles } from './styles';
import UserName from './../user-name/component'; import UserName from '../user-name/component';
import UserIcons from './../user-icons/component'; import UserIcons from '../user-icons/component';
const messages = defineMessages({ const messages = defineMessages({
presenter: { presenter: {
@ -371,15 +371,13 @@ class UserDropdown extends PureComponent {
dropdownVisible: true, dropdownVisible: true,
}; };
const isDropdownVisible = const isDropdownVisible = UserDropdown.checkIfDropdownIsVisible(
UserDropdown.checkIfDropdownIsVisible( dropdownContent.offsetTop,
dropdownContent.offsetTop, dropdownContent.offsetHeight,
dropdownContent.offsetHeight, );
);
if (!isDropdownVisible) { if (!isDropdownVisible) {
const offsetPageTop = const offsetPageTop = ((dropdownTrigger.offsetTop + dropdownTrigger.offsetHeight) - scrollContainer.scrollTop);
((dropdownTrigger.offsetTop + dropdownTrigger.offsetHeight) - scrollContainer.scrollTop);
nextState.dropdownOffset = window.innerHeight - offsetPageTop; nextState.dropdownOffset = window.innerHeight - offsetPageTop;
nextState.dropdownDirection = 'bottom'; nextState.dropdownDirection = 'bottom';
@ -409,9 +407,9 @@ class UserDropdown extends PureComponent {
const { clientType } = user; const { clientType } = user;
const isVoiceOnly = clientType === 'dial-in-user'; const isVoiceOnly = clientType === 'dial-in-user';
const iconUser = user.emoji.status !== 'none' ? const iconUser = user.emoji.status !== 'none'
(<Icon iconName={normalizeEmojiName(user.emoji.status)} />) : ? (<Icon iconName={normalizeEmojiName(user.emoji.status)} />)
user.name.toLowerCase().slice(0, 2); : user.name.toLowerCase().slice(0, 2);
const iconVoiceOnlyUser = (<Icon iconName="speak_louder" />); const iconVoiceOnlyUser = (<Icon iconName="speak_louder" />);
@ -450,7 +448,6 @@ class UserDropdown extends PureComponent {
const userItemContentsStyle = {}; const userItemContentsStyle = {};
userItemContentsStyle[styles.userItemContentsCompact] = compact;
userItemContentsStyle[styles.dropdown] = true; userItemContentsStyle[styles.dropdown] = true;
userItemContentsStyle[styles.userListItem] = !this.state.isActionsOpen; userItemContentsStyle[styles.userListItem] = !this.state.isActionsOpen;
userItemContentsStyle[styles.usertListItemWithMenu] = this.state.isActionsOpen; userItemContentsStyle[styles.usertListItemWithMenu] = this.state.isActionsOpen;
@ -473,7 +470,7 @@ class UserDropdown extends PureComponent {
const contents = ( const contents = (
<div <div
data-test={user.isCurrent ? "userListItemCurrent" : null} data-test={user.isCurrent ? 'userListItemCurrent' : null}
className={!actions.length ? styles.userListItem : null} className={!actions.length ? styles.userListItem : null}
> >
<div className={styles.userItemContents}> <div className={styles.userItemContents}>

View File

@ -68,11 +68,12 @@ export default class AnnotationFactory extends Component {
render() { render() {
const { annotationsInfo } = this.props; const { annotationsInfo } = this.props;
return ( return (
<g> <g>
{annotationsInfo ? {annotationsInfo
annotationsInfo.map(annotationInfo => this.renderAnnotation(annotationInfo)) ? annotationsInfo.map(annotationInfo => this.renderAnnotation(annotationInfo))
: null } : null }
</g> </g>
); );
} }

View File

@ -213,8 +213,8 @@ class WhiteboardToolbar extends Component {
} else if (this.state.thicknessSelected.value !== prevState.thicknessSelected.value) { } else if (this.state.thicknessSelected.value !== prevState.thicknessSelected.value) {
this.thicknessListIconRadius.beginElement(); this.thicknessListIconRadius.beginElement();
// 3rd case // 3rd case
} else if (this.state.annotationSelected.value !== 'text' && } else if (this.state.annotationSelected.value !== 'text'
prevState.annotationSelected.value === 'text') { && prevState.annotationSelected.value === 'text') {
this.thicknessListIconRadius.beginElement(); this.thicknessListIconRadius.beginElement();
this.thicknessListIconColor.beginElement(); this.thicknessListIconColor.beginElement();
} }
@ -339,17 +339,19 @@ class WhiteboardToolbar extends Component {
onBlur={this.closeSubMenu} onBlur={this.closeSubMenu}
className={cx(styles.toolbarButton, this.state.currentSubmenuOpen === 'annotationList' ? styles.toolbarActive : null)} className={cx(styles.toolbarButton, this.state.currentSubmenuOpen === 'annotationList' ? styles.toolbarActive : null)}
> >
{this.state.currentSubmenuOpen === 'annotationList' && annotations.length > 1 ? {this.state.currentSubmenuOpen === 'annotationList' && annotations.length > 1
<ToolbarSubmenu ? (
type="annotations" <ToolbarSubmenu
customIcon={false} type="annotations"
label="Annotations" customIcon={false}
onItemClick={this.handleAnnotationChange} label="Annotations"
objectsToRender={annotations} onItemClick={this.handleAnnotationChange}
objectSelected={this.state.annotationSelected} objectsToRender={annotations}
handleMouseEnter={this.handleMouseEnter} objectSelected={this.state.annotationSelected}
handleMouseLeave={this.handleMouseLeave} handleMouseEnter={this.handleMouseEnter}
/> handleMouseLeave={this.handleMouseLeave}
/>
)
: null} : null}
</ToolbarMenuItem> </ToolbarMenuItem>
); );
@ -367,17 +369,19 @@ class WhiteboardToolbar extends Component {
onBlur={this.closeSubMenu} onBlur={this.closeSubMenu}
className={cx(styles.toolbarButton, this.state.currentSubmenuOpen === 'fontSizeList' ? styles.toolbarActive : null)} className={cx(styles.toolbarButton, this.state.currentSubmenuOpen === 'fontSizeList' ? styles.toolbarActive : null)}
> >
{this.state.currentSubmenuOpen === 'fontSizeList' ? {this.state.currentSubmenuOpen === 'fontSizeList'
<ToolbarSubmenu ? (
type="font-size" <ToolbarSubmenu
customIcon type="font-size"
label="Font Size" customIcon
onItemClick={this.handleFontSizeChange} label="Font Size"
objectsToRender={this.props.fontSizes} onItemClick={this.handleFontSizeChange}
objectSelected={this.state.fontSizeSelected} objectsToRender={this.props.fontSizes}
handleMouseEnter={this.handleMouseEnter} objectSelected={this.state.fontSizeSelected}
handleMouseLeave={this.handleMouseLeave} handleMouseEnter={this.handleMouseEnter}
/> handleMouseLeave={this.handleMouseLeave}
/>
)
: null} : null}
</ToolbarMenuItem> </ToolbarMenuItem>
); );
@ -405,8 +409,8 @@ class WhiteboardToolbar extends Component {
return ( return (
<ToolbarMenuItem <ToolbarMenuItem
disabled={isDisabled} disabled={isDisabled}
label={isDisabled ? label={isDisabled
intl.formatMessage(intlMessages.toolbarLineThicknessDisabled) ? intl.formatMessage(intlMessages.toolbarLineThicknessDisabled)
: intl.formatMessage(intlMessages.toolbarLineThickness)} : intl.formatMessage(intlMessages.toolbarLineThickness)}
onItemClick={this.displaySubMenu} onItemClick={this.displaySubMenu}
objectToReturn="thicknessList" objectToReturn="thicknessList"
@ -414,17 +418,19 @@ class WhiteboardToolbar extends Component {
className={cx(styles.toolbarButton, this.state.currentSubmenuOpen === 'thicknessList' ? styles.toolbarActive : null)} className={cx(styles.toolbarButton, this.state.currentSubmenuOpen === 'thicknessList' ? styles.toolbarActive : null)}
customIcon={this.renderThicknessItemIcon()} customIcon={this.renderThicknessItemIcon()}
> >
{this.state.currentSubmenuOpen === 'thicknessList' ? {this.state.currentSubmenuOpen === 'thicknessList'
<ToolbarSubmenu ? (
type="thickness" <ToolbarSubmenu
customIcon type="thickness"
label="Thickness" customIcon
onItemClick={this.handleThicknessChange} label="Thickness"
objectsToRender={this.props.thicknessRadiuses} onItemClick={this.handleThicknessChange}
objectSelected={this.state.thicknessSelected} objectsToRender={this.props.thicknessRadiuses}
handleMouseEnter={this.handleMouseEnter} objectSelected={this.state.thicknessSelected}
handleMouseLeave={this.handleMouseLeave} handleMouseEnter={this.handleMouseEnter}
/> handleMouseLeave={this.handleMouseLeave}
/>
)
: null} : null}
</ToolbarMenuItem> </ToolbarMenuItem>
); );
@ -485,8 +491,8 @@ class WhiteboardToolbar extends Component {
return ( return (
<ToolbarMenuItem <ToolbarMenuItem
disabled={isDisabled} disabled={isDisabled}
label={isDisabled ? label={isDisabled
intl.formatMessage(intlMessages.toolbarLineColorDisabled) ? intl.formatMessage(intlMessages.toolbarLineColorDisabled)
: intl.formatMessage(intlMessages.toolbarLineColor)} : intl.formatMessage(intlMessages.toolbarLineColor)}
onItemClick={this.displaySubMenu} onItemClick={this.displaySubMenu}
objectToReturn="colorList" objectToReturn="colorList"
@ -494,17 +500,19 @@ class WhiteboardToolbar extends Component {
className={cx(styles.toolbarButton, this.state.currentSubmenuOpen === 'colorList' ? styles.toolbarActive : null)} className={cx(styles.toolbarButton, this.state.currentSubmenuOpen === 'colorList' ? styles.toolbarActive : null)}
customIcon={this.renderColorItemIcon()} customIcon={this.renderColorItemIcon()}
> >
{this.state.currentSubmenuOpen === 'colorList' ? {this.state.currentSubmenuOpen === 'colorList'
<ToolbarSubmenu ? (
type="color" <ToolbarSubmenu
customIcon type="color"
label="Color" customIcon
onItemClick={this.handleColorChange} label="Color"
objectsToRender={this.props.colors} onItemClick={this.handleColorChange}
objectSelected={this.state.colorSelected} objectsToRender={this.props.colors}
handleMouseEnter={this.handleMouseEnter} objectSelected={this.state.colorSelected}
handleMouseLeave={this.handleMouseLeave} handleMouseEnter={this.handleMouseEnter}
/> handleMouseLeave={this.handleMouseLeave}
/>
)
: null} : null}
</ToolbarMenuItem> </ToolbarMenuItem>
); );
@ -551,7 +559,7 @@ class WhiteboardToolbar extends Component {
label={intl.formatMessage(intlMessages.toolbarUndoAnnotation)} label={intl.formatMessage(intlMessages.toolbarUndoAnnotation)}
icon="undo" icon="undo"
onItemClick={this.handleUndo} 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)} label={intl.formatMessage(intlMessages.toolbarClearAnnotations)}
icon="delete" icon="delete"
onItemClick={this.handleClearAll} onItemClick={this.handleClearAll}
className={cx(styles.toolbarButton, styles.notActive)} className={styles.toolbarButton}
/> />
); );
} }
@ -574,13 +582,13 @@ class WhiteboardToolbar extends Component {
return ( return (
<ToolbarMenuItem <ToolbarMenuItem
label={multiUser ? label={multiUser
intl.formatMessage(intlMessages.toolbarMultiUserOff) ? intl.formatMessage(intlMessages.toolbarMultiUserOff)
: intl.formatMessage(intlMessages.toolbarMultiUserOn) : intl.formatMessage(intlMessages.toolbarMultiUserOn)
} }
icon={multiUser ? 'multi_whiteboard' : 'whiteboard'} icon={multiUser ? 'multi_whiteboard' : 'whiteboard'}
onItemClick={this.handleSwitchWhiteboardMode} onItemClick={this.handleSwitchWhiteboardMode}
className={cx(styles.toolbarButton, styles.notActive)} className={styles.toolbarButton}
/> />
); );
} }

View File

@ -93,13 +93,13 @@ class ToolbarSubmenu extends Component {
<rect x="20%" y="20%" width="60%" height="60%" fill={obj.value} /> <rect x="20%" y="20%" width="60%" height="60%" fill={obj.value} />
</svg> </svg>
); );
} else if (type === 'thickness') { } if (type === 'thickness') {
return ( return (
<svg className={styles.customSvgIcon}> <svg className={styles.customSvgIcon}>
<circle cx="50%" cy="50%" r={obj.value} /> <circle cx="50%" cy="50%" r={obj.value} />
</svg> </svg>
); );
} else if (type === 'font-size') { } if (type === 'font-size') {
return ( return (
<p className={styles.textThickness} style={{ fontSize: obj.value }}> <p className={styles.textThickness} style={{ fontSize: obj.value }}>
Aa Aa
@ -111,18 +111,19 @@ class ToolbarSubmenu extends Component {
} }
static getWrapperClassNames(type) { static getWrapperClassNames(type) {
if (type === 'color') { if (type === 'font-size') {
return cx(styles.colorList, styles.toolbarList);
} else if (type === 'thickness') {
return cx(styles.thicknessList, styles.toolbarList);
} else if (type === 'font-size') {
return cx(styles.fontSizeList, styles.toolbarList); return cx(styles.fontSizeList, styles.toolbarList);
} else if (type === 'annotations') { } if (
return cx(styles.annotationList, styles.toolbarList); type === 'annotations'
|| type === 'thickness'
|| type === 'color'
) {
return styles.toolbarList;
} }
return null; return null;
} }
constructor() { constructor() {
super(); super();
@ -183,21 +184,20 @@ class ToolbarSubmenu extends Component {
onMouseLeave={this.handleMouseLeave} onMouseLeave={this.handleMouseLeave}
className={ToolbarSubmenu.getWrapperClassNames(type)} className={ToolbarSubmenu.getWrapperClassNames(type)}
> >
{objectsToRender ? objectsToRender.map(obj => {objectsToRender ? objectsToRender.map(obj => (
( <ToolbarSubmenuItem
<ToolbarSubmenuItem label={this.formatSubmenuLabel(type, obj)}
label={this.formatSubmenuLabel(type, obj)} icon={!customIcon ? obj.icon : null}
icon={!customIcon ? obj.icon : null} customIcon={customIcon ? ToolbarSubmenu.getCustomIcon(type, obj) : null}
customIcon={customIcon ? ToolbarSubmenu.getCustomIcon(type, obj) : null} onItemClick={this.onItemClick}
onItemClick={this.onItemClick} objectToReturn={obj}
objectToReturn={obj} className={cx(
className={cx( styles.toolbarListButton,
styles.toolbarListButton, objectSelected.value === obj.value ? styles.selectedListButton : '',
objectSelected.value === obj.value ? styles.selectedListButton : '', )}
)} key={obj.value}
key={obj.value} />
/> )) : null}
)) : null}
</div> </div>
); );
} }

0
bigbluebutton-html5/package-lock.json generated Executable file → Normal file
View File

View File

@ -10,11 +10,9 @@
"start:prod": "meteor reset && ROOT_URL=http://127.0.0.1/html5client NODE_ENV=production meteor --production", "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", "start:dev": "ROOT_URL=http://127.0.0.1/html5client NODE_ENV=development meteor",
"test": "jest", "test": "jest",
"lint": "eslint . --ext .jsx,.js", "lint": "eslint . --ext .jsx,.js"
"precommit": "lint-staged"
}, },
"lint-staged": { "lint-staged": {
"gitDir": "../",
"linters": { "linters": {
"*.{js,jsx}": [ "*.{js,jsx}": [
"eslint --fix", "eslint --fix",
@ -28,65 +26,68 @@
"but Meteor 1.6.0.1 doesn't see it there for some reason", "but Meteor 1.6.0.1 doesn't see it there for some reason",
"need to investigate" "need to investigate"
], ],
"@browser-bunyan/server-stream": "^1.3.0", "@babel/runtime": "^7.2.0",
"autoprefixer": "~7.1.6", "@browser-bunyan/server-stream": "^1.5.0",
"autoprefixer": "~9.3.1",
"babel-plugin-react-remove-properties": "~0.2.5", "babel-plugin-react-remove-properties": "~0.2.5",
"babel-runtime": "~6.26.0", "babel-runtime": "~6.26.0",
"browser-bunyan": "^1.4.0", "browser-bunyan": "^1.5.0",
"browser-detect": "^0.2.28", "browser-detect": "^0.2.28",
"classnames": "^2.2.6", "classnames": "^2.2.6",
"clipboard": "~1.7.1", "clipboard": "^2.0.4",
"core-js": "^2.5.7", "core-js": "^2.6.0",
"eventemitter2": "~4.1.2", "eventemitter2": "~5.0.1",
"flat": "~4.0.0", "fibers": "^3.1.1",
"history": "~3.3.0", "flat": "~4.1.0",
"immutability-helper": "~2.4.0", "history": "~4.7.2",
"immutability-helper": "~2.8.1",
"langmap": "0.0.16", "langmap": "0.0.16",
"lodash": "~4.17.10", "lodash": "^4.17.11",
"makeup-screenreader-trap": "0.0.5", "makeup-screenreader-trap": "0.0.5",
"meteor-node-stubs": "^0.3.3", "meteor-node-stubs": "^0.4.1",
"node-sass": "^4.9.3", "node-sass": "^4.10.0",
"postcss-nested": "2.1.2", "postcss-nested": "4.1.0",
"probe-image-size": "~3.1.0", "probe-image-size": "~4.0.0",
"prop-types": "^15.6.2", "prop-types": "^15.6.2",
"re-resizable": "^4.8.1", "re-resizable": "^4.10.0",
"react": "~16.0.0", "react": "^16.6.3",
"react-autosize-textarea": "~0.4.9", "react-autosize-textarea": "^5.0.1",
"react-color": "~2.14.1", "react-color": "~2.14.1",
"react-dom": "^16.0.1", "react-dom": "^16.6.3",
"react-dropzone": "^4.2.13", "react-dropzone": "^7.0.1",
"react-intl": "~2.4.0", "react-intl": "~2.7.2",
"react-modal": "~3.0.4", "react-modal": "~3.6.1",
"react-render-in-browser": "^1.0.0", "react-render-in-browser": "^1.0.0",
"react-tabs": "~2.1.0", "react-tabs": "~2.3.0",
"react-toastify": "~2.1.2", "react-toastify": "^4.4.3",
"react-toggle": "~4.0.2", "react-toggle": "~4.0.2",
"react-transition-group": "~2.2.1", "react-transition-group": "~2.5.0",
"reconnecting-websocket": "~v3.2.2", "reconnecting-websocket": "~v4.1.10",
"redis": "~2.8.0", "redis": "~2.8.0",
"string-hash": "~1.1.3", "string-hash": "~1.1.3",
"tippy.js": "~2.0.2", "tippy.js": "^3.1.3",
"winston": "^2.4.4", "winston": "^3.1.0",
"yaml": "^1.0.0" "yaml": "^1.0.3"
}, },
"devDependencies": { "devDependencies": {
"axios": "^0.18.0", "chai": "~4.2.0",
"dotenv": "^6.1.0", "eslint": "~5.8.0",
"eslint": "~4.9.0", "eslint-config-airbnb": "~17.1.0",
"eslint-config-airbnb": "~16.1.0", "eslint-config-airbnb-base": "~13.1.0",
"eslint-config-airbnb-base": "~12.1.0", "eslint-plugin-import": "~2.14.0",
"eslint-plugin-import": "~2.8.0", "eslint-plugin-jsx-a11y": "~6.1.2",
"eslint-plugin-jsx-a11y": "~6.0.2", "eslint-plugin-react": "~7.11.1",
"eslint-plugin-react": "~7.4.0", "husky": "^1.1.4",
"husky": "~0.14.3", "lint-staged": "^8.0.5",
"jest": "^23.6.0", "postcss-modules-extract-imports": "2.0.0",
"lint-staged": "~4.3.0",
"postcss-modules-extract-imports": "1.1.0",
"postcss-modules-local-by-default": "1.2.0", "postcss-modules-local-by-default": "1.2.0",
"postcss-modules-scope": "1.1.0", "postcss-modules-scope": "1.1.0",
"postcss-modules-values": "1.3.0", "postcss-modules-values": "1.3.0",
"puppeteer": "^1.10.0", "wdio-junit-reporter": "~0.4.4",
"sha1": "^1.1.1" "wdio-spec-reporter": "^0.1.5",
"wdio-visual-regression-service": "~0.9.0",
"webdriver-manager": "~12.1.0",
"webdriverio": "^4.14.1"
}, },
"cssModules": { "cssModules": {
"cssClassNamingConvention": { "cssClassNamingConvention": {
@ -103,13 +104,13 @@
"autoprefixer": {} "autoprefixer": {}
} }
}, },
"jest": {
"modulePathIgnorePatterns": [
"/tests/webdriverio"
]
},
"repository": { "repository": {
"type": "git", "type": "git",
"url": "https://github.com/bigbluebutton/bigbluebutton.git" "url": "https://github.com/bigbluebutton/bigbluebutton.git"
},
"husky": {
"hooks": {
"pre-commit": "lint-staged"
}
} }
} }

View File

@ -28,9 +28,8 @@ class Clear extends Page {
// [] // []
const after = await util.getTestElements(this); const after = await util.getTestElements(this);
const response = const response = before[0].message == e.message
before[0].message == e.message && && after.length == 0;
after.length == 0;
return response; return response;
} }

View File

@ -24,9 +24,8 @@ class Send extends Page {
// [{ "name": "User1\nXX:XX XM", "message": "Hello world!" }] // [{ "name": "User1\nXX:XX XM", "message": "Hello world!" }]
const chat1 = await util.getTestElements(this); const chat1 = await util.getTestElements(this);
const response = const response = chat0.length == 0
chat0.length == 0 && && chat1[0].message == e.message;
chat1[0].message == e.message;
return response; return response;
} }

View File

@ -4,7 +4,7 @@ const ce = require('../core/elements');
async function openChat(test) { async function openChat(test) {
// TODO: Check this if it's open before click // TODO: Check this if it's open before click
await test.click(ce.userList); 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.chatBox);
await test.waitForSelector(e.chatMessages); await test.waitForSelector(e.chatMessages);
} }

View File

@ -19,8 +19,8 @@ async function createMeeting(params) {
const meetingID = `random-${getRandomInt(1000000, 10000000).toString()}`; const meetingID = `random-${getRandomInt(1000000, 10000000).toString()}`;
const mp = params.moderatorPW; const mp = params.moderatorPW;
const ap = params.attendeePW; const ap = params.attendeePW;
const query = `name=${meetingID}&meetingID=${meetingID}&attendeePW=${ap}&moderatorPW=${mp}&joinViaHtml5=true` + const query = `name=${meetingID}&meetingID=${meetingID}&attendeePW=${ap}&moderatorPW=${mp}&joinViaHtml5=true`
`&record=false&allowStartStopRecording=true&autoStartRecording=false&welcome=${params.welcome}`; + `&record=false&allowStartStopRecording=true&autoStartRecording=false&welcome=${params.welcome}`;
const apicall = `create${query}${params.secret}`; const apicall = `create${query}${params.secret}`;
const checksum = sha1(apicall); const checksum = sha1(apicall);
const url = `${params.server}/create?${query}&checksum=${checksum}`; const url = `${params.server}/create?${query}&checksum=${checksum}`;

View File

@ -12,7 +12,7 @@ class Page {
} }
getParentDir(dir) { getParentDir(dir) {
let tmp = dir.split('/'); const tmp = dir.split('/');
tmp.pop(); tmp.pop();
return tmp.join('/'); return tmp.join('/');
} }
@ -22,7 +22,7 @@ class Page {
this.browser = await puppeteer.launch(args); this.browser = await puppeteer.launch(args);
this.page = await this.browser.newPage(); this.page = await this.browser.newPage();
await this.setDownloadBehavior(this.parentDir + '/downloads'); await this.setDownloadBehavior(`${this.parentDir}/downloads`);
this.meetingId = await helper.createMeeting(params); this.meetingId = await helper.createMeeting(params);
const joinURL = helper.getJoinURL(this.meetingId, params, true); const joinURL = helper.getJoinURL(this.meetingId, params, true);
@ -33,7 +33,7 @@ class Page {
} }
async setDownloadBehavior(downloadPath) { async setDownloadBehavior(downloadPath) {
const downloadBehavior = { behavior: 'allow', downloadPath: downloadPath }; const downloadBehavior = { behavior: 'allow', downloadPath };
await this.page._client.send('Page.setDownloadBehavior', downloadBehavior); await this.page._client.send('Page.setDownloadBehavior', downloadBehavior);
} }
@ -113,9 +113,9 @@ class Page {
async screenshot(relief = false) { async screenshot(relief = false) {
if (relief) await helper.sleep(1000); if (relief) await helper.sleep(1000);
const filename = this.name + '-' + this.screenshotIndex + '.png'; const filename = `${this.name}-${this.screenshotIndex}.png`;
const path = this.parentDir + '/screenshots/' + filename; const path = `${this.parentDir}/screenshots/${filename}`;
await this.page.screenshot({ path: path }); await this.page.screenshot({ path });
this.screenshotIndex++; this.screenshotIndex++;
} }

View File

@ -32,7 +32,7 @@ class Slide extends Page {
console.log(svg2); console.log(svg2);
// TODO: Check test // TODO: Check test
return true return true;
} }
async getTestElements() { async getTestElements() {

View File

@ -23,7 +23,7 @@ class Upload extends Page {
await this.click(e.start); await this.click(e.start);
console.log('\nWaiting for the new presentation to upload...'); console.log('\nWaiting for the new presentation to upload...');
//await this.elementRemoved(e.start); // await this.elementRemoved(e.start);
await this.page.waitFor(10000); await this.page.waitFor(10000);
console.log('\nPresentation uploaded!'); console.log('\nPresentation uploaded!');
@ -38,7 +38,7 @@ class Upload extends Page {
console.log(slides1.svg); console.log(slides1.svg);
// TODO: Check test // TODO: Check test
return true return true;
} }
async getTestElements() { async getTestElements() {

View File

@ -29,7 +29,7 @@ class Draw extends Page {
console.log(shapes1); console.log(shapes1);
// TODO: Check test // TODO: Check test
return true return true;
} }
async getTestElements() { async getTestElements() {