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:
parent
68b710a222
commit
1f82ce3d19
|
@ -1,7 +1,9 @@
|
||||||
.unsupported-mobile-browser {
|
.unsupported-mobile-browser {
|
||||||
background-color: #fff;
|
background-color: #fff;
|
||||||
height: 100vh;
|
height: 100vh;
|
||||||
|
overflow: auto;
|
||||||
padding: 35px 0;
|
padding: 35px 0;
|
||||||
|
position: relative;
|
||||||
width: 100vw;
|
width: 100vw;
|
||||||
|
|
||||||
a {
|
a {
|
||||||
|
@ -12,6 +14,7 @@
|
||||||
color: $unsupportedBrowserTextColor;
|
color: $unsupportedBrowserTextColor;
|
||||||
margin: auto;
|
margin: auto;
|
||||||
max-width: 40em;
|
max-width: 40em;
|
||||||
|
padding-bottom: 40px;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
width: 75%;
|
width: 75%;
|
||||||
|
|
||||||
|
@ -20,7 +23,8 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&__text {
|
&__text,
|
||||||
|
.unsupported-dial-in {
|
||||||
font-size: 1.2em;
|
font-size: 1.2em;
|
||||||
line-height: em(29px, 21px);
|
line-height: em(29px, 21px);
|
||||||
margin-bottom: 0.65em;
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,14 +5,16 @@ import { I18nextProvider } from 'react-i18next';
|
||||||
import parseURLParams from '../../../base/config/parseURLParams';
|
import parseURLParams from '../../../base/config/parseURLParams';
|
||||||
import { i18next } from '../../../base/i18n';
|
import { i18next } from '../../../base/i18n';
|
||||||
|
|
||||||
import DialInInfoPage from './DialInInfoPage';
|
import { DialInSummary } from '../dial-in-summary';
|
||||||
|
|
||||||
document.addEventListener('DOMContentLoaded', () => {
|
document.addEventListener('DOMContentLoaded', () => {
|
||||||
const params = parseURLParams(window.location, true, 'search');
|
const params = parseURLParams(window.location, true, 'search');
|
||||||
|
|
||||||
ReactDOM.render(
|
ReactDOM.render(
|
||||||
<I18nextProvider i18n = { i18next }>
|
<I18nextProvider i18n = { i18next }>
|
||||||
<DialInInfoPage
|
<DialInSummary
|
||||||
|
className = 'dial-in-page'
|
||||||
|
clickableNumbers = { false }
|
||||||
room = { params.room } />
|
room = { params.room } />
|
||||||
</I18nextProvider>,
|
</I18nextProvider>,
|
||||||
document.getElementById('react')
|
document.getElementById('react')
|
||||||
|
|
|
@ -14,13 +14,24 @@ import NumbersList from './NumbersList';
|
||||||
*
|
*
|
||||||
* @extends Component
|
* @extends Component
|
||||||
*/
|
*/
|
||||||
class DialInInfoPage extends Component {
|
class DialInSummary extends Component {
|
||||||
/**
|
/**
|
||||||
* {@code DialInInfoPage} component's property types.
|
* {@code DialInSummary} component's property types.
|
||||||
*
|
*
|
||||||
* @static
|
* @static
|
||||||
*/
|
*/
|
||||||
static propTypes = {
|
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.
|
* 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}
|
* @type {Object}
|
||||||
* @property {number} conferenceID - The numeric ID of the conference, used
|
* @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
|
* @param {Object} props - The read-only properties with which the new
|
||||||
* instance is to be initialized.
|
* instance is to be initialized.
|
||||||
*/
|
*/
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
|
console.warn(props);
|
||||||
super(props);
|
super(props);
|
||||||
|
|
||||||
// Bind event handlers so they are only bound once for every instance.
|
// Bind event handlers so they are only bound once for every instance.
|
||||||
|
@ -97,6 +109,7 @@ class DialInInfoPage extends Component {
|
||||||
* @returns {ReactElement}
|
* @returns {ReactElement}
|
||||||
*/
|
*/
|
||||||
render() {
|
render() {
|
||||||
|
let className = '';
|
||||||
let contents;
|
let contents;
|
||||||
|
|
||||||
const { conferenceID, error, loading, numbersEnabled } = this.state;
|
const { conferenceID, error, loading, numbersEnabled } = this.state;
|
||||||
|
@ -108,6 +121,7 @@ class DialInInfoPage extends Component {
|
||||||
} else if (error) {
|
} else if (error) {
|
||||||
contents = error;
|
contents = error;
|
||||||
} else {
|
} else {
|
||||||
|
className = 'has-numbers';
|
||||||
contents = [
|
contents = [
|
||||||
conferenceID
|
conferenceID
|
||||||
? <ConferenceID
|
? <ConferenceID
|
||||||
|
@ -115,13 +129,14 @@ class DialInInfoPage extends Component {
|
||||||
key = 'conferenceID' />
|
key = 'conferenceID' />
|
||||||
: null,
|
: null,
|
||||||
<NumbersList
|
<NumbersList
|
||||||
|
clickableNumbers = { this.props.clickableNumbers }
|
||||||
key = 'numbers'
|
key = 'numbers'
|
||||||
numbers = { this.state.numbers } />
|
numbers = { this.state.numbers } />
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className = 'dial-in-page'>
|
<div className = { `${this.props.className} ${className}` }>
|
||||||
{ contents }
|
{ contents }
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
@ -217,4 +232,4 @@ class DialInInfoPage extends Component {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default translate(DialInInfoPage);
|
export default translate(DialInSummary);
|
|
@ -15,6 +15,12 @@ class NumbersList extends Component {
|
||||||
* @static
|
* @static
|
||||||
*/
|
*/
|
||||||
static propTypes = {
|
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
|
* The phone numbers to display. Can be an array of numbers
|
||||||
* or an object with countries as keys and 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>
|
<th>{ t('info.numbers') }</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody className = 'dial-in-numbers-body'>
|
||||||
{ showWithoutCountries
|
{ showWithoutCountries
|
||||||
? numbers.map(this._renderNumberRow)
|
? numbers.map(this._renderNumberRow)
|
||||||
: this._renderWithCountries() }
|
: this._renderWithCountries() }
|
||||||
|
@ -69,7 +75,8 @@ class NumbersList extends Component {
|
||||||
const rows = [];
|
const rows = [];
|
||||||
|
|
||||||
for (const [ country, numbers ] of Object.entries(this.props.numbers)) {
|
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(
|
rows.push(
|
||||||
<tr key = { country }>
|
<tr key = { country }>
|
||||||
|
@ -93,7 +100,7 @@ class NumbersList extends Component {
|
||||||
return (
|
return (
|
||||||
<tr key = { number }>
|
<tr key = { number }>
|
||||||
<td className = 'dial-in-number'>
|
<td className = 'dial-in-number'>
|
||||||
{ number }
|
{ this._renderNumberLink(number) }
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
);
|
);
|
||||||
|
@ -111,10 +118,34 @@ class NumbersList extends Component {
|
||||||
<div
|
<div
|
||||||
className = 'dial-in-number'
|
className = 'dial-in-number'
|
||||||
key = { number }>
|
key = { number }>
|
||||||
{ number }
|
{ this._renderNumberLink(number) }
|
||||||
</div>
|
</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);
|
export default translate(NumbersList);
|
|
@ -0,0 +1 @@
|
||||||
|
export { default as DialInSummary } from './DialInSummary';
|
|
@ -1,3 +1,4 @@
|
||||||
export { default as AddPeopleDialog } from './AddPeopleDialog';
|
export { default as AddPeopleDialog } from './AddPeopleDialog';
|
||||||
export { default as InfoDialogButton } from './InfoDialogButton';
|
export { default as InfoDialogButton } from './InfoDialogButton';
|
||||||
export { default as InviteButton } from './InviteButton';
|
export { default as InviteButton } from './InviteButton';
|
||||||
|
export { DialInSummary } from './dial-in-summary';
|
||||||
|
|
|
@ -2,10 +2,11 @@
|
||||||
|
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import React, { Component } from 'react';
|
import React, { Component } from 'react';
|
||||||
|
import { connect } from 'react-redux';
|
||||||
|
|
||||||
import { translate, translateToHTML } from '../../base/i18n';
|
import { translate, translateToHTML } from '../../base/i18n';
|
||||||
import { Platform } from '../../base/react';
|
import { Platform } from '../../base/react';
|
||||||
|
import { DialInSummary } from '../../invite';
|
||||||
import HideNotificationBarStyle from './HideNotificationBarStyle';
|
import HideNotificationBarStyle from './HideNotificationBarStyle';
|
||||||
|
|
||||||
declare var interfaceConfig: Object;
|
declare var interfaceConfig: Object;
|
||||||
|
@ -54,6 +55,11 @@ class UnsupportedMobileBrowser extends Component<*, *> {
|
||||||
* @static
|
* @static
|
||||||
*/
|
*/
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
|
/**
|
||||||
|
* The name of the conference attempting to being joined.
|
||||||
|
*/
|
||||||
|
_room: PropTypes.string,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The function to translate human-readable text.
|
* The function to translate human-readable text.
|
||||||
*
|
*
|
||||||
|
@ -122,12 +128,31 @@ class UnsupportedMobileBrowser extends Component<*, *> {
|
||||||
{ t(`${_TNS}.downloadApp`) }
|
{ t(`${_TNS}.downloadApp`) }
|
||||||
</button>
|
</button>
|
||||||
</a>
|
</a>
|
||||||
|
<DialInSummary
|
||||||
|
className = 'unsupported-dial-in'
|
||||||
|
clickableNumbers = { true }
|
||||||
|
room = { this.props._room } />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<HideNotificationBarStyle />
|
<HideNotificationBarStyle />
|
||||||
</div>
|
</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));
|
||||||
|
|
Loading…
Reference in New Issue