From b02d96231c25c37803ca24b5251b0be661c8c173 Mon Sep 17 00:00:00 2001 From: Hristo Terezov Date: Tue, 1 Sep 2020 14:19:04 -0500 Subject: [PATCH] ref(video-quality): Move all related code. --- react/features/base/conference/actionTypes.js | 24 ---- react/features/base/conference/actions.js | 37 ------ react/features/base/conference/constants.js | 12 -- react/features/base/conference/middleware.js | 96 +------------- react/features/base/conference/reducer.js | 19 +-- react/features/video-quality/actionTypes.js | 23 ++++ react/features/video-quality/actions.js | 39 +++++- .../OverflowMenuVideoQualityItem.web.js | 4 +- .../components/VideoQualitySlider.web.js | 6 +- react/features/video-quality/constants.js | 12 +- react/features/video-quality/functions.js | 4 +- react/features/video-quality/index.js | 1 + react/features/video-quality/middleware.js | 117 +++++++++++++++++- react/features/video-quality/reducer.js | 21 +++- react/features/video-quality/selector.js | 2 +- 15 files changed, 213 insertions(+), 204 deletions(-) create mode 100644 react/features/video-quality/actionTypes.js diff --git a/react/features/base/conference/actionTypes.js b/react/features/base/conference/actionTypes.js index 6b506dff9..eab734015 100644 --- a/react/features/base/conference/actionTypes.js +++ b/react/features/base/conference/actionTypes.js @@ -163,19 +163,6 @@ export const SET_DESKTOP_SHARING_ENABLED */ export const SET_FOLLOW_ME = 'SET_FOLLOW_ME'; -/** - * The type of (redux) action which sets the maximum video height that should be - * received from remote participants, even if the user prefers a larger video - * height. - * - * { - * type: SET_MAX_RECEIVER_VIDEO_QUALITY, - * maxReceiverVideoQuality: number - * } - */ -export const SET_MAX_RECEIVER_VIDEO_QUALITY - = 'SET_MAX_RECEIVER_VIDEO_QUALITY'; - /** * The type of (redux) action which sets the password to join or lock a specific * {@code JitsiConference}. @@ -210,17 +197,6 @@ export const SET_PASSWORD_FAILED = 'SET_PASSWORD_FAILED'; */ export const SET_PENDING_SUBJECT_CHANGE = 'SET_PENDING_SUBJECT_CHANGE'; -/** - * The type of (redux) action which sets the preferred maximum video height that - * should be sent to and received from remote participants. - * - * { - * type: SET_PREFERRED_VIDEO_QUALITY, - * preferredVideoQuality: number - * } - */ -export const SET_PREFERRED_VIDEO_QUALITY = 'SET_PREFERRED_VIDEO_QUALITY'; - /** * The type of (redux) action which sets the name of the room of the * conference to be joined. diff --git a/react/features/base/conference/actions.js b/react/features/base/conference/actions.js index f844ed297..f59cb6451 100644 --- a/react/features/base/conference/actions.js +++ b/react/features/base/conference/actions.js @@ -45,10 +45,8 @@ import { SEND_TONES, SET_DESKTOP_SHARING_ENABLED, SET_FOLLOW_ME, - SET_MAX_RECEIVER_VIDEO_QUALITY, SET_PASSWORD, SET_PASSWORD_FAILED, - SET_PREFERRED_VIDEO_QUALITY, SET_ROOM, SET_PENDING_SUBJECT_CHANGE, SET_START_MUTED_POLICY @@ -615,23 +613,6 @@ export function setFollowMe(enabled: boolean) { }; } -/** - * Sets the max frame height that should be received from remote videos. - * - * @param {number} maxReceiverVideoQuality - The max video frame height to - * receive. - * @returns {{ - * type: SET_MAX_RECEIVER_VIDEO_QUALITY, - * maxReceiverVideoQuality: number - * }} - */ -export function setMaxReceiverVideoQuality(maxReceiverVideoQuality: number) { - return { - type: SET_MAX_RECEIVER_VIDEO_QUALITY, - maxReceiverVideoQuality - }; -} - /** * Sets the password to join or lock a specific JitsiConference. * @@ -698,24 +679,6 @@ export function setPassword( }; } -/** - * Sets the max frame height the user prefers to send and receive from the - * remote participants. - * - * @param {number} preferredVideoQuality - The max video resolution to send and - * receive. - * @returns {{ - * type: SET_PREFERRED_VIDEO_QUALITY, - * preferredVideoQuality: number - * }} - */ -export function setPreferredVideoQuality(preferredVideoQuality: number) { - return { - type: SET_PREFERRED_VIDEO_QUALITY, - preferredVideoQuality - }; -} - /** * Sets (the name of) the room of the conference to be joined. * diff --git a/react/features/base/conference/constants.js b/react/features/base/conference/constants.js index 7b515efc6..fcb13302f 100644 --- a/react/features/base/conference/constants.js +++ b/react/features/base/conference/constants.js @@ -34,15 +34,3 @@ export const EMAIL_COMMAND = 'email'; * from the outside is not cool but it should suffice for now. */ export const JITSI_CONFERENCE_URL_KEY = Symbol('url'); - -/** - * The supported remote video resolutions. The values are currently based on - * available simulcast layers. - * - * @type {object} - */ -export const VIDEO_QUALITY_LEVELS = { - HIGH: 720, - STANDARD: 360, - LOW: 180 -}; diff --git a/react/features/base/conference/middleware.js b/react/features/base/conference/middleware.js index cf800c745..6ebc4a580 100644 --- a/react/features/base/conference/middleware.js +++ b/react/features/base/conference/middleware.js @@ -20,7 +20,7 @@ import { PARTICIPANT_UPDATED, PIN_PARTICIPANT } from '../participants'; -import { MiddlewareRegistry, StateListenerRegistry } from '../redux'; +import { MiddlewareRegistry } from '../redux'; import { TRACK_ADDED, TRACK_REMOVED } from '../tracks'; import { @@ -28,7 +28,6 @@ import { CONFERENCE_JOINED, CONFERENCE_SUBJECT_CHANGED, CONFERENCE_WILL_LEAVE, - DATA_CHANNEL_OPENED, SEND_TONES, SET_PENDING_SUBJECT_CHANGE, SET_ROOM @@ -81,9 +80,6 @@ MiddlewareRegistry.register(store => next => action => { _conferenceWillLeave(); break; - case DATA_CHANNEL_OPENED: - return _syncReceiveVideoQuality(store, next, action); - case PARTICIPANT_UPDATED: return _updateLocalParticipantInConference(store, next, action); @@ -104,31 +100,6 @@ MiddlewareRegistry.register(store => next => action => { return next(action); }); -/** - * Registers a change handler for state['features/base/conference'] to update - * the preferred video quality levels based on user preferred and internal - * settings. - */ -StateListenerRegistry.register( - /* selector */ state => state['features/base/conference'], - /* listener */ (currentState, store, previousState = {}) => { - const { - conference, - maxReceiverVideoQuality, - preferredVideoQuality - } = currentState; - const changedConference = conference !== previousState.conference; - const changedPreferredVideoQuality - = preferredVideoQuality !== previousState.preferredVideoQuality; - const changedMaxVideoQuality = maxReceiverVideoQuality !== previousState.maxReceiverVideoQuality; - - if (changedConference || changedPreferredVideoQuality || changedMaxVideoQuality) { - _setReceiverVideoConstraint(conference, preferredVideoQuality, maxReceiverVideoQuality); - } - if (changedConference || changedPreferredVideoQuality) { - _setSenderVideoConstraint(conference, preferredVideoQuality); - } - }); /** * Makes sure to leave a failed conference in order to release any allocated @@ -448,44 +419,6 @@ function _sendTones({ getState }, next, action) { return next(action); } -/** - * Helper function for updating the preferred receiver video constraint, based - * on the user preference and the internal maximum. - * - * @param {JitsiConference} conference - The JitsiConference instance for the - * current call. - * @param {number} preferred - The user preferred max frame height. - * @param {number} max - The maximum frame height the application should - * receive. - * @returns {void} - */ -function _setReceiverVideoConstraint(conference, preferred, max) { - if (conference) { - const value = Math.min(preferred, max); - - conference.setReceiverVideoConstraint(value); - logger.info(`setReceiverVideoConstraint: ${value}`); - } -} - -/** - * Helper function for updating the preferred sender video constraint, based - * on the user preference. - * - * @param {JitsiConference} conference - The JitsiConference instance for the - * current call. - * @param {number} preferred - The user preferred max frame height. - * @returns {void} - */ -function _setSenderVideoConstraint(conference, preferred) { - if (conference) { - conference.setSenderVideoConstraint(preferred) - .catch(err => { - logger.error(`Changing sender resolution to ${preferred} failed - ${err} `); - }); - } -} - /** * Notifies the feature base/conference that the action * {@code SET_ROOM} is being dispatched within a specific @@ -539,33 +472,6 @@ function _syncConferenceLocalTracksWithState({ getState }, action) { return promise || Promise.resolve(); } -/** - * Sets the maximum receive video quality. - * - * @param {Store} store - The redux store in which the specified {@code action} - * is being dispatched. - * @param {Dispatch} next - The redux {@code dispatch} function to dispatch the - * specified {@code action} to the specified {@code store}. - * @param {Action} action - The redux action {@code DATA_CHANNEL_STATUS_CHANGED} - * which is being dispatched in the specified {@code store}. - * @private - * @returns {Object} The value returned by {@code next(action)}. - */ -function _syncReceiveVideoQuality({ getState }, next, action) { - const { - conference, - maxReceiverVideoQuality, - preferredVideoQuality - } = getState()['features/base/conference']; - - _setReceiverVideoConstraint( - conference, - preferredVideoQuality, - maxReceiverVideoQuality); - - return next(action); -} - /** * Notifies the feature base/conference that the action {@code TRACK_ADDED} * or {@code TRACK_REMOVED} is being dispatched within a specific redux store. diff --git a/react/features/base/conference/reducer.js b/react/features/base/conference/reducer.js index b1f850b6c..d303d0c30 100644 --- a/react/features/base/conference/reducer.js +++ b/react/features/base/conference/reducer.js @@ -18,15 +18,12 @@ import { P2P_STATUS_CHANGED, SET_DESKTOP_SHARING_ENABLED, SET_FOLLOW_ME, - SET_MAX_RECEIVER_VIDEO_QUALITY, SET_PASSWORD, SET_PENDING_SUBJECT_CHANGE, - SET_PREFERRED_VIDEO_QUALITY, SET_ROOM, SET_SIP_GATEWAY_ENABLED, SET_START_MUTED_POLICY } from './actionTypes'; -import { VIDEO_QUALITY_LEVELS } from './constants'; import { isRoomValid } from './functions'; const DEFAULT_STATE = { @@ -35,11 +32,9 @@ const DEFAULT_STATE = { joining: undefined, leaving: undefined, locked: undefined, - maxReceiverVideoQuality: VIDEO_QUALITY_LEVELS.HIGH, membersOnly: undefined, password: undefined, - passwordRequired: undefined, - preferredVideoQuality: VIDEO_QUALITY_LEVELS.HIGH + passwordRequired: undefined }; /** @@ -90,24 +85,12 @@ ReducerRegistry.register( case SET_LOCATION_URL: return set(state, 'room', undefined); - case SET_MAX_RECEIVER_VIDEO_QUALITY: - return set( - state, - 'maxReceiverVideoQuality', - action.maxReceiverVideoQuality); - case SET_PASSWORD: return _setPassword(state, action); case SET_PENDING_SUBJECT_CHANGE: return set(state, 'pendingSubjectChange', action.subject); - case SET_PREFERRED_VIDEO_QUALITY: - return set( - state, - 'preferredVideoQuality', - action.preferredVideoQuality); - case SET_ROOM: return _setRoom(state, action); diff --git a/react/features/video-quality/actionTypes.js b/react/features/video-quality/actionTypes.js new file mode 100644 index 000000000..d3616f462 --- /dev/null +++ b/react/features/video-quality/actionTypes.js @@ -0,0 +1,23 @@ +/** + * The type of (redux) action which sets the preferred maximum video height that + * should be sent to and received from remote participants. + * + * { + * type: SET_PREFERRED_VIDEO_QUALITY, + * preferredVideoQuality: number + * } + */ +export const SET_PREFERRED_VIDEO_QUALITY = 'SET_PREFERRED_VIDEO_QUALITY'; + + +/** + * The type of (redux) action which sets the maximum video height that should be + * received from remote participants, even if the user prefers a larger video + * height. + * + * { + * type: SET_MAX_RECEIVER_VIDEO_QUALITY, + * maxReceiverVideoQuality: number + * } + */ +export const SET_MAX_RECEIVER_VIDEO_QUALITY = 'SET_MAX_RECEIVER_VIDEO_QUALITY'; diff --git a/react/features/video-quality/actions.js b/react/features/video-quality/actions.js index 3e4e5b9d6..4f4029d7b 100644 --- a/react/features/video-quality/actions.js +++ b/react/features/video-quality/actions.js @@ -2,10 +2,45 @@ import type { Dispatch } from 'redux'; -import { VIDEO_QUALITY_LEVELS } from '../base/conference'; - +import { SET_MAX_RECEIVER_VIDEO_QUALITY, SET_PREFERRED_VIDEO_QUALITY } from './actionTypes'; +import { VIDEO_QUALITY_LEVELS } from './constants'; import logger from './logger'; +/** + * Sets the max frame height the user prefers to send and receive from the + * remote participants. + * + * @param {number} preferredVideoQuality - The max video resolution to send and + * receive. + * @returns {{ + * type: SET_PREFERRED_VIDEO_QUALITY, + * preferredVideoQuality: number + * }} + */ +export function setPreferredVideoQuality(preferredVideoQuality: number) { + return { + type: SET_PREFERRED_VIDEO_QUALITY, + preferredVideoQuality + }; +} + +/** + * Sets the max frame height that should be received from remote videos. + * + * @param {number} maxReceiverVideoQuality - The max video frame height to + * receive. + * @returns {{ + * type: SET_MAX_RECEIVER_VIDEO_QUALITY, + * maxReceiverVideoQuality: number + * }} + */ +export function setMaxReceiverVideoQuality(maxReceiverVideoQuality: number) { + return { + type: SET_MAX_RECEIVER_VIDEO_QUALITY, + maxReceiverVideoQuality + }; +} + /** * Sets the maximum video size the local participant should send and receive from diff --git a/react/features/video-quality/components/OverflowMenuVideoQualityItem.web.js b/react/features/video-quality/components/OverflowMenuVideoQualityItem.web.js index 39c461201..da68a39a8 100644 --- a/react/features/video-quality/components/OverflowMenuVideoQualityItem.web.js +++ b/react/features/video-quality/components/OverflowMenuVideoQualityItem.web.js @@ -2,7 +2,6 @@ import React, { Component } from 'react'; -import { VIDEO_QUALITY_LEVELS } from '../../base/conference/constants'; import { translate } from '../../base/i18n'; import { Icon, @@ -12,6 +11,7 @@ import { IconVideoQualitySD } from '../../base/icons'; import { connect } from '../../base/redux'; +import { VIDEO_QUALITY_LEVELS } from '../constants'; /** * A map of of selectable receive resolutions to corresponding icons. @@ -104,7 +104,7 @@ class OverflowMenuVideoQualityItem extends Component { function _mapStateToProps(state) { return { _audioOnly: state['features/base/audio-only'].enabled, - _videoQuality: state['features/base/conference'].preferredVideoQuality + _videoQuality: state['features/video-quality'].preferredVideoQuality }; } diff --git a/react/features/video-quality/components/VideoQualitySlider.web.js b/react/features/video-quality/components/VideoQualitySlider.web.js index 288f24475..8ede03359 100644 --- a/react/features/video-quality/components/VideoQualitySlider.web.js +++ b/react/features/video-quality/components/VideoQualitySlider.web.js @@ -6,10 +6,11 @@ import type { Dispatch } from 'redux'; import { createToolbarEvent, sendAnalytics } from '../../analytics'; import { setAudioOnly } from '../../base/audio-only'; -import { VIDEO_QUALITY_LEVELS, setPreferredVideoQuality } from '../../base/conference'; import { translate } from '../../base/i18n'; import JitsiMeetJS from '../../base/lib-jitsi-meet'; import { connect } from '../../base/redux'; +import { setPreferredVideoQuality } from '../actions'; +import { VIDEO_QUALITY_LEVELS } from '../constants'; import logger from '../logger'; const { @@ -380,7 +381,8 @@ class VideoQualitySlider extends Component { */ function _mapStateToProps(state) { const { enabled: audioOnly } = state['features/base/audio-only']; - const { p2p, preferredVideoQuality } = state['features/base/conference']; + const { p2p } = state['features/base/conference']; + const { preferredVideoQuality } = state['features/video-quality']; return { _audioOnly: audioOnly, diff --git a/react/features/video-quality/constants.js b/react/features/video-quality/constants.js index 3306fd147..382c23dd4 100644 --- a/react/features/video-quality/constants.js +++ b/react/features/video-quality/constants.js @@ -1,4 +1,14 @@ -import { VIDEO_QUALITY_LEVELS } from '../base/conference'; +/** + * The supported remote video resolutions. The values are currently based on + * available simulcast layers. + * + * @type {object} + */ +export const VIDEO_QUALITY_LEVELS = { + HIGH: 720, + STANDARD: 360, + LOW: 180 +}; /** * Maps quality level names used in the config.videoQuality.minHeightForQualityLvl to the quality level constants used diff --git a/react/features/video-quality/functions.js b/react/features/video-quality/functions.js index a17e7fae5..30567e611 100644 --- a/react/features/video-quality/functions.js +++ b/react/features/video-quality/functions.js @@ -1,8 +1,6 @@ // @flow -import { VIDEO_QUALITY_LEVELS } from '../base/conference'; - -import { CFG_LVL_TO_APP_QUALITY_LVL } from './constants'; +import { CFG_LVL_TO_APP_QUALITY_LVL, VIDEO_QUALITY_LEVELS } from './constants'; /** diff --git a/react/features/video-quality/index.js b/react/features/video-quality/index.js index 6d28f521e..a946606b1 100644 --- a/react/features/video-quality/index.js +++ b/react/features/video-quality/index.js @@ -1,4 +1,5 @@ export * from './components'; export * from './actions'; +export * from './actionTypes'; import './reducer'; diff --git a/react/features/video-quality/middleware.js b/react/features/video-quality/middleware.js index 50f67a8c1..053efb164 100644 --- a/react/features/video-quality/middleware.js +++ b/react/features/video-quality/middleware.js @@ -2,14 +2,14 @@ import { CONFERENCE_JOINED, - VIDEO_QUALITY_LEVELS, - setMaxReceiverVideoQuality, - setPreferredVideoQuality + DATA_CHANNEL_OPENED } from '../base/conference'; import { getParticipantCount } from '../base/participants'; import { MiddlewareRegistry, StateListenerRegistry } from '../base/redux'; import { shouldDisplayTileView } from '../video-layout'; +import { setPreferredVideoQuality, setMaxReceiverVideoQuality } from './actions'; +import { VIDEO_QUALITY_LEVELS } from './constants'; import { getReceiverVideoQualityLevel } from './functions'; import logger from './logger'; import { getMinHeightForQualityLvlMap } from './selector'; @@ -21,6 +21,10 @@ import { getMinHeightForQualityLvlMap } from './selector'; * @returns {Function} */ MiddlewareRegistry.register(({ dispatch, getState }) => next => action => { + if (action.type === DATA_CHANNEL_OPENED) { + return _syncReceiveVideoQuality(getState, next, action); + } + const result = next(action); switch (action.type) { @@ -59,7 +63,7 @@ StateListenerRegistry.register( }, /* listener */ ({ displayTileView, participantCount, reducedUI, thumbnailHeight }, { dispatch, getState }) => { const state = getState(); - const { maxReceiverVideoQuality } = state['features/base/conference']; + const { maxReceiverVideoQuality } = state['features/video-quality']; const { maxFullResolutionParticipants = 2 } = state['features/base/config']; let newMaxRecvVideoQuality = VIDEO_QUALITY_LEVELS.HIGH; @@ -92,3 +96,108 @@ StateListenerRegistry.register( }, { deepEquals: true }); + +/** + * Helper function for updating the preferred receiver video constraint, based + * on the user preference and the internal maximum. + * + * @param {JitsiConference} conference - The JitsiConference instance for the + * current call. + * @param {number} preferred - The user preferred max frame height. + * @param {number} max - The maximum frame height the application should + * receive. + * @returns {void} + */ +function _setReceiverVideoConstraint(conference, preferred, max) { + if (conference) { + const value = Math.min(preferred, max); + + conference.setReceiverVideoConstraint(value); + logger.info(`setReceiverVideoConstraint: ${value}`); + } +} + +/** + * Helper function for updating the preferred sender video constraint, based + * on the user preference. + * + * @param {JitsiConference} conference - The JitsiConference instance for the + * current call. + * @param {number} preferred - The user preferred max frame height. + * @returns {void} + */ +function _setSenderVideoConstraint(conference, preferred) { + if (conference) { + conference.setSenderVideoConstraint(preferred) + .catch(err => { + logger.error(`Changing sender resolution to ${preferred} failed - ${err} `); + }); + } +} + +/** + * Sets the maximum receive video quality. + * + * @param {Function} getState - The redux function which returns the current redux state. + * @param {Dispatch} next - The redux {@code dispatch} function to dispatch the + * specified {@code action} to the specified {@code store}. + * @param {Action} action - The redux action {@code DATA_CHANNEL_STATUS_CHANGED} + * which is being dispatched in the specified {@code store}. + * @private + * @returns {Object} The value returned by {@code next(action)}. + */ +function _syncReceiveVideoQuality(getState, next, action) { + const state = getState(); + const { + conference + } = state['features/base/conference']; + const { + maxReceiverVideoQuality, + preferredVideoQuality + } = state['features/video-quality']; + + _setReceiverVideoConstraint( + conference, + preferredVideoQuality, + maxReceiverVideoQuality); + + return next(action); +} + + +/** + * Registers a change handler for state['features/base/conference'] to update + * the preferred video quality levels based on user preferred and internal + * settings. + */ +StateListenerRegistry.register( + /* selector */ state => { + const { conference } = state['features/base/conference']; + const { + maxReceiverVideoQuality, + preferredVideoQuality + } = state['features/video-quality']; + + return { + conference, + maxReceiverVideoQuality, + preferredVideoQuality + }; + }, + /* listener */ (currentState, store, previousState = {}) => { + const { + conference, + maxReceiverVideoQuality, + preferredVideoQuality + } = currentState; + const changedConference = conference !== previousState.conference; + const changedPreferredVideoQuality = preferredVideoQuality !== previousState.preferredVideoQuality; + const changedMaxVideoQuality = maxReceiverVideoQuality !== previousState.maxReceiverVideoQuality; + + if (changedConference || changedPreferredVideoQuality || changedMaxVideoQuality) { + _setReceiverVideoConstraint(conference, preferredVideoQuality, maxReceiverVideoQuality); + } + if (changedConference || changedPreferredVideoQuality) { + _setSenderVideoConstraint(conference, preferredVideoQuality); + } + }); diff --git a/react/features/video-quality/reducer.js b/react/features/video-quality/reducer.js index d1c17b4a0..c26fa66a5 100644 --- a/react/features/video-quality/reducer.js +++ b/react/features/video-quality/reducer.js @@ -1,21 +1,36 @@ -import { VIDEO_QUALITY_LEVELS } from '../base/conference'; import { SET_CONFIG } from '../base/config'; import { ReducerRegistry, set } from '../base/redux'; +import { SET_MAX_RECEIVER_VIDEO_QUALITY, SET_PREFERRED_VIDEO_QUALITY } from './actionTypes'; +import { VIDEO_QUALITY_LEVELS } from './constants'; import { validateMinHeightForQualityLvl } from './functions'; import logger from './logger'; +const STORE_NAME = 'features/video-quality'; + const DEFAULT_STATE = { - minHeightForQualityLvl: new Map() + maxReceiverVideoQuality: VIDEO_QUALITY_LEVELS.HIGH, + minHeightForQualityLvl: new Map(), + preferredVideoQuality: VIDEO_QUALITY_LEVELS.HIGH }; DEFAULT_STATE.minHeightForQualityLvl.set(360, VIDEO_QUALITY_LEVELS.STANDARD); DEFAULT_STATE.minHeightForQualityLvl.set(720, VIDEO_QUALITY_LEVELS.HIGH); -ReducerRegistry.register('features/base/videoquality', (state = DEFAULT_STATE, action) => { +ReducerRegistry.register(STORE_NAME, (state = DEFAULT_STATE, action) => { switch (action.type) { case SET_CONFIG: return _setConfig(state, action); + case SET_MAX_RECEIVER_VIDEO_QUALITY: + return set( + state, + 'maxReceiverVideoQuality', + action.maxReceiverVideoQuality); + case SET_PREFERRED_VIDEO_QUALITY: + return set( + state, + 'preferredVideoQuality', + action.preferredVideoQuality); } return state; diff --git a/react/features/video-quality/selector.js b/react/features/video-quality/selector.js index 45565cf16..d873092d5 100644 --- a/react/features/video-quality/selector.js +++ b/react/features/video-quality/selector.js @@ -7,5 +7,5 @@ * @returns {Map} */ export function getMinHeightForQualityLvlMap(state: Object): Map { - return state['features/base/videoquality'].minHeightForQualityLvl; + return state['features/video-quality'].minHeightForQualityLvl; }