feat(unsupported-browser): show dial-in for mobile

- Move the existing components for the static dial in page into
  a separate folder for easier reuse.
- Reuse those components for displaying dial-on numbers on the
  mobile page for unsupported browsers.
- Modify those components to support having tel protocol
  links on the dial-in numbers.
- Have DialInSummary, formerly DialInInfoPage, respect a
  passed in className prop for easier styling differences.
This commit is contained in:
Leonard Kim 2018-02-20 17:25:22 -08:00 committed by Дамян Минков
parent 68b710a222
commit 1f82ce3d19
11 changed files with 113 additions and 16 deletions

View File

@ -1,7 +1,9 @@
.unsupported-mobile-browser {
background-color: #fff;
height: 100vh;
overflow: auto;
padding: 35px 0;
position: relative;
width: 100vw;
a {
@ -12,6 +14,7 @@
color: $unsupportedBrowserTextColor;
margin: auto;
max-width: 40em;
padding-bottom: 40px;
text-align: center;
width: 75%;
@ -20,7 +23,8 @@
}
}
&__text {
&__text,
.unsupported-dial-in {
font-size: 1.2em;
line-height: em(29px, 21px);
margin-bottom: 0.65em;
@ -65,4 +69,22 @@
}
}
}
.unsupported-dial-in {
display: none;
&.has-numbers {
align-items: center;
display: flex;
flex-direction: column;
}
.dial-in-numbers-list {
color: $unsupportedBrowserTextColor;
}
.dial-in-numbers-body {
vertical-align: top;
}
}
}

View File

