feat(video-quality): persist.
This commit is contained in:
parent
43f36c8cfd
commit
25839b18d2
|
@ -12,6 +12,7 @@ import {
|
||||||
} from '../../base/icons';
|
} from '../../base/icons';
|
||||||
import { connect } from '../../base/redux';
|
import { connect } from '../../base/redux';
|
||||||
import { VIDEO_QUALITY_LEVELS } from '../constants';
|
import { VIDEO_QUALITY_LEVELS } from '../constants';
|
||||||
|
import { findNearestQualityLevel } from '../functions';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A map of of selectable receive resolutions to corresponding icons.
|
* A map of of selectable receive resolutions to corresponding icons.
|
||||||
|
@ -69,9 +70,10 @@ class OverflowMenuVideoQualityItem extends Component<Props> {
|
||||||
*/
|
*/
|
||||||
render() {
|
render() {
|
||||||
const { _audioOnly, _videoQuality } = this.props;
|
const { _audioOnly, _videoQuality } = this.props;
|
||||||
const icon = _audioOnly || !_videoQuality
|
const videoQualityLevel = findNearestQualityLevel(_videoQuality);
|
||||||
|
const icon = _audioOnly || !videoQualityLevel
|
||||||
? IconVideoQualityAudioOnly
|
? IconVideoQualityAudioOnly
|
||||||
: VIDEO_QUALITY_TO_ICON[_videoQuality];
|
: VIDEO_QUALITY_TO_ICON[videoQualityLevel];
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<li
|
<li
|
||||||
|
|
|
@ -316,10 +316,13 @@ class VideoQualitySlider extends Component<Props> {
|
||||||
return _sliderOptions.indexOf(audioOnlyOption);
|
return _sliderOptions.indexOf(audioOnlyOption);
|
||||||
}
|
}
|
||||||
|
|
||||||
const matchingOption = _sliderOptions.find(
|
for (let i = 0; i < _sliderOptions.length; i++) {
|
||||||
({ videoQuality }) => videoQuality === _sendrecvVideoQuality);
|
if (_sliderOptions[i].videoQuality >= _sendrecvVideoQuality) {
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return _sliderOptions.indexOf(matchingOption);
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
_onSliderChange: () => void;
|
_onSliderChange: () => void;
|
||||||
|
|
|
@ -2,6 +2,26 @@
|
||||||
|
|
||||||
import { CFG_LVL_TO_APP_QUALITY_LVL, VIDEO_QUALITY_LEVELS } from './constants';
|
import { CFG_LVL_TO_APP_QUALITY_LVL, VIDEO_QUALITY_LEVELS } from './constants';
|
||||||
|
|
||||||
|
const { LOW, STANDARD, HIGH } = VIDEO_QUALITY_LEVELS;
|
||||||
|
const videoQualityLevels = [ LOW, STANDARD, HIGH ];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Finds the nearest video quality level to the passed video quality.
|
||||||
|
*
|
||||||
|
* @param {number} videoQuality - The video quality.
|
||||||
|
* @returns {number|undefined} - The found quality level.
|
||||||
|
*/
|
||||||
|
export function findNearestQualityLevel(videoQuality: number) {
|
||||||
|
for (let i = 0; i < videoQualityLevels.length; i++) {
|
||||||
|
const level = videoQualityLevels[i];
|
||||||
|
|
||||||
|
if (level >= videoQuality) {
|
||||||
|
return level;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Selects {@code VIDEO_QUALITY_LEVELS} for the given {@link availableHeight} and threshold to quality mapping.
|
* Selects {@code VIDEO_QUALITY_LEVELS} for the given {@link availableHeight} and threshold to quality mapping.
|
||||||
|
|
|
@ -4,6 +4,7 @@ import {
|
||||||
CONFERENCE_JOINED,
|
CONFERENCE_JOINED,
|
||||||
DATA_CHANNEL_OPENED
|
DATA_CHANNEL_OPENED
|
||||||
} from '../base/conference';
|
} from '../base/conference';
|
||||||
|
import { SET_CONFIG } from '../base/config';
|
||||||
import { getParticipantCount } from '../base/participants';
|
import { getParticipantCount } from '../base/participants';
|
||||||
import { MiddlewareRegistry, StateListenerRegistry } from '../base/redux';
|
import { MiddlewareRegistry, StateListenerRegistry } from '../base/redux';
|
||||||
import { shouldDisplayTileView } from '../video-layout';
|
import { shouldDisplayTileView } from '../video-layout';
|
||||||
|
@ -39,6 +40,18 @@ MiddlewareRegistry.register(({ dispatch, getState }) => next => action => {
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case SET_CONFIG: {
|
||||||
|
const state = getState();
|
||||||
|
const { videoQuality = {} } = state['features/base/config'];
|
||||||
|
|
||||||
|
if (videoQuality.persist) {
|
||||||
|
dispatch(
|
||||||
|
setPreferredVideoQuality(
|
||||||
|
state['features/video-quality-persistent-storage'].persistedPrefferedVideoQuality));
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
|
|
|
@ -1,13 +1,11 @@
|
||||||
import { SET_CONFIG } from '../base/config';
|
import { SET_CONFIG } from '../base/config';
|
||||||
import { ReducerRegistry, set } from '../base/redux';
|
import { PersistenceRegistry, ReducerRegistry, set } from '../base/redux';
|
||||||
|
|
||||||
import { SET_MAX_RECEIVER_VIDEO_QUALITY, SET_PREFERRED_VIDEO_QUALITY } from './actionTypes';
|
import { SET_MAX_RECEIVER_VIDEO_QUALITY, SET_PREFERRED_VIDEO_QUALITY } from './actionTypes';
|
||||||
import { VIDEO_QUALITY_LEVELS } from './constants';
|
import { VIDEO_QUALITY_LEVELS } from './constants';
|
||||||
import { validateMinHeightForQualityLvl } from './functions';
|
import { validateMinHeightForQualityLvl } from './functions';
|
||||||
import logger from './logger';
|
import logger from './logger';
|
||||||
|
|
||||||
const STORE_NAME = 'features/video-quality';
|
|
||||||
|
|
||||||
const DEFAULT_STATE = {
|
const DEFAULT_STATE = {
|
||||||
maxReceiverVideoQuality: VIDEO_QUALITY_LEVELS.HIGH,
|
maxReceiverVideoQuality: VIDEO_QUALITY_LEVELS.HIGH,
|
||||||
minHeightForQualityLvl: new Map(),
|
minHeightForQualityLvl: new Map(),
|
||||||
|
@ -17,7 +15,27 @@ const DEFAULT_STATE = {
|
||||||
DEFAULT_STATE.minHeightForQualityLvl.set(360, VIDEO_QUALITY_LEVELS.STANDARD);
|
DEFAULT_STATE.minHeightForQualityLvl.set(360, VIDEO_QUALITY_LEVELS.STANDARD);
|
||||||
DEFAULT_STATE.minHeightForQualityLvl.set(720, VIDEO_QUALITY_LEVELS.HIGH);
|
DEFAULT_STATE.minHeightForQualityLvl.set(720, VIDEO_QUALITY_LEVELS.HIGH);
|
||||||
|
|
||||||
ReducerRegistry.register(STORE_NAME, (state = DEFAULT_STATE, action) => {
|
|
||||||
|
// When the persisted state is initialized the current state (for example the deafault state) is erased.
|
||||||
|
// In order to workaround this issue we need additional state for the persisted properties.
|
||||||
|
PersistenceRegistry.register('features/video-quality-persistent-storage');
|
||||||
|
|
||||||
|
ReducerRegistry.register('features/video-quality-persistent-storage', (state = {}, action) => {
|
||||||
|
switch (action.type) {
|
||||||
|
case SET_PREFERRED_VIDEO_QUALITY: {
|
||||||
|
const { preferredVideoQuality } = action;
|
||||||
|
|
||||||
|
return {
|
||||||
|
...state,
|
||||||
|
persistedPrefferedVideoQuality: preferredVideoQuality
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return state;
|
||||||
|
});
|
||||||
|
|
||||||
|
ReducerRegistry.register('features/video-quality', (state = DEFAULT_STATE, action) => {
|
||||||
switch (action.type) {
|
switch (action.type) {
|
||||||
case SET_CONFIG:
|
case SET_CONFIG:
|
||||||
return _setConfig(state, action);
|
return _setConfig(state, action);
|
||||||
|
@ -26,11 +44,14 @@ ReducerRegistry.register(STORE_NAME, (state = DEFAULT_STATE, action) => {
|
||||||
state,
|
state,
|
||||||
'maxReceiverVideoQuality',
|
'maxReceiverVideoQuality',
|
||||||
action.maxReceiverVideoQuality);
|
action.maxReceiverVideoQuality);
|
||||||
case SET_PREFERRED_VIDEO_QUALITY:
|
case SET_PREFERRED_VIDEO_QUALITY: {
|
||||||
return set(
|
const { preferredVideoQuality } = action;
|
||||||
state,
|
|
||||||
'preferredVideoQuality',
|
return {
|
||||||
action.preferredVideoQuality);
|
...state,
|
||||||
|
preferredVideoQuality
|
||||||
|
};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return state;
|
return state;
|
||||||
|
|
Loading…
Reference in New Issue