feat(filmstrip): Don't reorder in small meetings.

This commit is contained in:
Hristo Terezov 2022-03-15 12:34:46 -05:00
parent d4c314deb3
commit 16bcb1b217
6 changed files with 118 additions and 20 deletions

View File

@ -4,6 +4,7 @@ import type { Dispatch } from 'redux';
import { import {
getLocalParticipant, getLocalParticipant,
getParticipantById, getParticipantById,
getRemoteParticipantCount,
pinParticipant pinParticipant
} from '../base/participants'; } from '../base/participants';
import { shouldHideSelfView } from '../base/settings/functions.any'; import { shouldHideSelfView } from '../base/settings/functions.any';
@ -117,10 +118,14 @@ export function setVerticalViewDimensions() {
const disableSelfView = shouldHideSelfView(state); const disableSelfView = shouldHideSelfView(state);
const resizableFilmstrip = isFilmstripResizable(state); const resizableFilmstrip = isFilmstripResizable(state);
const _verticalViewGrid = showGridInVerticalView(state); const _verticalViewGrid = showGridInVerticalView(state);
const numberOfRemoteParticipants = getRemoteParticipantCount(state);
let gridView = {}; let gridView = {};
let thumbnails = {}; let thumbnails = {};
let filmstripDimensions = {}; let filmstripDimensions = {};
let hasScroll = false;
let remoteVideosContainerWidth;
let remoteVideosContainerHeight;
// grid view in the vertical filmstrip // grid view in the vertical filmstrip
if (_verticalViewGrid) { if (_verticalViewGrid) {
@ -143,7 +148,8 @@ export function setVerticalViewDimensions() {
numberOfVisibleTiles numberOfVisibleTiles
}); });
const thumbnailsTotalHeight = rows * (TILE_VERTICAL_MARGIN + height); const thumbnailsTotalHeight = rows * (TILE_VERTICAL_MARGIN + height);
const hasScroll = clientHeight < thumbnailsTotalHeight;
hasScroll = clientHeight < thumbnailsTotalHeight;
const widthOfFilmstrip = (columns * (TILE_HORIZONTAL_MARGIN + width)) + (hasScroll ? SCROLL_SIZE : 0); const widthOfFilmstrip = (columns * (TILE_HORIZONTAL_MARGIN + width)) + (hasScroll ? SCROLL_SIZE : 0);
const filmstripHeight = Math.min(clientHeight - TILE_VIEW_GRID_VERTICAL_MARGIN, thumbnailsTotalHeight); const filmstripHeight = Math.min(clientHeight - TILE_VIEW_GRID_VERTICAL_MARGIN, thumbnailsTotalHeight);
@ -165,6 +171,14 @@ export function setVerticalViewDimensions() {
}; };
} else { } else {
thumbnails = calculateThumbnailSizeForVerticalView(clientWidth, filmstripWidth.current, resizableFilmstrip); thumbnails = calculateThumbnailSizeForVerticalView(clientWidth, filmstripWidth.current, resizableFilmstrip);
remoteVideosContainerWidth
= thumbnails?.local?.width + TILE_VERTICAL_CONTAINER_HORIZONTAL_MARGIN + SCROLL_SIZE;
remoteVideosContainerHeight
= clientHeight - (disableSelfView ? 0 : thumbnails?.local?.height) - VERTICAL_FILMSTRIP_VERTICAL_MARGIN;
hasScroll
= remoteVideosContainerHeight
< (thumbnails?.remote.height + TILE_VERTICAL_MARGIN) * numberOfRemoteParticipants;
} }
dispatch({ dispatch({
@ -172,12 +186,11 @@ export function setVerticalViewDimensions() {
dimensions: { dimensions: {
...thumbnails, ...thumbnails,
remoteVideosContainer: _verticalViewGrid ? filmstripDimensions : { remoteVideosContainer: _verticalViewGrid ? filmstripDimensions : {
width: thumbnails?.local?.width width: remoteVideosContainerWidth,
+ TILE_VERTICAL_CONTAINER_HORIZONTAL_MARGIN + SCROLL_SIZE, height: remoteVideosContainerHeight
height: clientHeight - (disableSelfView ? 0 : thumbnails?.local?.height)
- VERTICAL_FILMSTRIP_VERTICAL_MARGIN
}, },
gridView gridView,
hasScroll
} }
}); });
}; };
@ -194,16 +207,24 @@ export function setHorizontalViewDimensions() {
const { clientHeight = 0, clientWidth = 0 } = state['features/base/responsive-ui']; const { clientHeight = 0, clientWidth = 0 } = state['features/base/responsive-ui'];
const disableSelfView = shouldHideSelfView(state); const disableSelfView = shouldHideSelfView(state);
const thumbnails = calculateThumbnailSizeForHorizontalView(clientHeight); const thumbnails = calculateThumbnailSizeForHorizontalView(clientHeight);
const remoteVideosContainerWidth
= clientWidth - (disableSelfView ? 0 : thumbnails?.local?.width) - HORIZONTAL_FILMSTRIP_MARGIN;
const remoteVideosContainerHeight
= thumbnails?.local?.height + TILE_VERTICAL_MARGIN + STAGE_VIEW_THUMBNAIL_VERTICAL_BORDER + SCROLL_SIZE;
const numberOfRemoteParticipants = getRemoteParticipantCount(state);
const hasScroll
= remoteVideosContainerHeight
< (thumbnails?.remote.width + TILE_HORIZONTAL_MARGIN) * numberOfRemoteParticipants;
dispatch({ dispatch({
type: SET_HORIZONTAL_VIEW_DIMENSIONS, type: SET_HORIZONTAL_VIEW_DIMENSIONS,
dimensions: { dimensions: {
...thumbnails, ...thumbnails,
remoteVideosContainer: { remoteVideosContainer: {
width: clientWidth - (disableSelfView ? 0 : thumbnails?.local?.width) - HORIZONTAL_FILMSTRIP_MARGIN, width: remoteVideosContainerWidth,
height: thumbnails?.local?.height height: remoteVideosContainerHeight
+ TILE_VERTICAL_MARGIN + STAGE_VIEW_THUMBNAIL_VERTICAL_BORDER + SCROLL_SIZE },
} hasScroll
} }
}); });
}; };

