浏览代码

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+.
master
Lyubo Marinov 7 年前
父节点
当前提交
dfebd692f3
共有 56 个文件被更改,包括 426 次插入376 次删除
  1. 17
    0
      .eslintrc.js
  2. 0
    22
      .jshintignore
  3. 0
    20
      .jshintrc
  4. 3
    4
      analytics.js
  5. 123
    124
      conference.js
  6. 14
    12
      modules/API/API.js
  7. 2
    2
      modules/API/external/external_api.js
  8. 8
    8
      modules/UI/audio_levels/AudioLevels.js
  9. 1
    2
      modules/UI/authentication/AuthHandler.js
  10. 6
    5
      modules/UI/shared_video/SharedVideo.js
  11. 4
    0
      modules/UI/side_pannels/chat/Replacement.js
  12. 26
    15
      modules/UI/util/MessageHandler.js
  13. 12
    12
      modules/UI/util/UIUtil.js
  14. 24
    24
      modules/UI/videolayout/Filmstrip.js
  15. 4
    3
      modules/UI/videolayout/LargeVideoManager.js
  16. 1
    2
      modules/UI/videolayout/RemoteVideo.js
  17. 4
    5
      modules/UI/videolayout/SmallVideo.js
  18. 16
    14
      modules/UI/videolayout/VideoContainer.js
  19. 8
    7
      modules/UI/videolayout/VideoLayout.js
  20. 33
    25
      modules/devices/mediaDeviceHelper.js
  21. 8
    7
      modules/keyboardshortcut/keyboardshortcut.js
  22. 1
    4
      modules/remotecontrol/Receiver.js
  23. 7
    7
      package.json
  24. 6
    2
      react/.eslintrc.js
  25. 4
    2
      react/features/app/actions.js
  26. 6
    6
      react/features/base/conference/actions.js
  27. 5
    0
      react/features/base/config/reducer.js
  28. 2
    2
      react/features/base/connection/reducer.js
  29. 2
    0
      react/features/base/i18n/i18next.js
  30. 3
    1
      react/features/base/lib-jitsi-meet/actions.js
  31. 2
    2
      react/features/base/lib-jitsi-meet/native/RTCPeerConnection.js
  32. 4
    2
      react/features/base/media/components/AbstractAudio.js
  33. 3
    1
      react/features/base/participants/components/Avatar.native.js
  34. 2
    0
      react/features/base/participants/middleware.js
  35. 2
    0
      react/features/base/react/components/web/InlineDialogFailure.js
  36. 6
    0
      react/features/base/react/components/web/Watermarks.js
  37. 4
    4
      react/features/conference/components/Conference.native.js
  38. 2
    2
      react/features/connection-stats/components/ConnectionStatsTable.js
  39. 2
    0
      react/features/contact-list/components/ContactListPanel.web.js
  40. 2
    0
      react/features/desktop-picker/components/DesktopPickerPane.js
  41. 1
    1
      react/features/device-selection/actions.js
  42. 3
    2
      react/features/dial-out/components/CountryIcon.js
  43. 2
    0
      react/features/feedback/components/FeedbackButton.web.js
  44. 2
    2
      react/features/feedback/components/FeedbackDialog.web.js
  45. 7
    4
      react/features/filmstrip/components/Filmstrip.native.js
  46. 3
    1
      react/features/filmstrip/functions.js
  47. 1
    1
      react/features/invite/components/AddPeopleDialog.web.js
  48. 5
    6
      react/features/invite/functions.js
  49. 3
    1
      react/features/mobile/background/actions.js
  50. 1
    1
      react/features/mobile/background/middleware.js
  51. 10
    3
      react/features/mobile/permissions/middleware.js
  52. 2
    0
      react/features/overlay/components/ReloadButton.js
  53. 1
    4
      react/features/remote-control/components/RemoteControlAuthorizationDialog.js
  54. 1
    2
      react/features/toolbox/components/Toolbar.web.js
  55. 1
    0
      react/features/welcome/components/LocalVideoTrackUnderlay.native.js
  56. 4
    0
      webpack.config.js

+ 17
- 0
.eslintrc.js 查看文件

26
         'flowtype'
26
         'flowtype'
27
     ],
27
     ],
