fix: Refactor client width computation.

* Unify chat open/close size changes and move them to redux.
* Fix responsive columns not accounting for chat.
This commit is contained in:
Mihai-Andrei Uscat 2021-03-23 14:06:43 +02:00 committed by GitHub
parent 5fd9dc74e4
commit 911aaed052
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 49 additions and 91 deletions

View File

@ -121,3 +121,15 @@
align-self: baseline;
}
}
.shift-right #filmstripRemoteVideosContainer {
/**
* Max-width corresponding to the ASPECT_RATIO_BREAKPOINT from features/filmstrip/constants,
* from which we subtract the chat size.
*/
@media only screen and (max-width: calc(500px + #{$sidebarWidth})) {
video {
object-fit: cover;
}
}
}

View File

@ -48,10 +48,10 @@
"i18next": "17.0.6",
"i18next-browser-languagedetector": "3.0.1",
"i18next-xhr-backend": "3.0.0",
"jQuery-Impromptu": "github:trentrichardson/jQuery-Impromptu#v6.0.0",
"jitsi-meet-logger": "github:jitsi/jitsi-meet-logger#v1.0.0",
"jquery": "3.5.1",
"jquery-i18next": "1.2.1",
"jQuery-Impromptu": "github:trentrichardson/jQuery-Impromptu#v6.0.0",
"js-md5": "0.6.1",
"jwt-decode": "2.2.0",
"lib-jitsi-meet": "github:jitsi/lib-jitsi-meet#4191198233ae64e3cb12349069c582724d09537c",

View File

