jiti-meet/react/features/welcome/components/WelcomePage.web.js

282 lines
8.8 KiB
JavaScript
Raw Normal View History

/* global interfaceConfig */
import React from 'react';
2017-03-01 02:55:12 +00:00
import { translate } from '../../base/i18n';
import { Platform, Watermarks } from '../../base/react';
2019-03-21 16:38:29 +00:00
import { connect } from '../../base/redux';
import { CalendarList } from '../../calendar-sync';
2018-08-01 16:41:54 +00:00
import { RecentList } from '../../recent-list';
import { SettingsButton, SETTINGS_TABS } from '../../settings';
import { AbstractWelcomePage, _mapStateToProps } from './AbstractWelcomePage';
import Tabs from './Tabs';
/**
2016-12-16 03:00:06 +00:00
* The Web container rendering the welcome page.
*
* @extends AbstractWelcomePage
*/
class WelcomePage extends AbstractWelcomePage {
/**
* Default values for {@code WelcomePage} component's properties.
*
* @static
*/
static defaultProps = {
_room: ''
};
/**
2016-12-16 03:00:06 +00:00
* Initializes a new WelcomePage instance.
*
* @param {Object} props - The read-only properties with which the new
* instance is to be initialized.
*/
constructor(props) {
super(props);
2016-12-16 03:00:06 +00:00
this.state = {
...this.state,
generateRoomnames:
interfaceConfig.GENERATE_ROOMNAMES_ON_WELCOME_PAGE,
selectedTab: 0
};
/**
* The HTML Element used as the container for additional content. Used
* for directly appending the additional content template to the dom.
*
* @private
* @type {HTMLTemplateElement|null}
*/
this._additionalContentRef = null;
/**
* The template to use as the main content for the welcome page. If
* not found then only the welcome page head will display.
*
* @private
* @type {HTMLTemplateElement|null}
*/
this._additionalContentTemplate = document.getElementById(
'welcome-page-additional-content-template');
2017-10-13 19:31:05 +00:00
// Bind event handlers so they are only bound once per instance.
this._onFormSubmit = this._onFormSubmit.bind(this);
2016-12-16 03:00:06 +00:00
this._onRoomChange = this._onRoomChange.bind(this);
this._setAdditionalContentRef
= this._setAdditionalContentRef.bind(this);
this._onTabSelected = this._onTabSelected.bind(this);
}
/**
* Implements React's {@link Component#componentDidMount()}. Invoked
* immediately after this component is mounted.
2016-12-16 03:00:06 +00:00
*
* @inheritdoc
* @returns {void}
*/
componentDidMount() {
document.body.classList.add('welcome-page');
2019-07-08 18:50:13 +00:00
document.title = interfaceConfig.APP_NAME;
if (this.state.generateRoomnames) {
this._updateRoomname();
}
if (this._shouldShowAdditionalContent()) {
this._additionalContentRef.appendChild(
this._additionalContentTemplate.content.cloneNode(true));
}
}
/**
* Removes the classname used for custom styling of the welcome page.
*
* @inheritdoc
* @returns {void}
*/
componentWillUnmount() {
super.componentWillUnmount();
document.body.classList.remove('welcome-page');
}
/**
* Implements React's {@link Component#render()}.
*
* @inheritdoc
* @returns {ReactElement|null}
*/
render() {
const { t } = this.props;
const { APP_NAME } = interfaceConfig;
const showAdditionalContent = this._shouldShowAdditionalContent();
return (
<div
className = { `welcome ${showAdditionalContent
? 'with-content' : 'without-content'}` }
id = 'welcome_page'>
<div className = 'welcome-watermark'>
<Watermarks />
</div>
<div className = 'header'>
<div className = 'welcome-page-settings'>
<SettingsButton
defaultTab = { SETTINGS_TABS.CALENDAR } />
</div>
<div className = 'header-image' />
<div className = 'header-text'>
<h1 className = 'header-text-title'>
{ t('welcomepage.title') }
</h1>
<p className = 'header-text-description'>
{ t('welcomepage.appDescription',
{ app: APP_NAME }) }
</p>
</div>
<div id = 'enter_room'>
<div className = 'enter-room-input-container'>
<div className = 'enter-room-title'>
{ t('welcomepage.enterRoomTitle') }
</div>
<form onSubmit = { this._onFormSubmit }>
<input
autoFocus = { true }
className = 'enter-room-input'
id = 'enter_room_field'
onChange = { this._onRoomChange }
2019-09-13 09:40:23 +00:00
pattern = '^[a-zA-Z0-9=\?]+$'
placeholder = { this.state.roomPlaceholder }
title = { t('welcomepage.onlyAsciiAllowed') }
type = 'text'
value = { this.state.room } />
</form>
</div>
<div
className = 'welcome-page-button'
id = 'enter_room_button'
onClick = { this._onJoin }>
{ t('welcomepage.go') }
</div>
</div>
{ this._renderTabs() }
</div>
{ showAdditionalContent
? <div
className = 'welcome-page-content'
ref = { this._setAdditionalContentRef } />
: null }
</div>
);
}
/**
* Prevents submission of the form and delegates join logic.
*
* @param {Event} event - The HTML Event which details the form submission.
* @private
* @returns {void}
*/
_onFormSubmit(event) {
event.preventDefault();
this._onJoin();
}
2016-12-16 03:00:06 +00:00
/**
* Overrides the super to account for the differences in the argument types
* provided by HTML and React Native text inputs.
*
* @inheritdoc
* @override
* @param {Event} event - The (HTML) Event which details the change such as
* the EventTarget.
* @protected
*/
_onRoomChange(event) {
super._onRoomChange(event.target.value);
}
/**
* Callback invoked when the desired tab to display should be changed.
*
* @param {number} tabIndex - The index of the tab within the array of
* displayed tabs.
* @private
* @returns {void}
*/
_onTabSelected(tabIndex) {
this.setState({ selectedTab: tabIndex });
}
/**
* Renders tabs to show previous meetings and upcoming calendar events. The
* tabs are purposefully hidden on mobile browsers.
*
* @returns {ReactElement|null}
*/
_renderTabs() {
const isMobileBrowser
= Platform.OS === 'android' || Platform.OS === 'ios';
if (isMobileBrowser) {
return null;
}
const { _calendarEnabled, t } = this.props;
const tabs = [];
if (_calendarEnabled) {
tabs.push({
label: t('welcomepage.calendar'),
content: <CalendarList />
});
}
tabs.push({
label: t('welcomepage.recentList'),
content: <RecentList />
});
return (
<Tabs
onSelect = { this._onTabSelected }
selected = { this.state.selectedTab }
tabs = { tabs } />);
}
/**
* Sets the internal reference to the HTMLDivElement used to hold the
* welcome page content.
*
* @param {HTMLDivElement} el - The HTMLElement for the div that is the root
* of the welcome page content.
* @private
* @returns {void}
*/
_setAdditionalContentRef(el) {
this._additionalContentRef = el;
}
/**
* Returns whether or not additional content should be displayed below
* the welcome page's header for entering a room name.
*
* @private
* @returns {boolean}
*/
_shouldShowAdditionalContent() {
return interfaceConfig.DISPLAY_WELCOME_PAGE_CONTENT
&& this._additionalContentTemplate
&& this._additionalContentTemplate.content
&& this._additionalContentTemplate.innerHTML.trim();
}
}
export default translate(connect(_mapStateToProps)(WelcomePage));