@ -20,12 +20,6 @@ import Tabs from './Tabs';
* /
export const ROOM _NAME _VALIDATE _PATTERN _STR = '^[^?&:\u0022\u0027%#]+$' ;
/ * *
* Maximum number of pixels corresponding to a mobile layout .
* @ type { number }
* /
const WINDOW _WIDTH _THRESHOLD = 425 ;
/ * *
* The Web container rendering the welcome page .
*
@ -78,6 +72,17 @@ class WelcomePage extends AbstractWelcomePage {
* /
this . _additionalToolbarContentRef = null ;
this . _additionalCardRef = null ;
/ * *
* The template to use as the additional card displayed near the main one .
*
* @ private
* @ type { HTMLTemplateElement | null }
* /
this . _additionalCardTemplate = document . getElementById (
'welcome-page-additional-card-template' ) ;
/ * *
* The template to use as the main content for the welcome page . If
* not found then only the welcome page head will display .
@ -102,12 +107,14 @@ class WelcomePage extends AbstractWelcomePage {
// Bind event handlers so they are only bound once per instance.
this . _onFormSubmit = this . _onFormSubmit . bind ( this ) ;
this . _onRoomChange = this . _onRoomChange . bind ( this ) ;
this . _setAdditionalCardRef = this . _setAdditionalCardRef . bind ( this ) ;
this . _setAdditionalContentRef
= this . _setAdditionalContentRef . bind ( this ) ;
this . _setRoomInputRef = this . _setRoomInputRef . bind ( this ) ;
this . _setAdditionalToolbarContentRef
= this . _setAdditionalToolbarContentRef . bind ( this ) ;
this . _onTabSelected = this . _onTabSelected . bind ( this ) ;
this . _renderFooter = this . _renderFooter . bind ( this ) ;
}
/ * *
@ -137,6 +144,12 @@ class WelcomePage extends AbstractWelcomePage {
this . _additionalToolbarContentTemplate . content . cloneNode ( true )
) ;
}
if ( this . _shouldShowAdditionalCard ( ) ) {
this . _additionalCardRef . appendChild (
this . _additionalCardTemplate . content . cloneNode ( true )
) ;
}
}
/ * *
@ -159,10 +172,10 @@ class WelcomePage extends AbstractWelcomePage {
* /
render ( ) {
const { _moderatedRoomServiceUrl , t } = this . props ;
const { APP _NAME , DEFAULT _WELCOME _PAGE _LOGO _URL } = interfaceConfig ;
const { DEFAULT _WELCOME _PAGE _LOGO _URL , DISPLAY _WELCOME _FOOTER } = interfaceConfig ;
const showAdditionalCard = this . _shouldShowAdditionalCard ( ) ;
const showAdditionalContent = this . _shouldShowAdditionalContent ( ) ;
const showAdditionalToolbarContent = this . _shouldShowAdditionalToolbarContent ( ) ;
const showResponsiveText = this . _shouldShowResponsiveText ( ) ;
return (
< div
@ -172,6 +185,7 @@ class WelcomePage extends AbstractWelcomePage {
< div className = 'welcome-watermark' >
< Watermarks defaultJitsiLogoURL = { DEFAULT _WELCOME _PAGE _LOGO _URL } / >
< / d i v >
< div className = 'header' >
< div className = 'welcome-page-settings' >
< SettingsButton
@ -184,64 +198,82 @@ class WelcomePage extends AbstractWelcomePage {
}
< / d i v >
< div className = 'header-image' / >
< div className = 'header-text ' >
< div className = 'header-container ' >
< h1 className = 'header-text-title' >
{ t ( 'welcomepage.title ' ) }
{ t ( 'welcomepage.jitsiMeet ' ) }
< / h 1 >
< p className = 'header-text-description' >
{ t ( 'welcomepage.appDescription' ,
{ app : APP _NAME } ) }
< / p >
< / d i v >
< div id = 'enter_room' >
< div className = 'enter-room-input-container' >
< div className = 'enter-room-title' >
{ t ( 'welcomepage.enterRoomTitle' ) }
< span className = 'header-text-subtitle' >
{ t ( 'welcomepage.secureMeetings' ) }
< / s p a n >
< div id = 'enter_room' >
< div className = 'enter-room-input-container' >
< form onSubmit = { this . _onFormSubmit } >
< input
aria - disabled = 'false'
aria - label = 'Meeting name input'
autoFocus = { true }
className = 'enter-room-input'
id = 'enter_room_field'
onChange = { this . _onRoomChange }
pattern = { ROOM _NAME _VALIDATE _PATTERN _STR }
placeholder = { this . state . roomPlaceholder }
ref = { this . _setRoomInputRef }
title = { t ( 'welcomepage.roomNameAllowedChars' ) }
type = 'text'
value = { this . state . room } / >
< div
className = { _moderatedRoomServiceUrl
? 'warning-with-link'
: 'warning-without-link' } >
{ this . _renderInsecureRoomNameWarning ( ) }
< / d i v >
< / f o r m >
< / d i v >
< form onSubmit = { this . _onFormSubmit } >
< input
autoFocus = { true }
className = 'enter-room-input'
id = 'enter_room_field'
onChange = { this . _onRoomChange }
pattern = { ROOM _NAME _VALIDATE _PATTERN _STR }
placeholder = { this . state . roomPlaceholder }
ref = { this . _setRoomInputRef }
title = { t ( 'welcomepage.roomNameAllowedChars' ) }
type = 'text'
value = { this . state . room } / >
{ this . _renderInsecureRoomNameWarning ( ) }
< / f o r m >
< button
aria - disabled = 'false'
aria - label = 'Start meeting'
className = 'welcome-page-button'
id = 'enter_room_button'
onClick = { this . _onFormSubmit }
tabIndex = '0'
type = 'button' >
{ t ( 'welcomepage.startMeeting' ) }
< / b u t t o n >
< / d i v >
< div
className = 'welcome-page-button'
id = 'enter_room_button'
onClick = { this . _onFormSubmit } >
{
showResponsiveText
? t ( 'welcomepage.goSmall' )
: t ( 'welcomepage.go' )
}
< / d i v >
< / d i v >
{ _moderatedRoomServiceUrl && (
< div id = 'moderated-meetings' >
< p >
{
translateToHTML (
{ _moderatedRoomServiceUrl && (
< div id = 'moderated-meetings' >
< p >
{
translateToHTML (
t , 'welcomepage.moderatedMessage' , { url : _moderatedRoomServiceUrl } )
}
< / p >
}
< / p >
< / d i v > ) }
< / d i v >
< / d i v >
< div className = 'welcome-cards-container' >
< div className = 'welcome-card-row' >
< div className = 'welcome-tabs welcome-card welcome-card--blue' >
{ this . _renderTabs ( ) }
< / d i v >
) }
{ this . _renderTabs ( ) }
{ showAdditionalCard
? < div
className = 'welcome-card welcome-card--dark'
ref = { this . _setAdditionalCardRef } / >
: null }
< / d i v >
{ showAdditionalContent
? < div
className = 'welcome-page-content'
ref = { this . _setAdditionalContentRef } / >
: null }
< / d i v >
{ showAdditionalContent
? < div
className = 'welcome-page-content'
ref = { this . _setAdditionalContentRef } / >
: null }
{ DISPLAY _WELCOME _FOOTER && this . _renderFooter ( ) }
< / d i v >
) ;
}
@ -302,6 +334,45 @@ class WelcomePage extends AbstractWelcomePage {
this . setState ( { selectedTab : tabIndex } ) ;
}
/ * *
* Renders the footer .
*
* @ returns { ReactElement }
* /
_renderFooter ( ) {
const { t } = this . props ;
const {
MOBILE _DOWNLOAD _LINK _ANDROID ,
MOBILE _DOWNLOAD _LINK _F _DROID ,
MOBILE _DOWNLOAD _LINK _IOS
} = interfaceConfig ;
return ( < footer className = 'welcome-footer' >
< div className = 'welcome-footer-centered' >
< div className = 'welcome-footer-padded' >
< div className = 'welcome-footer-row-block welcome-footer--row-1' >
< div className = 'welcome-footer-row-1-text' > { t ( 'welcomepage.jitsiOnMobile' ) } < / d i v >
< a
className = 'welcome-badge'
href = { MOBILE _DOWNLOAD _LINK _IOS } >
< img src = './images/app-store-badge.png' / >
< / a >
< a
className = 'welcome-badge'
href = { MOBILE _DOWNLOAD _LINK _ANDROID } >
< img src = './images/google-play-badge.png' / >
< / a >
< a
className = 'welcome-badge'
href = { MOBILE _DOWNLOAD _LINK _F _DROID } >
< img src = './images/f-droid-badge.png' / >
< / a >
< / d i v >
< / d i v >
< / d i v >
< / f o o t e r > ) ;
}
/ * *
* Renders tabs to show previous meetings and upcoming calendar events . The
* tabs are purposefully hidden on mobile browsers .
@ -342,6 +413,19 @@ class WelcomePage extends AbstractWelcomePage {
tabs = { tabs } / > ) ;
}
/ * *
* Sets the internal reference to the HTMLDivElement used to hold the
* additional card shown near the tabs card .
*
* @ param { HTMLDivElement } el - The HTMLElement for the div that is the root
* of the welcome page content .
* @ private
* @ returns { void }
* /
_setAdditionalCardRef ( el ) {
this . _additionalCardRef = el ;
}
/ * *
* Sets the internal reference to the HTMLDivElement used to hold the
* welcome page content .
@ -380,6 +464,19 @@ class WelcomePage extends AbstractWelcomePage {
this . _roomInputRef = el ;
}
/ * *
* Returns whether or not an additional card should be displayed near the tabs .
*
* @ private
* @ returns { boolean }
* /
_shouldShowAdditionalCard ( ) {
return interfaceConfig . DISPLAY _WELCOME _PAGE _ADDITIONAL _CARD
&& this . _additionalCardTemplate
&& this . _additionalCardTemplate . content
&& this . _additionalCardTemplate . innerHTML . trim ( ) ;
}
/ * *
* Returns whether or not additional content should be displayed below
* the welcome page ' s header for entering a room name .
@ -407,20 +504,6 @@ class WelcomePage extends AbstractWelcomePage {
&& this . _additionalToolbarContentTemplate . content
&& this . _additionalToolbarContentTemplate . innerHTML . trim ( ) ;
}
/ * *
* Returns whether or not the screen has a size smaller than a custom margin
* and therefore display different text in the go button .
*
* @ private
* @ returns { boolean }
* /
_shouldShowResponsiveText ( ) {
const { innerWidth } = window ;
return innerWidth <= WINDOW _WIDTH _THRESHOLD ;
}
}
export default translate ( connect ( _mapStateToProps ) ( WelcomePage ) ) ;