Przeglądaj źródła

Integrate Mobile landing in the Redux app

master
Ilya Daynatovich 8 lat temu
rodzic
commit
8248b14555

+ 11
- 0
react/features/app/actionTypes.js Wyświetl plik

21
  * }
21
  * }
22
  */
22
  */
23
 export const APP_WILL_UNMOUNT = Symbol('APP_WILL_UNMOUNT');
23
 export const APP_WILL_UNMOUNT = Symbol('APP_WILL_UNMOUNT');
24
+
25
+/**
26
+ * The type of this action sets the platform of user agent
27
+ * in order to decide to show the landing or not.
28
+ *
29
+ * {
30
+ *      type: APP_SET_PLATFORM,
31
+ *      platform: String
32
+ * }
33
+ */
34
+export const APP_SET_PLATFORM = Symbol('APP_SET_PLATFORM');

+ 51
- 6
react/features/app/actions.js Wyświetl plik

1
 import { setRoom } from '../base/conference';
1
 import { setRoom } from '../base/conference';
2
 import { getDomain, setDomain } from '../base/connection';
2
 import { getDomain, setDomain } from '../base/connection';
3
 import { loadConfig, setConfig } from '../base/lib-jitsi-meet';
3
 import { loadConfig, setConfig } from '../base/lib-jitsi-meet';
4
+import {
5
+    detectAndroid,
6
+    detectIOS
7
+} from '../base/util';
4
 
8
 
5
-import { APP_WILL_MOUNT, APP_WILL_UNMOUNT } from './actionTypes';
9
+import {
10
+    APP_WILL_MOUNT,
11
+    APP_WILL_UNMOUNT,
12
+    APP_SET_PLATFORM
13
+} from './actionTypes';
6
 import {
14
 import {
7
     _getRoomAndDomainFromUrlString,
15
     _getRoomAndDomainFromUrlString,
8
     _getRouteToRender,
16
     _getRouteToRender,
31
  */
39
  */
32
 export function appNavigate(urlOrRoom) {
40
 export function appNavigate(urlOrRoom) {
33
     return (dispatch, getState) => {
41
     return (dispatch, getState) => {
34
-        const oldDomain = getDomain(getState());
42
+        const state = getState();
43
+        const oldDomain = getDomain(state);
35
 
44
 
36
         const { domain, room } = _getRoomAndDomainFromUrlString(urlOrRoom);
45
         const { domain, room } = _getRoomAndDomainFromUrlString(urlOrRoom);
37
 
46
 
40
         // current conference and start a new one with the new room name or
49
         // current conference and start a new one with the new room name or
41
         // domain.
50
         // domain.
42
 
51
 
43
-        if (typeof domain === 'undefined' || oldDomain === domain) {
52
+        if (room === 'mobile-app') {
53
+            return;
54
+        } else if (typeof domain === 'undefined' || oldDomain === domain) {
44
             // If both domain and room vars became undefined, that means we're
55
             // If both domain and room vars became undefined, that means we're
45
             // actually dealing with just room name and not with URL.
56
             // actually dealing with just room name and not with URL.
46
             dispatch(
57
             dispatch(
87
             // start to not make app re-render conference page for two times.
98
             // start to not make app re-render conference page for two times.
88
             dispatch(setRoom(room));
99
             dispatch(setRoom(room));
89
             dispatch(setConfig(config));
100
             dispatch(setConfig(config));
90
-            _navigate(getState());
91
         }
101
         }
92
     };
102
     };
93
 }
103
 }
108
     };
118
     };
109
 }
119
 }
110
 
120
 
