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:
parent
5fd9dc74e4
commit
911aaed052
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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));
|
||||
});
|
||||
|
||||
/**
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue