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:
parent
d280f90676
commit
dfebd692f3
17
.eslintrc.js
17
.eslintrc.js
|
@ -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',
|
||||
{
|
||||
|
|
|
@ -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
|
20
.jshintrc
20
.jshintrc
|
@ -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
|
||||
}
|
|
@ -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);
|
||||
|
|
245
conference.js
245
conference.js
|
@ -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) => {
|
||||
|
||||
|
|
|
@ -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',
|
||||
|
|
|
@ -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}`
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
};
|
||||
|
|
|
@ -111,8 +111,7 @@ function initJWTTokenListener(room) {
|
|||
logger.error(
|
||||
"Authentication failed: ", err, errCode);
|
||||
unregister();
|
||||
}
|
||||
);
|
||||
});
|
||||
}).catch(function (error, code) {
|
||||
unregister();
|
||||
connection.disconnect();
|
||||
|
|
|
@ -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));
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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)))
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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 [];
|
||||
});
|
||||
}));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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';
|
||||
|
||||
|
|
14
package.json
14
package.json
|
@ -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": [
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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];
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
/* @flow */
|
||||
|
||||
import i18next from 'i18next';
|
||||
import I18nextXHRBackend from 'i18next-xhr-backend';
|
||||
|
||||
|
|
|
@ -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({
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
/* @flow */
|
||||
|
||||
import UIEvents from '../../../../service/UI/UIEvents';
|
||||
|
||||
import {
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
/* @flow */
|
||||
|
||||
import AKButton from '@atlaskit/button';
|
||||
import PropTypes from 'prop-types';
|
||||
import React, { Component } from 'react';
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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>
|
||||
}
|
||||
|
||||
{/*
|
||||
|
|
|
@ -311,8 +311,8 @@ class ConnectionStatsTable extends Component {
|
|||
_renderShowMoreLink() {
|
||||
const translationKey
|
||||
= this.props.shouldShowMore
|
||||
? 'connectionindicator.less'
|
||||
: 'connectionindicator.more';
|
||||
? 'connectionindicator.less'
|
||||
: 'connectionindicator.more';
|
||||
|
||||
return (
|
||||
<a
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
/* @flow */
|
||||
|
||||
import PropTypes from 'prop-types';
|
||||
import React, { Component } from 'react';
|
||||
import { connect } from 'react-redux';
|
||||
|
|
|
@ -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 }
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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 } />;
|
||||
}
|
||||
|
|
|
@ -23,6 +23,8 @@ class FeedbackButton extends Component {
|
|||
*/
|
||||
_conference: PropTypes.object,
|
||||
|
||||
dispatch: PropTypes.func,
|
||||
|
||||
/**
|
||||
* Invoked to obtain translated strings.
|
||||
*/
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -334,7 +334,7 @@ function _mapStateToProps(state) {
|
|||
inviteServiceUrl,
|
||||
peopleSearchQueryTypes,
|
||||
peopleSearchUrl
|
||||
} = state['features/base/config'];
|
||||
} = state['features/base/config'];
|
||||
|
||||
return {
|
||||
_conference: conference,
|
||||
|
|
|
@ -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) => {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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' },
|
||||
{
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
/* @flow */
|
||||
|
||||
import PropTypes from 'prop-types';
|
||||
import React, { Component } from 'react';
|
||||
import { connect } from 'react-redux';
|
||||
|
|
|
@ -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';
|
||||
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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 */
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue