diff --git a/react/features/conference/components/Conference.native.js b/react/features/conference/components/Conference.native.js
index 6afcafc9a..9bac3e0f5 100644
--- a/react/features/conference/components/Conference.native.js
+++ b/react/features/conference/components/Conference.native.js
@@ -1,9 +1,11 @@
+import PropTypes from 'prop-types';
import React, { Component } from 'react';
+import { View } from 'react-native';
import { connect as reactReduxConnect } from 'react-redux';
import { connect, disconnect } from '../../base/connection';
import { DialogContainer } from '../../base/dialog';
-import { Container } from '../../base/react';
+import { Container, LoadingIndicator } from '../../base/react';
import { createDesiredLocalTracks } from '../../base/tracks';
import { Filmstrip } from '../../filmstrip';
import { LargeVideo } from '../../large-video';
@@ -30,38 +32,44 @@ class Conference extends Component {
* @static
*/
static propTypes = {
+ /**
+ * The indicator which determines that we are still connecting to the
+ * conference which includes establishing the XMPP connection and then
+ * joining the room. If truthy, then an activity/loading indicator will
+ * be rendered.
+ *
+ * @private
+ */
+ _connecting: PropTypes.bool,
+
/**
* The handler which dispatches the (redux) action connect.
*
* @private
- * @type {Function}
*/
- _onConnect: React.PropTypes.func,
+ _onConnect: PropTypes.func,
/**
* The handler which dispatches the (redux) action disconnect.
*
* @private
- * @type {Function}
*/
- _onDisconnect: React.PropTypes.func,
+ _onDisconnect: PropTypes.func,
/**
* The handler which dispatches the (redux) action setToolboxVisible to
* show/hide the Toolbox.
*
* @private
- * @type {boolean}
*/
- _setToolboxVisible: React.PropTypes.func,
+ _setToolboxVisible: PropTypes.func,
/**
* The indicator which determines whether the Toolbox is visible.
*
* @private
- * @type {boolean}
*/
- _toolboxVisible: React.PropTypes.bool
+ _toolboxVisible: PropTypes.bool
};
/**
@@ -152,6 +160,16 @@ class Conference extends Component {
*/}
+ {/*
+ * The activity/loading indicator goes above everything, except
+ * the toolbox/toolbars and the dialogs.
+ */
+ this.props._connecting
+ &&
+
+
+ }
+
{/*
* The Toolbox is in a stacking layer above the Filmstrip.
*/}
@@ -264,11 +282,38 @@ function _mapDispatchToProps(dispatch) {
* @param {Object} state - The Redux state.
* @private
* @returns {{
+ * _connecting: boolean,
* _toolboxVisible: boolean
* }}
*/
function _mapStateToProps(state) {
+ const { connecting, connection } = state['features/base/connection'];
+ const { conference, joining, leaving } = state['features/base/conference'];
+
+ // XXX There is a window of time between the successful establishment of the
+ // XMPP connection and the subsequent commencement of joining the MUC during
+ // which the app does not appear to be doing anything according to the redux
+ // state. In order to not toggle the _connecting props during the window of
+ // time in question, define _connecting as follows:
+ // - the XMPP connection is connecting, or
+ // - the XMPP connection is connected and the conference is joining, or
+ // - the XMPP connection is connected and we have no conference yet, nor we
+ // are leaving one.
+ const connecting_
+ = connecting || (connection && (joining || (!conference && !leaving)));
+
return {
+ /**
+ * The indicator which determines that we are still connecting to the
+ * conference which includes establishing the XMPP connection and then
+ * joining the room. If truthy, then an activity/loading indicator will
+ * be rendered.
+ *
+ * @private
+ * @type {boolean}
+ */
+ _connecting: Boolean(connecting_),
+
/**
* The indicator which determines whether the Toolbox is visible.
*
diff --git a/react/features/conference/components/styles.js b/react/features/conference/components/styles.js
index 8962e2c2c..8b3fe78d0 100644
--- a/react/features/conference/components/styles.js
+++ b/react/features/conference/components/styles.js
@@ -15,5 +15,28 @@ export default createStyleSheet({
alignSelf: 'stretch',
backgroundColor: ColorPalette.appBackground,
flex: 1
- })
+ }),
+
+ /**
+ * The style of the View rendered while the conference is being connected
+ * (i.e. the XMPP connection is being established and the MUC is being
+ * joined).
+ */
+ connectingIndicator: {
+ alignItems: 'center',
+ bottom: 0,
+ justifyContent: 'center',
+ left: 0,
+ position: 'absolute',
+ right: 0,
+ top: 0,
+
+ // Because the background of LargeVideo varies wildly (e.g. the
+ // participant's video or avatar), the LoadingIndicator may be difficult
+ // to see. Reduce the variance of the background of LargeVideo and,
+ // thus, increase the visibility of LoadingIndicator by introducing
+ // contrast and translucency.
+ backgroundColor: ColorPalette.appBackground,
+ opacity: 0.5
+ }
});