Browse Source

[RN] Add conference connecting overlay

master
Bettenbuk Zoltan 6 years ago
parent
commit
8bb56be317

+ 3
- 0
lang/main.json View File

57
         },
57
         },
58
         "title": "Chat"
58
         "title": "Chat"
59
     },
59
     },
60
+    "connectingOverlay": {
61
+        "joiningRoom": "Connecting you to your meeting..."
62
+    },
60
     "connection": {
63
     "connection": {
61
         "ATTACHED": "Attached",
64
         "ATTACHED": "Attached",
62
         "AUTHENTICATING": "Authenticating",
65
         "AUTHENTICATING": "Authenticating",

+ 2
- 2
react/features/app/actions.js View File

55
         }
55
         }
56
 
56
 
57
         location.protocol || (location.protocol = 'https:');
57
         location.protocol || (location.protocol = 'https:');
58
+        const { contextRoot, host, room } = location;
58
         const locationURL = new URL(location.toString());
59
         const locationURL = new URL(location.toString());
59
 
60
 
60
-        dispatch(configWillLoad(locationURL));
61
+        dispatch(configWillLoad(locationURL, room));
61
 
62
 
62
         let protocol = location.protocol.toLowerCase();
63
         let protocol = location.protocol.toLowerCase();
63
-        const { contextRoot, host, room } = location;
64
 
64
 
65
         // The React Native app supports an app-specific scheme which is sure to not
65
         // The React Native app supports an app-specific scheme which is sure to not
66
         // be supported by fetch.
66
         // be supported by fetch.

+ 2
- 2
react/features/base/app/components/BaseApp.js View File

