Selaa lähdekoodia

audio-only,lastn: move audio-only and last N handling to standalone features

This refactors all handling of audio-only and last N to 2 features in preparation
for "low bandwidth mode".

The main motivation to do this is that lastN is a "global" setting so it helps
to have all processing for it in a single place.
master
Saúl Ibarra Corretgé 5 vuotta sitten
vanhempi
commit
467c9d36cf
35 muutettua tiedostoa jossa 422 lisäystä ja 394 poistoa
  1. 1
    2
      conference.js
  2. 2
    2
      react/features/app/components/AbstractApp.js
  3. 12
    0
      react/features/base/audio-only/actionTypes.js
  4. 64
    0
      react/features/base/audio-only/actions.js
  5. 6
    0
      react/features/base/audio-only/index.js
  6. 23
    0
      react/features/base/audio-only/reducer.js
  7. 0
    21
      react/features/base/conference/actionTypes.js
  8. 0
    67
      react/features/base/conference/actions.js
  9. 5
    101
      react/features/base/conference/middleware.js
  10. 0
    18
      react/features/base/conference/reducer.js
  11. 11
    0
      react/features/base/lastn/actionTypes.js
  12. 34
    0
      react/features/base/lastn/actions.js
  13. 6
    0
      react/features/base/lastn/index.js
  14. 160
    0
      react/features/base/lastn/middleware.js
  15. 57
    2
      react/features/base/media/middleware.js
  16. 1
    1
      react/features/base/participants/functions.js
  17. 1
    1
      react/features/base/settings/middleware.js
  18. 0
    1
      react/features/filmstrip/index.js
  19. 0
    52
      react/features/filmstrip/middleware.js
  20. 4
    3
      react/features/mobile/audio-mode/middleware.js
  21. 0
    37
      react/features/mobile/background/actions.js
  22. 2
    42
      react/features/mobile/background/middleware.native.js
  23. 0
    0
      react/features/mobile/background/middleware.web.js
  24. 15
    17
      react/features/mobile/background/reducer.js
  25. 1
    1
      react/features/mobile/call-integration/middleware.js
  26. 2
    2
      react/features/mobile/full-screen/middleware.js
  27. 1
    1
      react/features/mobile/proximity/middleware.js
  28. 1
    1
      react/features/mobile/wake-lock/middleware.js
  29. 2
    2
      react/features/toolbox/components/VideoMuteButton.js
  30. 2
    2
      react/features/toolbox/components/native/AudioOnlyButton.js
  31. 1
    1
      react/features/toolbox/components/native/ToggleCameraButton.js
  32. 1
    1
      react/features/video-quality/components/AbstractVideoQualityLabel.js
  33. 1
    1
      react/features/video-quality/components/OverflowMenuVideoQualityItem.web.js
  34. 1
    1
      react/features/video-quality/components/VideoQualityLabel.web.js
  35. 5
    14
      react/features/video-quality/components/VideoQualitySlider.web.js

+ 1
- 2
conference.js Näytä tiedosto