28
     'rules': {
28
     'rules': {
29
+        'indent': [
30
+            'error',
31
+            4,
32
+            {
33
+                'CallExpression': {
34
+                    arguments: 'off'
35
+                },
36
+                'FunctionDeclaration': {
37
+                    parameters: 2
38
+                },
39
+                'FunctionExpression': {
40
+                    parameters: 2
41
+                },
42
+                'MemberExpression': 'off',
43
+                'SwitchCase': 0
44
+            }
45
+        ],
29
         'new-cap': [
46
         'new-cap': [
30
             'error',
47
             'error',
31
             {
48
             {

+ 0
- 22
.jshintignore 查看文件

1
-# The following do not need to be checked because they do not represent JS
2
-# source code.
3
-build/
4
-debian/
5
-libs/
6
-node_modules/
7
-
8
-# The following are checked by ESLint with the maximum configuration which
9
-# supersedes JSHint.
10
-flow-typed/
11
-modules/API/
12
-modules/remotecontrol/
13
-modules/transport/
14
-react/
15
-
16
-# The following are checked by ESLint with the minimum configuration which does
17
-# not supersede JSHint but take advantage of advanced language features such as
18
-# Facebook Flow which are not supported by JSHint.
19
-app.js
20
-modules/translation/translation.js
21
-
22
-analytics.js

+ 0
- 20
.jshintrc 查看文件

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

+ 3
- 4
analytics.js 查看文件

1
 /* global ga */
1
 /* global ga */
2
+/* eslint-disable indent */
2
 
3
 
3
 (function (ctx) {
4
 (function (ctx) {
4
   function Analytics() {
5
   function Analytics() {
5
-    /* eslint-disable */
6
+    /* eslint-disable semi */
6
 
7
 
7
     /**
8
     /**
8
      * Google Analytics
9
      * Google Analytics
13
     ga('create', 'UA-319188-14', 'jit.si');
14
     ga('create', 'UA-319188-14', 'jit.si');
14
     ga('send', 'pageview');
15
     ga('send', 'pageview');
15
 
16
 
16
-    /* eslint-enable */
17
+    /* eslint-enable semi */
17
   }
18
   }
18
 
19
 
19
   Analytics.prototype.sendEvent = function (action, data) {
20
   Analytics.prototype.sendEvent = function (action, data) {
29
 
30
 
30
   if (typeof ctx.JitsiMeetJS === "undefined")
31
   if (typeof ctx.JitsiMeetJS === "undefined")
31
     ctx.JitsiMeetJS = {};
32
     ctx.JitsiMeetJS = {};
32
-
33
   if (typeof ctx.JitsiMeetJS.app === "undefined")
33
   if (typeof ctx.JitsiMeetJS.app === "undefined")
34
     ctx.JitsiMeetJS.app = {};
34
     ctx.JitsiMeetJS.app = {};
35
-
36
   if (typeof ctx.JitsiMeetJS.app.analyticsHandlers === "undefined")
35
   if (typeof ctx.JitsiMeetJS.app.analyticsHandlers === "undefined")
37
     ctx.JitsiMeetJS.app.analyticsHandlers = [];
36
     ctx.JitsiMeetJS.app.analyticsHandlers = [];
38
   ctx.JitsiMeetJS.app.analyticsHandlers.push(Analytics);
37
   ctx.JitsiMeetJS.app.analyticsHandlers.push(Analytics);

+ 123
- 124
conference.js 查看文件

123
 function connect(roomName) {
123
 function connect(roomName) {
124
     return openConnection({retry: true, roomName: roomName})
124
     return openConnection({retry: true, roomName: roomName})
125
             .catch(function (err) {
125
             .catch(function (err) {
126
-        if (err === ConnectionErrors.PASSWORD_REQUIRED) {
127
-            APP.UI.notifyTokenAuthFailed();
128
-        } else {
129
-            APP.UI.notifyConnectionFailed(err);
130
-        }
131
-        throw err;
132
-    });
126
+                if (err === ConnectionErrors.PASSWORD_REQUIRED) {
127
+                    APP.UI.notifyTokenAuthFailed();
128
+                } else {
129
+                    APP.UI.notifyConnectionFailed(err);
130
+                }
131
+                throw err;
132
+            });
133
 }
133
 }
134
 
134
 
135
 /**
135
 /**
286
         logger.error('CONFERENCE FAILED:', err, ...params);
286
         logger.error('CONFERENCE FAILED:', err, ...params);
287
 
287
 
288
         switch (err) {
288
         switch (err) {
289
-        case ConferenceErrors.CONNECTION_ERROR:
290
-            {
291
-                let [msg] = params;
292
-                APP.UI.notifyConnectionFailed(msg);
293
-            }
289
+        case ConferenceErrors.CONNECTION_ERROR: {
290
+            let [msg] = params;
291
+            APP.UI.notifyConnectionFailed(msg);
294
             break;
292
             break;
293
+        }
295
 
294
 
296
-        case ConferenceErrors.NOT_ALLOWED_ERROR:
297
-            {
298
-                // let's show some auth not allowed page
299
-                assignWindowLocationPathname('static/authError.html');
300
-            }
295
+        case ConferenceErrors.NOT_ALLOWED_ERROR: {
296
+            // let's show some auth not allowed page
297
+            assignWindowLocationPathname('static/authError.html');
301
             break;
298
             break;
299
+        }
302
 
300
 
303
-            // not enough rights to create conference
301
+        // not enough rights to create conference
304
         case ConferenceErrors.AUTHENTICATION_REQUIRED: {
302
         case ConferenceErrors.AUTHENTICATION_REQUIRED: {
305
-                // Schedule reconnect to check if someone else created the room.
306
-                this.reconnectTimeout = setTimeout(() => room.join(), 5000);
303
+            // Schedule reconnect to check if someone else created the room.
304
+            this.reconnectTimeout = setTimeout(() => room.join(), 5000);
307
 
305
 
308
-                const { password }
309
-                    = APP.store.getState()['features/base/conference'];
306
+            const { password }
307
+                = APP.store.getState()['features/base/conference'];
308
+
309
+            AuthHandler.requireAuth(room, password);
310
 
310
 
311
-                AuthHandler.requireAuth(room, password);
312
-            }
313
             break;
311
             break;
312
+        }
314
 
313
 
315
-        case ConferenceErrors.RESERVATION_ERROR:
316
-            {
317
-                let [code, msg] = params;
318
-                APP.UI.notifyReservationError(code, msg);
319
-            }
314
+        case ConferenceErrors.RESERVATION_ERROR: {
315
+            let [code, msg] = params;
316
+            APP.UI.notifyReservationError(code, msg);
320
             break;
317
             break;
318
+        }
321
 
319
 
322
         case ConferenceErrors.GRACEFUL_SHUTDOWN:
320
         case ConferenceErrors.GRACEFUL_SHUTDOWN:
323
             APP.UI.notifyGracefulShutdown();
321
             APP.UI.notifyGracefulShutdown();
327
             APP.UI.notifyInternalError();
325
             APP.UI.notifyInternalError();
328
             break;
326
             break;
329
 
327
 
330
-        case ConferenceErrors.CONFERENCE_DESTROYED:
331
-            {
332
-                let [reason] = params;
333
-                APP.UI.hideStats();
334
-                APP.UI.notifyConferenceDestroyed(reason);
335
-            }
328
+        case ConferenceErrors.CONFERENCE_DESTROYED: {
329
+            let [reason] = params;
330
+            APP.UI.hideStats();
331
+            APP.UI.notifyConferenceDestroyed(reason);
336
             break;
332
             break;
333
+        }
337
 
334
 
338
-            // FIXME FOCUS_DISCONNECTED is confusing event name.
339
-            // What really happens there is that the library is not ready yet,
340
-            // because Jicofo is not available, but it is going to give
341
-            // it another try.
342
-        case ConferenceErrors.FOCUS_DISCONNECTED:
343
-            {
344
-                let [focus, retrySec] = params;
345
-                APP.UI.notifyFocusDisconnected(focus, retrySec);
346
-            }
335
+        // FIXME FOCUS_DISCONNECTED is a confusing event name.
336
+        // What really happens there is that the library is not ready yet,
337
+        // because Jicofo is not available, but it is going to give it another
338
+        // try.
339
+        case ConferenceErrors.FOCUS_DISCONNECTED: {
340
+            let [focus, retrySec] = params;
341
+            APP.UI.notifyFocusDisconnected(focus, retrySec);
347
             break;
342
             break;
343
+        }
348
 
344
 
349
         case ConferenceErrors.FOCUS_LEFT:
345
         case ConferenceErrors.FOCUS_LEFT:
350
         case ConferenceErrors.VIDEOBRIDGE_NOT_AVAILABLE:
346
         case ConferenceErrors.VIDEOBRIDGE_NOT_AVAILABLE:
358
             connection.disconnect();
354
             connection.disconnect();
359
             APP.UI.notifyMaxUsersLimitReached();
355
             APP.UI.notifyMaxUsersLimitReached();
360
             break;
356
             break;
357
+
361
         case ConferenceErrors.INCOMPATIBLE_SERVER_VERSIONS:
358
         case ConferenceErrors.INCOMPATIBLE_SERVER_VERSIONS:
362
             reload();
359
             reload();
363
             break;
360
             break;
361
+
364
         default:
362
         default:
365
             this._handleConferenceFailed(err, ...params);
363
             this._handleConferenceFailed(err, ...params);
366
         }
364
         }
644
     init(options) {
642
     init(options) {
645
         this.roomName = options.roomName;
643
         this.roomName = options.roomName;
646
         // attaches global error handler, if there is already one, respect it
644
         // attaches global error handler, if there is already one, respect it
647
-        if (JitsiMeetJS.getGlobalOnErrorHandler){
645
+        if (JitsiMeetJS.getGlobalOnErrorHandler) {
648
             var oldOnErrorHandler = window.onerror;
646
             var oldOnErrorHandler = window.onerror;
649
             window.onerror = function (message, source, lineno, colno, error) {
647
             window.onerror = function (message, source, lineno, colno, error) {
650
                 JitsiMeetJS.getGlobalOnErrorHandler(
648
                 JitsiMeetJS.getGlobalOnErrorHandler(
656
 
654
 
657
             var oldOnUnhandledRejection = window.onunhandledrejection;
655
             var oldOnUnhandledRejection = window.onunhandledrejection;
658
             window.onunhandledrejection = function(event) {
656
             window.onunhandledrejection = function(event) {
659
-
660
-            JitsiMeetJS.getGlobalOnErrorHandler(
657
+                JitsiMeetJS.getGlobalOnErrorHandler(
661
                     null, null, null, null, event.reason);
658
                     null, null, null, null, event.reason);
662
 
659
 
663
                 if (oldOnUnhandledRejection)
660
                 if (oldOnUnhandledRejection)
664
                     oldOnUnhandledRejection(event);
661
                     oldOnUnhandledRejection(event);
665
             };
662
             };
666
         }
663
         }
667
-        return JitsiMeetJS.init(
668
-            Object.assign({
669
-                    enableAnalyticsLogging: isAnalyticsEnabled(APP.store)
670
-                },
671
-                config)
672
-            ).then(() => {
664
+        return (
665
+            JitsiMeetJS.init({
666
+                enableAnalyticsLogging: isAnalyticsEnabled(APP.store),
667
+                ...config
668
+            }).then(() => {
673
                 initAnalytics(APP.store);
669
                 initAnalytics(APP.store);
674
                 return this.createInitialLocalTracksAndConnect(
670
                 return this.createInitialLocalTracksAndConnect(
675
                     options.roomName, {
671
                     options.roomName, {
733
                 return new Promise((resolve, reject) => {
729
                 return new Promise((resolve, reject) => {
734
                     (new ConferenceConnector(resolve, reject)).connect();
730
                     (new ConferenceConnector(resolve, reject)).connect();
735
                 });
731
                 });
736
-        });
732
+            }));
737
     },
733
     },
738
     /**
734
     /**
739
      * Check if id is id of the local user.
735
      * Check if id is id of the local user.
1700
 
1696
 
1701
         room.on(
1697
         room.on(
1702
             ConferenceEvents.LAST_N_ENDPOINTS_CHANGED,
1698
             ConferenceEvents.LAST_N_ENDPOINTS_CHANGED,
1703
-            (leavingIds, enteringIds) => {
1704
-                APP.UI.handleLastNEndpoints(leavingIds, enteringIds);
1705
-        });
1699
+            (leavingIds, enteringIds) =>
1700
+                APP.UI.handleLastNEndpoints(leavingIds, enteringIds));
1706
 
1701
 
1707
         room.on(
1702
         room.on(
1708
             ConferenceEvents.P2P_STATUS,
1703
             ConferenceEvents.P2P_STATUS,
1709
-            (jitsiConference, p2p) => {
1710
-                APP.store.dispatch(p2pStatusChanged(p2p));
1711
-        });
1704
+            (jitsiConference, p2p) => APP.store.dispatch(p2pStatusChanged(p2p)));
1712
 
1705
 
1713
         room.on(
1706
         room.on(
1714
             ConferenceEvents.PARTICIPANT_CONN_STATUS_CHANGED,
1707
             ConferenceEvents.PARTICIPANT_CONN_STATUS_CHANGED,
1717
                     id, connectionStatus));
1710
                     id, connectionStatus));
1718
 
1711
 
1719
                 APP.UI.participantConnectionStatusChanged(id);
1712
                 APP.UI.participantConnectionStatusChanged(id);
1720
-        });
1713
+            });
1721
         room.on(ConferenceEvents.DOMINANT_SPEAKER_CHANGED, (id) => {
1714
         room.on(ConferenceEvents.DOMINANT_SPEAKER_CHANGED, (id) => {
1722
             APP.store.dispatch(dominantSpeakerChanged(id));
1715
             APP.store.dispatch(dominantSpeakerChanged(id));
1723
 
1716
 
1818
             APP.UI.setLocalRemoteControlActiveChanged();
1811
             APP.UI.setLocalRemoteControlActiveChanged();
1819
         });
1812
         });
1820
 
1813
 
1821
-        room.on(ConferenceEvents.PARTICIPANT_PROPERTY_CHANGED,
1822
-                (participant, name, oldValue, newValue) => {
1823
-            switch (name) {
1824
-            case 'raisedHand':
1825
-                APP.UI.setRaisedHandStatus(participant, newValue);
1826
-                break;
1827
-            case 'remoteControlSessionStatus':
1828
-                APP.UI.setRemoteControlActiveStatus(
1829
-                    participant.getId(),
1830
-                    newValue);
1831
-                break;
1832
-            default:
1833
-            // ignore
1834
-            }
1835
-        });
1814
+        room.on(
1815
+            ConferenceEvents.PARTICIPANT_PROPERTY_CHANGED,
1816
+            (participant, name, oldValue, newValue) => {
1817
+                switch (name) {
1818
+                case 'raisedHand':
1819
+                    APP.UI.setRaisedHandStatus(participant, newValue);
1820
+                    break;
1821
+                case 'remoteControlSessionStatus':
1822
+                    APP.UI.setRemoteControlActiveStatus(
1823
+                        participant.getId(),
1824
+                        newValue);
1825
+                    break;
1826
+                default:
1827
+                // ignore
1828
+                }
1829
+            });
1836
 
1830
 
1837
         room.on(ConferenceEvents.RECORDER_STATE_CHANGED, (status, error) => {
1831
         room.on(ConferenceEvents.RECORDER_STATE_CHANGED, (status, error) => {
1838
             logger.log("Received recorder status change: ", status, error);
1832
             logger.log("Received recorder status change: ", status, error);
1910
                         avatarURL: data.value
1904
                         avatarURL: data.value
1911
                     }));
1905
                     }));
1912
                 APP.UI.setUserAvatarUrl(from, data.value);
1906
                 APP.UI.setUserAvatarUrl(from, data.value);
1913
-        });
1907
+            });
1914
 
1908
 
1915
         room.addCommandListener(this.commands.defaults.AVATAR_ID,
1909
         room.addCommandListener(this.commands.defaults.AVATAR_ID,
1916
             (data, from) => {
1910
             (data, from) => {
1972
             });
1966
             });
1973
         });
1967
         });
1974
 
1968
 
1975
-        APP.UI.addListener(UIEvents.RESOLUTION_CHANGED,
1969
+        APP.UI.addListener(
1970
+            UIEvents.RESOLUTION_CHANGED,
1976
             (id, oldResolution, newResolution, delay) => {
1971
             (id, oldResolution, newResolution, delay) => {
1977
-            var logObject = {
1978
-                id: "resolution_change",
1979
-                participant: id,
1980
-                oldValue: oldResolution,
1981
-                newValue: newResolution,
1982
-                delay: delay
1972
+                var logObject = {
1973
+                    id: "resolution_change",
1974
+                    participant: id,
1975
+                    oldValue: oldResolution,
1976
+                    newValue: newResolution,
1977
+                    delay: delay
1983
                 };
1978
                 };
1984
-            room.sendApplicationLog(JSON.stringify(logObject));
1985
-
1986
-            // We only care about the delay between simulcast streams.
1987
-            // Longer delays will be caused by something else and will just
1988
-            // poison the data.
1989
-            if (delay < 2000) {
1990
-                JitsiMeetJS.analytics.sendEvent('stream.switch.delay',
1991
-                    {value: delay});
1992
-            }
1993
-        });
1979
+
1980
+                room.sendApplicationLog(JSON.stringify(logObject));
1981
+
1982
+                // We only care about the delay between simulcast streams.
1983
+                // Longer delays will be caused by something else and will just
1984
+                // poison the data.
1985
+                if (delay < 2000) {
1986
+                    JitsiMeetJS.analytics.sendEvent('stream.switch.delay',
1987
+                        {value: delay});
1988
+                }
1989
+            });
1994
 
1990
 
1995
         // Starts or stops the recording for the conference.
1991
         // Starts or stops the recording for the conference.
1996
         APP.UI.addListener(UIEvents.RECORDING_TOGGLED, (options) => {
1992
         APP.UI.addListener(UIEvents.RECORDING_TOGGLED, (options) => {
2112
             UIEvents.TOGGLE_SCREENSHARING, this.toggleScreenSharing.bind(this)
2108
             UIEvents.TOGGLE_SCREENSHARING, this.toggleScreenSharing.bind(this)
2113
         );
2109
         );
2114
 
2110
 
2115
-        APP.UI.addListener(UIEvents.UPDATE_SHARED_VIDEO,
2111
+        APP.UI.addListener(
2112
+            UIEvents.UPDATE_SHARED_VIDEO,
2116
             (url, state, time, isMuted, volume) => {
2113
             (url, state, time, isMuted, volume) => {
2117
-            // send start and stop commands once, and remove any updates
2118
-            // that had left
2119
-            if (state === 'stop' || state === 'start' || state === 'playing') {
2120
-                room.removeCommand(this.commands.defaults.SHARED_VIDEO);
2121
-                room.sendCommandOnce(this.commands.defaults.SHARED_VIDEO, {
2122
-                    value: url,
2123
-                    attributes: {
2124
-                        state: state,
2125
-                        time: time,
2126
-                        muted: isMuted,
2127
-                        volume: volume
2128
-                    }
2129
-                });
2130
-            }
2131
-            else {
2132
-                // in case of paused, in order to allow late users to join
2133
-                // paused
2134
-                room.removeCommand(this.commands.defaults.SHARED_VIDEO);
2135
-                room.sendCommand(this.commands.defaults.SHARED_VIDEO, {
2136
-                    value: url,
2137
-                    attributes: {
2138
-                        state: state,
2139
-                        time: time,
2140
-                        muted: isMuted,
2141
-                        volume: volume
2142
-                    }
2143
-                });
2144
-            }
2145
-        });
2114
+                // send start and stop commands once, and remove any updates
2115
+                // that had left
2116
+                if (state === 'stop'
2117
+                        || state === 'start'
2118
+                        || state === 'playing') {
2119
+                    room.removeCommand(this.commands.defaults.SHARED_VIDEO);
2120
+                    room.sendCommandOnce(this.commands.defaults.SHARED_VIDEO, {
2121
+                        value: url,
2122
+                        attributes: {
2123
+                            state: state,
2124
+                            time: time,
2125
+                            muted: isMuted,
2126
+                            volume: volume
2127
+                        }
2128
+                    });
2129
+                }
2130
+                else {
2131
+                    // in case of paused, in order to allow late users to join
2132
+                    // paused
2133
+                    room.removeCommand(this.commands.defaults.SHARED_VIDEO);
2134
+                    room.sendCommand(this.commands.defaults.SHARED_VIDEO, {
2135
+                        value: url,
2136
+                        attributes: {
2137
+                            state: state,
2138
+                            time: time,
2139
+                            muted: isMuted,
2140
+                            volume: volume
2141
+                        }
2142
+                    });
2143
+                }
2144
+            });
2146
         room.addCommandListener(
2145
         room.addCommandListener(
2147
             this.commands.defaults.SHARED_VIDEO, ({value, attributes}, id) => {
2146
             this.commands.defaults.SHARED_VIDEO, ({value, attributes}, id) => {
2148
 
2147
 

+ 14
- 12
modules/API/API.js 查看文件

72
 
72
 
73
         return false;
73
         return false;
74
     });
74
     });
75
-    transport.on('request', ({ data, name }, callback) => {
75
+    transport.on('request', ({ name }, callback) => {
76
         switch (name) {
76
         switch (name) {
77
         case 'is-audio-muted':
77
         case 'is-audio-muted':
78
             callback(APP.conference.isLocalAudioMuted());
78
             callback(APP.conference.isLocalAudioMuted());
145
  * Jitsi Meet.
145
  * Jitsi Meet.
146
  */
146
  */
147
 class API {
147
 class API {
148
+    _enabled: boolean;
149
+
148
     /**
150
     /**
149
      * Initializes the API. Setups message event listeners that will receive
151
      * Initializes the API. Setups message event listeners that will receive
150
      * information from external applications that embed Jitsi Meet. It also
152
      * information from external applications that embed Jitsi Meet. It also
179
      * @param {Object} event - The event to be sent.
181
      * @param {Object} event - The event to be sent.
180
      * @returns {void}
182
      * @returns {void}
181
      */
183
      */
182
-    _sendEvent(event = {}) {
184
+    _sendEvent(event: Object = {}) {
183
         if (this._enabled) {
185
         if (this._enabled) {
184
             transport.sendEvent(event);
186
             transport.sendEvent(event);
185
         }
187
         }
191
      * @param {string} message - Message body.
193
      * @param {string} message - Message body.
192
      * @returns {void}
194
      * @returns {void}
193
      */
195
      */
194
-    notifySendingChatMessage(message) {
196
+    notifySendingChatMessage(message: string) {
195
         this._sendEvent({
197
         this._sendEvent({
196
             name: 'outgoing-message',
198
             name: 'outgoing-message',
197
             message
199
             message
226
      * @param {string} id - User id.
228
      * @param {string} id - User id.
227
      * @returns {void}
229
      * @returns {void}
228
      */
230
      */
229
-    notifyUserJoined(id) {
231
+    notifyUserJoined(id: string) {
230
         this._sendEvent({
232
         this._sendEvent({
231
             name: 'participant-joined',
233
             name: 'participant-joined',
232
             id
234
             id
240
      * @param {string} id - User id.
242
      * @param {string} id - User id.
241
      * @returns {void}
243
      * @returns {void}
242
      */
244
      */
243
-    notifyUserLeft(id) {
245
+    notifyUserLeft(id: string) {
244
         this._sendEvent({
246
         this._sendEvent({
245
             name: 'participant-left',
247
             name: 'participant-left',
246
             id
248
             id
255
      * @param {string} displayname - User nickname.
257
      * @param {string} displayname - User nickname.
256
      * @returns {void}
258
      * @returns {void}
257
      */
259
      */
258
-    notifyDisplayNameChanged(id, displayname) {
260
+    notifyDisplayNameChanged(id: string, displayname: string) {
259
         this._sendEvent({
261
         this._sendEvent({
260
             name: 'display-name-change',
262
             name: 'display-name-change',
261
             displayname,
263
             displayname,
270
      * @param {string} roomName - The room name.
272
      * @param {string} roomName - The room name.
271
      * @returns {void}
273
      * @returns {void}
272
      */
274
      */
273
-    notifyConferenceJoined(roomName) {
275
+    notifyConferenceJoined(roomName: string) {
274
         this._sendEvent({
276
         this._sendEvent({
275
             name: 'video-conference-joined',
277
             name: 'video-conference-joined',
276
             roomName
278
             roomName
284
      * @param {string} roomName - User id.
286
      * @param {string} roomName - User id.
285
      * @returns {void}
287
      * @returns {void}
286
      */
288
      */
287
-    notifyConferenceLeft(roomName) {
289
+    notifyConferenceLeft(roomName: string) {
288
         this._sendEvent({
290
         this._sendEvent({
289
             name: 'video-conference-left',
291
             name: 'video-conference-left',
290
             roomName
292
             roomName
308
      * @param {boolean} muted - The new muted status.
310
      * @param {boolean} muted - The new muted status.
309
      * @returns {void}
311
      * @returns {void}
310
      */
312
      */
311
-    notifyAudioMutedStatusChanged(muted) {
313
+    notifyAudioMutedStatusChanged(muted: boolean) {
312
         this._sendEvent({
314
         this._sendEvent({
313
             name: 'audio-mute-status-changed',
315
             name: 'audio-mute-status-changed',
314
             muted
316
             muted
322
      * @param {boolean} muted - The new muted status.
324
      * @param {boolean} muted - The new muted status.
323
      * @returns {void}
325
      * @returns {void}
324
      */
326
      */
325
-    notifyVideoMutedStatusChanged(muted) {
327
+    notifyVideoMutedStatusChanged(muted: boolean) {
326
         this._sendEvent({
328
         this._sendEvent({
327
             name: 'video-mute-status-changed',
329
             name: 'video-mute-status-changed',
328
             muted
330
             muted
336
      * @param {boolean} available - True if available and false otherwise.
338
      * @param {boolean} available - True if available and false otherwise.
337
      * @returns {void}
339
      * @returns {void}
338
      */
340
      */
339
-    notifyAudioAvailabilityChanged(available) {
341
+    notifyAudioAvailabilityChanged(available: boolean) {
340
         audioAvailable = available;
342
         audioAvailable = available;
341
         this._sendEvent({
343
         this._sendEvent({
342
             name: 'audio-availability-changed',
344
             name: 'audio-availability-changed',
351
      * @param {boolean} available - True if available and false otherwise.
353
      * @param {boolean} available - True if available and false otherwise.
352
      * @returns {void}
354
      * @returns {void}
353
      */
355
      */
354
-    notifyVideoAvailabilityChanged(available) {
356
+    notifyVideoAvailabilityChanged(available: boolean) {
355
         videoAvailable = available;
357
         videoAvailable = available;
356
         this._sendEvent({
358
         this._sendEvent({
357
             name: 'video-availability-changed',
359
             name: 'video-availability-changed',

+ 2
- 2
modules/API/external/external_api.js 查看文件

87
     return urlObjectToString({
87
     return urlObjectToString({
88
         ...options,
88
         ...options,
89
         url:
89
         url:
90
-            `${options.noSSL ? 'http' : 'https'}://${domain
91
-                }/#jitsi_meet_external_api_id=${id}`
90
+            `${options.noSSL ? 'http' : 'https'}://${
91
+                domain}/#jitsi_meet_external_api_id=${id}`
92
     });
92
     });
93
 }
93
 }
94
 
94
 

+ 8
- 8
modules/UI/audio_levels/AudioLevels.js 查看文件

17
      * @param {number} opacity the opacity to set for the specified dot.
17
      * @param {number} opacity the opacity to set for the specified dot.
18
      */
18
      */
19
     _setDotLevel(elementID, index, opacity) {
19
     _setDotLevel(elementID, index, opacity) {
20
-
21
-        let audioSpan = document.getElementById(elementID)
22
-            .getElementsByClassName("audioindicator");
20
+        let audioSpan
21
+            = document.getElementById(elementID)
22
+                .getElementsByClassName("audioindicator");
23
 
23
 
24
         // Make sure the audio span is still around.
24
         // Make sure the audio span is still around.
25
         if (audioSpan && audioSpan.length > 0)
25
         if (audioSpan && audioSpan.length > 0)
72
     /**
72
     /**
73
      * Updates the large video shadow effect.
73
      * Updates the large video shadow effect.
74
      */
74
      */
75
-    _updateLargeVideoShadow (level) {
76
-        var scale = 2,
75
+    _updateLargeVideoShadow(level) {
76
+        const scale = 2;
77
 
77
 
78
         // Internal circle audio level.
78
         // Internal circle audio level.
79
-        int = {
79
+        const int = {
80
             level: level > 0.15 ? 20 : 0,
80
             level: level > 0.15 ? 20 : 0,
81
             color: interfaceConfig.AUDIO_LEVEL_PRIMARY_COLOR
81
             color: interfaceConfig.AUDIO_LEVEL_PRIMARY_COLOR
82
-        },
82
+        };
83
 
83
 
84
         // External circle audio level.
84
         // External circle audio level.
85
-        ext = {
85
+        const ext = {
86
             level: (int.level * scale * level + int.level).toFixed(0),
86
             level: (int.level * scale * level + int.level).toFixed(0),
87
             color: interfaceConfig.AUDIO_LEVEL_SECONDARY_COLOR
87
             color: interfaceConfig.AUDIO_LEVEL_SECONDARY_COLOR
88
         };
88
         };

+ 1
- 2
modules/UI/authentication/AuthHandler.js 查看文件

111
                                 logger.error(
111
                                 logger.error(
112
                                     "Authentication failed: ", err, errCode);
112
                                     "Authentication failed: ", err, errCode);
113
                                 unregister();
113
                                 unregister();
114
-                            }
115
-                        );
114
+                            });
116
                     }).catch(function (error, code) {
115
                     }).catch(function (error, code) {
117
                         unregister();
116
                         unregister();
118
                         connection.disconnect();
117
                         connection.disconnect();

+ 6
- 5
modules/UI/shared_video/SharedVideo.js 查看文件

90
         }
90
         }
91
 
91
 
92
         if(APP.conference.isLocalId(this.from)) {
92
         if(APP.conference.isLocalId(this.from)) {
93
-            showStopVideoPropmpt().then(() => {
93
+            showStopVideoPropmpt().then(
94
+                () => {
94
                     // make sure we stop updates for playing before we send stop
95
                     // make sure we stop updates for playing before we send stop
95
                     // if we stop it after receiving self presence, we can end
96
                     // if we stop it after receiving self presence, we can end
96
                     // up sending stop playing, and on the other end it will not
97
                     // up sending stop playing, and on the other end it will not
97
                     // stop
98
                     // stop
98
-                    if(this.intervalId) {
99
-                         clearInterval(this.intervalId);
100
-                         this.intervalId = null;
99
+                    if (this.intervalId) {
100
+                        clearInterval(this.intervalId);
101
+                        this.intervalId = null;
101
                     }
102
                     }
102
                     this.emitter.emit(
103
                     this.emitter.emit(
103
                         UIEvents.UPDATE_SHARED_VIDEO, this.url, 'stop');
104
                         UIEvents.UPDATE_SHARED_VIDEO, this.url, 'stop');
472
 
473
 
473
                 this.emitter.emit(
474
                 this.emitter.emit(
474
                     UIEvents.UPDATE_SHARED_VIDEO, null, 'removed');
475
                     UIEvents.UPDATE_SHARED_VIDEO, null, 'removed');
475
-        });
476
+            });
476
 
477
 
477
         APP.store.dispatch(participantLeft(this.url));
478
         APP.store.dispatch(participantLeft(this.url));
478
 
479
 

+ 4
- 0
modules/UI/side_pannels/chat/Replacement.js 查看文件

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

+ 26
- 15
modules/UI/util/MessageHandler.js 查看文件

120
      * the prompt is closed (optional)
120
      * the prompt is closed (optional)
121
      * @return the prompt that was created, or null
121
      * @return the prompt that was created, or null
122
      */
122
      */
123
-    openMessageDialog:
124
-        function(titleKey, messageKey, i18nOptions, closeFunction) {
123
+    openMessageDialog(titleKey, messageKey, i18nOptions, closeFunction) {
125
         if (!popupEnabled)
124
         if (!popupEnabled)
126
             return null;
125
             return null;
127
 
126
 
128
         let dialog = $.prompt(
127
         let dialog = $.prompt(
129
             APP.translation.generateTranslationHTML(messageKey, i18nOptions),
128
             APP.translation.generateTranslationHTML(messageKey, i18nOptions),
130
             {
129
             {
131
-            title: this._getFormattedTitleString(titleKey),
132
-            persistent: false,
133
-            promptspeed: 0,
134
-            classes: this._getDialogClasses(),
135
-            close: function (e, v, m, f) {
136
-                if(closeFunction)
137
-                    closeFunction(e, v, m, f);
138
-            }
139
-        });
130
+                title: this._getFormattedTitleString(titleKey),
131
+                persistent: false,
132
+                promptspeed: 0,
133
+                classes: this._getDialogClasses(),
134
+                close(e, v, m, f) {
135
+                    if(closeFunction)
136
+                        closeFunction(e, v, m, f);
137
+                }
138
+            });
140
         APP.translation.translateElement(dialog, i18nOptions);
139
         APP.translation.translateElement(dialog, i18nOptions);
141
         return $.prompt.getApi();
140
         return $.prompt.getApi();
142
     },
141
     },
271
      * @param {string} dontShowAgain.localStorageKey the key for the local
270
      * @param {string} dontShowAgain.localStorageKey the key for the local
272
      * storage. if not provided dontShowAgain.id will be used.
271
      * storage. if not provided dontShowAgain.id will be used.
273
      */
272
      */
274
-    openDialog: function (titleKey, msgString, persistent, buttons,
275
-        submitFunction, loadedFunction, closeFunction, dontShowAgain) {
273
+    openDialog(
274
+            titleKey,
275
+            msgString,
276
+            persistent,
277
+            buttons,
278
+            submitFunction,
279
+            loadedFunction,
280
+            closeFunction,
281
+            dontShowAgain) {
276
         if (!popupEnabled)
282
         if (!popupEnabled)
277
             return;
283
             return;
278
 
284
 
448
      * @param messageArguments object with the arguments for the message.
454
      * @param messageArguments object with the arguments for the message.
449
      * @param optional configurations for the notification (e.g. timeout)
455
      * @param optional configurations for the notification (e.g. timeout)
450
      */
456
      */
451
-    participantNotification: function(displayName, displayNameKey, cls,
452
-                    messageKey, messageArguments, timeout = 2500) {
457
+    participantNotification(
458
+            displayName,
459
+            displayNameKey,
460
+            cls,
461
+            messageKey,
462
+            messageArguments,
463
+            timeout = 2500) {
453
         APP.store.dispatch(
464
         APP.store.dispatch(
454
             showNotification(
465
             showNotification(
455
                 Notification,
466
                 Notification,

+ 12
- 12
modules/UI/util/UIUtil.js 查看文件

31
 /**
31
 /**
32
  * Created by hristo on 12/22/14.
32
  * Created by hristo on 12/22/14.
33
  */
33
  */
34
- var UIUtil = {
34
+var UIUtil = {
35
 
35
 
36
     /**
36
     /**
37
      * Returns the available video width.
37
      * Returns the available video width.
208
     },
208
     },
209
 
209
 
210
     redirect(url) {
210
     redirect(url) {
211
-         window.location.href = url;
211
+        window.location.href = url;
212
     },
212
     },
213
 
213
 
214
     /**
214
     /**
262
       * @param {Object} attrs object with properties
262
       * @param {Object} attrs object with properties
263
       * @returns {String} string of html element attributes
263
       * @returns {String} string of html element attributes
264
       */
264
       */
265
-     attrsToString(attrs) {
266
-         return Object.keys(attrs).map(
267
-             key => ` ${key}="${attrs[key]}"`
268
-         ).join(' ');
269
-     },
265
+    attrsToString(attrs) {
266
+        return (
267
+            Object.keys(attrs).map(key => ` ${key}="${attrs[key]}"`).join(' '));
268
+    },
270
 
269
 
271
     /**
270
     /**
272
      * Checks if the given DOM element is currently visible. The offsetParent
271
      * Checks if the given DOM element is currently visible. The offsetParent
299
 
298
 
300
             if (hideDelay && hideDelay > 0)
299
             if (hideDelay && hideDelay > 0)
301
                 setTimeout(
300
                 setTimeout(
302
-                    function () {
303
-                        selector.fadeOut(300,
304
-                        () => {selector.css({opacity: 0});}
305
-                    );
306
-                }, hideDelay);
301
+                    () => {
302
+                        selector.fadeOut(
303
+                            300,
304
+                            () => { selector.css({opacity: 0}); });
305
+                    },
306
+                    hideDelay);
307
         }
307
         }
308
         else {
308
         else {
309
             selector.fadeOut(300,
309
             selector.fadeOut(300,

+ 24
- 24
modules/UI/videolayout/Filmstrip.js 查看文件

249
         if(thumbs.localThumb) {
249
         if(thumbs.localThumb) {
250
             availableWidth = Math.floor(
250
             availableWidth = Math.floor(
251
                 (videoAreaAvailableWidth - (
251
                 (videoAreaAvailableWidth - (
252
-                UIUtil.parseCssInt(
253
-                    localVideoContainer.css('borderLeftWidth'), 10)
254
-                + UIUtil.parseCssInt(
255
-                    localVideoContainer.css('borderRightWidth'), 10)
256
-                + UIUtil.parseCssInt(
257
-                    localVideoContainer.css('paddingLeft'), 10)
258
-                + UIUtil.parseCssInt(
259
-                    localVideoContainer.css('paddingRight'), 10)
260
-                + UIUtil.parseCssInt(
261
-                    localVideoContainer.css('marginLeft'), 10)
262
-                + UIUtil.parseCssInt(
263
-                    localVideoContainer.css('marginRight'), 10)))
252
+                    UIUtil.parseCssInt(
253
+                        localVideoContainer.css('borderLeftWidth'), 10)
254
+                    + UIUtil.parseCssInt(
255
+                        localVideoContainer.css('borderRightWidth'), 10)
256
+                    + UIUtil.parseCssInt(
257
+                        localVideoContainer.css('paddingLeft'), 10)
258
+                    + UIUtil.parseCssInt(
259
+                        localVideoContainer.css('paddingRight'), 10)
260
+                    + UIUtil.parseCssInt(
261
+                        localVideoContainer.css('marginLeft'), 10)
262
+                    + UIUtil.parseCssInt(
263
+                        localVideoContainer.css('marginRight'), 10)))
264
             );
264
             );
265
         }
265
         }
266
 
266
 
271
             let remoteVideoContainer = thumbs.remoteThumbs.eq(0);
271
             let remoteVideoContainer = thumbs.remoteThumbs.eq(0);
272
             availableWidth = Math.floor(
272
             availableWidth = Math.floor(
273
                 (videoAreaAvailableWidth - numvids * (
273
                 (videoAreaAvailableWidth - numvids * (
274
-                UIUtil.parseCssInt(
275
-                    remoteVideoContainer.css('borderLeftWidth'), 10)
276
-                + UIUtil.parseCssInt(
277
-                    remoteVideoContainer.css('borderRightWidth'), 10)
278
-                + UIUtil.parseCssInt(
279
-                    remoteVideoContainer.css('paddingLeft'), 10)
280
-                + UIUtil.parseCssInt(
281
-                    remoteVideoContainer.css('paddingRight'), 10)
282
-                + UIUtil.parseCssInt(
283
-                    remoteVideoContainer.css('marginLeft'), 10)
284
-                + UIUtil.parseCssInt(
285
-                    remoteVideoContainer.css('marginRight'), 10)))
274
+                    UIUtil.parseCssInt(
275
+                        remoteVideoContainer.css('borderLeftWidth'), 10)
276
+                    + UIUtil.parseCssInt(
277
+                        remoteVideoContainer.css('borderRightWidth'), 10)
278
+                    + UIUtil.parseCssInt(
279
+                        remoteVideoContainer.css('paddingLeft'), 10)
280
+                    + UIUtil.parseCssInt(
281
+                        remoteVideoContainer.css('paddingRight'), 10)
282
+                    + UIUtil.parseCssInt(
283
+                        remoteVideoContainer.css('marginLeft'), 10)
284
+                    + UIUtil.parseCssInt(
285
+                        remoteVideoContainer.css('marginRight'), 10)))
286
             );
286
             );
287
         }
287
         }
288
 
288
 

+ 4
- 3
modules/UI/videolayout/LargeVideoManager.js 查看文件

293
      *
293
      *
294
      * @private
294
      * @private
295
      */
295
      */
296
-    updateParticipantConnStatusIndication (
297
-        id, showProblemsIndication, messageKey) {
298
-
296
+    updateParticipantConnStatusIndication(
297
+            id,
298
+            showProblemsIndication,
299
+            messageKey) {
299
         // Apply grey filter on the large video
300
         // Apply grey filter on the large video
300
         this.videoContainer.showRemoteConnectionProblemIndicator(
301
         this.videoContainer.showRemoteConnectionProblemIndicator(
301
             showProblemsIndication);
302
             showProblemsIndication);

+ 1
- 2
modules/UI/videolayout/RemoteVideo.js 查看文件

290
  * @param isMuted the new muted state to update to
290
  * @param isMuted the new muted state to update to
291
  */
291
  */
292
 RemoteVideo.prototype.updateRemoteVideoMenu = function (
292
 RemoteVideo.prototype.updateRemoteVideoMenu = function (
293
-    isMuted = this.isAudioMuted
294
-) {
293
+        isMuted = this.isAudioMuted) {
295
     this.isAudioMuted = isMuted;
294
     this.isAudioMuted = isMuted;
296
 
295
 
297
     this._generatePopupContent();
296
     this._generatePopupContent();

+ 4
- 5
modules/UI/videolayout/SmallVideo.js 查看文件

332
                     ? <VideoMutedIndicator
332
                     ? <VideoMutedIndicator
333
                         tooltipPosition = { tooltipPosition } />
333
                         tooltipPosition = { tooltipPosition } />
334
                     : null }
334
                     : null }
335
-                { this._isModerator
336
-                    && !interfaceConfig.DISABLE_FOCUS_INDICATOR
337
-                        ? <ModeratorIndicator
338
-                             tooltipPosition = { tooltipPosition } />
339
-                        : null }
335
+                { this._isModerator && !interfaceConfig.DISABLE_FOCUS_INDICATOR
336
+                    ? <ModeratorIndicator
337
+                        tooltipPosition = { tooltipPosition } />
338
+                    : null }
340
             </div>
339
             </div>
341
         </I18nextProvider>,
340
         </I18nextProvider>,
342
         statusBarContainer);
341
         statusBarContainer);

+ 16
- 14
modules/UI/videolayout/VideoContainer.js 查看文件

23
  * @param videoSpaceHeight the height of the available space
23
  * @param videoSpaceHeight the height of the available space
24
  * @return an array with 2 elements, the video width and the video height
24
  * @return an array with 2 elements, the video width and the video height
25
  */
25
  */
26
-function computeDesktopVideoSize(videoWidth,
27
-                             videoHeight,
28
-                             videoSpaceWidth,
29
-                             videoSpaceHeight) {
30
-
26
+function computeDesktopVideoSize(
27
+        videoWidth,
28
+        videoHeight,
29
+        videoSpaceWidth,
30
+        videoSpaceHeight) {
31
     let aspectRatio = videoWidth / videoHeight;
31
     let aspectRatio = videoWidth / videoHeight;
32
 
32
 
33
     let availableWidth = Math.max(videoWidth, videoSpaceWidth);
33
     let availableWidth = Math.max(videoWidth, videoSpaceWidth);
60
  * @param videoSpaceHeight the height of the video space
60
  * @param videoSpaceHeight the height of the video space
61
  * @return an array with 2 elements, the video width and the video height
61
  * @return an array with 2 elements, the video width and the video height
62
  */
62
  */
63
-function computeCameraVideoSize(videoWidth,
64
-                            videoHeight,
65
-                            videoSpaceWidth,
66
-                            videoSpaceHeight,
67
-                            videoLayoutFit) {
63
+function computeCameraVideoSize(
64
+        videoWidth,
65
+        videoHeight,
66
+        videoSpaceWidth,
67
+        videoSpaceHeight,
68
+        videoLayoutFit) {
68
     const aspectRatio = videoWidth / videoHeight;
69
     const aspectRatio = videoWidth / videoHeight;
69
     switch (videoLayoutFit) {
70
     switch (videoLayoutFit) {
70
     case 'height':
71
     case 'height':
110
  * @return an array with 2 elements, the horizontal indent and the vertical
111
  * @return an array with 2 elements, the horizontal indent and the vertical
111
  * indent
112
  * indent
112
  */
113
  */
113
-function getCameraVideoPosition(videoWidth,
114
-                                videoHeight,
115
-                                videoSpaceWidth,
116
-                                videoSpaceHeight) {
114
+function getCameraVideoPosition(
115
+        videoWidth,
116
+        videoHeight,
117
+        videoSpaceWidth,
118
+        videoSpaceHeight) {
117
     // Parent height isn't completely calculated when we position the video in
119
     // Parent height isn't completely calculated when we position the video in
118
     // full screen mode and this is why we use the screen height in this case.
120
     // full screen mode and this is why we use the screen height in this case.
119
     // Need to think it further at some point and implement it properly.
121
     // Need to think it further at some point and implement it properly.

+ 8
- 7
modules/UI/videolayout/VideoLayout.js 查看文件

602
     /**
602
     /**
603
      * Resizes thumbnails.
603
      * Resizes thumbnails.
604
      */
604
      */
605
-    resizeThumbnails (  animate = false,
606
-                        forceUpdate = false,
607
-                        onComplete = null) {
605
+    resizeThumbnails(
606
+            animate = false,
607
+            forceUpdate = false,
608
+            onComplete = null) {
608
         const { localVideo, remoteVideo }
609
         const { localVideo, remoteVideo }
609
             = Filmstrip.calculateThumbnailSize();
610
             = Filmstrip.calculateThumbnailSize();
610
 
611
 
870
      * @param completeFunction a function to be called when the video area is
871
      * @param completeFunction a function to be called when the video area is
871
      * resized.
872
      * resized.
872
      */
873
      */
873
-    resizeVideoArea (forceUpdate = false,
874
-                    animate = false,
875
-                    completeFunction = null) {
876
-
874
+    resizeVideoArea(
875
+            forceUpdate = false,
876
+            animate = false,
877
+            completeFunction = null) {
877
         if (largeVideo) {
878
         if (largeVideo) {
878
             largeVideo.updateContainerSize();
879
             largeVideo.updateContainerSize();
879
             largeVideo.resize(animate);
880
             largeVideo.resize(animate);

+ 33
- 25
modules/devices/mediaDeviceHelper.js 查看文件

156
      *  }}
156
      *  }}
157
      */
157
      */
158
     getNewMediaDevicesAfterDeviceListChanged(
158
     getNewMediaDevicesAfterDeviceListChanged(
159
-        newDevices, isSharingScreen, localVideo, localAudio) {
159
+            newDevices,
160
+            isSharingScreen,
161
+            localVideo,
162
+            localAudio) {
160
         return {
163
         return {
161
             audioinput: getNewAudioInputDevice(newDevices, localAudio),
164
             audioinput: getNewAudioInputDevice(newDevices, localAudio),
162
             videoinput: !isSharingScreen &&
165
             videoinput: !isSharingScreen &&
173
      * @returns {Promise.<JitsiLocalTrack[]>}
176
      * @returns {Promise.<JitsiLocalTrack[]>}
174
      */
177
      */
175
     createLocalTracksAfterDeviceListChanged(
178
     createLocalTracksAfterDeviceListChanged(
176
-        createLocalTracks, cameraDeviceId, micDeviceId) {
179
+            createLocalTracks,
180
+            cameraDeviceId,
181
+            micDeviceId) {
177
         let audioTrackError;
182
         let audioTrackError;
178
         let videoTrackError;
183
         let videoTrackError;
179
         let audioRequested = !!micDeviceId;
184
         let audioRequested = !!micDeviceId;
181
 
186
 
182
         if (audioRequested && videoRequested) {
187
         if (audioRequested && videoRequested) {
183
             // First we try to create both audio and video tracks together.
188
             // First we try to create both audio and video tracks together.
184
-            return createLocalTracks({
185
-                        devices: ['audio', 'video'],
186
-                        cameraDeviceId: cameraDeviceId,
187
-                        micDeviceId: micDeviceId
188
-                    })
189
-                    // If we fail to do this, try to create them separately.
190
-                    .catch(() => Promise.all([
191
-                        createAudioTrack(false).then(([stream]) => stream),
192
-                        createVideoTrack(false).then(([stream]) => stream)
193
-                    ]))
194
-                    .then(tracks => {
195
-                        if (audioTrackError) {
196
-                            APP.UI.showMicErrorNotification(audioTrackError);
197
-                        }
189
+            return (
190
+                createLocalTracks({
191
+                    devices: ['audio', 'video'],
192
+                    cameraDeviceId: cameraDeviceId,
193
+                    micDeviceId: micDeviceId
194
+                })
195
+                // If we fail to do this, try to create them separately.
196
+                .catch(() => Promise.all([
197
+                    createAudioTrack(false).then(([stream]) => stream),
198
+                    createVideoTrack(false).then(([stream]) => stream)
199
+                ]))
200
+                .then(tracks => {
201
+                    if (audioTrackError) {
202
+                        APP.UI.showMicErrorNotification(audioTrackError);
203
+                    }
198
 
204
 
199
-                        if (videoTrackError) {
200
-                            APP.UI.showCameraErrorNotification(videoTrackError);
201
-                        }
205
+                    if (videoTrackError) {
206
+                        APP.UI.showCameraErrorNotification(videoTrackError);
207
+                    }
202
 
208
 
203
-                        return tracks.filter(t => typeof t !== 'undefined');
204
-                    });
209
+                    return tracks.filter(t => typeof t !== 'undefined');
210
+                }));
205
         } else if (videoRequested && !audioRequested) {
211
         } else if (videoRequested && !audioRequested) {
206
             return createVideoTrack();
212
             return createVideoTrack();
207
         } else if (audioRequested && !videoRequested) {
213
         } else if (audioRequested && !videoRequested) {
211
         }
217
         }
212
 
218
 
213
         function createAudioTrack(showError) {
219
         function createAudioTrack(showError) {
214
-            return createLocalTracks({
220
+            return (
221
+                createLocalTracks({
215
                     devices: ['audio'],
222
                     devices: ['audio'],
216
                     cameraDeviceId: null,
223
                     cameraDeviceId: null,
217
                     micDeviceId: micDeviceId
224
                     micDeviceId: micDeviceId
220
                     audioTrackError = err;
227
                     audioTrackError = err;
221
                     showError && APP.UI.showMicErrorNotification(err);
228
                     showError && APP.UI.showMicErrorNotification(err);
222
                     return [];
229
                     return [];
223
-                });
230
+                }));
224
         }
231
         }
225
 
232
 
226
         function createVideoTrack(showError) {
233
         function createVideoTrack(showError) {
227
-            return createLocalTracks({
234
+            return (
235
+                createLocalTracks({
228
                     devices: ['video'],
236
                     devices: ['video'],
229
                     cameraDeviceId: cameraDeviceId,
237
                     cameraDeviceId: cameraDeviceId,
230
                     micDeviceId: null
238
                     micDeviceId: null
233
                     videoTrackError = err;
241
                     videoTrackError = err;
234
                     showError && APP.UI.showCameraErrorNotification(err);
242
                     showError && APP.UI.showCameraErrorNotification(err);
235
                     return [];
243
                     return [];
236
-                });
244
+                }));
237
         }
245
         }
238
     }
246
     }
239
 };
247
 };

+ 8
- 7
modules/keyboardshortcut/keyboardshortcut.js 查看文件

144
      * @param helpDescription the description of the shortcut that would appear
144
      * @param helpDescription the description of the shortcut that would appear
145
      * in the help menu
145
      * in the help menu
146
      */
146
      */
147
-    registerShortcut: function( shortcutChar,
148
-                                shortcutAttr,
149
-                                exec,
150
-                                helpDescription) {
147
+    registerShortcut(
148
+            shortcutChar,
149
+            shortcutAttr,
150
+            exec,
151
+            helpDescription) {
151
         _shortcuts[shortcutChar] = {
152
         _shortcuts[shortcutChar] = {
152
             character: shortcutChar,
153
             character: shortcutChar,
153
             shortcutAttr: shortcutAttr,
154
             shortcutAttr: shortcutAttr,
199
         if (typeof e.key === "string") {
200
         if (typeof e.key === "string") {
200
             return e.key;
201
             return e.key;
201
         }
202
         }
202
-        if (e.type === "keypress" && (
203
-                (e.which >= 32 && e.which <= 126) ||
204
-                (e.which >= 160 && e.which <= 255) )) {
203
+        if (e.type === "keypress"
204
+                && ((e.which >= 32 && e.which <= 126)
205
+                    || (e.which >= 160 && e.which <= 255) )) {
205
             return String.fromCharCode(e.which);
206
             return String.fromCharCode(e.which);
206
         }
207
         }
207
         // try to fallback (0-9A-Za-z and QWERTY keyboard)
208
         // try to fallback (0-9A-Za-z and QWERTY keyboard)

+ 1
- 4
modules/remotecontrol/Receiver.js 查看文件

15
 } from '../../service/remotecontrol/Constants';
15
 } from '../../service/remotecontrol/Constants';
16
 import * as RemoteControlEvents
16
 import * as RemoteControlEvents
17
     from '../../service/remotecontrol/RemoteControlEvents';
17
     from '../../service/remotecontrol/RemoteControlEvents';
18
-import {
19
-    Transport,
20
-    PostMessageTransportBackend
21
- } from '../transport';
18
+import { Transport, PostMessageTransportBackend } from '../transport';
22
 
19
 
23
 import RemoteControlParticipant from './RemoteControlParticipant';
20
 import RemoteControlParticipant from './RemoteControlParticipant';
24
 
21
 

+ 7
- 7
package.json 查看文件

72
     "strophe": "1.2.4",
72
     "strophe": "1.2.4",
73
     "strophejs-plugins": "0.0.7",
73
     "strophejs-plugins": "0.0.7",
74
     "styled-components": "1.3.0",
74
     "styled-components": "1.3.0",
75
-    "url-polyfill": "github/url-polyfill",
75
+    "url-polyfill": "github:github/url-polyfill",
76
     "uuid": "3.1.0",
76
     "uuid": "3.1.0",
77
     "xmldom": "0.1.27"
77
     "xmldom": "0.1.27"
78
   },
78
   },
79
   "devDependencies": {
79
   "devDependencies": {
80
     "babel-core": "6.26.0",
80
     "babel-core": "6.26.0",
81
-    "babel-eslint": "7.2.3",
81
+    "babel-eslint": "8.0.1",
82
     "babel-loader": "7.1.2",
82
     "babel-loader": "7.1.2",
83
     "babel-polyfill": "6.26.0",
83
     "babel-polyfill": "6.26.0",
84
     "babel-preset-es2015": "6.24.1",
84
     "babel-preset-es2015": "6.24.1",
86
     "babel-preset-stage-1": "6.24.1",
86
     "babel-preset-stage-1": "6.24.1",
87
     "clean-css": "3.4.25",
87
     "clean-css": "3.4.25",
88
     "css-loader": "0.28.5",
88
     "css-loader": "0.28.5",
89
-    "eslint": "3.19.0",
89
+    "eslint": "4.8.0",
90
     "eslint-plugin-flowtype": "2.30.4",
90
     "eslint-plugin-flowtype": "2.30.4",
91
     "eslint-plugin-import": "2.7.0",
91
     "eslint-plugin-import": "2.7.0",
92
-    "eslint-plugin-jsdoc": "3.1.2",
93
-    "eslint-plugin-react": "6.10.3",
94
-    "eslint-plugin-react-native": "3.0.1",
92
+    "eslint-plugin-jsdoc": "3.1.3",
93
+    "eslint-plugin-react": "7.4.0",
94
+    "eslint-plugin-react-native": "3.1.0",
95
     "expose-loader": "0.7.3",
95
     "expose-loader": "0.7.3",
96
     "file-loader": "0.11.2",
96
     "file-loader": "0.11.2",
97
     "flow-bin": "0.38.0",
97
     "flow-bin": "0.38.0",
109
   },
109
   },
110
   "license": "Apache-2.0",
110
   "license": "Apache-2.0",
111
   "scripts": {
111
   "scripts": {
112
-    "lint": "jshint . && eslint . && flow",
112
+    "lint": "eslint . && flow",
113
     "validate": "npm ls"
113
     "validate": "npm ls"
114
   },
114
   },
115
   "pre-commit": [
115
   "pre-commit": [

+ 6
- 2
react/.eslintrc.js 查看文件

185
         'id-blacklist': 0,
185
         'id-blacklist': 0,
186
         'id-length': 0,
186
         'id-length': 0,
187
         'id-match': 0,
187
         'id-match': 0,
188
-        'indent': [ 'error', 4, { 'SwitchCase': 0 } ],
189
         'jsx-quotes': [ 'error', 'prefer-single' ],
188
         'jsx-quotes': [ 'error', 'prefer-single' ],
190
         'key-spacing': 2,
189
         'key-spacing': 2,
191
         'keyword-spacing': 2,
190
         'keyword-spacing': 2,
387
         'react/jsx-no-undef': 2,
386
         'react/jsx-no-undef': 2,
388
         'react/jsx-pascal-case': 2,
387
         'react/jsx-pascal-case': 2,
389
         'react/jsx-sort-props': 2,
388
         'react/jsx-sort-props': 2,
390
-        'react/jsx-space-before-closing': 2,
389
+        'react/jsx-tag-spacing': [
390
+            'error',
391
+            {
392
+                'beforeSelfClosing': 'always'
393
+            }
394
+        ],
391
         'react/jsx-uses-react': 2,
395
         'react/jsx-uses-react': 2,
392
         'react/jsx-uses-vars': 2,
396
         'react/jsx-uses-vars': 2,
393
         'react/jsx-wrap-multilines': 2,
397
         'react/jsx-wrap-multilines': 2,

+ 4
- 2
react/features/app/actions.js 查看文件

1
+/* @flow */
2
+
1
 import { setRoom } from '../base/conference';
3
 import { setRoom } from '../base/conference';
2
 import { loadConfigError, setConfig } from '../base/config';
4
 import { loadConfigError, setConfig } from '../base/config';
3
 import { setLocationURL } from '../base/connection';
5
 import { setLocationURL } from '../base/connection';
132
  *     app: App
134
  *     app: App
133
  * }}
135
  * }}
134
  */
136
  */
135
-export function appWillMount(app) {
137
+export function appWillMount(app: Object) {
136
     return (dispatch: Dispatch<*>) => {
138
     return (dispatch: Dispatch<*>) => {
137
         dispatch({
139
         dispatch({
138
             type: APP_WILL_MOUNT,
140
             type: APP_WILL_MOUNT,
159
  *     app: App
161
  *     app: App
160
  * }}
162
  * }}
161
  */
163
  */
162
-export function appWillUnmount(app) {
164
+export function appWillUnmount(app: Object) {
163
     return {
165
     return {
164
         type: APP_WILL_UNMOUNT,
166
         type: APP_WILL_UNMOUNT,
165
         app
167
         app

+ 6
- 6
react/features/base/conference/actions.js 查看文件

256
  * @returns {Function}
256
  * @returns {Function}
257
  */
257
  */
258
 export function createConference() {
258
 export function createConference() {
259
-    return (dispatch, getState) => {
259
+    return (dispatch: Dispatch<*>, getState: Function) => {
260
         const state = getState();
260
         const state = getState();
261
         const { connection, locationURL } = state['features/base/connection'];
261
         const { connection, locationURL } = state['features/base/connection'];
262
 
262
 
297
  * @returns {Function}
297
  * @returns {Function}
298
  */
298
  */
299
 export function checkIfCanJoin() {
299
 export function checkIfCanJoin() {
300
-    return (dispatch, getState) => {
300
+    return (dispatch: Dispatch<*>, getState: Function) => {
301
         const { authRequired, password }
301
         const { authRequired, password }
302
             = getState()['features/base/conference'];
302
             = getState()['features/base/conference'];
303
 
303
 
412
  * is to be joined or locked.
412
  * is to be joined or locked.
413
  * @returns {Function}
413
  * @returns {Function}
414
  */
414
  */
415
-export function setPassword(conference, method, password) {
416
-    return (dispatch, getState) => {
415
+export function setPassword(conference, method: Function, password: string) {
416
+    return (dispatch: Dispatch<*>, getState: Function) => {
417
         switch (method) {
417
         switch (method) {
418
         case conference.join: {
418
         case conference.join: {
419
             let state = getState()['features/base/conference'];
419
             let state = getState()['features/base/conference'];
478
  *     receiveVideoQuality: number
478
  *     receiveVideoQuality: number
479
  * }}
479
  * }}
480
  */
480
  */
481
-export function setReceiveVideoQuality(receiveVideoQuality) {
481
+export function setReceiveVideoQuality(receiveVideoQuality: number) {
482
     return {
482
     return {
483
         type: SET_RECEIVE_VIDEO_QUALITY,
483
         type: SET_RECEIVE_VIDEO_QUALITY,
484
         receiveVideoQuality
484
         receiveVideoQuality
495
  *     room: string
495
  *     room: string
496
  * }}
496
  * }}
497
  */
497
  */
498
-export function setRoom(room) {
498
+export function setRoom(room: ?string) {
499
     return {
499
     return {
500
         type: SET_ROOM,
500
         type: SET_ROOM,
501
         room
501
         room

+ 5
- 0
react/features/base/config/reducer.js 查看文件

129
         newValue = set(newValue, 'p2p', {});
129
         newValue = set(newValue, 'p2p', {});
130
     }
130
     }
131
 
131
 
132
+    /* eslint-disable indent */
133
+
132
     // Translate the old config properties into the new config.p2p properties.
134
     // Translate the old config properties into the new config.p2p properties.
133
     for (const [ oldKey, newKey ]
135
     for (const [ oldKey, newKey ]
134
             of [
136
             of [
136
                 [ 'enableP2P', 'enabled' ],
138
                 [ 'enableP2P', 'enabled' ],
137
                 [ 'p2pStunServers', 'stunServers' ]
139
                 [ 'p2pStunServers', 'stunServers' ]
138
             ]) {
140
             ]) {
141
+
142
+    /* eslint-enable indent */
143
+
139
         if (oldKey in newValue) {
144
         if (oldKey in newValue) {
140
             const v = newValue[oldKey];
145
             const v = newValue[oldKey];
141
 
146
 

+ 2
- 2
react/features/base/connection/reducer.js 查看文件

158
 
158
 
159
     return {
159
     return {
160
         bosh:
160
         bosh:
161
-            `${String(protocol)}//${domain}${locationURI.contextRoot || '/'
162
-                }http-bind`,
161
+            `${String(protocol)}//${domain}${
162
+                locationURI.contextRoot || '/'}http-bind`,
163
         hosts: {
163
         hosts: {
164
             domain,
164
             domain,
165
 
165
 

+ 2
- 0
react/features/base/i18n/i18next.js 查看文件

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

+ 3
- 1
react/features/base/lib-jitsi-meet/actions.js 查看文件

1
+/* @flow */
2
+
1
 import type { Dispatch } from 'redux';
3
 import type { Dispatch } from 'redux';
2
 
4
 
3
 import JitsiMeetJS from './_';
5
 import JitsiMeetJS from './_';
95
  * @returns {Function}
97
  * @returns {Function}
96
  */
98
  */
97
 export function setWebRTCReady(webRTCReady: boolean | Promise<*>) {
99
 export function setWebRTCReady(webRTCReady: boolean | Promise<*>) {
98
-    return (dispatch: Dispatch<*>, getState: Function) => {
100
+    return (dispatch: Function, getState: Function) => {
99
         if (getState()['features/base/lib-jitsi-meet'].webRTCReady
101
         if (getState()['features/base/lib-jitsi-meet'].webRTCReady
100
                 !== webRTCReady) {
102
                 !== webRTCReady) {
101
             dispatch({
103
             dispatch({

+ 2
- 2
react/features/base/lib-jitsi-meet/native/RTCPeerConnection.js 查看文件

18
  */
18
  */
19
 export default function _RTCPeerConnection(...args) {
19
 export default function _RTCPeerConnection(...args) {
20
 
20
 
21
-    /* eslint-disable no-invalid-this */
21
+    /* eslint-disable indent, no-invalid-this */
22
 
22
 
23
     RTCPeerConnection.apply(this, args);
23
     RTCPeerConnection.apply(this, args);
24
 
24
 
44
         }
44
         }
45
     });
45
     });
46
 
46
 
47
-    /* eslint-enable no-invalid-this */
47
+    /* eslint-enable indent, no-invalid-this */
48
 }
48
 }
49
 
49
 
50
 _RTCPeerConnection.prototype = Object.create(RTCPeerConnection.prototype);
50
 _RTCPeerConnection.prototype = Object.create(RTCPeerConnection.prototype);

+ 4
- 2
react/features/base/media/components/AbstractAudio.js 查看文件

10
      * The (reference to the) {@link ReactElement} which actually implements
10
      * The (reference to the) {@link ReactElement} which actually implements
11
      * this {@code AbstractAudio}.
11
      * this {@code AbstractAudio}.
12
      */
12
      */
13
-    _ref: ?Object
13
+    _ref: ?Object;
14
+
15
+    _setRef: Function;
14
 
16
 
15
     /**
17
     /**
16
      * {@code AbstractAudio} component's property types.
18
      * {@code AbstractAudio} component's property types.
33
      * @param {Object} props - The read-only properties with which the new
35
      * @param {Object} props - The read-only properties with which the new
34
      * instance is to be initialized.
36
      * instance is to be initialized.
35
      */
37
      */
36
-    constructor(props) {
38
+    constructor(props: Object) {
37
         super(props);
39
         super(props);
38
 
40
 
39
         // Bind event handlers so they are only bound once for every instance.
41
         // Bind event handlers so they are only bound once for every instance.

+ 3
- 1
react/features/base/participants/components/Avatar.native.js 查看文件

95
             };
95
             };
96
 
96
 
97
             if (assignState) {
97
             if (assignState) {
98
+                // eslint-disable-next-line react/no-direct-mutation-state
98
                 this.state = nextState;
99
                 this.state = nextState;
99
             } else {
100
             } else {
100
                 this.setState(nextState);
101
                 this.setState(nextState);
134
                         observer,
135
                         observer,
135
                         /* immutable */ true);
136
                         /* immutable */ true);
136
                 } else if (assignState) {
137
                 } else if (assignState) {
138
+                    // eslint-disable-next-line react/no-direct-mutation-state
137
                     this.state = {
139
                     this.state = {
138
                         ...this.state,
140
                         ...this.state,
139
                         source: nextSource
141
                         source: nextSource
185
 
187
 
186
             for (let i = 0; i < uri.length; i++) {
188
             for (let i = 0; i < uri.length; i++) {
187
                 hash = uri.charCodeAt(i) + ((hash << 5) - hash);
189
                 hash = uri.charCodeAt(i) + ((hash << 5) - hash);
188
-                hash |= 0;  // Convert to 32-bit integer
190
+                hash |= 0; // Convert to 32-bit integer
189
             }
191
             }
190
 
192
 
191
             /* eslint-enable no-bitwise */
193
             /* eslint-enable no-bitwise */

+ 2
- 0
react/features/base/participants/middleware.js 查看文件

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

+ 2
- 0
react/features/base/react/components/web/InlineDialogFailure.js 查看文件

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

+ 6
- 0
react/features/base/react/components/web/Watermarks.js 查看文件

1
 /* @flow */
1
 /* @flow */
2
 
2
 
3
+import PropTypes from 'prop-types';
3
 import React, { Component } from 'react';
4
 import React, { Component } from 'react';
4
 import { connect } from 'react-redux';
5
 import { connect } from 'react-redux';
5
 
6
 
21
  * etc.
22
  * etc.
22
  */
23
  */
23
 class Watermarks extends Component {
24
 class Watermarks extends Component {
25
+    static propTypes = {
26
+        _isGuest: PropTypes.bool,
27
+        t: PropTypes.func
28
+    };
29
+
24
     state = {
30
     state = {
25
         brandWatermarkLink: String,
31
         brandWatermarkLink: String,
26
         jitsiWatermarkLink: String,
32
         jitsiWatermarkLink: String,

+ 4
- 4
react/features/conference/components/Conference.native.js 查看文件

203
                   * The activity/loading indicator goes above everything, except
203
                   * The activity/loading indicator goes above everything, except
204
                   * the toolbox/toolbars and the dialogs.
204
                   * the toolbox/toolbars and the dialogs.
205
                   */
205
                   */
206
-                  this.props._connecting
207
-                      && <View style = { styles.connectingIndicator }>
208
-                          <LoadingIndicator />
209
-                      </View>
206
+                    this.props._connecting
207
+                        && <View style = { styles.connectingIndicator }>
208
+                            <LoadingIndicator />
209
+                        </View>
210
                 }
210
                 }
211
 
211
 
212
                 {/*
212
                 {/*

+ 2
- 2
react/features/connection-stats/components/ConnectionStatsTable.js 查看文件

311
     _renderShowMoreLink() {
311
     _renderShowMoreLink() {
312
         const translationKey
312
         const translationKey
313
             = this.props.shouldShowMore
313
             = this.props.shouldShowMore
314
-            ? 'connectionindicator.less'
315
-            : 'connectionindicator.more';
314
+                ? 'connectionindicator.less'
315
+                : 'connectionindicator.more';
316
 
316
 
317
         return (
317
         return (
318
             <a
318
             <a

+ 2
- 0
react/features/contact-list/components/ContactListPanel.web.js 查看文件

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

+ 2
- 0
react/features/desktop-picker/components/DesktopPickerPane.js 查看文件

62
         const previews
62
         const previews
63
             = sources.map(
63
             = sources.map(
64
                 source =>
64
                 source =>
65
+
66
+                    // eslint-disable-next-line react/jsx-wrap-multilines
65
                     <DesktopSourcePreview
67
                     <DesktopSourcePreview
66
                         key = { source.id }
68
                         key = { source.id }
67
                         onClick = { onClick }
69
                         onClick = { onClick }

+ 1
- 1
react/features/device-selection/actions.js 查看文件

81
         const scope = `dialog_${API_ID}`;
81
         const scope = `dialog_${API_ID}`;
82
         const url = `${
82
         const url = `${
83
             window.location.origin}/static/deviceSelectionPopup.html#scope=${
83
             window.location.origin}/static/deviceSelectionPopup.html#scope=${
84
-                encodeURIComponent(JSON.stringify(scope))}`;
84
+            encodeURIComponent(JSON.stringify(scope))}`;
85
         const popup
85
         const popup
86
             = window.open(
86
             = window.open(
87
                 url,
87
                 url,

+ 3
- 2
react/features/dial-out/components/CountryIcon.js 查看文件

30
      */
30
      */
31
     render() {
31
     render() {
32
         const iconClassName
32
         const iconClassName
33
-            = `flag-icon flag-icon-${this.props.countryCode
34
-                } flag-icon-squared ${this.props.className}`;
33
+            = `flag-icon flag-icon-${
34
+                this.props.countryCode} flag-icon-squared ${
35
+                this.props.className}`;
35
 
36
 
36
         return <span className = { iconClassName } />;
37
         return <span className = { iconClassName } />;
37
     }
38
     }

+ 2
- 0
react/features/feedback/components/FeedbackButton.web.js 查看文件

23
          */
23
          */
24
         _conference: PropTypes.object,
24
         _conference: PropTypes.object,
25
 
25
 
26
+        dispatch: PropTypes.func,
27
+
26
         /**
28
         /**
27
          * Invoked to obtain translated strings.
29
          * Invoked to obtain translated strings.
28
          */
30
          */

+ 2
- 2
react/features/feedback/components/FeedbackDialog.web.js 查看文件

12
 
12
 
13
 declare var interfaceConfig: Object;
13
 declare var interfaceConfig: Object;
14
 
14
 
15
-const scoreAnimationClass = interfaceConfig.ENABLE_FEEDBACK_ANIMATION
16
-    ? 'shake-rotate' : '';
15
+const scoreAnimationClass
16
+    = interfaceConfig.ENABLE_FEEDBACK_ANIMATION ? 'shake-rotate' : '';
17
 
17
 
18
 /**
18
 /**
19
  * The scores to display for selecting. The score is the index in the array and
19
  * The scores to display for selecting. The score is the index in the array and

+ 7
- 4
react/features/filmstrip/components/Filmstrip.native.js 查看文件

53
                 visible = { this.props._visible }>
53
                 visible = { this.props._visible }>
54
                 <ScrollView
54
                 <ScrollView
55
 
55
 
56
-                    // eslint-disable-next-line react/jsx-curly-spacing
57
-                    contentContainerStyle = {
58
-                        styles.filmstripScrollViewContentContainer
59
-                    } // eslint-disable-line react/jsx-curly-spacing
56
+                    contentContainerStyle
57
+                        = { styles.filmstripScrollViewContentContainer }
60
                     horizontal = { true }
58
                     horizontal = { true }
61
                     showsHorizontalScrollIndicator = { false }
59
                     showsHorizontalScrollIndicator = { false }
62
                     showsVerticalScrollIndicator = { false }>
60
                     showsVerticalScrollIndicator = { false }>
63
                     {
61
                     {
62
+
63
+                        /* eslint-disable react/jsx-wrap-multilines */
64
+
64
                         this._sort(this.props._participants)
65
                         this._sort(this.props._participants)
65
                             .map(p =>
66
                             .map(p =>
66
                                 <Thumbnail
67
                                 <Thumbnail
67
                                     key = { p.id }
68
                                     key = { p.id }
68
                                     participant = { p } />)
69
                                     participant = { p } />)
70
+
71
+                        /* eslint-enable react/jsx-wrap-multilines */
69
                     }
72
                     }
70
                 </ScrollView>
73
                 </ScrollView>
71
             </Container>
74
             </Container>

+ 3
- 1
react/features/filmstrip/functions.js 查看文件

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

+ 1
- 1
react/features/invite/components/AddPeopleDialog.web.js 查看文件

334
         inviteServiceUrl,
334
         inviteServiceUrl,
335
         peopleSearchQueryTypes,
335
         peopleSearchQueryTypes,
336
         peopleSearchUrl
336
         peopleSearchUrl
337
-     } = state['features/base/config'];
337
+    } = state['features/base/config'];
338
 
338
 
339
     return {
339
     return {
340
         _conference: conference,
340
         _conference: conference,

+ 5
- 6
react/features/invite/functions.js 查看文件

10
  * executed - "conferenceRooms" | "user" | "room".
10
  * executed - "conferenceRooms" | "user" | "room".
11
  * @returns {Promise} - The promise created by the request.
11
  * @returns {Promise} - The promise created by the request.
12
  */
12
  */
13
-export function searchPeople(// eslint-disable-line max-params
14
-    serviceUrl,
15
-    jwt,
16
-    text,
17
-    queryTypes = [ 'conferenceRooms', 'user', 'room' ]
18
-) {
13
+export function searchPeople( // eslint-disable-line max-params
14
+        serviceUrl,
15
+        jwt,
16
+        text,
17
+        queryTypes = [ 'conferenceRooms', 'user', 'room' ]) {
19
     const queryTypesString = JSON.stringify(queryTypes);
18
     const queryTypesString = JSON.stringify(queryTypes);
20
 
19
 
21
     return new Promise((resolve, reject) => {
20
     return new Promise((resolve, reject) => {

+ 3
- 1
react/features/mobile/background/actions.js 查看文件

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

+ 1
- 1
react/features/mobile/background/middleware.js 查看文件

74
  * @private
74
  * @private
75
  * @returns {void}
75
  * @returns {void}
76
  */
76
  */
77
-function _appStateChanged(dispatch: Dispatch<*>, appState: string) {
77
+function _appStateChanged(dispatch: Function, appState: string) {
78
     let muted;
78
     let muted;
79
 
79
 
80
     switch (appState) {
80
     switch (appState) {

+ 10
- 3
react/features/mobile/permissions/middleware.js 查看文件

47
     // TODO i18n
47
     // TODO i18n
48
     const deviceType = trackType === 'video' ? 'Camera' : 'Microphone';
48
     const deviceType = trackType === 'video' ? 'Camera' : 'Microphone';
49
 
49
 
50
+    /* eslint-disable indent */
51
+
52
+    const message
53
+        = `${deviceType
54
+            } permission is required to participate in conferences with ${
55
+            trackType}. Please grant it in Settings.`;
56
+
57
+    /* eslint-ensable indent */
58
+
50
     Alert.alert(
59
     Alert.alert(
51
         'Permission required',
60
         'Permission required',
52
-        `${deviceType
53
-            } permission is required to participate in conferences with ${
54
-            trackType}. Please grant it in Settings.`,
61
+        message,
55
         [
62
         [
56
             { text: 'Cancel' },
63
             { text: 'Cancel' },
57
             {
64
             {

+ 2
- 0
react/features/overlay/components/ReloadButton.js 查看文件

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

+ 1
- 4
react/features/remote-control/components/RemoteControlAuthorizationDialog.js 查看文件

2
 import React, { Component } from 'react';
2
 import React, { Component } from 'react';
3
 import { connect } from 'react-redux';
3
 import { connect } from 'react-redux';
4
 
4
 
5
-import {
6
-    Dialog,
7
-    hideDialog
8
-} from '../../base/dialog';
5
+import { Dialog, hideDialog } from '../../base/dialog';
9
 import { translate } from '../../base/i18n';
6
 import { translate } from '../../base/i18n';
10
 import { getParticipantById } from '../../base/participants';
7
 import { getParticipantById } from '../../base/participants';
11
 
8
 

+ 1
- 2
react/features/toolbox/components/Toolbar.web.js 查看文件

123
      * @private
123
      * @private
124
      * @returns {ReactElement} A toolbar button.
124
      * @returns {ReactElement} A toolbar button.
125
      */
125
      */
126
-    _renderToolbarButton(
127
-                         keyValuePair: Array<*>): ReactElement<*> {
126
+    _renderToolbarButton(keyValuePair: Array<*>): ReactElement<*> {
128
         const [ key, button ] = keyValuePair;
127
         const [ key, button ] = keyValuePair;
129
 
128
 
130
         if (button.component) {
129
         if (button.component) {

+ 1
- 0
react/features/welcome/components/LocalVideoTrackUnderlay.native.js 查看文件

72
             };
72
             };
73
 
73
 
74
             if (assignState) {
74
             if (assignState) {
75
+                // eslint-disable-next-line react/no-direct-mutation-state
75
                 this.state = nextState;
76
                 this.state = nextState;
76
             } else {
77
             } else {
77
                 this.setState(nextState);
78
                 this.setState(nextState);

+ 4
- 0
webpack.config.js 查看文件

209
 
209
 
210
     const configs = module.exports;
210
     const configs = module.exports;
211
 
211
 
212
+    /* eslint-disable indent */
213
+
212
     if ((Array.isArray(configs) ? configs : Array(configs)).some(c => {
214
     if ((Array.isArray(configs) ? configs : Array(configs)).some(c => {
213
                 if (path.startsWith(c.output.publicPath)) {
215
                 if (path.startsWith(c.output.publicPath)) {
214
                     if (!minimize) {
216
                     if (!minimize) {
231
             })) {
233
             })) {
232
         return path;
234
         return path;
233
     }
235
     }
236
+
237
+    /* eslint-enable indent */
234
 }
238
 }

正在加载...
取消
保存