2022-10-20 12:11:27 +03:00
|
|
|
import { IReduxState } from '../app/types';
|
2022-10-19 14:38:38 +03:00
|
|
|
import { IStateful } from '../base/app/types';
|
2024-10-30 14:11:09 +01:00
|
|
|
import { hasAvailableDevices } from '../base/devices/functions.native';
|
2022-10-21 14:09:15 +03:00
|
|
|
import { TOOLBOX_ALWAYS_VISIBLE, TOOLBOX_ENABLED } from '../base/flags/constants';
|
|
|
|
|
import { getFeatureFlag } from '../base/flags/functions';
|
|
|
|
|
import { getParticipantCountWithFake } from '../base/participants/functions';
|
|
|
|
|
import { toState } from '../base/redux/functions';
|
2024-10-30 14:11:09 +01:00
|
|
|
import { isLocalVideoTrackDesktop } from '../base/tracks/functions.native';
|
2019-03-12 17:45:53 +00:00
|
|
|
|
2025-06-05 16:44:47 -05:00
|
|
|
import { MAIN_TOOLBAR_BUTTONS_PRIORITY, VISITORS_MODE_BUTTONS } from './constants';
|
2025-02-11 16:17:13 +02:00
|
|
|
import { isButtonEnabled } from './functions.any';
|
|
|
|
|
import { IGetVisibleNativeButtonsParams, IToolboxNativeButton } from './types';
|
2021-03-22 11:02:57 +02:00
|
|
|
|
2025-02-11 16:17:13 +02:00
|
|
|
export * from './functions.any';
|
2021-03-22 11:02:57 +02:00
|
|
|
|
2022-01-05 15:27:42 -05:00
|
|
|
/**
|
|
|
|
|
* Indicates if the desktop share button is disabled or not.
|
|
|
|
|
*
|
2022-10-20 12:11:27 +03:00
|
|
|
* @param {IReduxState} state - The state from the Redux store.
|
2022-01-05 15:27:42 -05:00
|
|
|
* @returns {boolean}
|
|
|
|
|
*/
|
2022-10-20 12:11:27 +03:00
|
|
|
export function isDesktopShareButtonDisabled(state: IReduxState) {
|
2022-01-05 15:27:42 -05:00
|
|
|
const { muted, unmuteBlocked } = state['features/base/media'].video;
|
|
|
|
|
const videoOrShareInProgress = !muted || isLocalVideoTrackDesktop(state);
|
|
|
|
|
|
|
|
|
|
return unmuteBlocked && !videoOrShareInProgress;
|
|
|
|
|
}
|
|
|
|
|
|
2019-03-12 17:45:53 +00:00
|
|
|
/**
|
|
|
|
|
* Returns true if the toolbox is visible.
|
|
|
|
|
*
|
2022-10-19 14:38:38 +03:00
|
|
|
* @param {IStateful} stateful - A function or object that can be
|
2019-03-12 17:45:53 +00:00
|
|
|
* resolved to Redux state by the function {@code toState}.
|
|
|
|
|
* @returns {boolean}
|
|
|
|
|
*/
|
2022-10-19 14:38:38 +03:00
|
|
|
export function isToolboxVisible(stateful: IStateful) {
|
2019-08-20 15:12:38 +02:00
|
|
|
const state = toState(stateful);
|
2021-09-28 14:52:31 +03:00
|
|
|
const { toolbarConfig } = state['features/base/config'];
|
|
|
|
|
const { alwaysVisible } = toolbarConfig || {};
|
2021-09-23 17:39:05 +03:00
|
|
|
const { enabled, visible } = state['features/toolbox'];
|
2021-07-09 07:36:19 -05:00
|
|
|
const participantCount = getParticipantCountWithFake(state);
|
2021-01-22 12:03:39 +02:00
|
|
|
const alwaysVisibleFlag = getFeatureFlag(state, TOOLBOX_ALWAYS_VISIBLE, false);
|
|
|
|
|
const enabledFlag = getFeatureFlag(state, TOOLBOX_ENABLED, true);
|
2019-03-12 17:45:53 +00:00
|
|
|
|
2021-09-23 17:39:05 +03:00
|
|
|
return enabledFlag && enabled
|
|
|
|
|
&& (alwaysVisible || visible || participantCount === 1 || alwaysVisibleFlag);
|
2019-03-12 17:45:53 +00:00
|
|
|
}
|
2020-11-04 09:32:06 +01:00
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Indicates if the video mute button is disabled or not.
|
|
|
|
|
*
|
2022-10-20 12:11:27 +03:00
|
|
|
* @param {IReduxState} state - The state from the Redux store.
|
2020-11-04 09:32:06 +01:00
|
|
|
* @returns {boolean}
|
|
|
|
|
*/
|
2022-10-20 12:11:27 +03:00
|
|
|
export function isVideoMuteButtonDisabled(state: IReduxState) {
|
2021-12-07 16:48:12 -05:00
|
|
|
const { muted, unmuteBlocked } = state['features/base/media'].video;
|
2021-11-30 15:08:25 -05:00
|
|
|
|
2021-12-07 16:48:12 -05:00
|
|
|
return !hasAvailableDevices(state, 'videoInput')
|
2024-10-30 14:11:09 +01:00
|
|
|
|| (unmuteBlocked && Boolean(muted));
|
2020-11-04 09:32:06 +01:00
|
|
|
}
|
2025-02-11 16:17:13 +02:00
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Returns all buttons that need to be rendered.
|
|
|
|
|
*
|
|
|
|
|
* @param {IGetVisibleButtonsParams} params - The parameters needed to extract the visible buttons.
|
|
|
|
|
* @returns {Object} - The visible buttons arrays .
|
|
|
|
|
*/
|
2025-04-14 16:19:52 -05:00
|
|
|
export function getVisibleNativeButtons(
|
2025-06-05 16:44:47 -05:00
|
|
|
{ allButtons, clientWidth, iAmVisitor, mainToolbarButtonsThresholds, toolbarButtons }: IGetVisibleNativeButtonsParams) {
|
|
|
|
|
let filteredButtons = Object.keys(allButtons).filter(key =>
|
2025-02-11 16:17:13 +02:00
|
|
|
typeof key !== 'undefined' // filter invalid buttons that may be coming from config.mainToolbarButtons override
|
|
|
|
|
&& isButtonEnabled(key, toolbarButtons));
|
|
|
|
|
|
2025-06-05 16:44:47 -05:00
|
|
|
if (iAmVisitor) {
|
|
|
|
|
filteredButtons = VISITORS_MODE_BUTTONS.filter(button => filteredButtons.indexOf(button) > -1);
|
|
|
|
|
}
|
|
|
|
|
|
2025-02-11 16:17:13 +02:00
|
|
|
const { order } = mainToolbarButtonsThresholds.find(({ width }) => clientWidth > width)
|
|
|
|
|
|| mainToolbarButtonsThresholds[mainToolbarButtonsThresholds.length - 1];
|
|
|
|
|
|
|
|
|
|
const mainToolbarButtonKeysOrder = [
|
|
|
|
|
...order.filter(key => filteredButtons.includes(key)),
|
|
|
|
|
...MAIN_TOOLBAR_BUTTONS_PRIORITY.filter(key => !order.includes(key) && filteredButtons.includes(key)),
|
|
|
|
|
...filteredButtons.filter(key => !order.includes(key) && !MAIN_TOOLBAR_BUTTONS_PRIORITY.includes(key))
|
|
|
|
|
];
|
|
|
|
|
|
|
|
|
|
const mainButtonsKeys = mainToolbarButtonKeysOrder.slice(0, order.length);
|
|
|
|
|
const overflowMenuButtons = filteredButtons.reduce((acc, key) => {
|
|
|
|
|
if (!mainButtonsKeys.includes(key)) {
|
|
|
|
|
acc.push(allButtons[key]);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return acc;
|
|
|
|
|
}, [] as IToolboxNativeButton[]);
|
|
|
|
|
|
|
|
|
|
// if we have 1 button in the overflow menu it is better to directly display it in the main toolbar by replacing
|
|
|
|
|
// the "More" menu button with it.
|
|
|
|
|
if (overflowMenuButtons.length === 1) {
|
|
|
|
|
const button = overflowMenuButtons.shift()?.key;
|
|
|
|
|
|
|
|
|
|
button && mainButtonsKeys.push(button);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const mainMenuButtons
|
|
|
|
|
= mainButtonsKeys.map(key => allButtons[key]).sort((a, b) => {
|
|
|
|
|
|
|
|
|
|
// Native toolbox includes hangup and overflowmenu button keys, too
|
|
|
|
|
// hangup goes last, overflowmenu goes second-to-last
|
|
|
|
|
if (a.key === 'hangup' || a.key === 'overflowmenu') {
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (b.key === 'hangup' || b.key === 'overflowmenu') {
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return 0; // other buttons are sorted by priority
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
return {
|
|
|
|
|
mainMenuButtons,
|
|
|
|
|
overflowMenuButtons
|
|
|
|
|
};
|
|
|
|
|
}
|