@@ -1345,8 +1345,7 @@ export default {
1345 1345
      * @returns {boolean}
1346 1346
      */
1347 1347
     isAudioOnly() {
1348
-        return Boolean(
1349
-            APP.store.getState()['features/base/conference'].audioOnly);
1348
+        return Boolean(APP.store.getState()['features/base/audio-only'].enabled);
1350 1349
     },
1351 1350
 
1352 1351
     videoSwitchInProgress: false,

+ 2
- 2
react/features/app/components/AbstractApp.js Näytä tiedosto

@@ -7,8 +7,8 @@ import { toURLString } from '../../base/util';
7 7
 import '../../follow-me';
8 8
 import { OverlayContainer } from '../../overlay';
9 9
 
10
-// Enable rejoin analytics
11
-import '../../rejoin';
10
+import '../../base/lastn'; // Register lastN middleware
11
+import '../../rejoin'; // Enable rejoin analytics
12 12
 
13 13
 import { appNavigate } from '../actions';
14 14
 import { getDefaultURL } from '../functions';

+ 12
- 0
react/features/base/audio-only/actionTypes.js Näytä tiedosto

@@ -0,0 +1,12 @@
1
+// @flow
2
+
3
+/**
4
+ * The type of (redux) action which sets the audio-only flag for the current
5
+ * conference.
6
+ *
7
+ * {
8
+ *     type: SET_AUDIO_ONLY,
9
+ *     audioOnly: boolean
10
+ * }
11
+ */
12
+export const SET_AUDIO_ONLY = 'SET_AUDIO_ONLY';

+ 64
- 0
react/features/base/audio-only/actions.js Näytä tiedosto

@@ -0,0 +1,64 @@
1
+// @flow
2
+
3
+import { getLogger } from 'jitsi-meet-logger';
4
+
5
+import UIEvents from '../../../../service/UI/UIEvents';
6
+
7
+import { createAudioOnlyChangedEvent, sendAnalytics } from '../../analytics';
8
+
9
+import { SET_AUDIO_ONLY } from './actionTypes';
10
+
11
+import type { Dispatch } from 'redux';
12
+
13
+declare var APP: Object;
14
+const logger = getLogger('features/base/audio-only');
15
+
16
+
17
+/**
18
+ * Sets the audio-only flag for the current JitsiConference.
19
+ *
20
+ * @param {boolean} audioOnly - True if the conference should be audio only;
21
+ * false, otherwise.
22
+ * @param {boolean} ensureVideoTrack - Define if conference should ensure
23
+ * to create a video track.
24
+ * @returns {{
25
+ *     type: SET_AUDIO_ONLY,
26
+ *     audioOnly: boolean,
27
+ *     ensureVideoTrack: boolean
28
+ * }}
29
+ */
30
+export function setAudioOnly(audioOnly: boolean, ensureVideoTrack: boolean = false) {
31
+    return (dispatch: Dispatch<any>, getState: Function) => {
32
+        const { enabled: oldValue } = getState()['features/base/audio-only'];
33
+
34
+        if (oldValue !== audioOnly) {
35
+            sendAnalytics(createAudioOnlyChangedEvent(audioOnly));
36
+            logger.log(`Audio-only ${audioOnly ? 'enabled' : 'disabled'}`);
37
+
38
+            dispatch({
39
+                type: SET_AUDIO_ONLY,
40
+                audioOnly,
41
+                ensureVideoTrack
42
+            });
43
+
44
+            if (typeof APP !== 'undefined') {
45
+                // TODO This should be a temporary solution that lasts only until video
46
+                // tracks and all ui is moved into react/redux on the web.
47
+                APP.UI.emitEvent(UIEvents.TOGGLE_AUDIO_ONLY, audioOnly);
48
+            }
49
+        }
50
+    };
51
+}
52
+
53
+/**
54
+ * Toggles the audio-only flag for the current JitsiConference.
55
+ *
56
+ * @returns {Function}
57
+ */
58
+export function toggleAudioOnly() {
59
+    return (dispatch: Dispatch<any>, getState: Function) => {
60
+        const { enabled } = getState()['features/base/audio-only'];
61
+
62
+        return dispatch(setAudioOnly(!enabled, true));
63
+    };
64
+}

+ 6
- 0
react/features/base/audio-only/index.js Näytä tiedosto

@@ -0,0 +1,6 @@
1
+// @flow
2
+
3
+export * from './actions';
4
+export * from './actionTypes';
5
+
6
+import './reducer';

+ 23
- 0
react/features/base/audio-only/reducer.js Näytä tiedosto

@@ -0,0 +1,23 @@
1
+// @flow
2
+
3
+import { ReducerRegistry } from '../redux';
4
+
5
+import { SET_AUDIO_ONLY } from './actionTypes';
6
+
7
+
8
+const DEFAULT_STATE = {
9
+    enabled: false
10
+};
11
+
12
+
13
+ReducerRegistry.register('features/base/audio-only', (state = DEFAULT_STATE, action) => {
14
+    switch (action.type) {
15
+    case SET_AUDIO_ONLY:
16
+        return {
17
+            ...state,
18
+            enabled: action.audioOnly
19
+        };
20
+    default:
21
+        return state;
22
+    }
23
+});

+ 0
- 21
react/features/base/conference/actionTypes.js Näytä tiedosto

@@ -118,17 +118,6 @@ export const LOCK_STATE_CHANGED = 'LOCK_STATE_CHANGED';
118 118
  */
119 119
 export const P2P_STATUS_CHANGED = 'P2P_STATUS_CHANGED';
120 120
 
121
-/**
122
- * The type of (redux) action which sets the audio-only flag for the current
123
- * conference.
124
- *
125
- * {
126
- *     type: SET_AUDIO_ONLY,
127
- *     audioOnly: boolean
128
- * }
129
- */
130
-export const SET_AUDIO_ONLY = 'SET_AUDIO_ONLY';
131
-
132 121
 /**
133 122
  * The type of (redux) action which sets the desktop sharing enabled flag for
134 123
  * the current conference.
@@ -152,16 +141,6 @@ export const SET_DESKTOP_SHARING_ENABLED
152 141
  */
153 142
 export const SET_FOLLOW_ME = 'SET_FOLLOW_ME';
154 143
 
155
-/**
156
- * The type of (redux) action which sets the video channel's lastN (value).
157
- *
158
- * {
159
- *     type: SET_LASTN,
160
- *     lastN: number
161
- * }
162
- */
163
-export const SET_LASTN = 'SET_LASTN';
164
-
165 144
 /**
166 145
  * The type of (redux) action which sets the maximum video height that should be
167 146
  * received from remote participants, even if the user prefers a larger video

+ 0
- 67
react/features/base/conference/actions.js Näytä tiedosto

@@ -35,10 +35,8 @@ import {
35 35
     KICKED_OUT,
36 36
     LOCK_STATE_CHANGED,
37 37
     P2P_STATUS_CHANGED,
38
-    SET_AUDIO_ONLY,
39 38
     SET_DESKTOP_SHARING_ENABLED,
40 39
     SET_FOLLOW_ME,
41
-    SET_LASTN,
42 40
     SET_MAX_RECEIVER_VIDEO_QUALITY,
43 41
     SET_PASSWORD,
44 42
     SET_PASSWORD_FAILED,
@@ -522,29 +520,6 @@ export function p2pStatusChanged(p2p: boolean) {
522 520
     };
523 521
 }
524 522
 
525
-/**
526
- * Sets the audio-only flag for the current JitsiConference.
527
- *
528
- * @param {boolean} audioOnly - True if the conference should be audio only;
529
- * false, otherwise.
530
- * @param {boolean} ensureVideoTrack - Define if conference should ensure
531
- * to create a video track.
532
- * @returns {{
533
- *     type: SET_AUDIO_ONLY,
534
- *     audioOnly: boolean,
535
- *     ensureVideoTrack: boolean
536
- * }}
537
- */
538
-export function setAudioOnly(
539
-        audioOnly: boolean,
540
-        ensureVideoTrack: boolean = false) {
541
-    return {
542
-        type: SET_AUDIO_ONLY,
543
-        audioOnly,
544
-        ensureVideoTrack
545
-    };
546
-}
547
-
548 523
 /**
549 524
  * Sets the flag for indicating if desktop sharing is enabled.
550 525
  *
@@ -577,35 +552,6 @@ export function setFollowMe(enabled: boolean) {
577 552
     };
578 553
 }
579 554
 
580
-/**
581
- * Sets the video channel's last N (value) of the current conference. A value of
582
- * undefined shall be used to reset it to the default value.
583
- *
584
- * @param {(number|undefined)} lastN - The last N value to be set.
585
- * @returns {Function}
586
- */
587
-export function setLastN(lastN: ?number) {
588
-    return (dispatch: Dispatch<any>, getState: Function) => {
589
-        if (typeof lastN === 'undefined') {
590
-            const config = getState()['features/base/config'];
591
-
592
-            /* eslint-disable no-param-reassign */
593
-
594
-            lastN = config.channelLastN;
595
-            if (typeof lastN === 'undefined') {
596
-                lastN = -1;
597
-            }
598
-
599
-            /* eslint-enable no-param-reassign */
600
-        }
601
-
602
-        dispatch({
603
-            type: SET_LASTN,
604
-            lastN
605
-        });
606
-    };
607
-}
608
-
609 555
 /**
610 556
  * Sets the max frame height that should be received from remote videos.
611 557
  *
@@ -754,19 +700,6 @@ export function setStartMutedPolicy(
754 700
     };
755 701
 }
756 702
 
757
-/**
758
- * Toggles the audio-only flag for the current JitsiConference.
759
- *
760
- * @returns {Function}
761
- */
762
-export function toggleAudioOnly() {
763
-    return (dispatch: Dispatch<any>, getState: Function) => {
764
-        const { audioOnly } = getState()['features/base/conference'];
765
-
766
-        return dispatch(setAudioOnly(!audioOnly, true));
767
-    };
768
-}
769
-
770 703
 /**
771 704
  * Changing conference subject.
772 705
  *

+ 5
- 101
react/features/base/conference/middleware.js Näytä tiedosto

@@ -4,7 +4,6 @@ import { reloadNow } from '../../app';
4 4
 import {
5 5
     ACTION_PINNED,
6 6
     ACTION_UNPINNED,
7
-    createAudioOnlyChangedEvent,
8 7
     createConnectionEvent,
9 8
     createOfferAnswerFailedEvent,
10 9
     createPinnedEvent,
@@ -12,7 +11,6 @@ import {
12 11
 } from '../../analytics';
13 12
 import { CONNECTION_ESTABLISHED, CONNECTION_FAILED } from '../connection';
14 13
 import { JitsiConferenceErrors } from '../lib-jitsi-meet';
15
-import { setVideoMuted, VIDEO_MUTISM_AUTHORITY } from '../media';
16 14
 import {
17 15
     getParticipantById,
18 16
     getPinnedParticipant,
@@ -20,14 +18,12 @@ import {
20 18
     PIN_PARTICIPANT
21 19
 } from '../participants';
22 20
 import { MiddlewareRegistry, StateListenerRegistry } from '../redux';
23
-import UIEvents from '../../../../service/UI/UIEvents';
24 21
 import { TRACK_ADDED, TRACK_REMOVED } from '../tracks';
25 22
 
26 23
 import {
27 24
     conferenceFailed,
28 25
     conferenceWillLeave,
29 26
     createConference,
30
-    setLastN,
31 27
     setSubject
32 28
 } from './actions';
33 29
 import {
@@ -36,16 +32,14 @@ import {
36 32
     CONFERENCE_SUBJECT_CHANGED,
37 33
     CONFERENCE_WILL_LEAVE,
38 34
     DATA_CHANNEL_OPENED,
39
-    SET_AUDIO_ONLY,
40
-    SET_LASTN,
41 35
     SET_PENDING_SUBJECT_CHANGE,
42 36
     SET_ROOM
43 37
 } from './actionTypes';
44 38
 import {
45 39
     _addLocalTracksToConference,
40
+    _removeLocalTracksFromConference,
46 41
     forEachConference,
47
-    getCurrentConference,
48
-    _removeLocalTracksFromConference
42
+    getCurrentConference
49 43
 } from './functions';
50 44
 
51 45
 const logger = require('jitsi-meet-logger').getLogger(__filename);
@@ -93,12 +87,6 @@ MiddlewareRegistry.register(store => next => action => {
93 87
     case PIN_PARTICIPANT:
94 88
         return _pinParticipant(store, next, action);
95 89
 
96
-    case SET_AUDIO_ONLY:
97
-        return _setAudioOnly(store, next, action);
98
-
99
-    case SET_LASTN:
100
-        return _setLastN(store, next, action);
101
-
102 90
     case SET_ROOM:
103 91
         return _setRoom(store, next, action);
104 92
 
@@ -197,21 +185,10 @@ function _conferenceFailed(store, next, action) {
197 185
  */
198 186
 function _conferenceJoined({ dispatch, getState }, next, action) {
199 187
     const result = next(action);
188
+    const { conference } = action;
189
+    const { pendingSubjectChange } = getState()['features/base/conference'];
200 190
 
201
-    const {
202
-        audioOnly,
203
-        conference,
204
-        pendingSubjectChange
205
-    } = getState()['features/base/conference'];
206
-
207
-    if (pendingSubjectChange) {
208
-        dispatch(setSubject(pendingSubjectChange));
209
-    }
210
-
211
-    // FIXME On Web the audio only mode for "start audio only" is toggled before
212
-    // conference is added to the redux store ("on conference joined" action)
213
-    // and the LastN value needs to be synchronized here.
214
-    audioOnly && conference.getLastN() !== 0 && dispatch(setLastN(0));
191
+    pendingSubjectChange && dispatch(setSubject(pendingSubjectChange));
215 192
 
216 193
     // FIXME: Very dirty solution. This will work on web only.
217 194
     // When the user closes the window or quits the browser, lib-jitsi-meet
@@ -460,79 +437,6 @@ function _pinParticipant({ getState }, next, action) {
460 437
     return next(action);
461 438
 }
462 439
 
463
-/**
464
- * Sets the audio-only flag for the current conference. When audio-only is set,
465
- * local video is muted and last N is set to 0 to avoid receiving remote video.
466
- *
467
- * @param {Store} store - The redux store in which the specified {@code action}
468
- * is being dispatched.
469
- * @param {Dispatch} next - The redux {@code dispatch} function to dispatch the
470
- * specified {@code action} to the specified {@code store}.
471
- * @param {Action} action - The redux action {@code SET_AUDIO_ONLY} which is
472
- * being dispatched in the specified {@code store}.
473
- * @private
474
- * @returns {Object} The value returned by {@code next(action)}.
475
- */
476
-function _setAudioOnly({ dispatch, getState }, next, action) {
477
-    const { audioOnly: oldValue } = getState()['features/base/conference'];
478
-    const result = next(action);
479
-    const { audioOnly: newValue } = getState()['features/base/conference'];
480
-
481
-    // Send analytics. We could've done it in the action creator setAudioOnly.
482
-    // I don't know why it has to happen as early as possible but the analytics
483
-    // were originally sent before the SET_AUDIO_ONLY action was even dispatched
484
-    // in the redux store so I'm now sending the analytics as early as possible.
485
-    if (oldValue !== newValue) {
486
-        sendAnalytics(createAudioOnlyChangedEvent(newValue));
487
-        logger.log(`Audio-only ${newValue ? 'enabled' : 'disabled'}`);
488
-    }
489
-
490
-    // Set lastN to 0 in case audio-only is desired; leave it as undefined,
491
-    // otherwise, and the default lastN value will be chosen automatically.
492
-    dispatch(setLastN(newValue ? 0 : undefined));
493
-
494
-    // Mute/unmute the local video.
495
-    dispatch(
496
-        setVideoMuted(
497
-            newValue,
498
-            VIDEO_MUTISM_AUTHORITY.AUDIO_ONLY,
499
-            action.ensureVideoTrack));
500
-
501
-    if (typeof APP !== 'undefined') {
502
-        // TODO This should be a temporary solution that lasts only until video
503
-        // tracks and all ui is moved into react/redux on the web.
504
-        APP.UI.emitEvent(UIEvents.TOGGLE_AUDIO_ONLY, newValue);
505
-    }
506
-
507
-    return result;
508
-}
509
-
510
-/**
511
- * Sets the last N (value) of the video channel in the conference.
512
- *
513
- * @param {Store} store - The redux store in which the specified {@code action}
514
- * is being dispatched.
515
- * @param {Dispatch} next - The redux {@code dispatch} function to dispatch the
516
- * specified {@code action} to the specified {@code store}.
517
- * @param {Action} action - The redux action {@code SET_LASTN} which is being
518
- * dispatched in the specified {@code store}.
519
- * @private
520
- * @returns {Object} The value returned by {@code next(action)}.
521
- */
522
-function _setLastN({ getState }, next, action) {
523
-    const { conference } = getState()['features/base/conference'];
524
-
525
-    if (conference) {
526
-        try {
527
-            conference.setLastN(action.lastN);
528
-        } catch (err) {
529
-            logger.error(`Failed to set lastN: ${err}`);
530
-        }
531
-    }
532
-
533
-    return next(action);
534
-}
535
-
536 440
 /**
537 441
  * Helper function for updating the preferred receiver video constraint, based
538 442
  * on the user preference and the internal maximum.

+ 0
- 18
react/features/base/conference/reducer.js Näytä tiedosto

@@ -15,7 +15,6 @@ import {
15 15
     CONFERENCE_WILL_LEAVE,
16 16
     LOCK_STATE_CHANGED,
17 17
     P2P_STATUS_CHANGED,
18
-    SET_AUDIO_ONLY,
19 18
     SET_DESKTOP_SHARING_ENABLED,
20 19
     SET_FOLLOW_ME,
21 20
     SET_MAX_RECEIVER_VIDEO_QUALITY,
@@ -76,9 +75,6 @@ ReducerRegistry.register(
76 75
         case P2P_STATUS_CHANGED:
77 76
             return _p2pStatusChanged(state, action);
78 77
 
79
-        case SET_AUDIO_ONLY:
80
-            return _setAudioOnly(state, action);
81
-
82 78
         case SET_DESKTOP_SHARING_ENABLED:
83 79
             return _setDesktopSharingEnabled(state, action);
84 80
 
@@ -346,20 +342,6 @@ function _p2pStatusChanged(state, action) {
346 342
     return set(state, 'p2p', action.p2p);
347 343
 }
348 344
 
349
-/**
350
- * Reduces a specific Redux action SET_AUDIO_ONLY of the feature
351
- * base/conference.
352
- *
353
- * @param {Object} state - The Redux state of the feature base/conference.
354
- * @param {Action} action - The Redux action SET_AUDIO_ONLY to reduce.
355
- * @private
356
- * @returns {Object} The new state of the feature base/conference after the
357
- * reduction of the specified action.
358
- */
359
-function _setAudioOnly(state, action) {
360
-    return set(state, 'audioOnly', action.audioOnly);
361
-}
362
-
363 345
 /**
364 346
  * Reduces a specific Redux action SET_DESKTOP_SHARING_ENABLED of the feature
365 347
  * base/conference.

+ 11
- 0
react/features/base/lastn/actionTypes.js Näytä tiedosto

@@ -0,0 +1,11 @@
1
+// @flow
2
+
3
+/**
4
+ * The type of (redux) action which sets the video channel's lastN (value).
5
+ *
6
+ * {
7
+ *     type: SET_LASTN,
8
+ *     lastN: number
9
+ * }
10
+ */
11
+export const SET_LASTN = 'SET_LASTN';

+ 34
- 0
react/features/base/lastn/actions.js Näytä tiedosto

@@ -0,0 +1,34 @@
1
+// @flow
2
+
3
+import { SET_LASTN } from './actionTypes';
4
+
5
+import type { Dispatch } from 'redux';
6
+
7
+/**
8
+ * Sets the video channel's last N (value) of the current conference. A value of
9
+ * undefined shall be used to reset it to the default value.
10
+ *
11
+ * @param {(number|undefined)} lastN - The last N value to be set.
12
+ * @returns {Function}
13
+ */
14
+export function setLastN(lastN: ?number) {
15
+    return (dispatch: Dispatch<any>, getState: Function) => {
16
+        if (typeof lastN === 'undefined') {
17
+            const config = getState()['features/base/config'];
18
+
19
+            /* eslint-disable no-param-reassign */
20
+
21
+            lastN = config.channelLastN;
22
+            if (typeof lastN === 'undefined') {
23
+                lastN = -1;
24
+            }
25
+
26
+            /* eslint-enable no-param-reassign */
27
+        }
28
+
29
+        dispatch({
30
+            type: SET_LASTN,
31
+            lastN
32
+        });
33
+    };
34
+}

+ 6
- 0
react/features/base/lastn/index.js Näytä tiedosto

@@ -0,0 +1,6 @@
1
+// @flow
2
+
3
+export * from './actions';
4
+export * from './actionTypes';
5
+
6
+import './middleware';

+ 160
- 0
react/features/base/lastn/middleware.js Näytä tiedosto

@@ -0,0 +1,160 @@
1
+// @flow
2
+
3
+import { getLogger } from 'jitsi-meet-logger';
4
+
5
+import { SET_FILMSTRIP_ENABLED } from '../../filmstrip/actionTypes';
6
+import { APP_STATE_CHANGED } from '../../mobile/background/actionTypes';
7
+
8
+import { SET_AUDIO_ONLY } from '../audio-only';
9
+import { CONFERENCE_JOINED } from '../conference/actionTypes';
10
+import { MiddlewareRegistry } from '../redux';
11
+
12
+import { setLastN } from './actions';
13
+import { SET_LASTN } from './actionTypes';
14
+
15
+declare var APP: Object;
16
+
17
+const logger = getLogger('features/base/lastn');
18
+
19
+
20
+MiddlewareRegistry.register(store => next => action => {
21
+    switch (action.type) {
22
+    case APP_STATE_CHANGED:
23
+        return _appStateChanged(store, next, action);
24
+
25
+    case CONFERENCE_JOINED:
26
+        return _conferenceJoined(store, next, action);
27
+
28
+    case SET_AUDIO_ONLY:
29
+        return _setAudioOnly(store, next, action);
30
+
31
+    case SET_FILMSTRIP_ENABLED:
32
+        return _setFilmstripEnabled(store, next, action);
33
+
34
+    case SET_LASTN:
35
+        return _setLastN(store, next, action);
36
+    }
37
+
38
+    return next(action);
39
+});
40
+
41
+/**
42
+ * Adjusts the lasN value based on the app state.
43
+ *
44
+ * @param {Store} store - The redux store in which the specified {@code action}
45
+ * is being dispatched.
46
+ * @param {Dispatch} next - The redux {@code dispatch} function to dispatch the
47
+ * specified {@code action} to the specified {@code store}.
48
+ * @param {Action} action - The redux action {@code APP_STATE_CHANGED} which is
49
+ * being dispatched in the specified {@code store}.
50
+ * @private
51
+ * @returns {Object} The value returned by {@code next(action)}.
52
+ */
53
+function _appStateChanged({ dispatch, getState }, next, action) {
54
+    const { enabled: audioOnly } = getState()['features/base/audio-only'];
55
+
56
+    if (!audioOnly) {
57
+        const { appState } = action;
58
+        const lastN = appState === 'active' ? undefined : 0;
59
+
60
+        dispatch(setLastN(lastN));
61
+        logger.log(`App state changed - updated lastN to ${String(lastN)}`);
62
+    }
63
+
64
+    return next(action);
65
+}
66
+
67
+/**
68
+ * Adjusts the lasN value upon joining a conference.
69
+ *
70
+ * @param {Store} store - The redux store in which the specified {@code action}
71
+ * is being dispatched.
72
+ * @param {Dispatch} next - The redux {@code dispatch} function to dispatch the
73
+ * specified {@code action} to the specified {@code store}.
74
+ * @param {Action} action - The redux action {@code CONFERENCE_JOINED} which is
75
+ * being dispatched in the specified {@code store}.
76
+ * @private
77
+ * @returns {Object} The value returned by {@code next(action)}.
78
+ */
79
+function _conferenceJoined({ dispatch, getState }, next, action) {
80
+    const { conference } = action;
81
+    const { enabled: audioOnly } = getState()['features/base/audio-only'];
82
+
83
+    audioOnly && conference.getLastN() !== 0 && dispatch(setLastN(0));
84
+
85
+    return next(action);
86
+}
87
+
88
+/**
89
+ * Sets the audio-only flag for the current conference. When audio-only is set,
90
+ * local video is muted and last N is set to 0 to avoid receiving remote video.
91
+ *
92
+ * @param {Store} store - The redux store in which the specified {@code action}
93
+ * is being dispatched.
94
+ * @param {Dispatch} next - The redux {@code dispatch} function to dispatch the
95
+ * specified {@code action} to the specified {@code store}.
96
+ * @param {Action} action - The redux action {@code SET_AUDIO_ONLY} which is
97
+ * being dispatched in the specified {@code store}.
98
+ * @private
99
+ * @returns {Object} The value returned by {@code next(action)}.
100
+ */
101
+function _setAudioOnly({ dispatch }, next, action) {
102
+    const { audioOnly } = action;
103
+
104
+    // Set lastN to 0 in case audio-only is desired; leave it as undefined,
105
+    // otherwise, and the default lastN value will be chosen automatically.
106
+    dispatch(setLastN(audioOnly ? 0 : undefined));
107
+
108
+    return next(action);
109
+}
110
+
111
+/**
112
+ * Notifies the feature filmstrip that the action {@link SET_FILMSTRIP_ENABLED}
113
+ * is being dispatched within a specific redux store.
114
+ *
115
+ * @param {Store} store - The redux store in which the specified action is being
116
+ * dispatched.
117
+ * @param {Dispatch} next - The redux dispatch function to dispatch the
118
+ * specified action to the specified store.
119
+ * @param {Action} action - The redux action {@code SET_FILMSTRIP_ENABLED} which
120
+ * is being dispatched in the specified store.
121
+ * @private
122
+ * @returns {Object} The value returned by {@code next(action)}.
123
+ */
124
+function _setFilmstripEnabled({ dispatch, getState }, next, action) {
125
+    // FIXME This action is not currently dispatched on web.
126
+    if (typeof APP === 'undefined') {
127
+        const { enabled } = action;
128
+        const { enabled: audioOnly } = getState()['features/base/audio-only'];
129
+
130
+        audioOnly || dispatch(setLastN(enabled ? undefined : 1));
131
+    }
132
+
133
+    return next(action);
134
+}
135
+
136
+/**
137
+ * Sets the last N (value) of the video channel in the conference.
138
+ *
139
+ * @param {Store} store - The redux store in which the specified {@code action}
140
+ * is being dispatched.
141
+ * @param {Dispatch} next - The redux {@code dispatch} function to dispatch the
142
+ * specified {@code action} to the specified {@code store}.
143
+ * @param {Action} action - The redux action {@code SET_LASTN} which is being
144
+ * dispatched in the specified {@code store}.
145
+ * @private
146
+ * @returns {Object} The value returned by {@code next(action)}.
147
+ */
148
+function _setLastN({ getState }, next, action) {
149
+    const { conference } = getState()['features/base/conference'];
150
+
151
+    if (conference) {
152
+        try {
153
+            conference.setLastN(action.lastN);
154
+        } catch (err) {
155
+            logger.error(`Failed to set lastN: ${err}`);
156
+        }
157
+    }
158
+
159
+    return next(action);
160
+}

+ 57
- 2
react/features/base/media/middleware.js Näytä tiedosto

@@ -4,16 +4,20 @@ import {
4 4
     createStartAudioOnlyEvent,
5 5
     createStartMutedConfigurationEvent,
6 6
     createSyncTrackStateEvent,
7
+    createTrackMutedEvent,
7 8
     sendAnalytics
8 9
 } from '../../analytics';
9
-import { isRoomValid, SET_ROOM, setAudioOnly } from '../conference';
10
+import { APP_STATE_CHANGED } from '../../mobile/background';
11
+
12
+import { SET_AUDIO_ONLY, setAudioOnly } from '../audio-only';
13
+import { isRoomValid, SET_ROOM } from '../conference';
10 14
 import JitsiMeetJS from '../lib-jitsi-meet';
11 15
 import { MiddlewareRegistry } from '../redux';
12 16
 import { getPropertyValue } from '../settings';
13 17
 import { setTrackMuted, TRACK_ADDED } from '../tracks';
14 18
 
15 19
 import { setAudioMuted, setCameraFacingMode, setVideoMuted } from './actions';
16
-import { CAMERA_FACING_MODE } from './constants';
20
+import { CAMERA_FACING_MODE, VIDEO_MUTISM_AUTHORITY } from './constants';
17 21
 import {
18 22
     _AUDIO_INITIAL_MEDIA_STATE,
19 23
     _VIDEO_INITIAL_MEDIA_STATE
@@ -29,6 +33,12 @@ const logger = require('jitsi-meet-logger').getLogger(__filename);
29 33
  */
30 34
 MiddlewareRegistry.register(store => next => action => {
31 35
     switch (action.type) {
36
+    case APP_STATE_CHANGED:
37
+        return _appStateChanged(store, next, action);
38
+
39
+    case SET_AUDIO_ONLY:
40
+        return _setAudioOnly(store, next, action);
41
+
32 42
     case SET_ROOM:
33 43
         return _setRoom(store, next, action);
34 44
 
@@ -45,6 +55,51 @@ MiddlewareRegistry.register(store => next => action => {
45 55
     return next(action);
46 56
 });
47 57
 
58
+/**
59
+ * Adjusts the video muted state based on the app state.
60
+ *
61
+ * @param {Store} store - The redux store in which the specified {@code action}
62
+ * is being dispatched.
63
+ * @param {Dispatch} next - The redux {@code dispatch} function to dispatch the
64
+ * specified {@code action} to the specified {@code store}.
65
+ * @param {Action} action - The redux action {@code APP_STATE_CHANGED} which is
66
+ * being dispatched in the specified {@code store}.
67
+ * @private
68
+ * @returns {Object} The value returned by {@code next(action)}.
69
+ */
70
+function _appStateChanged({ dispatch }, next, action) {
71
+    const { appState } = action;
72
+    const mute = appState !== 'active'; // Note that 'background' and 'inactive' are treated equal.
73
+
74
+    sendAnalytics(createTrackMutedEvent('video', 'background mode', mute));
75
+
76
+    dispatch(setVideoMuted(mute, VIDEO_MUTISM_AUTHORITY.BACKGROUND));
77
+
78
+    return next(action);
79
+}
80
+
81
+/**
82
+ * Adjusts the video muted state based on the audio-only state.
83
+ *
84
+ * @param {Store} store - The redux store in which the specified {@code action}
85
+ * is being dispatched.
86
+ * @param {Dispatch} next - The redux {@code dispatch} function to dispatch the
87
+ * specified {@code action} to the specified {@code store}.
88
+ * @param {Action} action - The redux action {@code SET_AUDIO_ONLY} which is
89
+ * being dispatched in the specified {@code store}.
90
+ * @private
91
+ * @returns {Object} The value returned by {@code next(action)}.
92
+ */
93
+function _setAudioOnly({ dispatch }, next, action) {
94
+    const { audioOnly } = action;
95
+
96
+    sendAnalytics(createTrackMutedEvent('video', 'audio-only mode', audioOnly));
97
+
98
+    dispatch(setVideoMuted(audioOnly, VIDEO_MUTISM_AUTHORITY.AUDIO_ONLY));
99
+
100
+    return next(action);
101
+}
102
+
48 103
 /**
49 104
  * Notifies the feature base/media that the action {@link SET_ROOM} is being
50 105
  * dispatched within a specific redux {@code store}.

+ 1
- 1
react/features/base/participants/functions.js Näytä tiedosto

@@ -314,7 +314,7 @@ export function shouldRenderParticipantVideo(
314 314
         return false;
315 315
     }
316 316
 
317
-    const audioOnly = state['features/base/conference'].audioOnly;
317
+    const audioOnly = state['features/base/audio-only'].enabled;
318 318
     const connectionStatus = participant.connectionStatus
319 319
         || JitsiParticipantConnectionStatus.ACTIVE;
320 320
     const videoTrack = getTrackByMediaTypeAndParticipant(

+ 1
- 1
react/features/base/settings/middleware.js Näytä tiedosto

@@ -1,6 +1,6 @@
1 1
 // @flow
2 2
 
3
-import { setAudioOnly } from '../conference';
3
+import { setAudioOnly } from '../audio-only';
4 4
 import { getLocalParticipant, participantUpdated } from '../participants';
5 5
 import { MiddlewareRegistry } from '../redux';
6 6
 

+ 0
- 1
react/features/filmstrip/index.js Näytä tiedosto

@@ -4,5 +4,4 @@ export * from './components';
4 4
 export * from './constants';
5 5
 export * from './functions';
6 6
 
7
-import './middleware';
8 7
 import './reducer';

+ 0
- 52
react/features/filmstrip/middleware.js Näytä tiedosto

@@ -1,52 +0,0 @@
1
-// @flow
2
-
3
-import { setLastN } from '../base/conference';
4
-import { MiddlewareRegistry } from '../base/redux';
5
-
6
-import { SET_FILMSTRIP_ENABLED } from './actionTypes';
7
-
8
-declare var APP: Object;
9
-
10
-MiddlewareRegistry.register(store => next => action => {
11
-    switch (action.type) {
12
-    case SET_FILMSTRIP_ENABLED:
13
-        return _setFilmstripEnabled(store, next, action);
14
-    }
15
-
16
-    return next(action);
17
-});
18
-
19
-/**
20
- * Notifies the feature filmstrip that the action {@link SET_FILMSTRIP_ENABLED}
21
- * is being dispatched within a specific redux store.
22
- *
23
- * @param {Store} store - The redux store in which the specified action is being
24
- * dispatched.
25
- * @param {Dispatch} next - The redux dispatch function to dispatch the
26
- * specified action to the specified store.
27
- * @param {Action} action - The redux action {@code SET_FILMSTRIP_ENABLED} which
28
- * is being dispatched in the specified store.
29
- * @private
30
- * @returns {Object} The value returned by {@code next(action)}.
31
- */
32
-function _setFilmstripEnabled({ dispatch, getState }, next, action) {
33
-    const result = next(action);
34
-
35
-    // FIXME This action is not currently dispatched on web.
36
-    if (typeof APP === 'undefined') {
37
-        const state = getState();
38
-        const { enabled } = state['features/filmstrip'];
39
-        const { audioOnly } = state['features/base/conference'];
40
-
41
-        // FIXME Audio-only mode fiddles with lastN as well. That's why we don't
42
-        // touch lastN in audio-only mode. But it's not clear what the value of
43
-        // lastN should be upon exit from audio-only mode if the filmstrip is
44
-        // disabled already. Currently, audio-only mode will set undefined
45
-        // regardless of whether the filmstrip is disabled. But we don't have a
46
-        // practical use case in which audio-only mode is exited while the
47
-        // filmstrip is disabled.
48
-        audioOnly || dispatch(setLastN(enabled ? undefined : 1));
49
-    }
50
-
51
-    return result;
52
-}

+ 4
- 3
react/features/mobile/audio-mode/middleware.js Näytä tiedosto

@@ -2,12 +2,12 @@
2 2
 
3 3
 import { NativeModules } from 'react-native';
4 4
 
5
+import { SET_AUDIO_ONLY } from '../../base/audio-only';
5 6
 import { APP_WILL_MOUNT } from '../../base/app';
6 7
 import {
7 8
     CONFERENCE_FAILED,
8 9
     CONFERENCE_LEFT,
9 10
     CONFERENCE_JOINED,
10
-    SET_AUDIO_ONLY,
11 11
     getCurrentConference
12 12
 } from '../../base/conference';
13 13
 import { MiddlewareRegistry } from '../../base/redux';
@@ -53,8 +53,9 @@ MiddlewareRegistry.register(({ getState }) => next => action => {
53 53
          */
54 54
         case CONFERENCE_JOINED:
55 55
         case SET_AUDIO_ONLY: {
56
-            const { audioOnly, conference }
57
-                = getState()['features/base/conference'];
56
+            const state = getState();
57
+            const { conference } = state['features/base/conference'];
58
+            const { enabled: audioOnly } = state['features/base/audio-only'];
58 59
 
59 60
             conference
60 61
                 && (mode = audioOnly

+ 0
- 37
react/features/mobile/background/actions.js Näytä tiedosto

@@ -1,14 +1,5 @@
1 1
 // @flow
2 2
 
3
-import type { Dispatch } from 'redux';
4
-
5
-import {
6
-    createTrackMutedEvent,
7
-    sendAnalytics
8
-} from '../../analytics';
9
-import { setLastN } from '../../base/conference';
10
-import { setVideoMuted, VIDEO_MUTISM_AUTHORITY } from '../../base/media';
11
-
12 3
 import { _SET_APP_STATE_LISTENER, APP_STATE_CHANGED } from './actionTypes';
13 4
 
14 5
 /**
@@ -28,34 +19,6 @@ export function _setAppStateListener(listener: ?Function) {
28 19
     };
29 20
 }
30 21
 
31
-/**
32
- * Signals that the app should mute video because it's now running in the
33
- * background, or unmute it because it came back from the background. If video
34
- * was already muted nothing will happen; otherwise, it will be muted. When
35
- * coming back from the background the previous state will be restored.
36
- *
37
- * @param {boolean} muted - True if video should be muted; false, otherwise.
38
- * @protected
39
- * @returns {Function}
40
- */
41
-export function _setBackgroundVideoMuted(muted: boolean) {
42
-    return (dispatch: Dispatch<any>, getState: Function) => {
43
-        // Disable remote video when we mute by setting lastN to 0. Skip it if
44
-        // the conference is in audio-only mode, as it's already configured to
45
-        // have no video. Leave it as undefined when unmuting, the default value
46
-        // for last N will be chosen automatically.
47
-        const { audioOnly } = getState()['features/base/conference'];
48
-
49
-        audioOnly || dispatch(setLastN(muted ? 0 : undefined));
50
-
51
-        sendAnalytics(createTrackMutedEvent(
52
-            'video',
53
-            'callkit.background.video'));
54
-
55
-        dispatch(setVideoMuted(muted, VIDEO_MUTISM_AUTHORITY.BACKGROUND));
56
-    };
57
-}
58
-
59 22
 /**
60 23
  * Signals that the App state has changed (in terms of execution state). The
61 24
  * application can be in 3 states: 'active', 'inactive' and 'background'.

react/features/mobile/background/middleware.js → react/features/mobile/background/middleware.native.js Näytä tiedosto

@@ -8,13 +8,9 @@ import { MiddlewareRegistry } from '../../base/redux';
8 8
 
9 9
 import {
10 10
     _setAppStateListener as _setAppStateListenerA,
11
-    _setBackgroundVideoMuted,
12 11
     appStateChanged
13 12
 } from './actions';
14
-import {
15
-    _SET_APP_STATE_LISTENER,
16
-    APP_STATE_CHANGED
17
-} from './actionTypes';
13
+import { _SET_APP_STATE_LISTENER } from './actionTypes';
18 14
 
19 15
 /**
20 16
  * Middleware that captures App lifetime actions and subscribes to application
@@ -31,15 +27,10 @@ MiddlewareRegistry.register(store => next => action => {
31 27
     case _SET_APP_STATE_LISTENER:
32 28
         return _setAppStateListenerF(store, next, action);
33 29
 
34
-    case APP_STATE_CHANGED:
35
-        _appStateChanged(store.dispatch, action.appState);
36
-        break;
37
-
38 30
     case APP_WILL_MOUNT: {
39 31
         const { dispatch } = store;
40 32
 
41
-        dispatch(
42
-            _setAppStateListenerA(_onAppStateChange.bind(undefined, dispatch)));
33
+        dispatch(_setAppStateListenerA(_onAppStateChange.bind(undefined, dispatch)));
43 34
         break;
44 35
     }
45 36
 
@@ -51,37 +42,6 @@ MiddlewareRegistry.register(store => next => action => {
51 42
     return next(action);
52 43
 });
53 44
 
54
-/**
55
- * Handles app state changes. Dispatches the necessary redux actions for the
56
- * local video to be muted when the app goes to the background, and to be
57
- * unmuted when the app comes back.
58
- *
59
- * @param {Dispatch} dispatch - The redux {@code dispatch} function.
60
- * @param {string} appState - The current app state.
61
- * @private
62
- * @returns {void}
63
- */
64
-function _appStateChanged(dispatch: Function, appState: string) {
65
-    let muted;
66
-
67
-    switch (appState) {
68
-    case 'active':
69
-        muted = false;
70
-        break;
71
-
72
-    case 'background':
73
-        muted = true;
74
-        break;
75
-
76
-    case 'inactive':
77
-    default:
78
-        // XXX: We purposely don't handle the 'inactive' app state.
79
-        return;
80
-    }
81
-
82
-    dispatch(_setBackgroundVideoMuted(muted));
83
-}
84
-
85 45
 /**
86 46
  * Called by React Native's AppState API to notify that the application state
87 47
  * has changed. Dispatches the change within the (associated) redux store.

+ 0
- 0
react/features/mobile/background/middleware.web.js Näytä tiedosto


+ 15
- 17
react/features/mobile/background/reducer.js Näytä tiedosto

@@ -14,22 +14,20 @@ const DEFAULT_STATE = {
14 14
     appState: 'active'
15 15
 };
16 16
 
17
-ReducerRegistry.register(
18
-    'features/background',
19
-    (state = DEFAULT_STATE, action) => {
20
-        switch (action.type) {
21
-        case _SET_APP_STATE_LISTENER:
22
-            return {
23
-                ...state,
24
-                appStateListener: action.listener
25
-            };
17
+ReducerRegistry.register('features/background', (state = DEFAULT_STATE, action) => {
18
+    switch (action.type) {
19
+    case _SET_APP_STATE_LISTENER:
20
+        return {
21
+            ...state,
22
+            appStateListener: action.listener
23
+        };
26 24
 
27
-        case APP_STATE_CHANGED:
28
-            return {
29
-                ...state,
30
-                appState: action.appState
31
-            };
32
-        }
25
+    case APP_STATE_CHANGED:
26
+        return {
27
+            ...state,
28
+            appState: action.appState
29
+        };
30
+    }
33 31
 
34
-        return state;
35
-    });
32
+    return state;
33
+});

+ 1
- 1
react/features/mobile/call-integration/middleware.js Näytä tiedosto

@@ -6,13 +6,13 @@ import uuid from 'uuid';
6 6
 import { createTrackMutedEvent, sendAnalytics } from '../../analytics';
7 7
 import { appNavigate } from '../../app';
8 8
 import { APP_WILL_MOUNT, APP_WILL_UNMOUNT } from '../../base/app';
9
+import { SET_AUDIO_ONLY } from '../../base/audio-only';
9 10
 import {
10 11
     CONFERENCE_FAILED,
11 12
     CONFERENCE_JOINED,
12 13
     CONFERENCE_LEFT,
13 14
     CONFERENCE_WILL_JOIN,
14 15
     CONFERENCE_WILL_LEAVE,
15
-    SET_AUDIO_ONLY,
16 16
     getConferenceName,
17 17
     getCurrentConference
18 18
 } from '../../base/conference';

+ 2
- 2
react/features/mobile/full-screen/middleware.js Näytä tiedosto

@@ -46,7 +46,7 @@ MiddlewareRegistry.register(store => next => action => {
46 46
 
47 47
 StateListenerRegistry.register(
48 48
     /* selector */ state => {
49
-        const { audioOnly } = state['features/base/conference'];
49
+        const { enabled: audioOnly } = state['features/base/audio-only'];
50 50
         const conference = getCurrentConference(state);
51 51
 
52 52
         return conference ? !audioOnly : false;
@@ -68,7 +68,7 @@ function _onImmersiveChange({ getState }) {
68 68
     const { appState } = state['features/background'];
69 69
 
70 70
     if (appState === 'active') {
71
-        const { audioOnly } = state['features/base/conference'];
71
+        const { enabled: audioOnly } = state['features/base/audio-only'];
72 72
         const conference = getCurrentConference(state);
73 73
         const fullScreen = conference ? !audioOnly : false;
74 74
 

+ 1
- 1
react/features/mobile/proximity/middleware.js Näytä tiedosto

@@ -11,7 +11,7 @@ import { StateListenerRegistry } from '../../base/redux';
11 11
  */
12 12
 StateListenerRegistry.register(
13 13
     /* selector */ state => {
14
-        const { audioOnly } = state['features/base/conference'];
14
+        const { enabled: audioOnly } = state['features/base/audio-only'];
15 15
         const conference = getCurrentConference(state);
16 16
 
17 17
         return Boolean(conference && audioOnly);

+ 1
- 1
react/features/mobile/wake-lock/middleware.js Näytä tiedosto

@@ -9,7 +9,7 @@ import { StateListenerRegistry } from '../../base/redux';
9 9
  */
10 10
 StateListenerRegistry.register(
11 11
     /* selector */ state => {
12
-        const { audioOnly } = state['features/base/conference'];
12
+        const { enabled: audioOnly } = state['features/base/audio-only'];
13 13
         const conference = getCurrentConference(state);
14 14
 
15 15
         return Boolean(conference && !audioOnly);

+ 2
- 2
react/features/toolbox/components/VideoMuteButton.js Näytä tiedosto

@@ -7,7 +7,7 @@ import {
7 7
     createToolbarEvent,
8 8
     sendAnalytics
9 9
 } from '../../analytics';
10
-import { setAudioOnly } from '../../base/conference';
10
+import { setAudioOnly } from '../../base/audio-only';
11 11
 import { translate } from '../../base/i18n';
12 12
 import {
13 13
     MEDIA_TYPE,
@@ -162,7 +162,7 @@ class VideoMuteButton extends AbstractVideoMuteButton<Props, *> {
162 162
  * }}
163 163
  */
164 164
 function _mapStateToProps(state): Object {
165
-    const { audioOnly } = state['features/base/conference'];
165
+    const { enabled: audioOnly } = state['features/base/audio-only'];
166 166
     const tracks = state['features/base/tracks'];
167 167
 
168 168
     return {

+ 2
- 2
react/features/toolbox/components/native/AudioOnlyButton.js Näytä tiedosto

@@ -1,6 +1,6 @@
1 1
 // @flow
2 2
 
3
-import { toggleAudioOnly } from '../../../base/conference';
3
+import { toggleAudioOnly } from '../../../base/audio-only';
4 4
 import { translate } from '../../../base/i18n';
5 5
 import { connect } from '../../../base/redux';
6 6
 import { AbstractButton } from '../../../base/toolbox';
@@ -66,7 +66,7 @@ class AudioOnlyButton extends AbstractButton<Props, *> {
66 66
  * }}
67 67
  */
68 68
 function _mapStateToProps(state): Object {
69
-    const { audioOnly } = state['features/base/conference'];
69
+    const { enabled: audioOnly } = state['features/base/audio-only'];
70 70
 
71 71
     return {
72 72
         _audioOnly: Boolean(audioOnly)

+ 1
- 1
react/features/toolbox/components/native/ToggleCameraButton.js Näytä tiedosto

@@ -71,7 +71,7 @@ class ToggleCameraButton extends AbstractButton<Props, *> {
71 71
  * }}
72 72
  */
73 73
 function _mapStateToProps(state): Object {
74
-    const { audioOnly } = state['features/base/conference'];
74
+    const { enabled: audioOnly } = state['features/base/audio-only'];
75 75
     const tracks = state['features/base/tracks'];
76 76
 
77 77
     return {

+ 1
- 1
react/features/video-quality/components/AbstractVideoQualityLabel.js Näytä tiedosto

@@ -33,7 +33,7 @@ export default class AbstractVideoQualityLabel<P: Props> extends Component<P> {
33 33
  * }}
34 34
  */
35 35
 export function _abstractMapStateToProps(state: Object) {
36
-    const { audioOnly } = state['features/base/conference'];
36
+    const { enabled: audioOnly } = state['features/base/audio-only'];
37 37
 
38 38
     return {
39 39
         _audioOnly: audioOnly

+ 1
- 1
react/features/video-quality/components/OverflowMenuVideoQualityItem.web.js Näytä tiedosto

@@ -96,7 +96,7 @@ class OverflowMenuVideoQualityItem extends Component<Props> {
96 96
  */
97 97
 function _mapStateToProps(state) {
98 98
     return {
99
-        _audioOnly: state['features/base/conference'].audioOnly,
99
+        _audioOnly: state['features/base/audio-only'].enabled,
100 100
         _receiverVideoQuality:
101 101
             state['features/base/conference'].preferredReceiverVideoQuality
102 102
     };

+ 1
- 1
react/features/video-quality/components/VideoQualityLabel.web.js Näytä tiedosto

@@ -156,7 +156,7 @@ function _mapResolutionToTranslationsKeys(resolution) {
156 156
  * }}
157 157
  */
158 158
 function _mapStateToProps(state) {
159
-    const { audioOnly } = state['features/base/conference'];
159
+    const { enabled: audioOnly } = state['features/base/audio-only'];
160 160
     const { resolution, participantId } = state['features/large-video'];
161 161
     const videoTrackOnLargeVideo = getTrackByMediaTypeAndParticipant(
162 162
         state['features/base/tracks'],

+ 5
- 14
react/features/video-quality/components/VideoQualitySlider.web.js Näytä tiedosto

@@ -4,15 +4,9 @@ import InlineMessage from '@atlaskit/inline-message';
4 4
 import React, { Component } from 'react';
5 5
 import type { Dispatch } from 'redux';
6 6
 
7
-import {
8
-    createToolbarEvent,
9
-    sendAnalytics
10
-} from '../../analytics';
11
-import {
12
-    VIDEO_QUALITY_LEVELS,
13
-    setAudioOnly,
14
-    setPreferredReceiverVideoQuality
15
-} from '../../base/conference';
7
+import { createToolbarEvent, sendAnalytics } from '../../analytics';
8
+import { setAudioOnly } from '../../base/audio-only';
9
+import { VIDEO_QUALITY_LEVELS, setPreferredReceiverVideoQuality } from '../../base/conference';
16 10
 import { translate } from '../../base/i18n';
17 11
 import JitsiMeetJS from '../../base/lib-jitsi-meet';
18 12
 import { connect } from '../../base/redux';
@@ -406,11 +400,8 @@ class VideoQualitySlider extends Component<Props> {
406 400
  * }}
407 401
  */
408 402
 function _mapStateToProps(state) {
409
-    const {
410
-        audioOnly,
411
-        p2p,
412
-        preferredReceiverVideoQuality
413
-    } = state['features/base/conference'];
403
+    const { enabled: audioOnly } = state['features/base/audio-only'];
404
+    const { p2p, preferredReceiverVideoQuality } = state['features/base/conference'];
414 405
 
415 406
     return {
416 407
         _audioOnly: audioOnly,

Loading…
Peruuta
Tallenna