2021-09-09 16:14:09 +03:00
|
|
|
import { batch } from 'react-redux';
|
2018-01-31 17:35:40 +01:00
|
|
|
|
2022-09-21 11:32:50 +03:00
|
|
|
import { IStore } from '../../app/types';
|
2021-03-23 14:06:43 +02:00
|
|
|
import { CHAT_SIZE } from '../../chat/constants';
|
2025-05-05 16:47:38 -05:00
|
|
|
import { getParticipantsPaneWidth } from '../../participants-pane/functions';
|
2021-03-23 14:06:43 +02:00
|
|
|
|
2022-05-06 05:18:57 -05:00
|
|
|
import {
|
|
|
|
|
CLIENT_RESIZED,
|
|
|
|
|
SAFE_AREA_INSETS_CHANGED,
|
|
|
|
|
SET_ASPECT_RATIO,
|
|
|
|
|
SET_CONTEXT_MENU_OPEN,
|
2023-01-25 17:02:26 +02:00
|
|
|
SET_NARROW_LAYOUT,
|
2022-05-06 05:18:57 -05:00
|
|
|
SET_REDUCED_UI
|
|
|
|
|
} from './actionTypes';
|
2020-01-24 16:28:47 +00:00
|
|
|
import { ASPECT_RATIO_NARROW, ASPECT_RATIO_WIDE } from './constants';
|
|
|
|
|
|
2018-02-02 14:39:27 +01:00
|
|
|
/**
|
|
|
|
|
* Size threshold for determining if we are in reduced UI mode or not.
|
2018-03-22 11:22:33 -05:00
|
|
|
*
|
|
|
|
|
* FIXME The logic to base {@code reducedUI} on a hardcoded width or height is
|
|
|
|
|
* very brittle because it's completely disconnected from the UI which wants to
|
|
|
|
|
* be rendered and, naturally, it broke on iPad where even the secondary Toolbar
|
|
|
|
|
* didn't fit in the height. We do need to measure the actual UI at runtime and
|
2019-11-08 17:42:39 +01:00
|
|
|
* determine whether and how to render it.
|
2018-02-02 14:39:27 +01:00
|
|
|
*/
|
2018-03-22 11:22:33 -05:00
|
|
|
const REDUCED_UI_THRESHOLD = 300;
|
2025-12-17 12:17:06 +02:00
|
|
|
const WEB_REDUCED_UI_THRESHOLD = 320;
|
2018-02-02 14:39:27 +01:00
|
|
|
|
2020-01-24 16:28:47 +00:00
|
|
|
/**
|
|
|
|
|
* Indicates a resize of the window.
|
|
|
|
|
*
|
|
|
|
|
* @param {number} clientWidth - The width of the window.
|
|
|
|
|
* @param {number} clientHeight - The height of the window.
|
|
|
|
|
* @returns {Object}
|
|
|
|
|
*/
|
|
|
|
|
export function clientResized(clientWidth: number, clientHeight: number) {
|
2022-09-21 11:32:50 +03:00
|
|
|
return (dispatch: IStore['dispatch'], getState: IStore['getState']) => {
|
2024-06-11 13:59:11 +03:00
|
|
|
if (!clientWidth && !clientHeight) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2021-03-23 14:06:43 +02:00
|
|
|
let availableWidth = clientWidth;
|
|
|
|
|
|
2021-04-21 16:48:05 +03:00
|
|
|
if (navigator.product !== 'ReactNative') {
|
2021-08-20 18:32:38 -05:00
|
|
|
const state = getState();
|
2025-05-05 16:47:38 -05:00
|
|
|
const { isOpen: isChatOpen, width } = state['features/chat'];
|
2021-08-20 18:32:38 -05:00
|
|
|
|
2021-04-21 16:48:05 +03:00
|
|
|
if (isChatOpen) {
|
2025-05-05 16:47:38 -05:00
|
|
|
availableWidth -= width?.current ?? CHAT_SIZE;
|
2021-04-21 16:48:05 +03:00
|
|
|
}
|
|
|
|
|
|
2025-05-05 16:47:38 -05:00
|
|
|
availableWidth -= getParticipantsPaneWidth(state);
|
2025-12-17 12:17:06 +02:00
|
|
|
|
|
|
|
|
dispatch(setReducedUI(availableWidth, clientHeight));
|
2021-03-23 14:06:43 +02:00
|
|
|
}
|
|
|
|
|
|
2021-09-09 16:14:09 +03:00
|
|
|
batch(() => {
|
|
|
|
|
dispatch({
|
|
|
|
|
type: CLIENT_RESIZED,
|
|
|
|
|
clientHeight,
|
2025-05-05 17:48:40 -05:00
|
|
|
clientWidth,
|
|
|
|
|
videoSpaceWidth: availableWidth
|
2021-09-09 16:14:09 +03:00
|
|
|
});
|
2025-05-05 17:48:40 -05:00
|
|
|
dispatch(setAspectRatio(availableWidth, clientHeight));
|
2021-03-23 14:06:43 +02:00
|
|
|
});
|
2020-01-24 16:28:47 +00:00
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
2017-10-13 11:13:46 -05:00
|
|
|
/**
|
2017-11-07 08:28:08 -06:00
|
|
|
* Sets the aspect ratio of the app's user interface based on specific width and
|
|
|
|
|
* height.
|
2017-10-13 11:13:46 -05:00
|
|
|
*
|
2017-11-07 08:28:08 -06:00
|
|
|
* @param {number} width - The width of the app's user interface.
|
|
|
|
|
* @param {number} height - The height of the app's user interface.
|
2017-10-13 11:13:46 -05:00
|
|
|
* @returns {{
|
2018-01-31 17:35:40 +01:00
|
|
|
* type: SET_ASPECT_RATIO,
|
|
|
|
|
* aspectRatio: Symbol
|
2017-10-13 11:13:46 -05:00
|
|
|
* }}
|
|
|
|
|
*/
|
2022-09-21 11:32:50 +03:00
|
|
|
export function setAspectRatio(width: number, height: number) {
|
|
|
|
|
return (dispatch: IStore['dispatch'], getState: IStore['getState']) => {
|
2018-01-31 17:35:40 +01:00
|
|
|
// Don't change the aspect ratio if width and height are the same, that
|
|
|
|
|
// is, if we transition to a 1:1 aspect ratio.
|
|
|
|
|
if (width !== height) {
|
|
|
|
|
const aspectRatio
|
|
|
|
|
= width < height ? ASPECT_RATIO_NARROW : ASPECT_RATIO_WIDE;
|
|
|
|
|
|
|
|
|
|
if (aspectRatio
|
2018-02-06 12:14:05 -06:00
|
|
|
!== getState()['features/base/responsive-ui'].aspectRatio) {
|
2018-01-31 17:35:40 +01:00
|
|
|
return dispatch({
|
|
|
|
|
type: SET_ASPECT_RATIO,
|
|
|
|
|
aspectRatio
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
}
|
2017-10-13 11:13:46 -05:00
|
|
|
};
|
|
|
|
|
}
|
2018-02-02 14:39:27 +01:00
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Sets the "reduced UI" property. In reduced UI mode some components will
|
|
|
|
|
* be hidden if there is no space to render them.
|
|
|
|
|
*
|
|
|
|
|
* @param {number} width - Current usable width.
|
|
|
|
|
* @param {number} height - Current usable height.
|
|
|
|
|
* @returns {{
|
|
|
|
|
* type: SET_REDUCED_UI,
|
|
|
|
|
* reducedUI: boolean
|
|
|
|
|
* }}
|
|
|
|
|
*/
|
2022-09-21 11:32:50 +03:00
|
|
|
export function setReducedUI(width: number, height: number) {
|
|
|
|
|
return (dispatch: IStore['dispatch'], getState: IStore['getState']) => {
|
2025-12-17 12:17:06 +02:00
|
|
|
const threshold = navigator.product === 'ReactNative'
|
|
|
|
|
? REDUCED_UI_THRESHOLD
|
|
|
|
|
: WEB_REDUCED_UI_THRESHOLD;
|
|
|
|
|
const reducedUI = Math.min(width, height) < threshold;
|
2018-02-02 14:39:27 +01:00
|
|
|
|
|
|
|
|
if (reducedUI !== getState()['features/base/responsive-ui'].reducedUI) {
|
|
|
|
|
return dispatch({
|
|
|
|
|
type: SET_REDUCED_UI,
|
|
|
|
|
reducedUI
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
}
|
2021-09-14 10:43:52 +03:00
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Sets whether the local or remote participant context menu is open.
|
|
|
|
|
*
|
|
|
|
|
* @param {boolean} isOpen - Whether local or remote context menu is open.
|
|
|
|
|
* @returns {Object}
|
|
|
|
|
*/
|
|
|
|
|
export function setParticipantContextMenuOpen(isOpen: boolean) {
|
|
|
|
|
return {
|
|
|
|
|
type: SET_CONTEXT_MENU_OPEN,
|
|
|
|
|
isOpen
|
|
|
|
|
};
|
|
|
|
|
}
|
2022-05-06 05:18:57 -05:00
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Sets the insets from the SafeAreaProvider.
|
|
|
|
|
*
|
|
|
|
|
* @param {Object} insets - The new insets to be set.
|
|
|
|
|
* @returns {{
|
|
|
|
|
* type: SAFE_AREA_INSETS_CHANGED,
|
|
|
|
|
* insets: Object
|
|
|
|
|
* }}
|
|
|
|
|
*/
|
2022-09-21 11:32:50 +03:00
|
|
|
export function setSafeAreaInsets(insets: Object) {
|
2022-05-06 05:18:57 -05:00
|
|
|
return {
|
|
|
|
|
type: SAFE_AREA_INSETS_CHANGED,
|
|
|
|
|
insets
|
|
|
|
|
};
|
|
|
|
|
}
|
2023-01-25 17:02:26 +02:00
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Sets narrow layout.
|
|
|
|
|
*
|
|
|
|
|
* @param {boolean} isNarrow - Whether is narrow layout.
|
|
|
|
|
* @returns {{
|
|
|
|
|
* type: SET_NARROW_LAYOUT,
|
|
|
|
|
* isNarrow: boolean
|
|
|
|
|
* }}
|
|
|
|
|
*/
|
|
|
|
|
export function setNarrowLayout(isNarrow: boolean) {
|
|
|
|
|
return {
|
|
|
|
|
type: SET_NARROW_LAYOUT,
|
|
|
|
|
isNarrow
|
|
|
|
|
};
|
|
|
|
|
}
|