diff --git a/react/features/base/flags/constants.js b/react/features/base/flags/constants.js index 2e17c8458..afbb328e5 100644 --- a/react/features/base/flags/constants.js +++ b/react/features/base/flags/constants.js @@ -38,6 +38,12 @@ export const CALENDAR_ENABLED = 'calendar.enabled'; */ export const CALL_INTEGRATION_ENABLED = 'call-integration.enabled'; +/** + * Flag indicating if car mode should be enabled. + * Default: enabled (true). + */ +export const CAR_MODE_ENABLED = 'car-mode.enabled'; + /** * Flag indicating if close captions should be enabled. * Default: enabled (true). diff --git a/react/features/base/lastn/middleware.js b/react/features/base/lastn/middleware.js index 3823f47c1..3fce14c99 100644 --- a/react/features/base/lastn/middleware.js +++ b/react/features/base/lastn/middleware.js @@ -52,6 +52,7 @@ const _updateLastN = debounce(({ dispatch, getState }) => { const config = state['features/base/config']; const { lastNLimits } = state['features/base/lastn']; const participantCount = getParticipantCount(state); + const { carMode } = state['features/video-layout']; // Select the (initial) lastN value based on the following preference order. // 1. The last-n value from 'startLastN' if it is specified in config.js @@ -68,8 +69,10 @@ const _updateLastN = debounce(({ dispatch, getState }) => { if (typeof appState !== 'undefined' && appState !== 'active') { lastNSelected = isLocalVideoTrackDesktop(state) ? 1 : 0; + } else if (carMode) { + lastNSelected = 0; } else if (audioOnly) { - const { remoteScreenShares, tileViewEnabled, carMode } = state['features/video-layout']; + const { remoteScreenShares, tileViewEnabled } = state['features/video-layout']; const largeVideoParticipantId = state['features/large-video'].participantId; const largeVideoParticipant = largeVideoParticipantId ? getParticipantById(state, largeVideoParticipantId) : undefined; @@ -77,7 +80,7 @@ const _updateLastN = debounce(({ dispatch, getState }) => { // Use tileViewEnabled state from redux here instead of determining if client should be in tile // view since we make an exception only for screenshare when in audio-only mode. If the user unpins // the screenshare, lastN will be set to 0 here. It will be set to 1 if screenshare has been auto pinned. - if (!carMode && !tileViewEnabled && largeVideoParticipant && !largeVideoParticipant.local) { + if (!tileViewEnabled && largeVideoParticipant && !largeVideoParticipant.local) { lastNSelected = (remoteScreenShares || []).includes(largeVideoParticipantId) ? 1 : 0; } else { lastNSelected = 0; diff --git a/react/features/toolbox/components/native/OpenCarmodeButton.tsx b/react/features/toolbox/components/native/OpenCarmodeButton.tsx index b09c29cad..141e34c95 100644 --- a/react/features/toolbox/components/native/OpenCarmodeButton.tsx +++ b/react/features/toolbox/components/native/OpenCarmodeButton.tsx @@ -1,3 +1,4 @@ +import { CAR_MODE_ENABLED, getFeatureFlag } from '../../../base/flags'; import { translate } from '../../../base/i18n'; import { IconCar } from '../../../base/icons'; import { connect } from '../../../base/redux'; @@ -25,4 +26,21 @@ class OpenCarmodeButton extends AbstractButton { } } -export default translate(connect()(OpenCarmodeButton)); +/** + * Maps part of the Redux state to the props of this component. + * + * @param {Object} state - The Redux state. + * @param {AbstractButtonProps} ownProps - The properties explicitly passed to the component instance. + * @private + * @returns {Object} + */ + function _mapStateToProps(state: Object, ownProps: AbstractButtonProps): Object { + const enabled = getFeatureFlag(state, CAR_MODE_ENABLED, true); + const { visible = enabled } = ownProps; + + return { + visible + }; +} + +export default translate(connect(_mapStateToProps)(OpenCarmodeButton)); diff --git a/react/features/video-layout/actionTypes.ts b/react/features/video-layout/actionTypes.ts index 741427cfa..32100f5a4 100644 --- a/react/features/video-layout/actionTypes.ts +++ b/react/features/video-layout/actionTypes.ts @@ -11,14 +11,14 @@ export const SCREEN_SHARE_REMOTE_PARTICIPANTS_UPDATED = 'SCREEN_SHARE_REMOTE_PARTICIPANTS_UPDATED'; /** - * The type of the action which sets the list of known remote virtual screen share participant IDs. + * The type of the action which tells whether we are in carmode. * * @returns {{ - * type: VIRTUAL_SCREENSHARE_REMOTE_PARTICIPANTS_UPDATED, - * participantIds: Array + * type: SET_CAR_MODE, + * enabled: boolean * }} */ -export const VIRTUAL_SCREENSHARE_REMOTE_PARTICIPANTS_UPDATED = 'VIRTUAL_SCREENSHARE_REMOTE_PARTICIPANTS_UPDATED'; +export const SET_CAR_MODE = ' SET_CAR_MODE'; /** * The type of the action which enables or disables the feature for showing @@ -32,11 +32,11 @@ export const VIRTUAL_SCREENSHARE_REMOTE_PARTICIPANTS_UPDATED = 'VIRTUAL_SCREENSH export const SET_TILE_VIEW = 'SET_TILE_VIEW'; /** - * The type of the action which tells whether we are in carmode. + * The type of the action which sets the list of known remote virtual screen share participant IDs. * * @returns {{ - * type: SET_CAR_MODE, - * enabled: boolean + * type: VIRTUAL_SCREENSHARE_REMOTE_PARTICIPANTS_UPDATED, + * participantIds: Array * }} */ -export const SET_CAR_MODE = ' SET_CAR_MODE'; +export const VIRTUAL_SCREENSHARE_REMOTE_PARTICIPANTS_UPDATED = 'VIRTUAL_SCREENSHARE_REMOTE_PARTICIPANTS_UPDATED'; diff --git a/react/features/video-layout/reducer.js b/react/features/video-layout/reducer.js index 827dd3970..324e2bc28 100644 --- a/react/features/video-layout/reducer.js +++ b/react/features/video-layout/reducer.js @@ -10,6 +10,14 @@ import { } from './actionTypes'; const DEFAULT_STATE = { + /** + * Whether we are in carmode. + * + * @public + * @type {boolean} + */ + carMode: false, + remoteScreenShares: [], /** @@ -22,15 +30,7 @@ const DEFAULT_STATE = { * @public * @type {boolean} */ - tileViewEnabled: undefined, - - /** - * Whether we are in carmode. - * - * @public - * @type {boolean} - */ - carMode: false + tileViewEnabled: undefined }; const STORE_NAME = 'features/video-layout'; @@ -44,17 +44,17 @@ ReducerRegistry.register(STORE_NAME, (state = DEFAULT_STATE, action) => { remoteScreenShares: action.participantIds }; - case SET_TILE_VIEW: - return { - ...state, - tileViewEnabled: action.enabled - }; - case SET_CAR_MODE: return { ...state, carMode: action.enabled }; + + case SET_TILE_VIEW: + return { + ...state, + tileViewEnabled: action.enabled + }; } return state;