117
     render() {
117
     render() {
118
         const { route: { component }, store } = this.state;
118
         const { route: { component }, store } = this.state;
119
 
119
 
120
-        if (store && component) {
120
+        if (store) {
121
             return (
121
             return (
122
                 <I18nextProvider i18n = { i18next }>
122
                 <I18nextProvider i18n = { i18next }>
123
                     <Provider store = { store }>
123
                     <Provider store = { store }>
160
      * @protected
160
      * @protected
161
      */
161
      */
162
     _createMainElement(component, props) {
162
     _createMainElement(component, props) {
163
-        return React.createElement(component, props || {});
163
+        return component ? React.createElement(component, props || {}) : null;
164
     }
164
     }
165
 
165
 
166
     /**
166
     /**

+ 4
- 0
react/features/base/color-scheme/defaultScheme.js View File

29
     'LargeVideo': {
29
     'LargeVideo': {
30
         background: ColorPalette.black
30
         background: ColorPalette.black
31
     },
31
     },
32
+    'LoadConfigOverlay': {
33
+        background: ColorPalette.black,
34
+        text: ColorPalette.white
35
+    },
32
     'Thumbnail': {
36
     'Thumbnail': {
33
         activeParticipantHighlight: ColorPalette.blue,
37
         activeParticipantHighlight: ColorPalette.blue,
34
         activeParticipantTint: ColorPalette.black,
38
         activeParticipantTint: ColorPalette.black,

+ 2
- 1
react/features/base/config/actionTypes.js View File

4
  *
4
  *
5
  * {
5
  * {
6
  *     type: CONFIG_WILL_LOAD,
6
  *     type: CONFIG_WILL_LOAD,
7
- *     locationURL: URL
7
+ *     locationURL: URL,
8
+ *     room: string
8
  * }
9
  * }
9
  */
10
  */
10
 export const CONFIG_WILL_LOAD = 'CONFIG_WILL_LOAD';
11
 export const CONFIG_WILL_LOAD = 'CONFIG_WILL_LOAD';

+ 6
- 3
react/features/base/config/actions.js View File

15
  *
15
  *
16
  * @param {URL} locationURL - The URL of the location which necessitated the
16
  * @param {URL} locationURL - The URL of the location which necessitated the
17
  * loading of a configuration.
17
  * loading of a configuration.
18
+ * @param {string} room - The name of the room (conference) for which we're loading the config for.
18
  * @returns {{
19
  * @returns {{
19
  *     type: CONFIG_WILL_LOAD,
20
  *     type: CONFIG_WILL_LOAD,
20
- *     locationURL: URL
21
+ *     locationURL: URL,
22
+ *     room: string
21
  * }}
23
  * }}
22
  */
24
  */
23
-export function configWillLoad(locationURL: URL) {
25
+export function configWillLoad(locationURL: URL, room: string) {
24
     return {
26
     return {
25
         type: CONFIG_WILL_LOAD,
27
         type: CONFIG_WILL_LOAD,
26
-        locationURL
28
+        locationURL,
29
+        room
27
     };
30
     };
28
 }
31
 }
29
 
32
 

+ 7
- 2
react/features/base/react/components/native/LoadingIndicator.js View File

7
 
7
 
8
 type Props = {
8
 type Props = {
9
 
9
 
10
+    /**
11
+     * The color of the spinner.
12
+     */
13
+    color: ?string,
14
+
10
     /**
15
     /**
11
      * Prop to set the size of the indicator. This is the same as the
16
      * Prop to set the size of the indicator. This is the same as the
12
      * prop of the native component.
17
      * prop of the native component.
27
      * @returns {ReactElement}
32
      * @returns {ReactElement}
28
      */
33
      */
29
     render() {
34
     render() {
35
+        const { color = ColorPalette.white } = this.props;
30
         let { size = 'large' } = this.props;
36
         let { size = 'large' } = this.props;
31
 
37
 
32
         if (size === 'medium') {
38
         if (size === 'medium') {
35
 
41
 
36
         const props = {
42
         const props = {
37
             animating: true,
43
             animating: true,
38
-            color: ColorPalette.white,
44
+            color,
39
             ...this.props,
45
             ...this.props,
40
             size
46
             size
41
         };
47
         };
43
         return (
49
         return (
44
             <ActivityIndicator
50
             <ActivityIndicator
45
                 animating = { true }
51
                 animating = { true }
46
-                color = { ColorPalette.white }
47
                 { ...props }
52
                 { ...props }
48
                 size = { size } />
53
                 size = { size } />
49
         );
54
         );

+ 8
- 8
react/features/overlay/actionTypes.js View File

15
     = 'MEDIA_PERMISSION_PROMPT_VISIBILITY_CHANGED';
15
     = 'MEDIA_PERMISSION_PROMPT_VISIBILITY_CHANGED';
16
 
16
 
17
 /**
17
 /**
18
- * The type of the Redux action which signals that a suspend was detected.
18
+ * Adjust the state of the fatal error which shows/hides the reload screen. See
19
+ * action methods's description for more info about each of the fields.
19
  *
20
  *
20
  * {
21
  * {
21
- *     type: SUSPEND_DETECTED
22
+ *     type: SET_FATAL_ERROR,
23
+ *     fatalError: ?Object
22
  * }
24
  * }
23
  * @public
25
  * @public
24
  */
26
  */
25
-export const SUSPEND_DETECTED = 'SUSPEND_DETECTED';
27
+export const SET_FATAL_ERROR = 'SET_FATAL_ERROR';
26
 
28
 
27
 /**
29
 /**
28
- * Adjust the state of the fatal error which shows/hides the reload screen. See
29
- * action methods's description for more info about each of the fields.
30
+ * The type of the Redux action which signals that a suspend was detected.
30
  *
31
  *
31
  * {
32
  * {
32
- *     type: SET_FATAL_ERROR,
33
- *     fatalError: ?Object
33
+ *     type: SUSPEND_DETECTED
34
  * }
34
  * }
35
  * @public
35
  * @public
36
  */
36
  */
37
-export const SET_FATAL_ERROR = 'SET_FATAL_ERROR';
37
+export const SUSPEND_DETECTED = 'SUSPEND_DETECTED';

+ 92
- 0
react/features/overlay/components/native/LoadConfigOverlay.js View File

1
+// @flow
2
+
3
+import React, { Component } from 'react';
4
+import { SafeAreaView, Text } from 'react-native';
5
+
6
+import { ColorSchemeRegistry } from '../../../base/color-scheme';
7
+import { translate } from '../../../base/i18n';
8
+import { LoadingIndicator } from '../../../base/react';
9
+import { connect } from '../../../base/redux';
10
+import { StyleType } from '../../../base/styles';
11
+
12
+import OverlayFrame from './OverlayFrame';
13
+import styles from './styles';
14
+
15
+type Props = {
16
+
17
+    /**
18
+     * The color schemed style of the component.
19
+     */
20
+    _styles: StyleType,
21
+
22
+    /**
23
+     * The Function to be invoked to translate i18n keys.
24
+     */
25
+    t: Function
26
+};
27
+
28
+/**
29
+ * Implements an overlay to tell the user that there is an operation in progress in the background during connect
30
+ * so then the app doesn't seem hung.
31
+ */
32
+class LoadConfigOverlay extends Component<Props> {
33
+    /**
34
+     * Determines whether this overlay needs to be rendered (according to a
35
+     * specific redux state). Called by {@link OverlayContainer}.
36
+     *
37
+     * @param {Object} state - The redux state.
38
+     * @returns {boolean} - If this overlay needs to be rendered, {@code true};
39
+     * {@code false}, otherwise.
40
+     */
41
+    static needsRender(state: Object) {
42
+        return Boolean(state['features/overlay'].loadConfigOverlayVisible);
43
+    }
44
+
45
+    /**
46
+     * Implements React's {@link Component#render()}.
47
+     *
48
+     * @inheritdoc
49
+     * @returns {ReactElement}
50
+     */
51
+    render() {
52
+        const { _styles } = this.props;
53
+
54
+        return (
55
+            <OverlayFrame>
56
+                <SafeAreaView
57
+                    style = { [
58
+                        styles.loadingOverlayWrapper,
59
+                        _styles.loadingOverlayWrapper
60
+                    ] }>
61
+                    <LoadingIndicator
62
+                        color = { _styles.indicatorColor }
63
+                        size = 'large'
64
+                        style = { styles.connectIndicator } />
65
+                    <Text
66
+                        style = { [
67
+                            styles.loadingOverlayText,
68
+                            _styles.loadingOverlayText
69
+                        ] }>
70
+                        { this.props.t('connectingOverlay.joiningRoom') }
71
+                    </Text>
72
+                </SafeAreaView>
73
+            </OverlayFrame>
74
+        );
75
+    }
76
+}
77
+
78
+/**
79
+ * Maps part of the Redux state to the props of this component.
80
+ *
81
+ * @param {Object} state - The Redux state.
82
+ * @returns {{
83
+ *     _styles: StyleType
84
+ * }}
85
+ */
86
+function _mapStateToProps(state) {
87
+    return {
88
+        _styles: ColorSchemeRegistry.get(state, 'LoadConfigOverlay')
89
+    };
90
+}
91
+
92
+export default translate(connect(_mapStateToProps)(LoadConfigOverlay));

+ 1
- 1
react/features/overlay/components/native/OverlayFrame.js View File

3
 import React, { Component, type Node } from 'react';
3
 import React, { Component, type Node } from 'react';
4
 import { SafeAreaView, View } from 'react-native';
4
 import { SafeAreaView, View } from 'react-native';
5
 
5
 
6
-import { overlayFrame as styles } from './styles';
6
+import styles from './styles';
7
 
7
 
8
 /**
8
 /**
9
  * The type of the React {@code Component} props of {@code OverlayFrame}.
9
  * The type of the React {@code Component} props of {@code OverlayFrame}.

+ 1
- 0
react/features/overlay/components/native/index.js View File

1
 // @flow
1
 // @flow
2
 
2
 
3
+export { default as LoadConfigOverlay } from './LoadConfigOverlay';
3
 export { default as OverlayFrame } from './OverlayFrame';
4
 export { default as OverlayFrame } from './OverlayFrame';
4
 export { default as PageReloadOverlay } from './PageReloadOverlay';
5
 export { default as PageReloadOverlay } from './PageReloadOverlay';

+ 34
- 3
react/features/overlay/components/native/styles.js View File

2
 
2
 
3
 import { StyleSheet } from 'react-native';
3
 import { StyleSheet } from 'react-native';
4
 
4
 
5
-import { ColorPalette } from '../../../base/styles';
5
+import { ColorSchemeRegistry, schemeColor } from '../../../base/color-scheme';
6
+import { BoxModel, ColorPalette } from '../../../base/styles';
6
 
7
 
7
 /**
8
 /**
8
- * The React {@code Component} styles of {@code OverlayFrame}.
9
+ * The React {@code Component} styles of the overlay feature.
9
  */
10
  */
10
-export const overlayFrame = createStyleSheet({
11
+export default {
12
+    connectIndicator: {
13
+        margin: BoxModel.margin
14
+    },
15
+
11
     /**
16
     /**
12
      * Style for a backdrop overlay covering the screen the the overlay is
17
      * Style for a backdrop overlay covering the screen the the overlay is
13
      * rendered.
18
      * rendered.
17
         backgroundColor: ColorPalette.black
22
         backgroundColor: ColorPalette.black
18
     },
23
     },
19
 
24
 
25
+    loadingOverlayText: {
26
+        color: ColorPalette.white
27
+    },
28
+
29
+    loadingOverlayWrapper: {
30
+        alignItems: 'center',
31
+        flex: 1,
32
+        flexDirection: 'column',
33
+        justifyContent: 'center'
34
+    },
35
+
20
     safeContainer: {
36
     safeContainer: {
21
         flex: 1
37
         flex: 1
22
     }
38
     }
39
+};
40
+
41
+/**
42
+ * Color schemed styles for all the component based on the abstract dialog.
43
+ */
44
+ColorSchemeRegistry.register('LoadConfigOverlay', {
45
+    indicatorColor: schemeColor('text'),
46
+
47
+    loadingOverlayText: {
48
+        color: schemeColor('text')
49
+    },
50
+
51
+    loadingOverlayWrapper: {
52
+        backgroundColor: schemeColor('background')
53
+    }
23
 });
54
 });

+ 2
- 45
react/features/overlay/functions.js View File

1
 // @flow
1
 // @flow
2
 
2
 
3
-import {
4
-    PageReloadFilmstripOnlyOverlay,
5
-    PageReloadOverlay,
6
-    SuspendedFilmstripOnlyOverlay,
7
-    SuspendedOverlay,
8
-    UserMediaPermissionsFilmstripOnlyOverlay,
9
-    UserMediaPermissionsOverlay
10
-} from './components';
11
-
12
-declare var interfaceConfig: Object;
13
-
14
-/**
15
- * Returns the list of available overlays that might be rendered.
16
- *
17
- * @private
18
- * @returns {Array<?React$ComponentType<*>>}
19
- */
20
-function _getOverlays() {
21
-    const filmstripOnly
22
-        = typeof interfaceConfig === 'object' && interfaceConfig.filmStripOnly;
23
-    let overlays;
24
-
25
-    if (filmstripOnly) {
26
-        overlays = [
27
-            PageReloadFilmstripOnlyOverlay,
28
-            SuspendedFilmstripOnlyOverlay,
29
-            UserMediaPermissionsFilmstripOnlyOverlay
30
-        ];
31
-    } else {
32
-        overlays = [
33
-            PageReloadOverlay
34
-        ];
35
-    }
36
-
37
-    // Mobile only has a PageReloadOverlay.
38
-    if (navigator.product !== 'ReactNative') {
39
-        overlays.push(...[
40
-            SuspendedOverlay,
41
-            UserMediaPermissionsOverlay
42
-        ]);
43
-    }
44
-
45
-    return overlays;
46
-}
3
+import { getOverlays } from './overlays';
47
 
4
 
48
 /**
5
 /**
49
  * Returns the overlay to be currently rendered.
6
  * Returns the overlay to be currently rendered.
52
  * @returns {?React$ComponentType<*>}
9
  * @returns {?React$ComponentType<*>}
53
  */
10
  */
54
 export function getOverlayToRender(state: Object) {
11
 export function getOverlayToRender(state: Object) {
55
-    for (const overlay of _getOverlays()) {
12
+    for (const overlay of getOverlays()) {
56
         // react-i18n / react-redux wrap components and thus we cannot access
13
         // react-i18n / react-redux wrap components and thus we cannot access
57
         // the wrapped component's static methods directly.
14
         // the wrapped component's static methods directly.
58
         const component = overlay.WrappedComponent || overlay;
15
         const component = overlay.WrappedComponent || overlay;

+ 18
- 0
react/features/overlay/overlays.native.js View File

1
+// @flow
2
+
3
+import {
4
+    LoadConfigOverlay,
5
+    PageReloadOverlay
6
+} from './components/native';
7
+
8
+/**
9
+ * Returns the list of available platform specific overlays.
10
+ *
11
+ * @returns {Array<React$Element>}
12
+ */
13
+export function getOverlays(): Array<React$Element<*>> {
14
+    return [
15
+        LoadConfigOverlay,
16
+        PageReloadOverlay
17
+    ];
18
+}

+ 38
- 0
react/features/overlay/overlays.web.js View File

1
+// @flow
2
+
3
+import {
4
+    PageReloadFilmstripOnlyOverlay,
5
+    PageReloadOverlay,
6
+    SuspendedFilmstripOnlyOverlay,
7
+    SuspendedOverlay,
8
+    UserMediaPermissionsFilmstripOnlyOverlay,
9
+    UserMediaPermissionsOverlay
10
+} from './components/web';
11
+
12
+declare var interfaceConfig: Object;
13
+
14
+/**
15
+ * Returns the list of available platform specific overlays.
16
+ *
17
+ * @returns {Array<Object>}
18
+ */
19
+export function getOverlays(): Array<Object> {
20
+    const overlays = [
21
+        SuspendedOverlay,
22
+        UserMediaPermissionsOverlay
23
+    ];
24
+
25
+    const filmstripOnly
26
+            = typeof interfaceConfig === 'object' && interfaceConfig.filmStripOnly;
27
+
28
+    if (filmstripOnly) {
29
+        overlays.push(
30
+            PageReloadFilmstripOnlyOverlay,
31
+            SuspendedFilmstripOnlyOverlay,
32
+            UserMediaPermissionsFilmstripOnlyOverlay);
33
+    } else {
34
+        overlays.push(PageReloadOverlay);
35
+    }
36
+
37
+    return overlays;
38
+}

+ 24
- 4
react/features/overlay/reducer.js View File

1
 // @flow
1
 // @flow
2
 
2
 
3
+import { CONFIG_WILL_LOAD, LOAD_CONFIG_ERROR, SET_CONFIG } from '../base/config';
3
 import { assign, ReducerRegistry, set } from '../base/redux';
4
 import { assign, ReducerRegistry, set } from '../base/redux';
4
 
5
 
5
 import {
6
 import {
15
  */
16
  */
16
 ReducerRegistry.register('features/overlay', (state = { }, action) => {
17
 ReducerRegistry.register('features/overlay', (state = { }, action) => {
17
     switch (action.type) {
18
     switch (action.type) {
19
+    case CONFIG_WILL_LOAD:
20
+        return _setShowLoadConfigOverlay(state, Boolean(action.room));
21
+
22
+    case LOAD_CONFIG_ERROR:
23
+    case SET_CONFIG:
24
+        return _setShowLoadConfigOverlay(false);
25
+
18
     case MEDIA_PERMISSION_PROMPT_VISIBILITY_CHANGED:
26
     case MEDIA_PERMISSION_PROMPT_VISIBILITY_CHANGED:
19
         return _mediaPermissionPromptVisibilityChanged(state, action);
27
         return _mediaPermissionPromptVisibilityChanged(state, action);
20
 
28
 
48
 }
56
 }
49
 
57
 
50
 /**
58
 /**
51
- * Reduces a specific redux action SUSPEND_DETECTED of the feature overlay.
59
+ * Sets the {@code LoadConfigOverlay} overlay visible or not.
52
  *
60
  *
53
  * @param {Object} state - The redux state of the feature overlay.
61
  * @param {Object} state - The redux state of the feature overlay.
54
- * @private
62
+ * @param {boolean} show - Whether to show or not the overlay.
55
  * @returns {Object} The new state of the feature overlay after the reduction of
63
  * @returns {Object} The new state of the feature overlay after the reduction of
56
  * the specified action.
64
  * the specified action.
57
  */
65
  */
58
-function _suspendDetected(state) {
59
-    return set(state, 'suspendDetected', true);
66
+function _setShowLoadConfigOverlay(state, show) {
67
+    return set(state, 'loadConfigOverlayVisible', show);
60
 }
68
 }
61
 
69
 
62
 /**
70
 /**
72
 function _setFatalError(state, { fatalError }) {
80
 function _setFatalError(state, { fatalError }) {
73
     return set(state, 'fatalError', fatalError);
81
     return set(state, 'fatalError', fatalError);
74
 }
82
 }
83
+
84
+/**
85
+ * Reduces a specific redux action SUSPEND_DETECTED of the feature overlay.
86
+ *
87
+ * @param {Object} state - The redux state of the feature overlay.
88
+ * @private
89
+ * @returns {Object} The new state of the feature overlay after the reduction of
90
+ * the specified action.
91
+ */
92
+function _suspendDetected(state) {
93
+    return set(state, 'suspendDetected', true);
94
+}

Loading…
Cancel
Save