Comply w/ coding style
This commit is contained in:
parent
1fa4a53a48
commit
cbcee201f0
|
@ -131,6 +131,6 @@ $linkHoverFontColor: #287ade;
|
|||
/**
|
||||
* Landing
|
||||
*/
|
||||
$primaryUnsupportedBrowserButtonBgColor: #17a0db;
|
||||
$unsupportedBrowserButtonBgColor: #ff9a00;
|
||||
$unsupportedBrowserTextColor: #4a4a4a;
|
||||
$primaryUnsupportedBrowserButtonBgColor: #17a0db;
|
||||
|
|
|
@ -67,7 +67,7 @@
|
|||
@import '404';
|
||||
@import 'policy';
|
||||
@import 'filmstrip';
|
||||
@import 'unsupported-browser/mobile-browser-page';
|
||||
@import 'unsupported-browser/unsupported_browser';
|
||||
@import 'unsupported-browser/unsupported-desktop-browser';
|
||||
@import 'unsupported-browser/unsupported-mobile-browser';
|
||||
|
||||
/* Modules END */
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
.browser {
|
||||
display: inline-block;
|
||||
margin: 1em 7px;
|
||||
width: 138px;
|
||||
vertical-align: middle;
|
||||
.supported-browser {
|
||||
color: #929391;
|
||||
display: inline-block;
|
||||
font-size: 20px;
|
||||
margin: 1em 7px;
|
||||
vertical-align: middle;
|
||||
width: 138px;
|
||||
|
||||
&__button {
|
||||
background-color: #62c82a;
|
||||
|
@ -12,11 +12,11 @@
|
|||
border-radius: 10px;
|
||||
color: #FFFFFF;
|
||||
font-size: 12px;
|
||||
height: 26px;
|
||||
margin: 15px auto 0px auto;
|
||||
padding-top: 13px;
|
||||
text-align: center;
|
||||
width: 115px;
|
||||
height: 26px;
|
||||
padding-top: 13px;
|
||||
margin: 15px auto 0px auto;
|
||||
}
|
||||
|
||||
&__link {
|
||||
|
@ -45,39 +45,39 @@
|
|||
margin: 20px auto 0px auto;
|
||||
|
||||
&_chrome {
|
||||
width: 78px;
|
||||
height: 78px;
|
||||
background-image: url('../../images/chrome.png');
|
||||
height: 78px;
|
||||
width: 78px;
|
||||
}
|
||||
|
||||
&_chromium {
|
||||
width: 77px;
|
||||
height: 78px;
|
||||
background-image: url('../../images/chromium.png');
|
||||
height: 78px;
|
||||
width: 77px;
|
||||
}
|
||||
|
||||
&_firefox {
|
||||
width: 86px;
|
||||
height: 80px;
|
||||
background-image: url('../../images/firefox.png');
|
||||
height: 80px;
|
||||
width: 86px;
|
||||
}
|
||||
|
||||
&_opera {
|
||||
width: 73px;
|
||||
height: 78px;
|
||||
background-image: url('../../images/opera.png');
|
||||
height: 78px;
|
||||
width: 73px;
|
||||
}
|
||||
|
||||
&_ie {
|
||||
width: 80px;
|
||||
height: 78px;
|
||||
background-image: url('../../images/ie.png');
|
||||
height: 78px;
|
||||
width: 80px;
|
||||
}
|
||||
|
||||
&_safari {
|
||||
width: 78px;
|
||||
height: 79px;
|
||||
background-image: url('../../images/safari.png');
|
||||
height: 79px;
|
||||
width: 78px;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -91,30 +91,30 @@
|
|||
}
|
||||
|
||||
&__tile {
|
||||
width: 138px;
|
||||
height: 163px;
|
||||
margin-top: 5px;
|
||||
background-color: #e8e8e8;
|
||||
border: 1px solid #cfcfcf;
|
||||
border-radius: 10px;
|
||||
height: 163px;
|
||||
margin-top: 5px;
|
||||
width: 138px;
|
||||
}
|
||||
}
|
||||
|
||||
.unsupported-browser {
|
||||
.unsupported-desktop-browser {
|
||||
display: block;
|
||||
position: absolute;
|
||||
width:500px;
|
||||
height: 565px;
|
||||
overflow:hidden;
|
||||
text-align: center;
|
||||
margin: auto;
|
||||
overflow:hidden;
|
||||
position: absolute;
|
||||
text-align: center;
|
||||
top: 0; left: 0; bottom: 0; right: 0;
|
||||
width:500px;
|
||||
|
||||
&__page {
|
||||
display:inline-block;
|
||||
font-size: 28px;
|
||||
vertical-align:middle;
|
||||
padding-top: 25px;
|
||||
vertical-align:middle;
|
||||
}
|
||||
|
||||
&__title {
|
||||
|
@ -123,10 +123,10 @@
|
|||
}
|
||||
|
||||
&-wrapper {
|
||||
background: #fff;
|
||||
display: block;
|
||||
height: 100%;
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: #fff;
|
||||
}
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
.mobile-browser-page {
|
||||
.unsupported-mobile-browser {
|
||||
background-color: #fff;
|
||||
height: 100vh;
|
||||
padding: 35px 0;
|
||||
|
@ -22,9 +22,9 @@
|
|||
margin-bottom: 0.65em;
|
||||
|
||||
&_small {
|
||||
font-size: 1.5em;
|
||||
margin-bottom: 1em;
|
||||
margin-top: em(21, 18);
|
||||
font-size: 1.5em;
|
||||
|
||||
strong {
|
||||
font-size: em(21, 18);
|
|
@ -42,13 +42,7 @@ export function appNavigate(urlOrRoom) {
|
|||
// domain.
|
||||
|
||||
if (typeof domain === 'undefined' || oldDomain === domain) {
|
||||
// If both domain and room vars became undefined, that means we're
|
||||
// actually dealing with just room name and not with URL.
|
||||
dispatch(
|
||||
_setRoomAndNavigate(
|
||||
typeof room === 'undefined' && typeof domain === 'undefined'
|
||||
? urlOrRoom
|
||||
: room));
|
||||
dispatchSetRoomAndNavigate();
|
||||
} else if (oldDomain !== domain) {
|
||||
// Update domain without waiting for config to be loaded to prevent
|
||||
// race conditions when we will start to load config multiple times.
|
||||
|
@ -61,14 +55,7 @@ export function appNavigate(urlOrRoom) {
|
|||
.then(
|
||||
config => configLoaded(/* err */ undefined, config),
|
||||
err => configLoaded(err, /* config */ undefined))
|
||||
.then(() => {
|
||||
const link = typeof room === 'undefined'
|
||||
&& typeof domain === 'undefined'
|
||||
? urlOrRoom
|
||||
: room;
|
||||
|
||||
dispatch(_setRoomAndNavigate(link));
|
||||
});
|
||||
.then(dispatchSetRoomAndNavigate);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -94,6 +81,21 @@ export function appNavigate(urlOrRoom) {
|
|||
|
||||
dispatch(setConfig(config));
|
||||
}
|
||||
|
||||
/**
|
||||
* Dispatches _setRoomAndNavigate in the Redux store.
|
||||
*
|
||||
* @returns {void}
|
||||
*/
|
||||
function dispatchSetRoomAndNavigate() {
|
||||
// If both domain and room vars became undefined, that means we're
|
||||
// actually dealing with just room name and not with URL.
|
||||
dispatch(
|
||||
_setRoomAndNavigate(
|
||||
typeof room === 'undefined' && typeof domain === 'undefined'
|
||||
? urlOrRoom
|
||||
: room));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -129,6 +131,21 @@ export function appWillUnmount(app) {
|
|||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Navigates to a route in accord with a specific Redux state.
|
||||
*
|
||||
* @param {Object} state - The Redux state which determines/identifies the route
|
||||
* to navigate to.
|
||||
* @private
|
||||
* @returns {void}
|
||||
*/
|
||||
function _navigate(state) {
|
||||
const app = state['features/app'].app;
|
||||
const routeToRender = _getRouteToRender(state);
|
||||
|
||||
app._navigate(routeToRender);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets room and navigates to new route if needed.
|
||||
*
|
||||
|
@ -139,11 +156,6 @@ export function appWillUnmount(app) {
|
|||
function _setRoomAndNavigate(newRoom) {
|
||||
return (dispatch, getState) => {
|
||||
dispatch(setRoom(newRoom));
|
||||
|
||||
const state = getState();
|
||||
const { app } = state['features/app'];
|
||||
const newRoute = _getRouteToRender(state);
|
||||
|
||||
app._navigate(newRoute);
|
||||
_navigate(getState());
|
||||
};
|
||||
}
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
import React, { Component } from 'react';
|
||||
import { Provider } from 'react-redux';
|
||||
|
||||
import { RouteRegistry } from '../../base/navigator';
|
||||
import {
|
||||
localParticipantJoined,
|
||||
localParticipantLeft
|
||||
} from '../../base/participants';
|
||||
import { RouteRegistry } from '../../base/navigator';
|
||||
|
||||
import {
|
||||
appNavigate,
|
||||
|
@ -32,7 +32,7 @@ export class AbstractApp extends Component {
|
|||
* The URL, if any, with which the app was launched.
|
||||
*/
|
||||
url: React.PropTypes.string
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes a new App instance.
|
||||
|
@ -211,38 +211,37 @@ export class AbstractApp extends Component {
|
|||
* @returns {void}
|
||||
*/
|
||||
_navigate(route) {
|
||||
const currentRoute = this.state.route || {};
|
||||
|
||||
if (!RouteRegistry.areRoutesEqual(route, currentRoute)) {
|
||||
let nextState = {
|
||||
...this.state,
|
||||
route
|
||||
};
|
||||
|
||||
// The Web App was using react-router so it utilized react-router's
|
||||
// onEnter. During the removal of react-router, modifications were
|
||||
// minimized by preserving the onEnter interface:
|
||||
// (1) Router would provide its nextState to the Route's onEnter.
|
||||
// As the role of Router is now this AbstractApp, provide its
|
||||
// nextState.
|
||||
// (2) A replace function would be provided to the Route in case it
|
||||
// chose to redirect to another path.
|
||||
this._onRouteEnter(route, nextState, pathname => {
|
||||
// FIXME In order to minimize the modifications related to the
|
||||
// removal of react-router, the Web implementation is provided
|
||||
// bellow because the replace function is used on Web only at
|
||||
// the time of this writing. Provide a platform-agnostic
|
||||
// implementation. It should likely find the best Route matching
|
||||
// the specified pathname and navigate to it.
|
||||
window.location.pathname = pathname;
|
||||
|
||||
// Do not proceed with the route because it chose to redirect to
|
||||
// another path.
|
||||
nextState = undefined;
|
||||
});
|
||||
|
||||
nextState && this.setState(nextState);
|
||||
if (RouteRegistry.areRoutesEqual(this.state.route, route)) {
|
||||
return;
|
||||
}
|
||||
|
||||
let nextState = {
|
||||
...this.state,
|
||||
route
|
||||
};
|
||||
|
||||
// The Web App was using react-router so it utilized react-router's
|
||||
// onEnter. During the removal of react-router, modifications were
|
||||
// minimized by preserving the onEnter interface:
|
||||
// (1) Router would provide its nextState to the Route's onEnter. As the
|
||||
// role of Router is now this AbstractApp, provide its nextState.
|
||||
// (2) A replace function would be provided to the Route in case it
|
||||
// chose to redirect to another path.
|
||||
this._onRouteEnter(route, nextState, pathname => {
|
||||
// FIXME In order to minimize the modifications related to the
|
||||
// removal of react-router, the Web implementation is provided
|
||||
// bellow because the replace function is used on Web only at the
|
||||
// time of this writing. Provide a platform-agnostic implementation.
|
||||
// It should likely find the best Route matching the specified
|
||||
// pathname and navigate to it.
|
||||
window.location.pathname = pathname;
|
||||
|
||||
// Do not proceed with the route because it chose to redirect to
|
||||
// another path.
|
||||
nextState = undefined;
|
||||
});
|
||||
|
||||
nextState && this.setState(nextState);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -11,20 +11,6 @@
|
|||
* without needing to create additional inter-feature dependencies.
|
||||
*/
|
||||
class RouteRegistry {
|
||||
/**
|
||||
* Method checking whether route objects are equal by value. Returns true if
|
||||
* and only if key values of the first object are equal to key values of
|
||||
* the second one.
|
||||
*
|
||||
* @param {Object} newRoute - New route object to be compared.
|
||||
* @param {Object} oldRoute - Old route object to be compared.
|
||||
* @returns {boolean}
|
||||
*/
|
||||
areRoutesEqual(newRoute, oldRoute) {
|
||||
return Object.keys(newRoute)
|
||||
.every(key => newRoute[key] === oldRoute[key]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes a new RouteRegistry instance.
|
||||
*/
|
||||
|
@ -37,6 +23,31 @@ class RouteRegistry {
|
|||
this._routeRegistry = new Set();
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines whether two specific Routes are equal i.e. they describe one
|
||||
* and the same abstract route.
|
||||
*
|
||||
* @param {Object} a - The Route to compare to b.
|
||||
* @param {Object} b - The Route to compare to a.
|
||||
* @returns {boolean} True if the specified a and b describe one and the
|
||||
* same abstract route; otherwise, false.
|
||||
*/
|
||||
areRoutesEqual(a, b) {
|
||||
if (a === b) { // reflexive
|
||||
return true;
|
||||
}
|
||||
if (!a) {
|
||||
return !b;
|
||||
}
|
||||
if (!b) {
|
||||
return !a;
|
||||
}
|
||||
|
||||
return (
|
||||
Object.keys(a).every(key => a[key] === b[key])
|
||||
&& /* symmetric */ this.areRoutesEqual(b, a));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all registered routes.
|
||||
*
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
export * from './interceptComponent';
|
||||
export * from './loadScript';
|
||||
export * from './roomnameGenerator';
|
||||
export * from './componentInterceptor';
|
||||
|
|
|
@ -1,8 +1,5 @@
|
|||
import { Platform } from '../react';
|
||||
|
||||
import {
|
||||
MobileBrowserPage
|
||||
} from '../../unsupported-browser';
|
||||
import { UnsupportedMobileBrowser } from '../../unsupported-browser';
|
||||
|
||||
/**
|
||||
* Array of rules defining whether we should intercept component to render
|
||||
|
@ -21,16 +18,16 @@ const RULES = [
|
|||
* WebRTC support on Android).
|
||||
*
|
||||
* @param {Object} state - Object containing Redux state.
|
||||
* @returns {MobileBrowserPage|void} If the rule is satisfied then
|
||||
* we should intercept existing component by MobileBrowserPage.
|
||||
* @returns {UnsupportedMobileBrowser|void} If the rule is satisfied then
|
||||
* we should intercept existing component by UnsupportedMobileBrowser.
|
||||
*/
|
||||
state => {
|
||||
const OS = Platform.OS;
|
||||
const { mobileBrowserPageIsShown }
|
||||
= state['features/unsupported-browser'];
|
||||
= state['features/unsupported-browser'];
|
||||
|
||||
if ((OS === 'android' || OS === 'ios') && !mobileBrowserPageIsShown) {
|
||||
return MobileBrowserPage;
|
||||
return UnsupportedMobileBrowser;
|
||||
}
|
||||
}
|
||||
];
|
||||
|
@ -49,12 +46,11 @@ export function interceptComponent(stateOrGetState, currentComponent) {
|
|||
let result;
|
||||
const state
|
||||
= typeof stateOrGetState === 'function'
|
||||
? stateOrGetState()
|
||||
: stateOrGetState;
|
||||
? stateOrGetState()
|
||||
: stateOrGetState;
|
||||
|
||||
for (const rule of RULES) {
|
||||
result = rule(state);
|
||||
|
||||
if (result) {
|
||||
break;
|
||||
}
|
|
@ -1,119 +0,0 @@
|
|||
import React, { Component } from 'react';
|
||||
|
||||
/**
|
||||
* Array of all supported browsers.
|
||||
*/
|
||||
const SUPPORTED_BROWSERS = [
|
||||
{
|
||||
link: 'http://google.com/chrome',
|
||||
name: 'chrome',
|
||||
plugin: false,
|
||||
title: 'Chrome 44+'
|
||||
}, {
|
||||
link: 'http://www.chromium.org/',
|
||||
name: 'chromium',
|
||||
plugin: false,
|
||||
title: 'Chromium 44+'
|
||||
}, {
|
||||
link: 'http://www.opera.com',
|
||||
name: 'opera',
|
||||
plugin: false,
|
||||
title: 'Opera 32+'
|
||||
}, {
|
||||
link: 'http://www.getfirefox.com/',
|
||||
name: 'firefox',
|
||||
plugin: false,
|
||||
title: 'Firefox and Iceweasel 40+'
|
||||
}, {
|
||||
link: 'https://temasys.atlassian.net/wiki/display/TWPP/WebRTC+Plugins',
|
||||
name: 'ie',
|
||||
plugin: 'Temasys 0.8.854+',
|
||||
title: 'IE'
|
||||
}, {
|
||||
link: 'https://temasys.atlassian.net/wiki/display/TWPP/WebRTC+Plugins',
|
||||
name: 'safari',
|
||||
plugin: 'Temasys 0.8.854+',
|
||||
title: 'Safari'
|
||||
}
|
||||
];
|
||||
|
||||
/**
|
||||
* React component representing unsupported browser page.
|
||||
*
|
||||
* @class UnsupportedBrowserPage
|
||||
*/
|
||||
export default class UnsupportedBrowserPage extends Component {
|
||||
/**
|
||||
* Renders the component.
|
||||
*
|
||||
* @returns {ReactElement}
|
||||
*/
|
||||
render() {
|
||||
return (
|
||||
<div className = 'unsupported-browser-wrapper'>
|
||||
<div className = 'unsupported-browser'>
|
||||
<div className = 'unsupported-browser__content'>
|
||||
<h2 className = 'unsupported-browser__title'>
|
||||
This application is currently only supported by
|
||||
</h2>
|
||||
{ this._getSupportedBrowsersLayout() }
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates layout for the list of supported browsers.
|
||||
*
|
||||
* @returns {ReactElement}
|
||||
* @private
|
||||
*/
|
||||
_getSupportedBrowsersLayout() {
|
||||
return (
|
||||
<div className = 'browser-list'>
|
||||
{ SUPPORTED_BROWSERS.map(this._getSupportedBrowser) }
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Method that generated layout for supported browser object.
|
||||
*
|
||||
* @param {Object} browser - Object containing information about supported
|
||||
* browser.
|
||||
* @returns {ReactElement}
|
||||
* @private
|
||||
*/
|
||||
_getSupportedBrowser(browser) {
|
||||
let pluginHtml = null;
|
||||
const logoClassName = `browser__logo browser__logo_${browser.name}`;
|
||||
|
||||
// Browsers not supporting WebRTC could support application
|
||||
// with Temasys plugin installed.
|
||||
if (browser.plugin) {
|
||||
const className = 'browser__text_small';
|
||||
|
||||
pluginHtml = <p className = { className }>({ browser.plugin })</p>;
|
||||
}
|
||||
|
||||
return (
|
||||
<div
|
||||
className = 'browser'
|
||||
key = { browser.name }>
|
||||
<div className = 'browser__text'>
|
||||
{ browser.title }
|
||||
{ pluginHtml }
|
||||
</div>
|
||||
<div className = 'browser__tile'>
|
||||
<div className = { logoClassName } />
|
||||
<a
|
||||
className = 'browser__link'
|
||||
href = { browser.link }>
|
||||
<div className = 'browser__button'>DOWNLOAD</div>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,125 @@
|
|||
import React, { Component } from 'react';
|
||||
|
||||
/**
|
||||
* The list of all browsers supported by the application.
|
||||
*/
|
||||
const SUPPORTED_BROWSERS = [
|
||||
{
|
||||
link: 'http://google.com/chrome',
|
||||
name: 'chrome',
|
||||
title: 'Chrome 44+'
|
||||
}, {
|
||||
link: 'http://www.chromium.org/',
|
||||
name: 'chromium',
|
||||
title: 'Chromium 44+'
|
||||
}, {
|
||||
link: 'http://www.getfirefox.com/',
|
||||
name: 'firefox',
|
||||
title: 'Firefox and Iceweasel 40+'
|
||||
}, {
|
||||
link: 'http://www.opera.com',
|
||||
name: 'opera',
|
||||
title: 'Opera 32+'
|
||||
}, {
|
||||
link: 'https://temasys.atlassian.net/wiki/display/TWPP/WebRTC+Plugins',
|
||||
name: 'ie',
|
||||
plugin: 'Temasys 0.8.854+',
|
||||
title: 'IE'
|
||||
}, {
|
||||
link: 'https://temasys.atlassian.net/wiki/display/TWPP/WebRTC+Plugins',
|
||||
name: 'safari',
|
||||
plugin: 'Temasys 0.8.854+',
|
||||
title: 'Safari'
|
||||
}
|
||||
];
|
||||
|
||||
/**
|
||||
* React component representing unsupported browser page.
|
||||
*
|
||||
* @class UnsupportedDesktopBrowser
|
||||
*/
|
||||
export default class UnsupportedDesktopBrowser extends Component {
|
||||
/**
|
||||
* Renders the component.
|
||||
*
|
||||
* @returns {ReactElement}
|
||||
*/
|
||||
render() {
|
||||
const ns = 'unsupported-desktop-browser';
|
||||
|
||||
return (
|
||||
<div className = { `${ns}-wrapper` }>
|
||||
<div className = { ns }>
|
||||
<div className = { `${ns}__content` }>
|
||||
<h2 className = { `${ns}__title` }>
|
||||
This application is currently only supported by
|
||||
</h2>
|
||||
{
|
||||
this._renderSupportedBrowsers()
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders a specific browser supported by the application.
|
||||
*
|
||||
* @param {Object} browser - The (information about the) browser supported
|
||||
* by the application to render.
|
||||
* @private
|
||||
* @returns {ReactElement}
|
||||
*/
|
||||
_renderSupportedBrowser(browser) {
|
||||
const { link, name, plugin, title } = browser;
|
||||
const ns = 'supported-browser';
|
||||
|
||||
// Browsers which do not support WebRTC could support the application
|
||||
// with the Temasys plugin.
|
||||
const pluginElement
|
||||
= plugin
|
||||
? <p className = { `${ns}__text_small` }>{ plugin }</p>
|
||||
: null;
|
||||
|
||||
return (
|
||||
<div
|
||||
className = { ns }
|
||||
key = { name }>
|
||||
<div className = { `${ns}__text` }>
|
||||
{
|
||||
title
|
||||
}
|
||||
{
|
||||
pluginElement
|
||||
}
|
||||
</div>
|
||||
<div className = { `${ns}__tile` }>
|
||||
<div
|
||||
className = { `${ns}__logo ${ns}__logo_${name}` } />
|
||||
<a
|
||||
className = { `${ns}__link` }
|
||||
href = { link }>
|
||||
<div className = { `${ns}__button` }>DOWNLOAD</div>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders the list of browsers supported by the application.
|
||||
*
|
||||
* @private
|
||||
* @returns {ReactElement}
|
||||
*/
|
||||
_renderSupportedBrowsers() {
|
||||
return (
|
||||
<div className = 'supported-browser-list'>
|
||||
{
|
||||
SUPPORTED_BROWSERS.map(this._renderSupportedBrowser)
|
||||
}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
|
@ -1,9 +1,9 @@
|
|||
import React, { Component } from 'react';
|
||||
import { connect } from 'react-redux';
|
||||
|
||||
import { appNavigate } from '../../app';
|
||||
import { Platform } from '../../base/react';
|
||||
|
||||
import { appNavigate } from '../../app';
|
||||
import { mobileBrowserPageIsShown } from '../actions';
|
||||
|
||||
/**
|
||||
|
@ -18,12 +18,21 @@ const URLS = {
|
|||
/**
|
||||
* React component representing mobile browser page.
|
||||
*
|
||||
* @class MobileBrowserPage
|
||||
* @class UnsupportedMobileBrowser
|
||||
*/
|
||||
class MobileBrowserPage extends Component {
|
||||
class UnsupportedMobileBrowser extends Component {
|
||||
/**
|
||||
* Mobile browser page component's property types.
|
||||
*
|
||||
* @static
|
||||
*/
|
||||
static propTypes = {
|
||||
dispatch: React.PropTypes.func,
|
||||
room: React.PropTypes.string
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor of MobileBrowserPage component.
|
||||
* Constructor of UnsupportedMobileBrowser component.
|
||||
*
|
||||
* @param {Object} props - The read-only React Component props with which
|
||||
* the new instance is to be initialized.
|
||||
|
@ -35,16 +44,6 @@ class MobileBrowserPage extends Component {
|
|||
this._onClickJoin = this._onClickJoin.bind(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Mobile browser page component's property types.
|
||||
*
|
||||
* @static
|
||||
*/
|
||||
static propTypes = {
|
||||
dispatch: React.PropTypes.func,
|
||||
room: React.PropTypes.string
|
||||
};
|
||||
|
||||
/**
|
||||
* React lifecycle method triggered after component is mounted.
|
||||
*
|
||||
|
@ -62,13 +61,14 @@ class MobileBrowserPage extends Component {
|
|||
componentWillMount() {
|
||||
const { room } = this.props;
|
||||
let btnText;
|
||||
let link = '';
|
||||
let link;
|
||||
|
||||
if (room) {
|
||||
btnText = 'Join the conversation';
|
||||
link += room;
|
||||
link = room;
|
||||
} else {
|
||||
btnText = 'Start a conference';
|
||||
link = '';
|
||||
}
|
||||
|
||||
this.setState({
|
||||
|
@ -77,38 +77,23 @@ class MobileBrowserPage extends Component {
|
|||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Navigates to the next state of the app.
|
||||
*
|
||||
* @returns {void}
|
||||
* @private
|
||||
*/
|
||||
_onClickJoin() {
|
||||
const { link } = this.state;
|
||||
|
||||
this.props.dispatch(appNavigate(link));
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders component.
|
||||
*
|
||||
* @returns {ReactElement}
|
||||
*/
|
||||
render() {
|
||||
const { btnText } = this.state;
|
||||
const blockPrefix = 'mobile-browser-page';
|
||||
const textClasses = `${blockPrefix}__text ${blockPrefix}__text_small`;
|
||||
let primaryButtonClasses = `${blockPrefix}__button`;
|
||||
|
||||
primaryButtonClasses += ` ${blockPrefix}__button_primary`;
|
||||
const ns = 'unsupported-mobile-browser';
|
||||
const primaryButtonClasses
|
||||
= `${ns}__button ${ns}__button_primary`;
|
||||
|
||||
return (
|
||||
<div className = { blockPrefix }>
|
||||
<div className = { `${blockPrefix}__body` }>
|
||||
<div className = { ns }>
|
||||
<div className = { `${ns}__body` }>
|
||||
<img
|
||||
className = { `${blockPrefix}__logo` }
|
||||
className = { `${ns}__logo` }
|
||||
src = '/images/logo-blue.svg' />
|
||||
<p className = { `${blockPrefix}__text` }>
|
||||
<p className = { `${ns}__text` }>
|
||||
You need <strong>Jitsi Meet</strong> to join a
|
||||
conversation on your mobile
|
||||
</p>
|
||||
|
@ -117,24 +102,37 @@ class MobileBrowserPage extends Component {
|
|||
Download the App
|
||||
</button>
|
||||
</a>
|
||||
<p className = { textClasses }>
|
||||
<p className = { `${ns}__text ${ns}__text_small` }>
|
||||
or if you already have it
|
||||
<br />
|
||||
<strong>then</strong>
|
||||
</p>
|
||||
<button
|
||||
className = 'mobile-browser-page__button'
|
||||
className = { `${ns}__button` }
|
||||
onClick = { this._onClickJoin }>
|
||||
{ btnText }
|
||||
{
|
||||
this.state.btnText
|
||||
}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Navigates to the next state of the app.
|
||||
*
|
||||
* @private
|
||||
* @returns {void}
|
||||
*/
|
||||
_onClickJoin() {
|
||||
this.props.dispatch(appNavigate(this.state.link));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Maps (parts of) the Redux state to the associated MobileBrowserPage's props.
|
||||
* Maps (parts of) the Redux state to the associated UnsupportedMobileBrowser's
|
||||
* props.
|
||||
*
|
||||
* @param {Object} state - Redux state.
|
||||
* @returns {{
|
||||
|
@ -147,4 +145,4 @@ function mapStateToProps(state) {
|
|||
};
|
||||
}
|
||||
|
||||
export default connect(mapStateToProps)(MobileBrowserPage);
|
||||
export default connect(mapStateToProps)(UnsupportedMobileBrowser);
|
|
@ -1,2 +1,4 @@
|
|||
export { default as MobileBrowserPage } from './MobileBrowserPage';
|
||||
export { default as UnsupportedBrowserPage } from './UnsupportedBrowserPage';
|
||||
export { default as UnsupportedDesktopBrowser }
|
||||
from './UnsupportedDesktopBrowser';
|
||||
export { default as UnsupportedMobileBrowser }
|
||||
from './UnsupportedMobileBrowser';
|
||||
|
|
Loading…
Reference in New Issue