diff --git a/react/features/app/components/App.native.js b/react/features/app/components/App.native.js
index 3bcd8f7a2..cb6ae4559 100644
--- a/react/features/app/components/App.native.js
+++ b/react/features/app/components/App.native.js
@@ -7,7 +7,10 @@ import { Linking } from 'react-native';
import '../../analytics';
import '../../authentication';
import { Platform } from '../../base/react';
-import { AspectRatioDetector } from '../../base/responsive-ui';
+import {
+ AspectRatioDetector,
+ ReducedUIDetector
+} from '../../base/responsive-ui';
import '../../mobile/audio-mode';
import '../../mobile/background';
import '../../mobile/callkit';
@@ -97,7 +100,9 @@ export class App extends AbstractApp {
_createElement(component, props) {
return (
- { super._createElement(component, props) }
+
+ { super._createElement(component, props) }
+
);
}
diff --git a/react/features/app/components/App.web.js b/react/features/app/components/App.web.js
index 5103ba96a..615564cb2 100644
--- a/react/features/app/components/App.web.js
+++ b/react/features/app/components/App.web.js
@@ -1,6 +1,7 @@
import { AtlasKitThemeProvider } from '@atlaskit/theme';
import React from 'react';
+import '../../base/responsive-ui';
import { getLocationContextRoot } from '../../base/util';
import '../../room-lock';
diff --git a/react/features/base/responsive-ui/actionTypes.js b/react/features/base/responsive-ui/actionTypes.js
index da7dabff6..55e4299ba 100644
--- a/react/features/base/responsive-ui/actionTypes.js
+++ b/react/features/base/responsive-ui/actionTypes.js
@@ -8,3 +8,16 @@
* }
*/
export const SET_ASPECT_RATIO = Symbol('SET_ASPECT_RATIO');
+
+/**
+ * The type of redux action which signals that the reduces UI mode was enabled
+ * or disabled.
+ *
+ * {
+ * type: SET_REDUCED_UI,
+ * reducedUI: boolean
+ * }
+ *
+ * @public
+ */
+export const SET_REDUCED_UI = Symbol('SET_REDUCED_UI');
diff --git a/react/features/base/responsive-ui/actions.js b/react/features/base/responsive-ui/actions.js
index b31db0025..c7ddd9bea 100644
--- a/react/features/base/responsive-ui/actions.js
+++ b/react/features/base/responsive-ui/actions.js
@@ -1,10 +1,15 @@
// @flow
-import { SET_ASPECT_RATIO } from './actionTypes';
+import { SET_ASPECT_RATIO, SET_REDUCED_UI } from './actionTypes';
import { ASPECT_RATIO_NARROW, ASPECT_RATIO_WIDE } from './constants';
import type { Dispatch } from 'redux';
+/**
+ * Size threshold for determining if we are in reduced UI mode or not.
+ */
+const REDUCED_UI_THRESHOLD = 240;
+
/**
* Sets the aspect ratio of the app's user interface based on specific width and
* height.
@@ -34,3 +39,27 @@ export function setAspectRatio(width: number, height: number): Object {
}
};
}
+
+/**
+ * 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
+ * }}
+ */
+export function setReducedUI(width: number, height: number) {
+ return (dispatch: Dispatch<*>, getState: Function) => {
+ const reducedUI = Math.min(width, height) < REDUCED_UI_THRESHOLD;
+
+ if (reducedUI !== getState()['features/base/responsive-ui'].reducedUI) {
+ return dispatch({
+ type: SET_REDUCED_UI,
+ reducedUI
+ });
+ }
+ };
+}
diff --git a/react/features/base/responsive-ui/components/ReducedUIDetector.js b/react/features/base/responsive-ui/components/ReducedUIDetector.js
new file mode 100644
index 000000000..2c7f1c2c6
--- /dev/null
+++ b/react/features/base/responsive-ui/components/ReducedUIDetector.js
@@ -0,0 +1,72 @@
+// @flow
+
+import React, { Component } from 'react';
+import { connect } from 'react-redux';
+
+import { setReducedUI } from '../actions';
+import DimensionsDetector from './DimensionsDetector';
+
+
+/**
+ * ReducedUIDetector component's property types.
+ */
+type Props = {
+
+ /**
+ * The "onDimensionsHandler" handler.
+ */
+ _onDimensionsChanged: Function,
+
+ /**
+ * Any nested components.
+ */
+ children: React$Node
+};
+
+/**
+ * A root {@link View} which captures the 'onLayout' event and figures out
+ * if the UI is reduced.
+ */
+class ReducedUIDetector extends Component {
+ /**
+ * Renders the root view and it's children.
+ *
+ * @returns {Component}
+ */
+ render() {
+ return (
+
+ { this.props.children }
+
+ );
+ }
+}
+
+/**
+ * Maps dispatching of the reduced UI actions to React component props.
+ *
+ * @param {Function} dispatch - Redux action dispatcher.
+ * @private
+ * @returns {{
+ * _onDimensionsChanged: Function
+ * }}
+ */
+function _mapDispatchToProps(dispatch) {
+ return {
+ /**
+ * Handles the "on dimensions changed" event and dispatches the
+ * reduced UI action.
+ *
+ * @param {number} width - The new width for the component.
+ * @param {number} height - The new height for the component.
+ * @private
+ * @returns {void}
+ */
+ _onDimensionsChanged(width: number, height: number) {
+ dispatch(setReducedUI(width, height));
+ }
+ };
+}
+
+export default connect(undefined, _mapDispatchToProps)(ReducedUIDetector);
diff --git a/react/features/base/responsive-ui/components/index.js b/react/features/base/responsive-ui/components/index.js
index 74f71b3f1..4b999a952 100644
--- a/react/features/base/responsive-ui/components/index.js
+++ b/react/features/base/responsive-ui/components/index.js
@@ -1,3 +1,4 @@
export * from './AspectRatioAware';
export { default as AspectRatioDetector } from './AspectRatioDetector';
export { default as DimensionsDetector } from './DimensionsDetector';
+export { default as ReducedUIDetector } from './ReducedUIDetector';
diff --git a/react/features/base/responsive-ui/reducer.js b/react/features/base/responsive-ui/reducer.js
index 88d3a375d..d614df196 100644
--- a/react/features/base/responsive-ui/reducer.js
+++ b/react/features/base/responsive-ui/reducer.js
@@ -1,13 +1,14 @@
import { ReducerRegistry, set } from '../redux';
-import { SET_ASPECT_RATIO } from './actionTypes';
+import { SET_ASPECT_RATIO, SET_REDUCED_UI } from './actionTypes';
import { ASPECT_RATIO_NARROW } from './constants';
/**
* The initial redux state of the feature base/responsive-ui.
*/
const _INITIAL_STATE = {
- aspectRatio: ASPECT_RATIO_NARROW
+ aspectRatio: ASPECT_RATIO_NARROW,
+ reducedUI: false
};
ReducerRegistry.register(
@@ -16,6 +17,9 @@ ReducerRegistry.register(
switch (action.type) {
case SET_ASPECT_RATIO:
return set(state, 'aspectRatio', action.aspectRatio);
+
+ case SET_REDUCED_UI:
+ return set(state, 'reducedUI', action.reducedUI);
}
return state;