View File

@ -88,6 +88,11 @@ type Props = {
*/ */
_filmstripHeight: number, _filmstripHeight: number,
/**
* Whether or not we have scroll on the filmstrip.
*/
_hasScroll: boolean,
/** /**
* Whether this is a recorder or not. * Whether this is a recorder or not.
*/ */
@ -567,6 +572,7 @@ class Filmstrip extends PureComponent <Props, State> {
_currentLayout, _currentLayout,
_filmstripHeight, _filmstripHeight,
_filmstripWidth, _filmstripWidth,
_hasScroll,
_remoteParticipantsLength, _remoteParticipantsLength,
_resizableFilmstrip, _resizableFilmstrip,
_rows, _rows,
@ -620,7 +626,7 @@ class Filmstrip extends PureComponent <Props, State> {
if (_currentLayout === LAYOUTS.HORIZONTAL_FILMSTRIP_VIEW) { if (_currentLayout === LAYOUTS.HORIZONTAL_FILMSTRIP_VIEW) {
const itemSize = _thumbnailWidth + TILE_HORIZONTAL_MARGIN; const itemSize = _thumbnailWidth + TILE_HORIZONTAL_MARGIN;
const isNotOverflowing = (_remoteParticipantsLength * itemSize) <= _filmstripWidth; const isNotOverflowing = !_hasScroll;
props.itemSize = itemSize; props.itemSize = itemSize;
@ -632,7 +638,7 @@ class Filmstrip extends PureComponent <Props, State> {
} else if (_currentLayout === LAYOUTS.VERTICAL_FILMSTRIP_VIEW) { } else if (_currentLayout === LAYOUTS.VERTICAL_FILMSTRIP_VIEW) {
const itemSize = _thumbnailHeight + TILE_VERTICAL_MARGIN; const itemSize = _thumbnailHeight + TILE_VERTICAL_MARGIN;
const isNotOverflowing = (_remoteParticipantsLength * itemSize) <= _filmstripHeight; const isNotOverflowing = !_hasScroll;
if (isNotOverflowing) { if (isNotOverflowing) {
props.className += ' is-not-overflowing'; props.className += ' is-not-overflowing';
@ -768,7 +774,7 @@ function _mapStateToProps(state) {
gridDimensions: dimensions = {}, gridDimensions: dimensions = {},
filmstripHeight, filmstripHeight,
filmstripWidth, filmstripWidth,
hasScroll = false, hasScroll: tileViewHasScroll,
thumbnailSize: tileViewThumbnailSize thumbnailSize: tileViewThumbnailSize
} = state['features/filmstrip'].tileViewDimensions; } = state['features/filmstrip'].tileViewDimensions;
const _currentLayout = getCurrentLayout(state); const _currentLayout = getCurrentLayout(state);
@ -776,6 +782,7 @@ function _mapStateToProps(state) {
const _resizableFilmstrip = isFilmstripResizable(state); const _resizableFilmstrip = isFilmstripResizable(state);
const _verticalViewGrid = showGridInVerticalView(state); const _verticalViewGrid = showGridInVerticalView(state);
let gridDimensions = dimensions; let gridDimensions = dimensions;
let _hasScroll = false;
const { clientHeight, clientWidth } = state['features/base/responsive-ui']; const { clientHeight, clientWidth } = state['features/base/responsive-ui'];
const availableSpace = clientHeight - filmstripHeight; const availableSpace = clientHeight - filmstripHeight;
@ -806,7 +813,8 @@ function _mapStateToProps(state) {
switch (_currentLayout) { switch (_currentLayout) {
case LAYOUTS.TILE_VIEW: case LAYOUTS.TILE_VIEW:
if (hasScroll) { _hasScroll = Boolean(tileViewHasScroll);
if (_hasScroll) {
videosClassName += ' has-scroll'; videosClassName += ' has-scroll';
} }
_thumbnailSize = tileViewThumbnailSize; _thumbnailSize = tileViewThumbnailSize;
@ -814,8 +822,14 @@ function _mapStateToProps(state) {
remoteFilmstripWidth = filmstripWidth; remoteFilmstripWidth = filmstripWidth;
break; break;
case LAYOUTS.VERTICAL_FILMSTRIP_VIEW: { case LAYOUTS.VERTICAL_FILMSTRIP_VIEW: {
const { remote, remoteVideosContainer, gridView } = state['features/filmstrip'].verticalViewDimensions; const {
remote,
remoteVideosContainer,
gridView,
hasScroll
} = state['features/filmstrip'].verticalViewDimensions;
_hasScroll = Boolean(hasScroll);
remoteFilmstripHeight = remoteVideosContainer?.height - (!_verticalViewGrid && shouldReduceHeight remoteFilmstripHeight = remoteVideosContainer?.height - (!_verticalViewGrid && shouldReduceHeight
? TOOLBAR_HEIGHT : 0); ? TOOLBAR_HEIGHT : 0);
remoteFilmstripWidth = remoteVideosContainer?.width; remoteFilmstripWidth = remoteVideosContainer?.width;
@ -833,8 +847,9 @@ function _mapStateToProps(state) {
break; break;
} }
case LAYOUTS.HORIZONTAL_FILMSTRIP_VIEW: { case LAYOUTS.HORIZONTAL_FILMSTRIP_VIEW: {
const { remote, remoteVideosContainer } = state['features/filmstrip'].horizontalViewDimensions; const { remote, remoteVideosContainer, hasScroll } = state['features/filmstrip'].horizontalViewDimensions;
_hasScroll = Boolean(hasScroll);
_thumbnailSize = remote; _thumbnailSize = remote;
remoteFilmstripHeight = remoteVideosContainer?.height; remoteFilmstripHeight = remoteVideosContainer?.height;
remoteFilmstripWidth = remoteVideosContainer?.width; remoteFilmstripWidth = remoteVideosContainer?.width;
@ -849,6 +864,7 @@ function _mapStateToProps(state) {
_disableSelfView: disableSelfView, _disableSelfView: disableSelfView,
_filmstripHeight: remoteFilmstripHeight, _filmstripHeight: remoteFilmstripHeight,
_filmstripWidth: remoteFilmstripWidth, _filmstripWidth: remoteFilmstripWidth,
_hasScroll,
_iAmRecorder: Boolean(iAmRecorder), _iAmRecorder: Boolean(iAmRecorder),
_isFilmstripButtonEnabled: isButtonEnabled('filmstrip', state), _isFilmstripButtonEnabled: isButtonEnabled('filmstrip', state),
_isToolboxVisible: isToolboxVisible(state), _isToolboxVisible: isToolboxVisible(state),

View File

@ -1,6 +1,7 @@
// @flow // @flow
import { setRemoteParticipants } from './actions'; import { setRemoteParticipants } from './actions';
import { isReorderingEnabled } from './functions';
/** /**
* Computes the reorderd list of the remote participants. * Computes the reorderd list of the remote participants.
@ -12,11 +13,9 @@ import { setRemoteParticipants } from './actions';
*/ */
export function updateRemoteParticipants(store: Object, participantId: ?number) { export function updateRemoteParticipants(store: Object, participantId: ?number) {
const state = store.getState(); const state = store.getState();
const { testing = {} } = state['features/base/config'];
const enableThumbnailReordering = testing.enableThumbnailReordering ?? true;
let reorderedParticipants = []; let reorderedParticipants = [];
if (!enableThumbnailReordering) { if (!isReorderingEnabled(state)) {
if (participantId) { if (participantId) {
const { remoteParticipants } = state['features/filmstrip']; const { remoteParticipants } = state['features/filmstrip'];

View File

@ -88,3 +88,17 @@ export function getColumnCount(stateful: Object | Function) {
return Math.min(3, participantCount); return Math.min(3, participantCount);
} }
/**
* Returns true if thumbnail reordering is enabled and false otherwise.
*
* @param {Object} state - The redux state.
* @returns {boolean} - True if thumbnail reordering is enabled and false otherwise.
*/
export function isReorderingEnabled(state) {
const { testing = {} } = state['features/base/config'];
const enableThumbnailReordering = testing.enableThumbnailReordering ?? true;
return enableThumbnailReordering;
}

View File

@ -601,3 +601,44 @@ export function getVerticalViewMaxWidth(state) {
return maxWidth; return maxWidth;
} }
/**
* Returns true if thumbnail reordering is enabled and false otherwise.
* Note: The function will return false if all participants are displayed on the screen.
*
* @param {Object} state - The redux state.
* @returns {boolean} - True if thumbnail reordering is enabled and false otherwise.
*/
export function isReorderingEnabled(state) {
const { testing = {} } = state['features/base/config'];
const enableThumbnailReordering = testing.enableThumbnailReordering ?? true;
return enableThumbnailReordering && isFilmstripScollVisible(state);
}
/**
* Returns true if the scroll is displayed and false otherwise.
*
* @param {Object} state - The redux state.
* @returns {boolean} - True if the scroll is displayed and false otherwise.
*/
export function isFilmstripScollVisible(state) {
const _currentLayout = getCurrentLayout(state);
let hasScroll = false;
switch (_currentLayout) {
case LAYOUTS.TILE_VIEW:
({ hasScroll = false } = state['features/filmstrip'].tileViewDimensions);
break;
case LAYOUTS.VERTICAL_FILMSTRIP_VIEW: {
({ hasScroll = false } = state['features/filmstrip'].verticalViewDimensions);
break;
}
case LAYOUTS.HORIZONTAL_FILMSTRIP_VIEW: {
({ hasScroll = false } = state['features/filmstrip'].horizontalViewDimensions);
break;
}
}
return hasScroll;
}

View File

@ -19,7 +19,7 @@ import {
ASPECT_RATIO_BREAKPOINT, ASPECT_RATIO_BREAKPOINT,
DISPLAY_DRAWER_THRESHOLD DISPLAY_DRAWER_THRESHOLD
} from './constants'; } from './constants';
import { isFilmstripResizable } from './functions.web'; import { isFilmstripResizable, isFilmstripScollVisible, updateRemoteParticipants } from './functions';
import './subscriber.any'; import './subscriber.any';
@ -140,3 +140,10 @@ StateListenerRegistry.register(
/* listener */(_, store) => { /* listener */(_, store) => {
store.dispatch(setVerticalViewDimensions()); store.dispatch(setVerticalViewDimensions());
}); });
/**
* Listens for changes in the filmstrip scroll visibility.
*/
StateListenerRegistry.register(
/* selector */ state => isFilmstripScollVisible(state),
/* listener */ (_, store) => updateRemoteParticipants(store));