Introduce Platform in React
React Native provides a Platform abstraction which React does not provide.
This commit is contained in:
parent
7de5c9c1d2
commit
62bafcaf63
|
@ -1,16 +1,5 @@
|
|||
import { Symbol } from '../base/react';
|
||||
|
||||
/**
|
||||
* The type of this action sets the platform of user agent in order to decide to
|
||||
* show the landing or not.
|
||||
*
|
||||
* {
|
||||
* type: APP_SET_PLATFORM,
|
||||
* platform: string
|
||||
* }
|
||||
*/
|
||||
export const APP_SET_PLATFORM = Symbol('APP_SET_PLATFORM');
|
||||
|
||||
/**
|
||||
* The type of the actions which signals that a specific App will mount (in the
|
||||
* terms of React).
|
||||
|
|
|
@ -1,16 +1,9 @@
|
|||
import { setRoom } from '../base/conference';
|
||||
import { getDomain, setDomain } from '../base/connection';
|
||||
import { loadConfig, setConfig } from '../base/lib-jitsi-meet';
|
||||
import {
|
||||
detectAndroid,
|
||||
detectIOS
|
||||
} from '../base/util';
|
||||
import { Platform } from '../base/react';
|
||||
|
||||
import {
|
||||
APP_WILL_MOUNT,
|
||||
APP_WILL_UNMOUNT,
|
||||
APP_SET_PLATFORM
|
||||
} from './actionTypes';
|
||||
import { APP_WILL_MOUNT, APP_WILL_UNMOUNT } from './actionTypes';
|
||||
import {
|
||||
_getRoomAndDomainFromUrlString,
|
||||
_getRouteToRender,
|
||||
|
@ -134,21 +127,6 @@ export function appWillUnmount(app) {
|
|||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Detects the platform of user agent and signals that platform detected.
|
||||
*
|
||||
* @returns {Function}
|
||||
*/
|
||||
export function detectPlatform() {
|
||||
return dispatch => {
|
||||
if (detectAndroid()) {
|
||||
dispatch(_setPlatform('android'));
|
||||
} else if (detectIOS()) {
|
||||
dispatch(_setPlatform('ios'));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Navigates to route corresponding to current room name.
|
||||
*
|
||||
|
@ -163,23 +141,6 @@ function _navigate(state) {
|
|||
app._navigate(routeToRender);
|
||||
}
|
||||
|
||||
/**
|
||||
* Signals that user agent platform is mobile and it has been already detected.
|
||||
*
|
||||
* @param {string} platform - Mobile user agent platform.
|
||||
* @returns {{
|
||||
* type: APP_SET_PLATFORM,
|
||||
* platform: string
|
||||
* }}
|
||||
* @private
|
||||
*/
|
||||
function _setPlatform(platform) {
|
||||
return {
|
||||
type: APP_SET_PLATFORM,
|
||||
platform
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets room and navigates to new route if needed.
|
||||
*
|
||||
|
@ -194,13 +155,15 @@ function _setRoomAndNavigate(newRoom) {
|
|||
dispatch(setRoom(newRoom));
|
||||
|
||||
const state = getState();
|
||||
const { platform } = state['features/app'];
|
||||
const { room } = state['features/base/conference'];
|
||||
const { landingIsShown } = state['features/landing'];
|
||||
const { landingIsShown } = state['features/unsupported-browser'];
|
||||
|
||||
// If user agent is mobile browser and landing wasn't shown we
|
||||
// should recheck which component to render.
|
||||
if ((platform && !landingIsShown) || room !== oldRoom) {
|
||||
// If the user agent is a mobile browser and landing hasn't been shown
|
||||
// yet, we should recheck which component to render.
|
||||
const OS = Platform.OS;
|
||||
|
||||
if (((OS === 'android' || OS === 'ios') && !landingIsShown)
|
||||
|| room !== oldRoom) {
|
||||
_navigate(state);
|
||||
}
|
||||
};
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { appInit, detectPlatform } from '../actions';
|
||||
import { appInit } from '../actions';
|
||||
import { AbstractApp } from './AbstractApp';
|
||||
|
||||
/**
|
||||
|
@ -22,7 +22,6 @@ export class App extends AbstractApp {
|
|||
componentWillMount(...args) {
|
||||
super.componentWillMount(...args);
|
||||
|
||||
this.props.store.dispatch(detectPlatform());
|
||||
this.props.store.dispatch(appInit());
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,12 @@
|
|||
/* global APP, JitsiMeetJS, loggingConfig */
|
||||
|
||||
import { isRoomValid } from '../base/conference';
|
||||
import { RouteRegistry } from '../base/navigator';
|
||||
import { Platform } from '../base/react';
|
||||
import { Conference } from '../conference';
|
||||
import { Landing } from '../unsupported-browser';
|
||||
import { WelcomePage } from '../welcome';
|
||||
|
||||
import URLProcessor from '../../../modules/config/URLProcessor';
|
||||
import KeyboardShortcut
|
||||
from '../../../modules/keyboardshortcut/keyboardshortcut';
|
||||
|
@ -7,13 +14,6 @@ import settings from '../../../modules/settings/Settings';
|
|||
import getTokenData from '../../../modules/tokendata/TokenData';
|
||||
import JitsiMeetLogStorage from '../../../modules/util/JitsiMeetLogStorage';
|
||||
|
||||
import { detectIOS, detectAndroid } from '../base/util';
|
||||
|
||||
// XXX We should import landing feature here in order to update router registry.
|
||||
import { Landing } from '../landing';
|
||||
import { Conference } from '../conference';
|
||||
import { WelcomePage } from '../welcome';
|
||||
|
||||
const Logger = require('jitsi-meet-logger');
|
||||
|
||||
export { _getRoomAndDomainFromUrlString } from './functions.native';
|
||||
|
@ -27,20 +27,22 @@ export { _getRoomAndDomainFromUrlString } from './functions.native';
|
|||
* @returns {Route}
|
||||
*/
|
||||
export function _getRouteToRender(stateOrGetState) {
|
||||
const OS = Platform.OS;
|
||||
const state
|
||||
= typeof stateOrGetState === 'function'
|
||||
? stateOrGetState()
|
||||
: stateOrGetState;
|
||||
|
||||
const { platform } = state['features/app'];
|
||||
const { room } = state['features/base/conference'];
|
||||
const { landingIsShown } = state['features/landing'];
|
||||
// If landing was shown, there is no need to show it again.
|
||||
const { landingIsShown } = state['features/unsupported-browser'];
|
||||
let component;
|
||||
|
||||
let component = isRoomValid(room) ? Conference : WelcomePage;
|
||||
if ((OS === 'android' || OS === 'ios') && !landingIsShown) {
|
||||
component = Landing;
|
||||
} else {
|
||||
const { room } = state['features/base/conference'];
|
||||
|
||||
// If landing was shown there is no need to show it again.
|
||||
if (platform && !landingIsShown) {
|
||||
component = detectAndroid() || detectIOS() ? Landing : component;
|
||||
component = isRoomValid(room) ? Conference : WelcomePage;
|
||||
}
|
||||
|
||||
return RouteRegistry.getRouteByComponent(component);
|
||||
|
|
|
@ -1,10 +1,6 @@
|
|||
import { ReducerRegistry } from '../base/redux';
|
||||
|
||||
import {
|
||||
APP_WILL_MOUNT,
|
||||
APP_WILL_UNMOUNT,
|
||||
APP_SET_PLATFORM
|
||||
} from './actionTypes';
|
||||
import { APP_WILL_MOUNT, APP_WILL_UNMOUNT } from './actionTypes';
|
||||
|
||||
ReducerRegistry.register('features/app', (state = {}, action) => {
|
||||
switch (action.type) {
|
||||
|
@ -32,13 +28,6 @@ ReducerRegistry.register('features/app', (state = {}, action) => {
|
|||
};
|
||||
}
|
||||
break;
|
||||
|
||||
case APP_SET_PLATFORM:
|
||||
return {
|
||||
...state,
|
||||
platform: action.platform
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
return state;
|
||||
|
|
|
@ -1,17 +0,0 @@
|
|||
/**
|
||||
* Returns true if user agent is run on Android.
|
||||
*
|
||||
* @returns {boolean}
|
||||
*/
|
||||
export function detectAndroid() {
|
||||
return Boolean(navigator.userAgent.match(/Android/i));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if user agent is run on iOS.
|
||||
*
|
||||
* @returns {boolean}
|
||||
*/
|
||||
export function detectIOS() {
|
||||
return Boolean(navigator.userAgent.match(/iP(ad|hone|od)/i));
|
||||
}
|
|
@ -1,3 +1,2 @@
|
|||
export * from './detectDevices';
|
||||
export * from './loadScript';
|
||||
export * from './roomnameGenerator';
|
||||
|
|
|
@ -1,21 +0,0 @@
|
|||
import { ReducerRegistry } from '../base/redux';
|
||||
|
||||
import { LANDING_IS_SHOWN } from './actionTypes';
|
||||
|
||||
ReducerRegistry.register('features/landing', (state = {}, action) => {
|
||||
switch (action.type) {
|
||||
case LANDING_IS_SHOWN:
|
||||
return {
|
||||
...state,
|
||||
|
||||
/**
|
||||
* Flag that shows that mobile landing is shown.
|
||||
*
|
||||
* @type {boolean}
|
||||
*/
|
||||
landingIsShown: true
|
||||
};
|
||||
}
|
||||
|
||||
return state;
|
||||
});
|
|
@ -2,11 +2,17 @@ import React, { Component } from 'react';
|
|||
import { connect } from 'react-redux';
|
||||
import { Link } from 'react-router';
|
||||
|
||||
import { Platform } from '../../base/react';
|
||||
|
||||
import { landingIsShown } from '../actions';
|
||||
|
||||
const LINKS = {
|
||||
'android': 'https://play.google.com/store/apps/details?id=org.jitsi.meet',
|
||||
'ios': 'https://itunes.apple.com/us/app/jitsi-meet/id1165103905'
|
||||
/**
|
||||
* The map of platforms to URLs at which the mobile app for the associated
|
||||
* platform is available for download.
|
||||
*/
|
||||
const URLS = {
|
||||
android: 'https://play.google.com/store/apps/details?id=org.jitsi.meet',
|
||||
ios: 'https://itunes.apple.com/us/app/jitsi-meet/id1165103905'
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -15,9 +21,13 @@ const LINKS = {
|
|||
* @class Landing
|
||||
*/
|
||||
class Landing extends Component {
|
||||
/**
|
||||
* Landing component's property types.
|
||||
*
|
||||
* @static
|
||||
*/
|
||||
static propTypes = {
|
||||
dispatch: React.PropTypes.func,
|
||||
platform: React.PropTypes.string,
|
||||
room: React.PropTypes.string
|
||||
}
|
||||
|
||||
|
@ -59,7 +69,6 @@ class Landing extends Component {
|
|||
* @returns {ReactElement}
|
||||
*/
|
||||
render() {
|
||||
const { platform } = this.props;
|
||||
const { btnText, link } = this.state;
|
||||
const primaryButtonClasses = 'landing__button landing__button_primary';
|
||||
|
||||
|
@ -70,22 +79,23 @@ class Landing extends Component {
|
|||
className = 'landing__logo'
|
||||
src = '/images/logo-blue.svg' />
|
||||
<p className = 'landing__text'>
|
||||
You need <strong>Jitsi Meet</strong> to join a
|
||||
conversation on your mobile
|
||||
You need <strong>Jitsi Meet</strong> to join a
|
||||
conversation on your mobile
|
||||
</p>
|
||||
<a href = { LINKS[platform] }>
|
||||
<button
|
||||
className = { primaryButtonClasses }>
|
||||
<a href = { URLS[Platform.OS] }>
|
||||
<button className = { primaryButtonClasses }>
|
||||
Download the App
|
||||
</button>
|
||||
</a>
|
||||
<p className = 'landing__text landing__text_small'>
|
||||
or if you already have it
|
||||
<br /><strong>then</strong>
|
||||
or if you already have it
|
||||
<br />
|
||||
<strong>then</strong>
|
||||
</p>
|
||||
<Link to = { link }>
|
||||
<button
|
||||
className = 'landing__button'>{ btnText }</button>
|
||||
<button className = 'landing__button'>
|
||||
{ btnText }
|
||||
</button>
|
||||
</Link>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -98,13 +108,11 @@ class Landing extends Component {
|
|||
*
|
||||
* @param {Object} state - Redux state.
|
||||
* @returns {{
|
||||
* platform: string,
|
||||
* room: string
|
||||
* }}
|
||||
*/
|
||||
function mapStateToProps(state) {
|
||||
return {
|
||||
platform: state['features/app'].platform,
|
||||
room: state['features/base/conference'].room
|
||||
};
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
import { ReducerRegistry } from '../base/redux';
|
||||
|
||||
import { LANDING_IS_SHOWN } from './actionTypes';
|
||||
|
||||
ReducerRegistry.register(
|
||||
'features/unsupported-browser',
|
||||
(state = {}, action) => {
|
||||
switch (action.type) {
|
||||
case LANDING_IS_SHOWN:
|
||||
return {
|
||||
...state,
|
||||
|
||||
/**
|
||||
* Flag that shows that mobile landing is shown.
|
||||
*
|
||||
* @type {boolean}
|
||||
*/
|
||||
landingIsShown: true
|
||||
};
|
||||
}
|
||||
|
||||
return state;
|
||||
});
|
Loading…
Reference in New Issue