121
+/**
122
+ * Detects the platform of user agent and
123
+ * signals that platform detected.
124
+ *
125
+ * @returns {Function}
126
+ */
127
+export function detectPlatform() {
128
+    return dispatch => {
129
+        if (detectAndroid()) {
130
+            dispatch(_setPlatform('android'));
131
+        } else if (detectIOS()) {
132
+            dispatch(_setPlatform('ios'));
133
+        }
134
+    };
135
+}
136
+
137
+/**
138
+ * Signals that user agent platform is mobile and it has
139
+ * been already detected.
140
+ *
141
+ * @param {string} platform - Mobile user agent platform.
142
+ * @returns {{type, platform: string}}
143
+ * @private
144
+ */
145
+export function _setPlatform(platform) {
146
+    return {
147
+        type: APP_SET_PLATFORM,
148
+        platform
149
+    };
150
+}
151
+
111
 /**
152
 /**
112
  * Signals that a specific App will unmount (in the terms of React).
153
  * Signals that a specific App will unmount (in the terms of React).
113
  *
154
  *
152
         dispatch(setRoom(newRoom));
193
         dispatch(setRoom(newRoom));
153
 
194
 
154
         const state = getState();
195
         const state = getState();
155
-        const room = state['features/base/conference'].room;
196
+        const { platform } = state['features/app'];
197
+        const { room } = state['features/base/conference'];
198
+        const { landingIsShown } = state['features/landing'];
156
 
199
 
157
-        if (room !== oldRoom) {
200
+        // If user agent is mobile browser and landing wasn't shown we
201
+        // should recheck which component to render.
202
+        if ((platform && !landingIsShown) || room !== oldRoom) {
158
             _navigate(state);
203
             _navigate(state);
159
         }
204
         }
160
     };
205
     };

+ 2
- 1
react/features/app/components/App.web.js Wyświetl plik

1
-import { appInit } from '../actions';
1
+import { appInit, detectPlatform } from '../actions';
2
 import { AbstractApp } from './AbstractApp';
2
 import { AbstractApp } from './AbstractApp';
3
 
3
 
4
 /**
4
 /**
22
     componentWillMount(...args) {
22
     componentWillMount(...args) {
23
         super.componentWillMount(...args);
23
         super.componentWillMount(...args);
24
 
24
 
25
+        this.props.store.dispatch(detectPlatform());
25
         this.props.store.dispatch(appInit());
26
         this.props.store.dispatch(appInit());
26
     }
27
     }
27
 
28
 

+ 35
- 0
react/features/app/functions.web.js Wyświetl plik

7
 import getTokenData from '../../../modules/tokendata/TokenData';
7
 import getTokenData from '../../../modules/tokendata/TokenData';
8
 import JitsiMeetLogStorage from '../../../modules/util/JitsiMeetLogStorage';
8
 import JitsiMeetLogStorage from '../../../modules/util/JitsiMeetLogStorage';
9
 
9
 
10
+import { detectIOS, detectAndroid } from '../base/util';
11
+
12
+// XXX We should import landing feature here in order to update router registry.
13
+import { Landing } from '../landing';
14
+import { Conference } from '../conference';
15
+import { WelcomePage } from '../welcome';
16
+
10
 const Logger = require('jitsi-meet-logger');
17
 const Logger = require('jitsi-meet-logger');
11
 
18
 
12
 export * from './functions.native';
19
 export * from './functions.native';
13
 
20
 
21
+/**
22
+ * Determines which route is to be rendered in order to depict a specific Redux
23
+ * store.
24
+ *
25
+ * @param {(Object|Function)} stateOrGetState - Redux state or Regux getState()
26
+ * method.
27
+ * @returns {Route}
28
+ */
29
+export function _getRouteToRender(stateOrGetState) {
30
+    const state
31
+        = typeof stateOrGetState === 'function'
32
+            ? stateOrGetState()
33
+            : stateOrGetState;
34
+
35
+    const { platform } = state['features/app'];
36
+    const { room } = state['features/base/conference'];
37
+    const { landingIsShown } = state['features/landing'];
38
+
39
+    let component = isRoomValid(room) ? Conference : WelcomePage;
40
+
41
+    // If landing was shown there is no need to show it again.
42
+    if (platform && !landingIsShown) {
43
+        component = detectAndroid() || detectIOS() ? Landing : component;
44
+    }
45
+
46
+    return RouteRegistry.getRouteByComponent(component);
47
+}
48
+
14
 /**
49
 /**
15
  * Temporary solution. Later we'll get rid of global APP and set its properties
50
  * Temporary solution. Later we'll get rid of global APP and set its properties
16
  * in redux store.
51
  * in redux store.

+ 12
- 1
react/features/app/reducer.js Wyświetl plik

1
 import { ReducerRegistry } from '../base/redux';
1
 import { ReducerRegistry } from '../base/redux';
2
 
2
 
3
-import { APP_WILL_MOUNT, APP_WILL_UNMOUNT } from './actionTypes';
3
+import {
4
+    APP_WILL_MOUNT,
5
+    APP_WILL_UNMOUNT,
6
+    APP_SET_PLATFORM
7
+} from './actionTypes';
4
 
8
 
5
 ReducerRegistry.register('features/app', (state = {}, action) => {
9
 ReducerRegistry.register('features/app', (state = {}, action) => {
6
     switch (action.type) {
10
     switch (action.type) {
28
             };
32
             };
29
         }
33
         }
30
         break;
34
         break;
35
+
36
+    case APP_SET_PLATFORM:
37
+        return {
38
+            ...state,
39
+            platform: action.platform
40
+        };
41
+
31
     }
42
     }
32
 
43
 
33
     return state;
44
     return state;

+ 0
- 20
react/features/base/util/detectDevices.js Wyświetl plik

21
 
21
 
22
     return false;
22
     return false;
23
 }
23
 }
24
-
25
-/**
26
- * Transforms hash map with parameters to query string.
27
- *
28
- * @param {Object} params - Hash map to be processed into query string.
29
- * @returns {string}
30
- */
31
-export function serializeQuery(params) {
32
-    return Object.keys(params).reduce((str, key, index) => {
33
-        const encodedKey = encodeURIComponent(key);
34
-        const encodedValue = encodeURIComponent(params[key]);
35
-        let separator = '&';
36
-
37
-        if (index === 0) {
38
-            separator = '?';
39
-        }
40
-
41
-        return `${str}${separator}${encodedKey}=${encodedValue}`;
42
-    }, '');
43
-}