@ -2,6 +2,8 @@
import type { Dispatch } from 'redux';
import { CHAT_SIZE } from '../../chat/constants';
import { CLIENT_RESIZED, SET_ASPECT_RATIO, SET_REDUCED_UI } from './actionTypes';
import { ASPECT_RATIO_NARROW, ASPECT_RATIO_WIDE } from './constants';
@ -24,10 +26,20 @@ const REDUCED_UI_THRESHOLD = 300;
* @returns {Object}
*/
export function clientResized(clientWidth: number, clientHeight: number) {
return {
type: CLIENT_RESIZED,
clientHeight,
clientWidth
return (dispatch: Dispatch<any>, getState: Function) => {
const state = getState();
const { isOpen } = state['features/chat'];
let availableWidth = clientWidth;
if (isOpen && navigator.product !== 'ReactNative') {
availableWidth -= CHAT_SIZE;
}
return dispatch({
type: CLIENT_RESIZED,
clientHeight,
clientWidth: availableWidth
});
};
}

View File

@ -2,7 +2,6 @@
import { pinParticipant } from '../base/participants';
import { toState } from '../base/redux';
import { CHAT_SIZE } from '../chat/constants';
import { SET_HORIZONTAL_VIEW_DIMENSIONS, SET_TILE_VIEW_DIMENSIONS } from './actionTypes';
import { calculateThumbnailSizeForHorizontalView, calculateThumbnailSizeForTileView } from './functions';
@ -27,19 +26,12 @@ const TILE_VIEW_SIDE_MARGINS = 20;
export function setTileViewDimensions(dimensions: Object, windowSize: Object, stateful: Object | Function) {
const state = toState(stateful);
const { clientWidth, clientHeight } = windowSize;
const heightToUse = clientHeight;
let widthToUse = clientWidth;
const { isOpen } = state['features/chat'];
const { disableResponsiveTiles } = state['features/base/config'];
if (isOpen) {
widthToUse -= CHAT_SIZE;
}
const thumbnailSize = calculateThumbnailSizeForTileView({
...dimensions,
clientWidth: widthToUse,
clientHeight: heightToUse,
clientWidth,
clientHeight,
disableResponsiveTiles
});
const filmstripWidth = dimensions.columns * (TILE_VIEW_SIDE_MARGINS + thumbnailSize.width);

View File

@ -1,6 +1,7 @@
// @flow
import { StateListenerRegistry, equals } from '../base/redux';
import { clientResized } from '../base/responsive-ui';
import { setFilmstripVisible } from '../filmstrip/actions';
import { setOverflowDrawer } from '../toolbox/actions.web';
import { getCurrentLayout, getTileViewGridDimensions, shouldDisplayTileView, LAYOUTS } from '../video-layout';
@ -73,12 +74,12 @@ StateListenerRegistry.register(
});
/**
* Listens for changes in the chat state to calculate the dimensions of the tile view grid and the tiles.
* Listens for changes in the chat state to recompute available width.
*/
StateListenerRegistry.register(
/* selector */ state => state['features/chat'].isOpen,
/* listener */ (isChatOpen, store) => {
const state = store.getState();
const { innerWidth, innerHeight } = window;
if (isChatOpen) {
// $FlowFixMe
@ -88,21 +89,7 @@ StateListenerRegistry.register(
document.body.classList.remove('shift-right');
}
if (shouldDisplayTileView(state)) {
const gridDimensions = getTileViewGridDimensions(state);
const { clientHeight, clientWidth } = state['features/base/responsive-ui'];
store.dispatch(
setTileViewDimensions(
gridDimensions,
{
clientHeight,
clientWidth
},
store
)
);
}
store.dispatch(clientResized(innerWidth, innerHeight));
});
/**

View File

@ -35,7 +35,7 @@ import { connect } from '../../../base/redux';
import { OverflowMenuItem } from '../../../base/toolbox/components';
import { getLocalVideoTrack, toggleScreensharing } from '../../../base/tracks';
import { isVpaasMeeting } from '../../../billing-counter/functions';
import { CHAT_SIZE, ChatCounter, toggleChat } from '../../../chat';
import { ChatCounter, toggleChat } from '../../../chat';
import { InviteMore } from '../../../conference';
import { EmbedMeetingDialog } from '../../../embed-meeting';
import { SharedDocumentButton } from '../../../etherpad';
@ -100,6 +100,11 @@ type Props = {
*/
_chatOpen: boolean,
/**
* The width of the client.
*/
_clientWidth: number,
/**
* The {@code JitsiConference} for the current conference.
*/
@ -208,17 +213,6 @@ type Props = {
t: Function
};
/**
* The type of the React {@code Component} state of {@link Toolbox}.
*/
type State = {
/**
* The width of the browser's window.
*/
windowWidth: number
};
declare var APP: Object;
/**
@ -226,7 +220,7 @@ declare var APP: Object;
*
* @extends Component
*/
class Toolbox extends Component<Props, State> {
class Toolbox extends Component<Props> {
/**
* Initializes a new {@code Toolbox} instance.
*
@ -239,7 +233,6 @@ class Toolbox extends Component<Props, State> {
// Bind event handlers so they are only bound once per instance.
this._onMouseOut = this._onMouseOut.bind(this);
this._onMouseOver = this._onMouseOver.bind(this);
this._onResize = this._onResize.bind(this);
this._onSetOverflowVisible = this._onSetOverflowVisible.bind(this);
this._onTabIn = this._onTabIn.bind(this);
@ -261,10 +254,6 @@ class Toolbox extends Component<Props, State> {
this._onToolbarToggleScreenshare = this._onToolbarToggleScreenshare.bind(this);
this._onToolbarOpenLocalRecordingInfoDialog = this._onToolbarOpenLocalRecordingInfoDialog.bind(this);
this._onShortcutToggleTileView = this._onShortcutToggleTileView.bind(this);
this.state = {
windowWidth: window.innerWidth
};
}
/**
@ -316,8 +305,6 @@ class Toolbox extends Component<Props, State> {
shortcut.helpDescription);
}
});
window.addEventListener('resize', this._onResize);
}
/**
@ -337,10 +324,6 @@ class Toolbox extends Component<Props, State> {
this._onSetOverflowVisible(false);
this.props.dispatch(setToolbarHovered(false));
}
if (this.props._chatOpen !== prevProps._chatOpen) {
this._onResize();
}
}
/**
@ -352,8 +335,6 @@ class Toolbox extends Component<Props, State> {
componentWillUnmount() {
[ 'A', 'C', 'D', 'R', 'S' ].forEach(letter =>
APP.keyboardshortcut.unregisterShortcut(letter));
window.removeEventListener('resize', this._onResize);
}
/**
@ -558,28 +539,6 @@ class Toolbox extends Component<Props, State> {
this.props.dispatch(setToolbarHovered(true));
}
_onResize: () => void;
/**
* A window resize handler used to calculate the number of buttons we can
* fit in the toolbar.
*
* @private
* @returns {void}
*/
_onResize() {
let widthToUse = window.innerWidth;
// Take chat size into account when resizing toolbox.
if (this.props._chatOpen) {
widthToUse -= CHAT_SIZE;
}
if (this.state.windowWidth !== widthToUse) {
this.setState({ windowWidth: widthToUse });
}
}
_onSetOverflowVisible: (boolean) => void;
@ -1251,12 +1210,13 @@ class Toolbox extends Component<Props, State> {
*/
_renderToolboxContent() {
const {
_clientWidth,
_isMobile,
_overflowMenuVisible,
t
} = this.props;
const buttonSet = getToolbarAdditionalButtons(this.state.windowWidth, _isMobile);
const buttonSet = getToolbarAdditionalButtons(_clientWidth, _isMobile);
const toolbarAccLabel = 'toolbar.accessibilityLabel.moreActionsMenu';
const showOverflowMenuButton = buttonSet.has('overflow');
const containerClassName = `toolbox-content${_isMobile ? ' toolbox-content-mobile' : ''}`;
@ -1331,6 +1291,7 @@ function _mapStateToProps(state) {
const localParticipant = getLocalParticipant(state);
const localRecordingStates = state['features/local-recording'];
const localVideo = getLocalVideoTrack(state['features/base/tracks']);
const { clientWidth } = state['features/base/responsive-ui'];
let desktopSharingDisabledTooltipKey;
@ -1345,6 +1306,7 @@ function _mapStateToProps(state) {
return {
_chatOpen: state['features/chat'].isOpen,
_clientWidth: clientWidth,
_conference: conference,
_desktopSharingEnabled: desktopSharingEnabled,
_desktopSharingDisabledTooltipKey: desktopSharingDisabledTooltipKey,

View File

@ -2,7 +2,6 @@
import { getFeatureFlag, TILE_VIEW_ENABLED } from '../base/flags';
import { getPinnedParticipant, getParticipantCount } from '../base/participants';
import { CHAT_SIZE } from '../chat/constants';
import {
ASPECT_RATIO_BREAKPOINT,
DEFAULT_MAX_COLUMNS,
@ -46,26 +45,20 @@ export function getMaxColumnCount(state: Object) {
if (!disableResponsiveTiles) {
const { clientWidth } = state['features/base/responsive-ui'];
let availableWidth = clientWidth;
const participantCount = getParticipantCount(state);
const { isOpen } = state['features/chat'];
if (isOpen) {
availableWidth -= CHAT_SIZE;
}
// If there are just two participants in a conference, enforce single-column view for mobile size.
if (participantCount === 2 && availableWidth < ASPECT_RATIO_BREAKPOINT) {
if (participantCount === 2 && clientWidth < ASPECT_RATIO_BREAKPOINT) {
return Math.min(1, Math.max(configuredMax, 1));
}
// Enforce single column view at very small screen widths.
if (availableWidth < SINGLE_COLUMN_BREAKPOINT) {
if (clientWidth < SINGLE_COLUMN_BREAKPOINT) {
return Math.min(1, Math.max(configuredMax, 1));
}
// Enforce two column view below breakpoint.
if (availableWidth < TWO_COLUMN_BREAKPOINT) {
if (clientWidth < TWO_COLUMN_BREAKPOINT) {
return Math.min(2, Math.max(configuredMax, 1));
}
}