diff --git a/react/features/conference/middleware.js b/react/features/conference/middleware.js index cf8fcf42f..b7d131105 100644 --- a/react/features/conference/middleware.js +++ b/react/features/conference/middleware.js @@ -3,10 +3,8 @@ import { appNavigate } from '../app/actions'; import { CONFERENCE_JOINED, KICKED_OUT, - VIDEO_QUALITY_LEVELS, conferenceLeft, - getCurrentConference, - setPreferredVideoQuality + getCurrentConference } from '../base/conference'; import { hideDialog, isDialogOpen } from '../base/dialog'; import { setActiveModalId } from '../base/modal'; @@ -32,12 +30,6 @@ MiddlewareRegistry.register(store => next => action => { dispatch(setToolboxEnabled(!reducedUI)); dispatch(setFilmstripEnabled(!reducedUI)); - dispatch( - setPreferredVideoQuality( - reducedUI - ? VIDEO_QUALITY_LEVELS.LOW - : VIDEO_QUALITY_LEVELS.HIGH)); - break; } diff --git a/react/features/filmstrip/actionTypes.js b/react/features/filmstrip/actionTypes.js index 509ecc09e..4d0576e13 100644 --- a/react/features/filmstrip/actionTypes.js +++ b/react/features/filmstrip/actionTypes.js @@ -34,7 +34,19 @@ export const SET_FILMSTRIP_VISIBLE = 'SET_FILMSTRIP_VISIBLE'; * * { * type: SET_TILE_VIEW_DIMENSIONS, - * dimensions: Object + * dimensions: { + * gridDimensions: { + * columns: number, + * height: number, + * visibleRows: number, + * width: number + * }, + * thumbnailSize: { + * height: number, + * width: number + * }, + * filmstripWidth: number + * } * } */ export const SET_TILE_VIEW_DIMENSIONS = 'SET_TILE_VIEW_DIMENSIONS'; diff --git a/react/features/filmstrip/actions.native.js b/react/features/filmstrip/actions.native.js index 0276b2853..39721a1ed 100644 --- a/react/features/filmstrip/actions.native.js +++ b/react/features/filmstrip/actions.native.js @@ -3,7 +3,8 @@ import { SET_FILMSTRIP_ENABLED, SET_FILMSTRIP_HOVERED, - SET_FILMSTRIP_VISIBLE + SET_FILMSTRIP_VISIBLE, + SET_TILE_VIEW_DIMENSIONS } from './actionTypes'; /** @@ -53,3 +54,26 @@ export function setFilmstripVisible(visible: boolean) { visible }; } + +/** + * Sets the dimensions of the tile view grid. The action is only partially implemented on native as not all + * of the values are currently used. Check the description of {@link SET_TILE_VIEW_DIMENSIONS} for the full set + * of properties. + * + * @param {Object} dimensions - The tile view dimensions. + * @param {Object} thumbnailSize - The size of an individual video thumbnail. + * @param {number} thumbnailSize.height - The height of an individual video thumbnail. + * @param {number} thumbnailSize.width - The width of an individual video thumbnail. + * @returns {{ + * type: SET_TILE_VIEW_DIMENSIONS, + * dimensions: Object + * }} + */ +export function setTileViewDimensions({ thumbnailSize }: Object) { + return { + type: SET_TILE_VIEW_DIMENSIONS, + dimensions: { + thumbnailSize + } + }; +} diff --git a/react/features/filmstrip/components/native/TileView.js b/react/features/filmstrip/components/native/TileView.js index 91c23e0b1..f86279fca 100644 --- a/react/features/filmstrip/components/native/TileView.js +++ b/react/features/filmstrip/components/native/TileView.js @@ -8,12 +8,9 @@ import { } from 'react-native'; import type { Dispatch } from 'redux'; -import { - getNearestReceiverVideoQualityLevel, - setMaxReceiverVideoQuality -} from '../../../base/conference'; import { connect } from '../../../base/redux'; import { ASPECT_RATIO_NARROW } from '../../../base/responsive-ui/constants'; +import { setTileViewDimensions } from '../../actions'; import Thumbnail from './Thumbnail'; import styles from './styles'; @@ -266,10 +263,14 @@ class TileView extends Component { * @returns {void} */ _updateReceiverQuality() { - const { height } = this._getTileDimensions(); - const qualityLevel = getNearestReceiverVideoQualityLevel(height); + const { height, width } = this._getTileDimensions(); - this.props.dispatch(setMaxReceiverVideoQuality(qualityLevel)); + this.props.dispatch(setTileViewDimensions({ + thumbnailSize: { + height, + width + } + })); } } diff --git a/react/features/filmstrip/middleware.web.js b/react/features/filmstrip/middleware.web.js index 6ec99b69c..8abd7a92c 100644 --- a/react/features/filmstrip/middleware.web.js +++ b/react/features/filmstrip/middleware.web.js @@ -1,7 +1,6 @@ // @flow import Filmstrip from '../../../modules/UI/videolayout/Filmstrip'; -import { getNearestReceiverVideoQualityLevel, setMaxReceiverVideoQuality } from '../base/conference'; import { MiddlewareRegistry } from '../base/redux'; import { CLIENT_RESIZED } from '../base/responsive-ui'; import { @@ -48,9 +47,6 @@ MiddlewareRegistry.register(store => next => action => { if (shouldDisplayTileView(state)) { const { width, height } = state['features/filmstrip'].tileViewDimensions.thumbnailSize; - const qualityLevel = getNearestReceiverVideoQualityLevel(height); - - store.dispatch(setMaxReceiverVideoQuality(qualityLevel)); // Once the thumbnails are reactified this should be moved there too. Filmstrip.resizeThumbnailsForTileView(width, height, true); diff --git a/react/features/video-layout/subscriber.js b/react/features/video-layout/subscriber.js index fb76d35ea..89a9f67e8 100644 --- a/react/features/video-layout/subscriber.js +++ b/react/features/video-layout/subscriber.js @@ -2,10 +2,6 @@ import debounce from 'lodash/debounce'; -import { - VIDEO_QUALITY_LEVELS, - setMaxReceiverVideoQuality -} from '../base/conference'; import { getPinnedParticipant, pinParticipant @@ -32,8 +28,6 @@ StateListenerRegistry.register( dispatch(selectParticipant()); if (!displayTileView) { - dispatch(setMaxReceiverVideoQuality(VIDEO_QUALITY_LEVELS.HIGH)); - if (_getAutoPinSetting()) { _updateAutoPinnedParticipant(store); } diff --git a/react/features/video-quality/middleware.js b/react/features/video-quality/middleware.js index 227178dc0..6ba7806f9 100644 --- a/react/features/video-quality/middleware.js +++ b/react/features/video-quality/middleware.js @@ -1,8 +1,14 @@ // @flow -import { CONFERENCE_JOINED } from '../base/conference/actionTypes'; -import { setPreferredVideoQuality } from '../base/conference/actions'; -import { MiddlewareRegistry } from '../base/redux'; +import { + CONFERENCE_JOINED, + VIDEO_QUALITY_LEVELS, + getNearestReceiverVideoQualityLevel, + setMaxReceiverVideoQuality, + setPreferredVideoQuality +} from '../base/conference'; +import { MiddlewareRegistry, StateListenerRegistry } from '../base/redux'; +import { shouldDisplayTileView } from '../video-layout'; import logger from './logger'; @@ -31,3 +37,35 @@ MiddlewareRegistry.register(({ dispatch, getState }) => next => action => { return result; }); + +/** + * Implements a state listener in order to calculate max receiver video quality. + */ +StateListenerRegistry.register( + /* selector */ state => { + const { reducedUI } = state['features/base/responsive-ui']; + const _shouldDisplayTileView = shouldDisplayTileView(state); + const thumbnailSize = state['features/filmstrip']?.tileViewDimensions?.thumbnailSize; + + return { + displayTileView: _shouldDisplayTileView, + reducedUI, + thumbnailHeight: thumbnailSize?.height + }; + }, + /* listener */ ({ displayTileView, reducedUI, thumbnailHeight }, { dispatch, getState }) => { + const { maxReceiverVideoQuality } = getState()['features/base/conference']; + let newMaxRecvVideoQuality = VIDEO_QUALITY_LEVELS.HIGH; + + if (reducedUI) { + newMaxRecvVideoQuality = VIDEO_QUALITY_LEVELS.LOW; + } else if (displayTileView && !Number.isNaN(thumbnailHeight)) { + newMaxRecvVideoQuality = getNearestReceiverVideoQualityLevel(thumbnailHeight); + } + + if (maxReceiverVideoQuality !== newMaxRecvVideoQuality) { + dispatch(setMaxReceiverVideoQuality(newMaxRecvVideoQuality)); + } + }, { + deepEquals: true + });