@ -5,14 +5,16 @@ import { I18nextProvider } from 'react-i18next';
import parseURLParams from '../../../base/config/parseURLParams';
import { i18next } from '../../../base/i18n';
import DialInInfoPage from './DialInInfoPage';
import { DialInSummary } from '../dial-in-summary';
document.addEventListener('DOMContentLoaded', () => {
const params = parseURLParams(window.location, true, 'search');
ReactDOM.render(
<I18nextProvider i18n = { i18next }>
<DialInInfoPage
<DialInSummary
className = 'dial-in-page'
clickableNumbers = { false }
room = { params.room } />
</I18nextProvider>,
document.getElementById('react')

View File

@ -14,13 +14,24 @@ import NumbersList from './NumbersList';
*
* @extends Component
*/
class DialInInfoPage extends Component {
class DialInSummary extends Component {
/**
* {@code DialInInfoPage} component's property types.
* {@code DialInSummary} component's property types.
*
* @static
*/
static propTypes = {
/**
* Additional CSS classnames to append to the root of the component.
*/
className: PropTypes.string,
/**
* Whether or not numbers should include links with the telephone
* protocol.
*/
clickableNumbers: PropTypes.bool,
/**
* The name of the conference to show a conferenceID for.
*/
@ -33,7 +44,7 @@ class DialInInfoPage extends Component {
};
/**
* {@code DialInInfoPage} component's local state.
* {@code DialInSummary} component's local state.
*
* @type {Object}
* @property {number} conferenceID - The numeric ID of the conference, used
@ -53,12 +64,13 @@ class DialInInfoPage extends Component {
};
/**
* Initializes a new {@code DialInInfoPage} instance.
* Initializes a new {@code DialInSummary} instance.
*
* @param {Object} props - The read-only properties with which the new
* instance is to be initialized.
*/
constructor(props) {
console.warn(props);
super(props);
// Bind event handlers so they are only bound once for every instance.
@ -97,6 +109,7 @@ class DialInInfoPage extends Component {
* @returns {ReactElement}
*/
render() {
let className = '';
let contents;
const { conferenceID, error, loading, numbersEnabled } = this.state;
@ -108,6 +121,7 @@ class DialInInfoPage extends Component {
} else if (error) {
contents = error;
} else {
className = 'has-numbers';
contents = [
conferenceID
? <ConferenceID
@ -115,13 +129,14 @@ class DialInInfoPage extends Component {
key = 'conferenceID' />
: null,
<NumbersList
clickableNumbers = { this.props.clickableNumbers }
key = 'numbers'
numbers = { this.state.numbers } />
];
}
return (
<div className = 'dial-in-page'>
<div className = { `${this.props.className} ${className}` }>
{ contents }
</div>
);
@ -217,4 +232,4 @@ class DialInInfoPage extends Component {
}
}
export default translate(DialInInfoPage);
export default translate(DialInSummary);

View File

@ -15,6 +15,12 @@ class NumbersList extends Component {
* @static
*/
static propTypes = {
/**
* Whether or not numbers should include links with the telephone
* protocol.
*/
clickableNumbers: PropTypes.bool,
/**
* The phone numbers to display. Can be an array of numbers
* or an object with countries as keys and an array of numbers
@ -51,7 +57,7 @@ class NumbersList extends Component {
<th>{ t('info.numbers') }</th>
</tr>
</thead>
<tbody>
<tbody className = 'dial-in-numbers-body'>
{ showWithoutCountries
? numbers.map(this._renderNumberRow)
: this._renderWithCountries() }
@ -69,7 +75,8 @@ class NumbersList extends Component {
const rows = [];
for (const [ country, numbers ] of Object.entries(this.props.numbers)) {
const formattedNumbers = numbers.map(this._renderNumberDiv);
const formattedNumbers = numbers.map(
number => this._renderNumberDiv(number));
rows.push(
<tr key = { country }>
@ -93,7 +100,7 @@ class NumbersList extends Component {
return (
<tr key = { number }>
<td className = 'dial-in-number'>
{ number }
{ this._renderNumberLink(number) }
</td>
</tr>
);
@ -111,10 +118,34 @@ class NumbersList extends Component {
<div
className = 'dial-in-number'
key = { number }>
{ number }
{ this._renderNumberLink(number) }
</div>
);
}
/**
* Renders a ReactElement for displaying a telephone number. If the
* component prop {@code clickableNumbers} is true, then the number will
* have a link with the telephone protocol.
*
* @param {string} number - The phone number to display.
* @private
* @returns {ReactElement}
*/
_renderNumberLink(number) {
if (this.props.clickableNumbers) {
return (
<a
href = { `tel:${number}` }
key = { number } >
{ number }
</a>
);
}
return number;
}
}
export default translate(NumbersList);

View File

@ -0,0 +1 @@
export { default as DialInSummary } from './DialInSummary';

View File

@ -1,3 +1,4 @@
export { default as AddPeopleDialog } from './AddPeopleDialog';
export { default as InfoDialogButton } from './InfoDialogButton';
export { default as InviteButton } from './InviteButton';
export { DialInSummary } from './dial-in-summary';

View File

@ -2,10 +2,11 @@
import PropTypes from 'prop-types';
import React, { Component } from 'react';
import { connect } from 'react-redux';
import { translate, translateToHTML } from '../../base/i18n';
import { Platform } from '../../base/react';
import { DialInSummary } from '../../invite';
import HideNotificationBarStyle from './HideNotificationBarStyle';
declare var interfaceConfig: Object;
@ -54,6 +55,11 @@ class UnsupportedMobileBrowser extends Component<*, *> {
* @static
*/
static propTypes = {
/**
* The name of the conference attempting to being joined.
*/
_room: PropTypes.string,
/**
* The function to translate human-readable text.
*
@ -122,12 +128,31 @@ class UnsupportedMobileBrowser extends Component<*, *> {
{ t(`${_TNS}.downloadApp`) }
</button>
</a>
<DialInSummary
className = 'unsupported-dial-in'
clickableNumbers = { true }
room = { this.props._room } />
</div>
<HideNotificationBarStyle />
</div>
);
}
}
export default translate(UnsupportedMobileBrowser);
/**
* Maps (parts of) the Redux state to the associated props for the
* {@code UnsupportedMobileBrowser} component.
*
* @param {Object} state - The Redux state.
* @private
* @returns {{
* _room: string
* }}
*/
function _mapStateToProps(state) {
return {
_room: state['features/base/conference'].room
};
}
export default translate(connect(_mapStateToProps)(UnsupportedMobileBrowser));