Comply w/ coding style

This commit is contained in:
Lyubomir Marinov 2017-01-25 16:11:44 -06:00
parent 1fa4a53a48
commit cbcee201f0
13 changed files with 304 additions and 280 deletions

View File

@ -131,6 +131,6 @@ $linkHoverFontColor: #287ade;
/**
* Landing
*/
$primaryUnsupportedBrowserButtonBgColor: #17a0db;
$unsupportedBrowserButtonBgColor: #ff9a00;
$unsupportedBrowserTextColor: #4a4a4a;
$primaryUnsupportedBrowserButtonBgColor: #17a0db;

View File

@ -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 */

View File

@ -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;
}
}

View File

@ -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);

View File

@ -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());
};
}

View File

@ -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,9 +211,10 @@ export class AbstractApp extends Component {
* @returns {void}
*/
_navigate(route) {
const currentRoute = this.state.route || {};
if (RouteRegistry.areRoutesEqual(this.state.route, route)) {
return;
}
if (!RouteRegistry.areRoutesEqual(route, currentRoute)) {
let nextState = {
...this.state,
route
@ -222,18 +223,17 @@ export class AbstractApp extends Component {
// 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.
// (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.
// 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
@ -243,7 +243,6 @@ export class AbstractApp extends Component {
nextState && this.setState(nextState);
}
}
/**
* Notifies this App that a specific Route is about to be rendered.

View File

@ -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.
*

View File

@ -1,3 +1,3 @@
export * from './interceptComponent';
export * from './loadScript';
export * from './roomnameGenerator';
export * from './componentInterceptor';

View File

@ -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,8 +18,8 @@ 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;
@ -30,7 +27,7 @@ const RULES = [
= state['features/unsupported-browser'];
if ((OS === 'android' || OS === 'ios') && !mobileBrowserPageIsShown) {
return MobileBrowserPage;
return UnsupportedMobileBrowser;
}
}
];
@ -54,7 +51,6 @@ export function interceptComponent(stateOrGetState, currentComponent) {
for (const rule of RULES) {
result = rule(state);
if (result) {
break;
}

View File

@ -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>
);
}
}

View File

@ -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>
);
}
}

View File

@ -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);

View File

@ -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';