+ 0
- 1
react/features/conference/route.js Wyświetl plik

5
 import ConferenceUrl from '../../../modules/URL/ConferenceUrl';
5
 import ConferenceUrl from '../../../modules/URL/ConferenceUrl';
6
 
6
 
7
 import { RouteRegistry } from '../base/navigator';
7
 import { RouteRegistry } from '../base/navigator';
8
-import { detectIOS, detectAndroid, serializeQuery } from '../base/util';
9
 import { Conference } from './components';
8
 import { Conference } from './components';
10
 
9
 
11
 const logger = require('jitsi-meet-logger').getLogger(__filename);
10
 const logger = require('jitsi-meet-logger').getLogger(__filename);

+ 18
- 10
react/features/landing/components/Landing.js Wyświetl plik

1
 import React, { Component } from 'react';
1
 import React, { Component } from 'react';
2
-import { Link } from 'react-router';
3
 import { connect } from 'react-redux';
2
 import { connect } from 'react-redux';
3
+import { Link } from 'react-router';
4
 import { landingIsShown } from '../actions';
4
 import { landingIsShown } from '../actions';
5
 
5
 
6
 const links = {
6
 const links = {
14
  * @class Landing
14
  * @class Landing
15
  */
15
  */
16
 class Landing extends Component {
16
 class Landing extends Component {
17
+
17
     /**
18
     /**
18
      * React lifecycle method triggered after
19
      * React lifecycle method triggered after
19
      * component is mount.
20
      * component is mount.
26
 
27
 
27
     static propTypes = {
28
     static propTypes = {
28
         dispatch: React.PropTypes.func,
29
         dispatch: React.PropTypes.func,
29
-        location: React.PropTypes.object
30
+        platform: React.PropTypes.string,
31
+        room: React.PropTypes.string
30
     };
32
     };
31
 
33
 
32
     /**
34
     /**
36
      * @returns {void}
38
      * @returns {void}
37
      */
39
      */
38
     componentWillMount() {
40
     componentWillMount() {
39
-        const { query } = this.props.location;
40
-        const { conferenceName, platform } = query;
41
+        const { room } = this.props;
41
         let btnText;
42
         let btnText;
42
         let link = '/';
43
         let link = '/';
43
 
44
 
44
-        if (conferenceName) {
45
+        if (room) {
45
             btnText = 'Join the conversation';
46
             btnText = 'Join the conversation';
46
-            link += conferenceName;
47
+            link += room;
47
         } else {
48
         } else {
48
             btnText = 'Start a conference';
49
             btnText = 'Start a conference';
49
         }
50
         }
50
 
51
 
51
         this.setState({
52
         this.setState({
52
             btnText,
53
             btnText,
53
-            link,
54
-            platform
54
+            link
55
         });
55
         });
56
     }
56
     }
57
 
57
 
61
      * @returns {ReactElement}
61
      * @returns {ReactElement}
62
      */
62
      */
63
     render() {
63
     render() {
64
-        const { btnText, link, platform } = this.state;
64
+        const { platform } = this.props;
65
+        const { btnText, link } = this.state;
65
         const primaryButtonClasses = 'landing__button landing__button_primary';
66
         const primaryButtonClasses = 'landing__button landing__button_primary';
66
 
67
 
67
         return (
68
         return (
94
     }
95
     }
95
 }
96
 }
96
 
97
 
97
-export default connect()(Landing);
98
+const mapStateToProps = state => {
99
+    return {
100
+        platform: state['features/app'].platform,
101
+        room: state['features/base/conference'].room
102
+    };
103
+};
104
+
105
+export default connect(mapStateToProps)(Landing);

+ 1
- 9
react/features/landing/route.js Wyświetl plik

3
 
3
 
4
 RouteRegistry.register({
4
 RouteRegistry.register({
5
     component: Landing,
5
     component: Landing,
6
-    path: '/mobile-app',
7
-    onEnter: store => () => {
8
-        const state = store.getState();
9
-        const { landingIsShown } = state;
10
-
11
-        if (landingIsShown) {
12
-            return;
13
-        }
14
-    }
6
+    path: '/mobile-app'
15
 });
7
 });

Ładowanie…
Anuluj
Zapisz