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' 'flowtype'
], ],
'rules': { 'rules': {
'indent': [
'error',
4,
{
'CallExpression': {
arguments: 'off'
},
'FunctionDeclaration': {
parameters: 2
},
'FunctionExpression': {
parameters: 2
},
'MemberExpression': 'off',
'SwitchCase': 0
}
],
'new-cap': [ 'new-cap': [
'error', '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 */ /* global ga */
/* eslint-disable indent */
(function (ctx) { (function (ctx) {
function Analytics() { function Analytics() {
/* eslint-disable */ /* eslint-disable semi */
/** /**
* Google Analytics * Google Analytics
@ -13,7 +14,7 @@
ga('create', 'UA-319188-14', 'jit.si'); ga('create', 'UA-319188-14', 'jit.si');
ga('send', 'pageview'); ga('send', 'pageview');
/* eslint-enable */ /* eslint-enable semi */
} }
Analytics.prototype.sendEvent = function (action, data) { Analytics.prototype.sendEvent = function (action, data) {
@ -29,10 +30,8 @@
if (typeof ctx.JitsiMeetJS === "undefined") if (typeof ctx.JitsiMeetJS === "undefined")
ctx.JitsiMeetJS = {}; ctx.JitsiMeetJS = {};
if (typeof ctx.JitsiMeetJS.app === "undefined") if (typeof ctx.JitsiMeetJS.app === "undefined")
ctx.JitsiMeetJS.app = {}; ctx.JitsiMeetJS.app = {};
if (typeof ctx.JitsiMeetJS.app.analyticsHandlers === "undefined") if (typeof ctx.JitsiMeetJS.app.analyticsHandlers === "undefined")
ctx.JitsiMeetJS.app.analyticsHandlers = []; ctx.JitsiMeetJS.app.analyticsHandlers = [];
ctx.JitsiMeetJS.app.analyticsHandlers.push(Analytics); ctx.JitsiMeetJS.app.analyticsHandlers.push(Analytics);

View File

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

View File

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

View File

@ -87,8 +87,8 @@ function generateURL(domain, options = {}) {
return urlObjectToString({ return urlObjectToString({
...options, ...options,
url: url:
`${options.noSSL ? 'http' : 'https'}://${domain `${options.noSSL ? 'http' : 'https'}://${
}/#jitsi_meet_external_api_id=${id}` 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. * @param {number} opacity the opacity to set for the specified dot.
*/ */
_setDotLevel(elementID, index, opacity) { _setDotLevel(elementID, index, opacity) {
let audioSpan
let audioSpan = document.getElementById(elementID) = document.getElementById(elementID)
.getElementsByClassName("audioindicator"); .getElementsByClassName("audioindicator");
// Make sure the audio span is still around. // Make sure the audio span is still around.
if (audioSpan && audioSpan.length > 0) if (audioSpan && audioSpan.length > 0)
@ -72,17 +72,17 @@ const AudioLevels = {
/** /**
* Updates the large video shadow effect. * Updates the large video shadow effect.
*/ */
_updateLargeVideoShadow (level) { _updateLargeVideoShadow(level) {
var scale = 2, const scale = 2;
// Internal circle audio level. // Internal circle audio level.
int = { const int = {
level: level > 0.15 ? 20 : 0, level: level > 0.15 ? 20 : 0,
color: interfaceConfig.AUDIO_LEVEL_PRIMARY_COLOR color: interfaceConfig.AUDIO_LEVEL_PRIMARY_COLOR
}, };
// External circle audio level. // External circle audio level.
ext = { const ext = {
level: (int.level * scale * level + int.level).toFixed(0), level: (int.level * scale * level + int.level).toFixed(0),
color: interfaceConfig.AUDIO_LEVEL_SECONDARY_COLOR color: interfaceConfig.AUDIO_LEVEL_SECONDARY_COLOR
}; };

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -18,7 +18,7 @@ import { RTCPeerConnection, RTCSessionDescription } from 'react-native-webrtc';
*/ */
export default function _RTCPeerConnection(...args) { export default function _RTCPeerConnection(...args) {
/* eslint-disable no-invalid-this */ /* eslint-disable indent, no-invalid-this */
RTCPeerConnection.apply(this, args); 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); _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 * The (reference to the) {@link ReactElement} which actually implements
* this {@code AbstractAudio}. * this {@code AbstractAudio}.
*/ */
_ref: ?Object _ref: ?Object;
_setRef: Function;
/** /**
* {@code AbstractAudio} component's property types. * {@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 * @param {Object} props - The read-only properties with which the new
* instance is to be initialized. * instance is to be initialized.
*/ */
constructor(props) { constructor(props: Object) {
super(props); super(props);
// Bind event handlers so they are only bound once for every instance. // 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) { if (assignState) {
// eslint-disable-next-line react/no-direct-mutation-state
this.state = nextState; this.state = nextState;
} else { } else {
this.setState(nextState); this.setState(nextState);
@ -134,6 +135,7 @@ export default class Avatar extends Component {
observer, observer,
/* immutable */ true); /* immutable */ true);
} else if (assignState) { } else if (assignState) {
// eslint-disable-next-line react/no-direct-mutation-state
this.state = { this.state = {
...this.state, ...this.state,
source: nextSource source: nextSource
@ -185,7 +187,7 @@ export default class Avatar extends Component {
for (let i = 0; i < uri.length; i++) { for (let i = 0; i < uri.length; i++) {
hash = uri.charCodeAt(i) + ((hash << 5) - hash); 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 */ /* eslint-enable no-bitwise */

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -12,8 +12,8 @@ import { cancelFeedback, submitFeedback } from '../actions';
declare var interfaceConfig: Object; declare var interfaceConfig: Object;
const scoreAnimationClass = interfaceConfig.ENABLE_FEEDBACK_ANIMATION const scoreAnimationClass
? 'shake-rotate' : ''; = interfaceConfig.ENABLE_FEEDBACK_ANIMATION ? 'shake-rotate' : '';
/** /**
* The scores to display for selecting. The score is the index in the array and * 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 }> visible = { this.props._visible }>
<ScrollView <ScrollView
// eslint-disable-next-line react/jsx-curly-spacing contentContainerStyle
contentContainerStyle = { = { styles.filmstripScrollViewContentContainer }
styles.filmstripScrollViewContentContainer
} // eslint-disable-line react/jsx-curly-spacing
horizontal = { true } horizontal = { true }
showsHorizontalScrollIndicator = { false } showsHorizontalScrollIndicator = { false }
showsVerticalScrollIndicator = { false }> showsVerticalScrollIndicator = { false }>
{ {
/* eslint-disable react/jsx-wrap-multilines */
this._sort(this.props._participants) this._sort(this.props._participants)
.map(p => .map(p =>
<Thumbnail <Thumbnail
key = { p.id } key = { p.id }
participant = { p } />) participant = { p } />)
/* eslint-enable react/jsx-wrap-multilines */
} }
</ScrollView> </ScrollView>
</Container> </Container>

View File

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

View File

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

View File

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

View File

@ -1,3 +1,5 @@
/* @flow */
import { setLastN } from '../../base/conference'; import { setLastN } from '../../base/conference';
import { setVideoMuted, VIDEO_MUTISM_AUTHORITY } from '../../base/media'; import { setVideoMuted, VIDEO_MUTISM_AUTHORITY } from '../../base/media';
@ -31,7 +33,7 @@ export function _setAppStateListener(listener: ?Function) {
* @returns {Function} * @returns {Function}
*/ */
export function _setBackgroundVideoMuted(muted: boolean) { 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 // 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 // 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 // have no video. Leave it as undefined when unmuting, the default value

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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