eslint 4.8.0

ESLint 4.8.0 discovers a lot of error related to formatting. While I
tried to fix as many of them as possible, a portion of them actually go
against our coding style. In such a case, I've disabled the indent rule
which effectively leaves it as it was before ESLint 4.8.0.

Additionally, remove jshint because it's becoming a nuisance with its
lack of understanding of ES2015+.
This commit is contained in:
Lyubo Marinov 2017-10-02 18:08:07 -05:00
parent d280f90676
commit dfebd692f3
56 changed files with 425 additions and 375 deletions

View File

@ -26,6 +26,23 @@ module.exports = {
'flowtype'
],
'rules': {
'indent': [
'error',
4,
{
'CallExpression': {
arguments: 'off'
},
'FunctionDeclaration': {
parameters: 2
},
'FunctionExpression': {
parameters: 2
},
'MemberExpression': 'off',
'SwitchCase': 0
}
],
'new-cap': [
'error',
{

View File

@ -1,22 +0,0 @@
# The following do not need to be checked because they do not represent JS
# source code.
build/
debian/
libs/
node_modules/
# The following are checked by ESLint with the maximum configuration which
# supersedes JSHint.
flow-typed/
modules/API/
modules/remotecontrol/
modules/transport/
react/
# The following are checked by ESLint with the minimum configuration which does
# not supersede JSHint but take advantage of advanced language features such as
# Facebook Flow which are not supported by JSHint.
app.js
modules/translation/translation.js
analytics.js

View File

@ -1,20 +0,0 @@
{
// Refer to http://jshint.com/docs/options/ for an exhaustive list of options
"asi": false, // true: Tolerate Automatic Semicolon Insertion (no semicolons)
"expr": true, // true: Tolerate `ExpressionStatement` as Programs
"loopfunc": true, // true: Tolerate functions being defined in loops
"curly": false, // true: Require {} for every new block or scope
"evil": true, // true: Tolerate use of `eval` and `new Function()`
"white": true,
"undef": true, // true: Require all non-global variables to be declared (prevents global leaks)
"browser": true, // Web Browser (window, document, etc)
"node": true, // Node.js
"trailing": true,
"indent": 4, // {int} Number of spaces to use for indentation
"latedef": true, // true: Require variables/functions to be defined before being used
"newcap": true, // true: Require capitalization of all constructor functions e.g. `new F()`
"maxlen": 80, // {int} Max number of characters per line
"latedef": false, //This option prohibits the use of a variable before it was defined
"laxbreak": true, //Ignore line breaks around "=", "==", "&&", etc.
"esnext": true //support ES2015
}

View File

@ -1,8 +1,9 @@
/* global ga */
/* eslint-disable indent */
(function (ctx) {
function Analytics() {
/* eslint-disable */
/* eslint-disable semi */
/**
* Google Analytics
@ -13,7 +14,7 @@
ga('create', 'UA-319188-14', 'jit.si');
ga('send', 'pageview');
/* eslint-enable */
/* eslint-enable semi */
}
Analytics.prototype.sendEvent = function (action, data) {
@ -29,10 +30,8 @@
if (typeof ctx.JitsiMeetJS === "undefined")
ctx.JitsiMeetJS = {};
if (typeof ctx.JitsiMeetJS.app === "undefined")
ctx.JitsiMeetJS.app = {};
if (typeof ctx.JitsiMeetJS.app.analyticsHandlers === "undefined")
ctx.JitsiMeetJS.app.analyticsHandlers = [];
ctx.JitsiMeetJS.app.analyticsHandlers.push(Analytics);

View File

@ -123,13 +123,13 @@ const commands = {
function connect(roomName) {
return openConnection({retry: true, roomName: roomName})
.catch(function (err) {
if (err === ConnectionErrors.PASSWORD_REQUIRED) {
APP.UI.notifyTokenAuthFailed();
} else {
APP.UI.notifyConnectionFailed(err);
}
throw err;
});
if (err === ConnectionErrors.PASSWORD_REQUIRED) {
APP.UI.notifyTokenAuthFailed();
} else {
APP.UI.notifyConnectionFailed(err);
}
throw err;
});
}
/**
@ -286,38 +286,36 @@ class ConferenceConnector {
logger.error('CONFERENCE FAILED:', err, ...params);
switch (err) {
case ConferenceErrors.CONNECTION_ERROR:
{
let [msg] = params;
APP.UI.notifyConnectionFailed(msg);
}
case ConferenceErrors.CONNECTION_ERROR: {
let [msg] = params;
APP.UI.notifyConnectionFailed(msg);
break;
}
case ConferenceErrors.NOT_ALLOWED_ERROR:
{
// let's show some auth not allowed page
assignWindowLocationPathname('static/authError.html');
}
case ConferenceErrors.NOT_ALLOWED_ERROR: {
// let's show some auth not allowed page
assignWindowLocationPathname('static/authError.html');
break;
}
// not enough rights to create conference
// not enough rights to create conference
case ConferenceErrors.AUTHENTICATION_REQUIRED: {
// Schedule reconnect to check if someone else created the room.
this.reconnectTimeout = setTimeout(() => room.join(), 5000);
// Schedule reconnect to check if someone else created the room.
this.reconnectTimeout = setTimeout(() => room.join(), 5000);
const { password }
= APP.store.getState()['features/base/conference'];
const { password }
= APP.store.getState()['features/base/conference'];
AuthHandler.requireAuth(room, password);
AuthHandler.requireAuth(room, password);
}
break;
}
case ConferenceErrors.RESERVATION_ERROR:
{
let [code, msg] = params;
APP.UI.notifyReservationError(code, msg);
}
case ConferenceErrors.RESERVATION_ERROR: {
let [code, msg] = params;
APP.UI.notifyReservationError(code, msg);
break;
}
case ConferenceErrors.GRACEFUL_SHUTDOWN:
APP.UI.notifyGracefulShutdown();
@ -327,24 +325,22 @@ class ConferenceConnector {
APP.UI.notifyInternalError();
break;
case ConferenceErrors.CONFERENCE_DESTROYED:
{
let [reason] = params;
APP.UI.hideStats();
APP.UI.notifyConferenceDestroyed(reason);
}
case ConferenceErrors.CONFERENCE_DESTROYED: {
let [reason] = params;
APP.UI.hideStats();
APP.UI.notifyConferenceDestroyed(reason);
break;
}
// FIXME FOCUS_DISCONNECTED is confusing event name.
// What really happens there is that the library is not ready yet,
// because Jicofo is not available, but it is going to give
// it another try.
case ConferenceErrors.FOCUS_DISCONNECTED:
{
let [focus, retrySec] = params;
APP.UI.notifyFocusDisconnected(focus, retrySec);
}
// FIXME FOCUS_DISCONNECTED is a confusing event name.
// What really happens there is that the library is not ready yet,
// because Jicofo is not available, but it is going to give it another
// try.
case ConferenceErrors.FOCUS_DISCONNECTED: {
let [focus, retrySec] = params;
APP.UI.notifyFocusDisconnected(focus, retrySec);
break;
}
case ConferenceErrors.FOCUS_LEFT:
case ConferenceErrors.VIDEOBRIDGE_NOT_AVAILABLE:
@ -358,9 +354,11 @@ class ConferenceConnector {
connection.disconnect();
APP.UI.notifyMaxUsersLimitReached();
break;
case ConferenceErrors.INCOMPATIBLE_SERVER_VERSIONS:
reload();
break;
default:
this._handleConferenceFailed(err, ...params);
}
@ -644,7 +642,7 @@ export default {
init(options) {
this.roomName = options.roomName;
// attaches global error handler, if there is already one, respect it
if (JitsiMeetJS.getGlobalOnErrorHandler){
if (JitsiMeetJS.getGlobalOnErrorHandler) {
var oldOnErrorHandler = window.onerror;
window.onerror = function (message, source, lineno, colno, error) {
JitsiMeetJS.getGlobalOnErrorHandler(
@ -656,20 +654,18 @@ export default {
var oldOnUnhandledRejection = window.onunhandledrejection;
window.onunhandledrejection = function(event) {
JitsiMeetJS.getGlobalOnErrorHandler(
JitsiMeetJS.getGlobalOnErrorHandler(
null, null, null, null, event.reason);
if (oldOnUnhandledRejection)
oldOnUnhandledRejection(event);
};
}
return JitsiMeetJS.init(
Object.assign({
enableAnalyticsLogging: isAnalyticsEnabled(APP.store)
},
config)
).then(() => {
return (
JitsiMeetJS.init({
enableAnalyticsLogging: isAnalyticsEnabled(APP.store),
...config
}).then(() => {
initAnalytics(APP.store);
return this.createInitialLocalTracksAndConnect(
options.roomName, {
@ -733,7 +729,7 @@ export default {
return new Promise((resolve, reject) => {
(new ConferenceConnector(resolve, reject)).connect();
});
});
}));
},
/**
* Check if id is id of the local user.
@ -1700,15 +1696,12 @@ export default {
room.on(
ConferenceEvents.LAST_N_ENDPOINTS_CHANGED,
(leavingIds, enteringIds) => {
APP.UI.handleLastNEndpoints(leavingIds, enteringIds);
});
(leavingIds, enteringIds) =>
APP.UI.handleLastNEndpoints(leavingIds, enteringIds));
room.on(
ConferenceEvents.P2P_STATUS,
(jitsiConference, p2p) => {
APP.store.dispatch(p2pStatusChanged(p2p));
});
(jitsiConference, p2p) => APP.store.dispatch(p2pStatusChanged(p2p)));
room.on(
ConferenceEvents.PARTICIPANT_CONN_STATUS_CHANGED,
@ -1717,7 +1710,7 @@ export default {
id, connectionStatus));
APP.UI.participantConnectionStatusChanged(id);
});
});
room.on(ConferenceEvents.DOMINANT_SPEAKER_CHANGED, (id) => {
APP.store.dispatch(dominantSpeakerChanged(id));
@ -1818,21 +1811,22 @@ export default {
APP.UI.setLocalRemoteControlActiveChanged();
});
room.on(ConferenceEvents.PARTICIPANT_PROPERTY_CHANGED,
(participant, name, oldValue, newValue) => {
switch (name) {
case 'raisedHand':
APP.UI.setRaisedHandStatus(participant, newValue);
break;
case 'remoteControlSessionStatus':
APP.UI.setRemoteControlActiveStatus(
participant.getId(),
newValue);
break;
default:
// ignore
}
});
room.on(
ConferenceEvents.PARTICIPANT_PROPERTY_CHANGED,
(participant, name, oldValue, newValue) => {
switch (name) {
case 'raisedHand':
APP.UI.setRaisedHandStatus(participant, newValue);
break;
case 'remoteControlSessionStatus':
APP.UI.setRemoteControlActiveStatus(
participant.getId(),
newValue);
break;
default:
// ignore
}
});
room.on(ConferenceEvents.RECORDER_STATE_CHANGED, (status, error) => {
logger.log("Received recorder status change: ", status, error);
@ -1910,7 +1904,7 @@ export default {
avatarURL: data.value
}));
APP.UI.setUserAvatarUrl(from, data.value);
});
});
room.addCommandListener(this.commands.defaults.AVATAR_ID,
(data, from) => {
@ -1972,25 +1966,27 @@ export default {
});
});
APP.UI.addListener(UIEvents.RESOLUTION_CHANGED,
APP.UI.addListener(
UIEvents.RESOLUTION_CHANGED,
(id, oldResolution, newResolution, delay) => {
var logObject = {
id: "resolution_change",
participant: id,
oldValue: oldResolution,
newValue: newResolution,
delay: delay
var logObject = {
id: "resolution_change",
participant: id,
oldValue: oldResolution,
newValue: newResolution,
delay: delay
};
room.sendApplicationLog(JSON.stringify(logObject));
// We only care about the delay between simulcast streams.
// Longer delays will be caused by something else and will just
// poison the data.
if (delay < 2000) {
JitsiMeetJS.analytics.sendEvent('stream.switch.delay',
{value: delay});
}
});
room.sendApplicationLog(JSON.stringify(logObject));
// We only care about the delay between simulcast streams.
// Longer delays will be caused by something else and will just
// poison the data.
if (delay < 2000) {
JitsiMeetJS.analytics.sendEvent('stream.switch.delay',
{value: delay});
}
});
// Starts or stops the recording for the conference.
APP.UI.addListener(UIEvents.RECORDING_TOGGLED, (options) => {
@ -2112,37 +2108,40 @@ export default {
UIEvents.TOGGLE_SCREENSHARING, this.toggleScreenSharing.bind(this)
);
APP.UI.addListener(UIEvents.UPDATE_SHARED_VIDEO,
APP.UI.addListener(
UIEvents.UPDATE_SHARED_VIDEO,
(url, state, time, isMuted, volume) => {
// send start and stop commands once, and remove any updates
// that had left
if (state === 'stop' || state === 'start' || state === 'playing') {
room.removeCommand(this.commands.defaults.SHARED_VIDEO);
room.sendCommandOnce(this.commands.defaults.SHARED_VIDEO, {
value: url,
attributes: {
state: state,
time: time,
muted: isMuted,
volume: volume
}
});
}
else {
// in case of paused, in order to allow late users to join
// paused
room.removeCommand(this.commands.defaults.SHARED_VIDEO);
room.sendCommand(this.commands.defaults.SHARED_VIDEO, {
value: url,
attributes: {
state: state,
time: time,
muted: isMuted,
volume: volume
}
});
}
});
// send start and stop commands once, and remove any updates
// that had left
if (state === 'stop'
|| state === 'start'
|| state === 'playing') {
room.removeCommand(this.commands.defaults.SHARED_VIDEO);
room.sendCommandOnce(this.commands.defaults.SHARED_VIDEO, {
value: url,
attributes: {
state: state,
time: time,
muted: isMuted,
volume: volume
}
});
}
else {
// in case of paused, in order to allow late users to join
// paused
room.removeCommand(this.commands.defaults.SHARED_VIDEO);
room.sendCommand(this.commands.defaults.SHARED_VIDEO, {
value: url,
attributes: {
state: state,
time: time,
muted: isMuted,
volume: volume
}
});
}
});
room.addCommandListener(
this.commands.defaults.SHARED_VIDEO, ({value, attributes}, id) => {

View File

@ -72,7 +72,7 @@ function initCommands() {
return false;
});
transport.on('request', ({ data, name }, callback) => {
transport.on('request', ({ name }, callback) => {
switch (name) {
case 'is-audio-muted':
callback(APP.conference.isLocalAudioMuted());
@ -145,6 +145,8 @@ function toggleScreenSharing() {
* Jitsi Meet.
*/
class API {
_enabled: boolean;
/**
* Initializes the API. Setups message event listeners that will receive
* information from external applications that embed Jitsi Meet. It also
@ -179,7 +181,7 @@ class API {
* @param {Object} event - The event to be sent.
* @returns {void}
*/
_sendEvent(event = {}) {
_sendEvent(event: Object = {}) {
if (this._enabled) {
transport.sendEvent(event);
}
@ -191,7 +193,7 @@ class API {
* @param {string} message - Message body.
* @returns {void}
*/
notifySendingChatMessage(message) {
notifySendingChatMessage(message: string) {
this._sendEvent({
name: 'outgoing-message',
message
@ -226,7 +228,7 @@ class API {
* @param {string} id - User id.
* @returns {void}
*/
notifyUserJoined(id) {
notifyUserJoined(id: string) {
this._sendEvent({
name: 'participant-joined',
id
@ -240,7 +242,7 @@ class API {
* @param {string} id - User id.
* @returns {void}
*/
notifyUserLeft(id) {
notifyUserLeft(id: string) {
this._sendEvent({
name: 'participant-left',
id
@ -255,7 +257,7 @@ class API {
* @param {string} displayname - User nickname.
* @returns {void}
*/
notifyDisplayNameChanged(id, displayname) {
notifyDisplayNameChanged(id: string, displayname: string) {
this._sendEvent({
name: 'display-name-change',
displayname,
@ -270,7 +272,7 @@ class API {
* @param {string} roomName - The room name.
* @returns {void}
*/
notifyConferenceJoined(roomName) {
notifyConferenceJoined(roomName: string) {
this._sendEvent({
name: 'video-conference-joined',
roomName
@ -284,7 +286,7 @@ class API {
* @param {string} roomName - User id.
* @returns {void}
*/
notifyConferenceLeft(roomName) {
notifyConferenceLeft(roomName: string) {
this._sendEvent({
name: 'video-conference-left',
roomName
@ -308,7 +310,7 @@ class API {
* @param {boolean} muted - The new muted status.
* @returns {void}
*/
notifyAudioMutedStatusChanged(muted) {
notifyAudioMutedStatusChanged(muted: boolean) {
this._sendEvent({
name: 'audio-mute-status-changed',
muted
@ -322,7 +324,7 @@ class API {
* @param {boolean} muted - The new muted status.
* @returns {void}
*/
notifyVideoMutedStatusChanged(muted) {
notifyVideoMutedStatusChanged(muted: boolean) {
this._sendEvent({
name: 'video-mute-status-changed',
muted
@ -336,7 +338,7 @@ class API {
* @param {boolean} available - True if available and false otherwise.
* @returns {void}
*/
notifyAudioAvailabilityChanged(available) {
notifyAudioAvailabilityChanged(available: boolean) {
audioAvailable = available;
this._sendEvent({
name: 'audio-availability-changed',
@ -351,7 +353,7 @@ class API {
* @param {boolean} available - True if available and false otherwise.
* @returns {void}
*/
notifyVideoAvailabilityChanged(available) {
notifyVideoAvailabilityChanged(available: boolean) {
videoAvailable = available;
this._sendEvent({
name: 'video-availability-changed',

View File

@ -87,8 +87,8 @@ function generateURL(domain, options = {}) {
return urlObjectToString({
...options,
url:
`${options.noSSL ? 'http' : 'https'}://${domain
}/#jitsi_meet_external_api_id=${id}`
`${options.noSSL ? 'http' : 'https'}://${
domain}/#jitsi_meet_external_api_id=${id}`
});
}

View File

@ -17,9 +17,9 @@ const AudioLevels = {
* @param {number} opacity the opacity to set for the specified dot.
*/
_setDotLevel(elementID, index, opacity) {
let audioSpan = document.getElementById(elementID)
.getElementsByClassName("audioindicator");
let audioSpan
= document.getElementById(elementID)
.getElementsByClassName("audioindicator");
// Make sure the audio span is still around.
if (audioSpan && audioSpan.length > 0)
@ -72,17 +72,17 @@ const AudioLevels = {
/**
* Updates the large video shadow effect.
*/
_updateLargeVideoShadow (level) {
var scale = 2,
_updateLargeVideoShadow(level) {
const scale = 2;
// Internal circle audio level.
int = {
const int = {
level: level > 0.15 ? 20 : 0,
color: interfaceConfig.AUDIO_LEVEL_PRIMARY_COLOR
},
};
// External circle audio level.
ext = {
const ext = {
level: (int.level * scale * level + int.level).toFixed(0),
color: interfaceConfig.AUDIO_LEVEL_SECONDARY_COLOR
};

View File

@ -111,8 +111,7 @@ function initJWTTokenListener(room) {
logger.error(
"Authentication failed: ", err, errCode);
unregister();
}
);
});
}).catch(function (error, code) {
unregister();
connection.disconnect();

View File

@ -90,14 +90,15 @@ export default class SharedVideoManager {
}
if(APP.conference.isLocalId(this.from)) {
showStopVideoPropmpt().then(() => {
showStopVideoPropmpt().then(
() => {
// make sure we stop updates for playing before we send stop
// if we stop it after receiving self presence, we can end
// up sending stop playing, and on the other end it will not
// stop
if(this.intervalId) {
clearInterval(this.intervalId);
this.intervalId = null;
if (this.intervalId) {
clearInterval(this.intervalId);
this.intervalId = null;
}
this.emitter.emit(
UIEvents.UPDATE_SHARED_VIDEO, this.url, 'stop');
@ -472,7 +473,7 @@ export default class SharedVideoManager {
this.emitter.emit(
UIEvents.UPDATE_SHARED_VIDEO, null, 'removed');
});
});
APP.store.dispatch(participantLeft(this.url));

View File

@ -21,6 +21,8 @@ export function processReplacements(body) {
export function linkify(inputText) {
var replacedText, replacePattern1, replacePattern2, replacePattern3;
/* eslint-disable no-useless-escape */
//URLs starting with http://, https://, or ftp://
replacePattern1 = /(\b(https?|ftp):\/\/[-A-Z0-9+&@#\/%?=~_|!:,.;]*[-A-Z0-9+&@#\/%=~_|])/gim;
replacedText = inputText.replace(replacePattern1, '<a href="$1" target="_blank" rel="noopener noreferrer">$1</a>');
@ -33,6 +35,8 @@ export function linkify(inputText) {
replacePattern3 = /(([a-zA-Z0-9\-\_\.])+@[a-zA-Z\_]+?(\.[a-zA-Z]{2,6})+)/gim;
replacedText = replacedText.replace(replacePattern3, '<a href="mailto:$1">$1</a>');
/* eslint-enable no-useless-escape */
return replacedText;
}

View File

@ -120,23 +120,22 @@ var messageHandler = {
* the prompt is closed (optional)
* @return the prompt that was created, or null
*/
openMessageDialog:
function(titleKey, messageKey, i18nOptions, closeFunction) {
openMessageDialog(titleKey, messageKey, i18nOptions, closeFunction) {
if (!popupEnabled)
return null;
let dialog = $.prompt(
APP.translation.generateTranslationHTML(messageKey, i18nOptions),
{
title: this._getFormattedTitleString(titleKey),
persistent: false,
promptspeed: 0,
classes: this._getDialogClasses(),
close: function (e, v, m, f) {
if(closeFunction)
closeFunction(e, v, m, f);
}
});
title: this._getFormattedTitleString(titleKey),
persistent: false,
promptspeed: 0,
classes: this._getDialogClasses(),
close(e, v, m, f) {
if(closeFunction)
closeFunction(e, v, m, f);
}
});
APP.translation.translateElement(dialog, i18nOptions);
return $.prompt.getApi();
},
@ -271,8 +270,15 @@ var messageHandler = {
* @param {string} dontShowAgain.localStorageKey the key for the local
* storage. if not provided dontShowAgain.id will be used.
*/
openDialog: function (titleKey, msgString, persistent, buttons,
submitFunction, loadedFunction, closeFunction, dontShowAgain) {
openDialog(
titleKey,
msgString,
persistent,
buttons,
submitFunction,
loadedFunction,
closeFunction,
dontShowAgain) {
if (!popupEnabled)
return;
@ -448,8 +454,13 @@ var messageHandler = {
* @param messageArguments object with the arguments for the message.
* @param optional configurations for the notification (e.g. timeout)
*/
participantNotification: function(displayName, displayNameKey, cls,
messageKey, messageArguments, timeout = 2500) {
participantNotification(
displayName,
displayNameKey,
cls,
messageKey,
messageArguments,
timeout = 2500) {
APP.store.dispatch(
showNotification(
Notification,

View File

@ -31,7 +31,7 @@ const IndicatorFontSizes = {
/**
* Created by hristo on 12/22/14.
*/
var UIUtil = {
var UIUtil = {
/**
* Returns the available video width.
@ -208,7 +208,7 @@ const IndicatorFontSizes = {
},
redirect(url) {
window.location.href = url;
window.location.href = url;
},
/**
@ -262,11 +262,10 @@ const IndicatorFontSizes = {
* @param {Object} attrs object with properties
* @returns {String} string of html element attributes
*/
attrsToString(attrs) {
return Object.keys(attrs).map(
key => ` ${key}="${attrs[key]}"`
).join(' ');
},
attrsToString(attrs) {
return (
Object.keys(attrs).map(key => ` ${key}="${attrs[key]}"`).join(' '));
},
/**
* Checks if the given DOM element is currently visible. The offsetParent
@ -299,11 +298,12 @@ const IndicatorFontSizes = {
if (hideDelay && hideDelay > 0)
setTimeout(
function () {
selector.fadeOut(300,
() => {selector.css({opacity: 0});}
);
}, hideDelay);
() => {
selector.fadeOut(
300,
() => { selector.css({opacity: 0}); });
},
hideDelay);
}
else {
selector.fadeOut(300,

View File

@ -249,18 +249,18 @@ const Filmstrip = {
if(thumbs.localThumb) {
availableWidth = Math.floor(
(videoAreaAvailableWidth - (
UIUtil.parseCssInt(
localVideoContainer.css('borderLeftWidth'), 10)
+ UIUtil.parseCssInt(
localVideoContainer.css('borderRightWidth'), 10)
+ UIUtil.parseCssInt(
localVideoContainer.css('paddingLeft'), 10)
+ UIUtil.parseCssInt(
localVideoContainer.css('paddingRight'), 10)
+ UIUtil.parseCssInt(
localVideoContainer.css('marginLeft'), 10)
+ UIUtil.parseCssInt(
localVideoContainer.css('marginRight'), 10)))
UIUtil.parseCssInt(
localVideoContainer.css('borderLeftWidth'), 10)
+ UIUtil.parseCssInt(
localVideoContainer.css('borderRightWidth'), 10)
+ UIUtil.parseCssInt(
localVideoContainer.css('paddingLeft'), 10)
+ UIUtil.parseCssInt(
localVideoContainer.css('paddingRight'), 10)
+ UIUtil.parseCssInt(
localVideoContainer.css('marginLeft'), 10)
+ UIUtil.parseCssInt(
localVideoContainer.css('marginRight'), 10)))
);
}
@ -271,18 +271,18 @@ const Filmstrip = {
let remoteVideoContainer = thumbs.remoteThumbs.eq(0);
availableWidth = Math.floor(
(videoAreaAvailableWidth - numvids * (
UIUtil.parseCssInt(
remoteVideoContainer.css('borderLeftWidth'), 10)
+ UIUtil.parseCssInt(
remoteVideoContainer.css('borderRightWidth'), 10)
+ UIUtil.parseCssInt(
remoteVideoContainer.css('paddingLeft'), 10)
+ UIUtil.parseCssInt(
remoteVideoContainer.css('paddingRight'), 10)
+ UIUtil.parseCssInt(
remoteVideoContainer.css('marginLeft'), 10)
+ UIUtil.parseCssInt(
remoteVideoContainer.css('marginRight'), 10)))
UIUtil.parseCssInt(
remoteVideoContainer.css('borderLeftWidth'), 10)
+ UIUtil.parseCssInt(
remoteVideoContainer.css('borderRightWidth'), 10)
+ UIUtil.parseCssInt(
remoteVideoContainer.css('paddingLeft'), 10)
+ UIUtil.parseCssInt(
remoteVideoContainer.css('paddingRight'), 10)
+ UIUtil.parseCssInt(
remoteVideoContainer.css('marginLeft'), 10)
+ UIUtil.parseCssInt(
remoteVideoContainer.css('marginRight'), 10)))
);
}

View File

@ -293,9 +293,10 @@ export default class LargeVideoManager {
*
* @private
*/
updateParticipantConnStatusIndication (
id, showProblemsIndication, messageKey) {
updateParticipantConnStatusIndication(
id,
showProblemsIndication,
messageKey) {
// Apply grey filter on the large video
this.videoContainer.showRemoteConnectionProblemIndicator(
showProblemsIndication);

View File

@ -290,8 +290,7 @@ RemoteVideo.prototype._setAudioVolume = function (newVal) {
* @param isMuted the new muted state to update to
*/
RemoteVideo.prototype.updateRemoteVideoMenu = function (
isMuted = this.isAudioMuted
) {
isMuted = this.isAudioMuted) {
this.isAudioMuted = isMuted;
this._generatePopupContent();

View File

@ -332,11 +332,10 @@ SmallVideo.prototype.updateStatusBar = function () {
? <VideoMutedIndicator
tooltipPosition = { tooltipPosition } />
: null }
{ this._isModerator
&& !interfaceConfig.DISABLE_FOCUS_INDICATOR
? <ModeratorIndicator
tooltipPosition = { tooltipPosition } />
: null }
{ this._isModerator && !interfaceConfig.DISABLE_FOCUS_INDICATOR
? <ModeratorIndicator
tooltipPosition = { tooltipPosition } />
: null }
</div>
</I18nextProvider>,
statusBarContainer);

View File

@ -23,11 +23,11 @@ const logger = require('jitsi-meet-logger').getLogger(__filename);
* @param videoSpaceHeight the height of the available space
* @return an array with 2 elements, the video width and the video height
*/
function computeDesktopVideoSize(videoWidth,
videoHeight,
videoSpaceWidth,
videoSpaceHeight) {
function computeDesktopVideoSize(
videoWidth,
videoHeight,
videoSpaceWidth,
videoSpaceHeight) {
let aspectRatio = videoWidth / videoHeight;
let availableWidth = Math.max(videoWidth, videoSpaceWidth);
@ -60,11 +60,12 @@ function computeDesktopVideoSize(videoWidth,
* @param videoSpaceHeight the height of the video space
* @return an array with 2 elements, the video width and the video height
*/
function computeCameraVideoSize(videoWidth,
videoHeight,
videoSpaceWidth,
videoSpaceHeight,
videoLayoutFit) {
function computeCameraVideoSize(
videoWidth,
videoHeight,
videoSpaceWidth,
videoSpaceHeight,
videoLayoutFit) {
const aspectRatio = videoWidth / videoHeight;
switch (videoLayoutFit) {
case 'height':
@ -110,10 +111,11 @@ function computeCameraVideoSize(videoWidth,
* @return an array with 2 elements, the horizontal indent and the vertical
* indent
*/
function getCameraVideoPosition(videoWidth,
videoHeight,
videoSpaceWidth,
videoSpaceHeight) {
function getCameraVideoPosition(
videoWidth,
videoHeight,
videoSpaceWidth,
videoSpaceHeight) {
// Parent height isn't completely calculated when we position the video in
// full screen mode and this is why we use the screen height in this case.
// Need to think it further at some point and implement it properly.

View File

@ -602,9 +602,10 @@ var VideoLayout = {
/**
* Resizes thumbnails.
*/
resizeThumbnails ( animate = false,
forceUpdate = false,
onComplete = null) {
resizeThumbnails(
animate = false,
forceUpdate = false,
onComplete = null) {
const { localVideo, remoteVideo }
= Filmstrip.calculateThumbnailSize();
@ -870,10 +871,10 @@ var VideoLayout = {
* @param completeFunction a function to be called when the video area is
* resized.
*/
resizeVideoArea (forceUpdate = false,
animate = false,
completeFunction = null) {
resizeVideoArea(
forceUpdate = false,
animate = false,
completeFunction = null) {
if (largeVideo) {
largeVideo.updateContainerSize();
largeVideo.resize(animate);

View File

@ -156,7 +156,10 @@ export default {
* }}
*/
getNewMediaDevicesAfterDeviceListChanged(
newDevices, isSharingScreen, localVideo, localAudio) {
newDevices,
isSharingScreen,
localVideo,
localAudio) {
return {
audioinput: getNewAudioInputDevice(newDevices, localAudio),
videoinput: !isSharingScreen &&
@ -173,7 +176,9 @@ export default {
* @returns {Promise.<JitsiLocalTrack[]>}
*/
createLocalTracksAfterDeviceListChanged(
createLocalTracks, cameraDeviceId, micDeviceId) {
createLocalTracks,
cameraDeviceId,
micDeviceId) {
let audioTrackError;
let videoTrackError;
let audioRequested = !!micDeviceId;
@ -181,27 +186,28 @@ export default {
if (audioRequested && videoRequested) {
// First we try to create both audio and video tracks together.
return createLocalTracks({
devices: ['audio', 'video'],
cameraDeviceId: cameraDeviceId,
micDeviceId: micDeviceId
})
// If we fail to do this, try to create them separately.
.catch(() => Promise.all([
createAudioTrack(false).then(([stream]) => stream),
createVideoTrack(false).then(([stream]) => stream)
]))
.then(tracks => {
if (audioTrackError) {
APP.UI.showMicErrorNotification(audioTrackError);
}
return (
createLocalTracks({
devices: ['audio', 'video'],
cameraDeviceId: cameraDeviceId,
micDeviceId: micDeviceId
})
// If we fail to do this, try to create them separately.
.catch(() => Promise.all([
createAudioTrack(false).then(([stream]) => stream),
createVideoTrack(false).then(([stream]) => stream)
]))
.then(tracks => {
if (audioTrackError) {
APP.UI.showMicErrorNotification(audioTrackError);
}
if (videoTrackError) {
APP.UI.showCameraErrorNotification(videoTrackError);
}
if (videoTrackError) {
APP.UI.showCameraErrorNotification(videoTrackError);
}
return tracks.filter(t => typeof t !== 'undefined');
});
return tracks.filter(t => typeof t !== 'undefined');
}));
} else if (videoRequested && !audioRequested) {
return createVideoTrack();
} else if (audioRequested && !videoRequested) {
@ -211,7 +217,8 @@ export default {
}
function createAudioTrack(showError) {
return createLocalTracks({
return (
createLocalTracks({
devices: ['audio'],
cameraDeviceId: null,
micDeviceId: micDeviceId
@ -220,11 +227,12 @@ export default {
audioTrackError = err;
showError && APP.UI.showMicErrorNotification(err);
return [];
});
}));
}
function createVideoTrack(showError) {
return createLocalTracks({
return (
createLocalTracks({
devices: ['video'],
cameraDeviceId: cameraDeviceId,
micDeviceId: null
@ -233,7 +241,7 @@ export default {
videoTrackError = err;
showError && APP.UI.showCameraErrorNotification(err);
return [];
});
}));
}
}
};

View File

@ -144,10 +144,11 @@ const KeyboardShortcut = {
* @param helpDescription the description of the shortcut that would appear
* in the help menu
*/
registerShortcut: function( shortcutChar,
shortcutAttr,
exec,
helpDescription) {
registerShortcut(
shortcutChar,
shortcutAttr,
exec,
helpDescription) {
_shortcuts[shortcutChar] = {
character: shortcutChar,
shortcutAttr: shortcutAttr,
@ -199,9 +200,9 @@ const KeyboardShortcut = {
if (typeof e.key === "string") {
return e.key;
}
if (e.type === "keypress" && (
(e.which >= 32 && e.which <= 126) ||
(e.which >= 160 && e.which <= 255) )) {
if (e.type === "keypress"
&& ((e.which >= 32 && e.which <= 126)
|| (e.which >= 160 && e.which <= 255) )) {
return String.fromCharCode(e.which);
}
// try to fallback (0-9A-Za-z and QWERTY keyboard)

View File

@ -15,10 +15,7 @@ import {
} from '../../service/remotecontrol/Constants';
import * as RemoteControlEvents
from '../../service/remotecontrol/RemoteControlEvents';
import {
Transport,
PostMessageTransportBackend
} from '../transport';
import { Transport, PostMessageTransportBackend } from '../transport';
import RemoteControlParticipant from './RemoteControlParticipant';

View File

@ -72,13 +72,13 @@
"strophe": "1.2.4",
"strophejs-plugins": "0.0.7",
"styled-components": "1.3.0",
"url-polyfill": "github/url-polyfill",
"url-polyfill": "github:github/url-polyfill",
"uuid": "3.1.0",
"xmldom": "0.1.27"
},
"devDependencies": {
"babel-core": "6.26.0",
"babel-eslint": "7.2.3",
"babel-eslint": "8.0.1",
"babel-loader": "7.1.2",
"babel-polyfill": "6.26.0",
"babel-preset-es2015": "6.24.1",
@ -86,12 +86,12 @@
"babel-preset-stage-1": "6.24.1",
"clean-css": "3.4.25",
"css-loader": "0.28.5",
"eslint": "3.19.0",
"eslint": "4.8.0",
"eslint-plugin-flowtype": "2.30.4",
"eslint-plugin-import": "2.7.0",
"eslint-plugin-jsdoc": "3.1.2",
"eslint-plugin-react": "6.10.3",
"eslint-plugin-react-native": "3.0.1",
"eslint-plugin-jsdoc": "3.1.3",
"eslint-plugin-react": "7.4.0",
"eslint-plugin-react-native": "3.1.0",
"expose-loader": "0.7.3",
"file-loader": "0.11.2",
"flow-bin": "0.38.0",
@ -109,7 +109,7 @@
},
"license": "Apache-2.0",
"scripts": {
"lint": "jshint . && eslint . && flow",
"lint": "eslint . && flow",
"validate": "npm ls"
},
"pre-commit": [

View File

@ -185,7 +185,6 @@ module.exports = {
'id-blacklist': 0,
'id-length': 0,
'id-match': 0,
'indent': [ 'error', 4, { 'SwitchCase': 0 } ],
'jsx-quotes': [ 'error', 'prefer-single' ],
'key-spacing': 2,
'keyword-spacing': 2,
@ -387,7 +386,12 @@ module.exports = {
'react/jsx-no-undef': 2,
'react/jsx-pascal-case': 2,
'react/jsx-sort-props': 2,
'react/jsx-space-before-closing': 2,
'react/jsx-tag-spacing': [
'error',
{
'beforeSelfClosing': 'always'
}
],
'react/jsx-uses-react': 2,
'react/jsx-uses-vars': 2,
'react/jsx-wrap-multilines': 2,

View File

@ -1,3 +1,5 @@
/* @flow */
import { setRoom } from '../base/conference';
import { loadConfigError, setConfig } from '../base/config';
import { setLocationURL } from '../base/connection';
@ -132,7 +134,7 @@ function _appNavigateToOptionalLocation(
* app: App
* }}
*/
export function appWillMount(app) {
export function appWillMount(app: Object) {
return (dispatch: Dispatch<*>) => {
dispatch({
type: APP_WILL_MOUNT,
@ -159,7 +161,7 @@ export function appWillMount(app) {
* app: App
* }}
*/
export function appWillUnmount(app) {
export function appWillUnmount(app: Object) {
return {
type: APP_WILL_UNMOUNT,
app

View File

@ -256,7 +256,7 @@ export function conferenceWillLeave(conference) {
* @returns {Function}
*/
export function createConference() {
return (dispatch, getState) => {
return (dispatch: Dispatch<*>, getState: Function) => {
const state = getState();
const { connection, locationURL } = state['features/base/connection'];
@ -297,7 +297,7 @@ export function createConference() {
* @returns {Function}
*/
export function checkIfCanJoin() {
return (dispatch, getState) => {
return (dispatch: Dispatch<*>, getState: Function) => {
const { authRequired, password }
= getState()['features/base/conference'];
@ -412,8 +412,8 @@ export function setLastN(lastN: ?number) {
* is to be joined or locked.
* @returns {Function}
*/
export function setPassword(conference, method, password) {
return (dispatch, getState) => {
export function setPassword(conference, method: Function, password: string) {
return (dispatch: Dispatch<*>, getState: Function) => {
switch (method) {
case conference.join: {
let state = getState()['features/base/conference'];
@ -478,7 +478,7 @@ export function setPassword(conference, method, password) {
* receiveVideoQuality: number
* }}
*/
export function setReceiveVideoQuality(receiveVideoQuality) {
export function setReceiveVideoQuality(receiveVideoQuality: number) {
return {
type: SET_RECEIVE_VIDEO_QUALITY,
receiveVideoQuality
@ -495,7 +495,7 @@ export function setReceiveVideoQuality(receiveVideoQuality) {
* room: string
* }}
*/
export function setRoom(room) {
export function setRoom(room: ?string) {
return {
type: SET_ROOM,
room

View File

@ -129,6 +129,8 @@ function _translateLegacyConfig(oldValue: Object) {
newValue = set(newValue, 'p2p', {});
}
/* eslint-disable indent */
// Translate the old config properties into the new config.p2p properties.
for (const [ oldKey, newKey ]
of [
@ -136,6 +138,9 @@ function _translateLegacyConfig(oldValue: Object) {
[ 'enableP2P', 'enabled' ],
[ 'p2pStunServers', 'stunServers' ]
]) {
/* eslint-enable indent */
if (oldKey in newValue) {
const v = newValue[oldKey];

View File

@ -158,8 +158,8 @@ function _constructOptions(locationURL: URL) {
return {
bosh:
`${String(protocol)}//${domain}${locationURI.contextRoot || '/'
}http-bind`,
`${String(protocol)}//${domain}${
locationURI.contextRoot || '/'}http-bind`,
hosts: {
domain,

View File

@ -1,3 +1,5 @@
/* @flow */
import i18next from 'i18next';
import I18nextXHRBackend from 'i18next-xhr-backend';

View File

@ -1,3 +1,5 @@
/* @flow */
import type { Dispatch } from 'redux';
import JitsiMeetJS from './_';
@ -95,7 +97,7 @@ export function libInitError(error: Error) {
* @returns {Function}
*/
export function setWebRTCReady(webRTCReady: boolean | Promise<*>) {
return (dispatch: Dispatch<*>, getState: Function) => {
return (dispatch: Function, getState: Function) => {
if (getState()['features/base/lib-jitsi-meet'].webRTCReady
!== webRTCReady) {
dispatch({

View File

@ -18,7 +18,7 @@ import { RTCPeerConnection, RTCSessionDescription } from 'react-native-webrtc';
*/
export default function _RTCPeerConnection(...args) {
/* eslint-disable no-invalid-this */
/* eslint-disable indent, no-invalid-this */
RTCPeerConnection.apply(this, args);
@ -44,7 +44,7 @@ export default function _RTCPeerConnection(...args) {
}
});
/* eslint-enable no-invalid-this */
/* eslint-enable indent, no-invalid-this */
}
_RTCPeerConnection.prototype = Object.create(RTCPeerConnection.prototype);

View File

@ -10,7 +10,9 @@ export default class AbstractAudio extends Component {
* The (reference to the) {@link ReactElement} which actually implements
* this {@code AbstractAudio}.
*/
_ref: ?Object
_ref: ?Object;
_setRef: Function;
/**
* {@code AbstractAudio} component's property types.
@ -33,7 +35,7 @@ export default class AbstractAudio extends Component {
* @param {Object} props - The read-only properties with which the new
* instance is to be initialized.
*/
constructor(props) {
constructor(props: Object) {
super(props);
// Bind event handlers so they are only bound once for every instance.

View File

@ -95,6 +95,7 @@ export default class Avatar extends Component {
};
if (assignState) {
// eslint-disable-next-line react/no-direct-mutation-state
this.state = nextState;
} else {
this.setState(nextState);
@ -134,6 +135,7 @@ export default class Avatar extends Component {
observer,
/* immutable */ true);
} else if (assignState) {
// eslint-disable-next-line react/no-direct-mutation-state
this.state = {
...this.state,
source: nextSource
@ -185,7 +187,7 @@ export default class Avatar extends Component {
for (let i = 0; i < uri.length; i++) {
hash = uri.charCodeAt(i) + ((hash << 5) - hash);
hash |= 0; // Convert to 32-bit integer
hash |= 0; // Convert to 32-bit integer
}
/* eslint-enable no-bitwise */

View File

@ -1,3 +1,5 @@
/* @flow */
import UIEvents from '../../../../service/UI/UIEvents';
import {

View File

@ -1,3 +1,5 @@
/* @flow */
import AKButton from '@atlaskit/button';
import PropTypes from 'prop-types';
import React, { Component } from 'react';

View File

@ -1,5 +1,6 @@
/* @flow */
import PropTypes from 'prop-types';
import React, { Component } from 'react';
import { connect } from 'react-redux';
@ -21,6 +22,11 @@ const _RIGHT_WATERMARK_STYLE = {
* etc.
*/
class Watermarks extends Component {
static propTypes = {
_isGuest: PropTypes.bool,
t: PropTypes.func
};
state = {
brandWatermarkLink: String,
jitsiWatermarkLink: String,

View File

@ -203,10 +203,10 @@ class Conference extends Component {
* The activity/loading indicator goes above everything, except
* the toolbox/toolbars and the dialogs.
*/
this.props._connecting
&& <View style = { styles.connectingIndicator }>
<LoadingIndicator />
</View>
this.props._connecting
&& <View style = { styles.connectingIndicator }>
<LoadingIndicator />
</View>
}
{/*

View File

@ -311,8 +311,8 @@ class ConnectionStatsTable extends Component {
_renderShowMoreLink() {
const translationKey
= this.props.shouldShowMore
? 'connectionindicator.less'
: 'connectionindicator.more';
? 'connectionindicator.less'
: 'connectionindicator.more';
return (
<a

View File

@ -1,3 +1,5 @@
/* @flow */
import PropTypes from 'prop-types';
import React, { Component } from 'react';
import { connect } from 'react-redux';

View File

@ -62,6 +62,8 @@ class DesktopPickerPane extends Component {
const previews
= sources.map(
source =>
// eslint-disable-next-line react/jsx-wrap-multilines
<DesktopSourcePreview
key = { source.id }
onClick = { onClick }

View File

@ -81,7 +81,7 @@ function _openDeviceSelectionDialogInPopup() {
const scope = `dialog_${API_ID}`;
const url = `${
window.location.origin}/static/deviceSelectionPopup.html#scope=${
encodeURIComponent(JSON.stringify(scope))}`;
encodeURIComponent(JSON.stringify(scope))}`;
const popup
= window.open(
url,

View File

@ -30,8 +30,9 @@ export default class CountryIcon extends Component {
*/
render() {
const iconClassName
= `flag-icon flag-icon-${this.props.countryCode
} flag-icon-squared ${this.props.className}`;
= `flag-icon flag-icon-${
this.props.countryCode} flag-icon-squared ${
this.props.className}`;
return <span className = { iconClassName } />;
}

View File

@ -23,6 +23,8 @@ class FeedbackButton extends Component {
*/
_conference: PropTypes.object,
dispatch: PropTypes.func,
/**
* Invoked to obtain translated strings.
*/

View File

@ -12,8 +12,8 @@ import { cancelFeedback, submitFeedback } from '../actions';
declare var interfaceConfig: Object;
const scoreAnimationClass = interfaceConfig.ENABLE_FEEDBACK_ANIMATION
? 'shake-rotate' : '';
const scoreAnimationClass
= interfaceConfig.ENABLE_FEEDBACK_ANIMATION ? 'shake-rotate' : '';
/**
* The scores to display for selecting. The score is the index in the array and

View File

@ -53,19 +53,22 @@ class Filmstrip extends Component {
visible = { this.props._visible }>
<ScrollView
// eslint-disable-next-line react/jsx-curly-spacing
contentContainerStyle = {
styles.filmstripScrollViewContentContainer
} // eslint-disable-line react/jsx-curly-spacing
contentContainerStyle
= { styles.filmstripScrollViewContentContainer }
horizontal = { true }
showsHorizontalScrollIndicator = { false }
showsVerticalScrollIndicator = { false }>
{
/* eslint-disable react/jsx-wrap-multilines */
this._sort(this.props._participants)
.map(p =>
<Thumbnail
key = { p.id }
participant = { p } />)
/* eslint-enable react/jsx-wrap-multilines */
}
</ScrollView>
</Container>

View File

@ -1,3 +1,5 @@
/* @flow */
declare var interfaceConfig: Object;
import {
@ -12,7 +14,7 @@ import {
* @param {Object} state - The full redux state.
* @returns {boolean} - True if remote video thumbnails should be displayed.
*/
export function shouldRemoteVideosBeVisible(state) {
export function shouldRemoteVideosBeVisible(state: Object) {
const participants = state['features/base/participants'];
const participantsCount = participants.length;

View File

@ -334,7 +334,7 @@ function _mapStateToProps(state) {
inviteServiceUrl,
peopleSearchQueryTypes,
peopleSearchUrl
} = state['features/base/config'];
} = state['features/base/config'];
return {
_conference: conference,

View File

@ -10,12 +10,11 @@ declare var $: Function;
* executed - "conferenceRooms" | "user" | "room".
* @returns {Promise} - The promise created by the request.
*/
export function searchPeople(// eslint-disable-line max-params
serviceUrl,
jwt,
text,
queryTypes = [ 'conferenceRooms', 'user', 'room' ]
) {
export function searchPeople( // eslint-disable-line max-params
serviceUrl,
jwt,
text,
queryTypes = [ 'conferenceRooms', 'user', 'room' ]) {
const queryTypesString = JSON.stringify(queryTypes);
return new Promise((resolve, reject) => {

View File

@ -1,3 +1,5 @@
/* @flow */
import { setLastN } from '../../base/conference';
import { setVideoMuted, VIDEO_MUTISM_AUTHORITY } from '../../base/media';
@ -31,7 +33,7 @@ export function _setAppStateListener(listener: ?Function) {
* @returns {Function}
*/
export function _setBackgroundVideoMuted(muted: boolean) {
return (dispatch, getState) => {
return (dispatch: Dispatch<*>, getState: Function) => {
// Disable remote video when we mute by setting lastN to 0. Skip it if
// the conference is in audio-only mode, as it's already configured to
// have no video. Leave it as undefined when unmuting, the default value

View File

@ -74,7 +74,7 @@ MiddlewareRegistry.register(store => next => action => {
* @private
* @returns {void}
*/
function _appStateChanged(dispatch: Dispatch<*>, appState: string) {
function _appStateChanged(dispatch: Function, appState: string) {
let muted;
switch (appState) {

View File

@ -47,11 +47,18 @@ function _alertPermissionErrorWithSettings(trackType) {
// TODO i18n
const deviceType = trackType === 'video' ? 'Camera' : 'Microphone';
/* eslint-disable indent */
const message
= `${deviceType
} permission is required to participate in conferences with ${
trackType}. Please grant it in Settings.`;
/* eslint-ensable indent */
Alert.alert(
'Permission required',
`${deviceType
} permission is required to participate in conferences with ${
trackType}. Please grant it in Settings.`,
message,
[
{ text: 'Cancel' },
{

View File

@ -1,3 +1,5 @@
/* @flow */
import PropTypes from 'prop-types';
import React, { Component } from 'react';
import { connect } from 'react-redux';

View File

@ -2,10 +2,7 @@ import PropTypes from 'prop-types';
import React, { Component } from 'react';
import { connect } from 'react-redux';
import {
Dialog,
hideDialog
} from '../../base/dialog';
import { Dialog, hideDialog } from '../../base/dialog';
import { translate } from '../../base/i18n';
import { getParticipantById } from '../../base/participants';

View File

@ -123,8 +123,7 @@ class Toolbar extends Component {
* @private
* @returns {ReactElement} A toolbar button.
*/
_renderToolbarButton(
keyValuePair: Array<*>): ReactElement<*> {
_renderToolbarButton(keyValuePair: Array<*>): ReactElement<*> {
const [ key, button ] = keyValuePair;
if (button.component) {

View File

@ -72,6 +72,7 @@ class LocalVideoTrackUnderlay extends Component {
};
if (assignState) {
// eslint-disable-next-line react/no-direct-mutation-state
this.state = nextState;
} else {
this.setState(nextState);

View File

@ -209,6 +209,8 @@ function devServerProxyBypass({ path }) {
const configs = module.exports;
/* eslint-disable indent */
if ((Array.isArray(configs) ? configs : Array(configs)).some(c => {
if (path.startsWith(c.output.publicPath)) {
if (!minimize) {
@ -231,4 +233,6 @@ function devServerProxyBypass({ path }) {
})) {
return path;
}
/* eslint-enable indent */
}