feat(welcome_page): Redesign welcome page
|
@ -7,9 +7,8 @@
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
position: relative;
|
position: relative;
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
overflow: auto;
|
overflow: auto;
|
||||||
|
width: 100%;
|
||||||
|
|
||||||
.meetings-list-empty {
|
.meetings-list-empty {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
|
@ -20,11 +19,34 @@
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
|
|
||||||
.description {
|
.description {
|
||||||
font-size: 16px;
|
color: #2f3237;
|
||||||
padding: 20px;
|
font-size: 14px;
|
||||||
|
line-height: 18px;
|
||||||
|
margin-bottom: 16px;
|
||||||
|
max-width: 436px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.meetings-list-empty-image {
|
||||||
|
text-align: center;
|
||||||
|
margin: 24px 0 20px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.meetings-list-empty-button {
|
||||||
|
align-items: center;
|
||||||
|
color: #0163FF;
|
||||||
|
cursor: pointer;
|
||||||
|
display: flex;
|
||||||
|
font-size: 14px;
|
||||||
|
line-height: 18px;
|
||||||
|
margin: 24px 0 32px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.meetings-list-empty-icon {
|
||||||
|
display: inline-block;
|
||||||
|
margin-right: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
.button {
|
.button {
|
||||||
background: #0074E0;
|
background: #0074E0;
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
|
@ -32,7 +54,7 @@
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
padding: 5px 10px;
|
padding: 8px;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -43,12 +65,13 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.item {
|
.item {
|
||||||
background: rgba(255,255,255,0.50);
|
background: #fff;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
|
border-radius: 4px;
|
||||||
display: inline-flex;
|
display: inline-flex;
|
||||||
margin-top: 5px;
|
margin: 4px 4px 0 4px;
|
||||||
min-height: 92px;
|
min-height: 60px;
|
||||||
width: 100%;
|
width: calc(100% - 8px);
|
||||||
word-break: break-word;
|
word-break: break-word;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
|
@ -61,37 +84,41 @@
|
||||||
.left-column {
|
.left-column {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
width: 140px;
|
|
||||||
flex-grow: 0;
|
flex-grow: 0;
|
||||||
padding-left: 30px;
|
padding-left: 16px;
|
||||||
padding-top: 25px;
|
padding-top: 13px;
|
||||||
|
|
||||||
.date {
|
|
||||||
font-weight: bold;
|
|
||||||
padding-bottom: 5px;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.right-column {
|
.right-column {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
flex-grow: 1;
|
flex-grow: 1;
|
||||||
padding-left: 30px;
|
padding-left: 16px;
|
||||||
padding-top: 25px;
|
padding-top: 13px;
|
||||||
|
position: relative;
|
||||||
.title {
|
|
||||||
font-size: 16px;
|
|
||||||
font-weight: bold;
|
|
||||||
padding-bottom: 5px;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.title {
|
||||||
|
font-size: 12px;
|
||||||
|
font-weight: 600;
|
||||||
|
line-height: 16px;
|
||||||
|
padding-bottom: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.subtitle {
|
||||||
|
color: #5E6D7A;
|
||||||
|
font-weight: normal;
|
||||||
|
font-size: 12px;
|
||||||
|
line-height: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
.actions {
|
.actions {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
flex-grow: 0;
|
flex-grow: 0;
|
||||||
padding-right: 30px;
|
margin-right: 16px;
|
||||||
}
|
}
|
||||||
|
|
||||||
&.with-click-handler {
|
&.with-click-handler {
|
||||||
|
@ -99,7 +126,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
&.with-click-handler:hover {
|
&.with-click-handler:hover {
|
||||||
background-color: #75A7E7;
|
background-color: #c7ddff;
|
||||||
}
|
}
|
||||||
|
|
||||||
.add-button {
|
.add-button {
|
||||||
|
@ -120,4 +147,20 @@
|
||||||
display: block
|
display: block
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.delete-meeting {
|
||||||
|
display: none;
|
||||||
|
margin-right: 16px;
|
||||||
|
position: absolute;
|
||||||
|
|
||||||
|
&> svg {
|
||||||
|
fill: #0074e0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.item:hover {
|
||||||
|
.delete-meeting {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,6 +30,67 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
@media only screen and (max-width: $verySmallScreen) {
|
@media only screen and (max-width: $verySmallScreen) {
|
||||||
|
.welcome {
|
||||||
|
#enter_room {
|
||||||
|
position: relative;
|
||||||
|
height: 42px;
|
||||||
|
|
||||||
|
.welcome-page-button {
|
||||||
|
font-size: 16px;
|
||||||
|
left: 0;
|
||||||
|
position: absolute;
|
||||||
|
top: 68px;
|
||||||
|
text-align: center;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.header {
|
||||||
|
background: #06345E;
|
||||||
|
background-image: linear-gradient(180deg, rgba(8, 110, 202, 0.8) 0%, rgba(8, 110, 202, 0) 100%);
|
||||||
|
|
||||||
|
#enter_room {
|
||||||
|
.enter-room-input-container {
|
||||||
|
padding-right: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.warning-without-link,
|
||||||
|
.warning-with-link {
|
||||||
|
top: 120px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.welcome-tabs {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.header-text-title {
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.welcome-cards-container {
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.without-content {
|
||||||
|
.header {
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#moderated-meetings {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.welcome-footer-row-block {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
.welcome-badge {
|
||||||
|
margin-right: 16px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#videoResolutionLabel {
|
#videoResolutionLabel {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
|
@ -161,71 +161,47 @@ $unsupportedDesktopBrowserTextFontSize: 21px;
|
||||||
/**
|
/**
|
||||||
* The size of the default watermark.
|
* The size of the default watermark.
|
||||||
*/
|
*/
|
||||||
$watermarkWidth: 186px;
|
$watermarkWidth: 71px;
|
||||||
$watermarkHeight: 74px;
|
$watermarkHeight: 32px;
|
||||||
|
|
||||||
$welcomePageWatermarkWidth: 186px;
|
$welcomePageWatermarkWidth: 71px;
|
||||||
$welcomePageWatermarkHeight: 74px;
|
$welcomePageWatermarkHeight: 32px;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Welcome page variables.
|
* Welcome page variables.
|
||||||
*/
|
*/
|
||||||
$welcomePageDescriptionColor: #fff;
|
$welcomePageDescriptionColor: #fff;
|
||||||
$welcomePageFontFamily: inherit;
|
$welcomePageFontFamily: inherit;
|
||||||
$welcomePageBackground: linear-gradient(-90deg, #1251AE 0%, #0074FF 50%, #1251AE 100%);
|
$welcomePageBackground: none;
|
||||||
$welcomePageTitleColor: #fff;
|
$welcomePageTitleColor: #fff;
|
||||||
|
|
||||||
$welcomePageHeaderBackground: none;
|
$welcomePageHeaderBackground: linear-gradient(0deg, rgba(0, 0, 0, 0.2), rgba(0, 0, 0, 0.2)), url('/images/welcome-background.png');
|
||||||
$welcomePageHeaderBackgroundSmall: none;
|
|
||||||
$welcomePageHeaderBackgroundPosition: none;
|
$welcomePageHeaderBackgroundPosition: none;
|
||||||
$welcomePageHeaderBackgroundRepeat: none;
|
$welcomePageHeaderBackgroundRepeat: none;
|
||||||
$welcomePageHeaderBackgroundSize: none;
|
$welcomePageHeaderBackgroundSize: cover;
|
||||||
$welcomePageHeaderPaddingBottom: 0px;
|
$welcomePageHeaderPaddingBottom: 0px;
|
||||||
$welcomePageHeaderMinHeight: fit-content;
|
$welcomePageHeaderTitleMaxWidth: initial;
|
||||||
|
$welcomePageHeaderTextAlign: center;
|
||||||
|
|
||||||
$welcomePageHeaderTextMarginTop: 35px;
|
$welcomePageHeaderContainerDisplay: flex;
|
||||||
$welcomePageHeaderTextMarginBottom: 35px;
|
$welcomePageHeaderContainerMargin: 146px 32px 0 32px;
|
||||||
$welcomePageHeaderTextDisplay: flex;
|
|
||||||
$welcomePageHeaderTextWidth: 650px;
|
|
||||||
|
|
||||||
$welcomePageHeaderTextTitleMarginBottom: 16px;
|
$welcomePageHeaderTextTitleMarginBottom: 0;
|
||||||
$welcomePageHeaderTextTitleFontSize: 2.5rem;
|
$welcomePageHeaderTextTitleFontSize: 42px;
|
||||||
$welcomePageHeaderTextTitleFontWeight: 500;
|
$welcomePageHeaderTextTitleFontWeight: normal;
|
||||||
$welcomePageHeaderTextTitleLineHeight: 1.18;
|
$welcomePageHeaderTextTitleLineHeight: 50px;
|
||||||
$welcomePageHeaderTextTitleOpacity: 1;
|
$welcomePageHeaderTextTitleOpacity: 1;
|
||||||
|
|
||||||
$welcomePageHeaderTextDescriptionDisplay: inherit;
|
|
||||||
$welcomePageHeaderTextDescriptionFontSize: 1rem;
|
|
||||||
$welcomePageHeaderTextDescriptionFontWeight: 400;
|
|
||||||
$welcomePageHeaderTextDescriptionLineHeight: 24px;
|
|
||||||
$welcomePageHeaderTextDescriptionMarginBottom: 20px;
|
|
||||||
$welcomePageHeaderTextDescriptionAlignSelf: inherit;
|
|
||||||
|
|
||||||
$welcomePageEnterRoomDisplay: flex;
|
$welcomePageEnterRoomDisplay: flex;
|
||||||
$welcomePageEnterRoomWidth: 680px;
|
$welcomePageEnterRoomWidth: calc(100% - 32px);
|
||||||
$welcomePageEnterRoomPadding: 25px 30px;
|
$welcomePageEnterRoomPadding: 4px;
|
||||||
$welcomePageEnterRoomBorderRadius: 0px;
|
$welcomePageEnterRoomMargin: 0 auto;
|
||||||
|
|
||||||
$welcomePageEnterRoomInputContainerPadding: 0 8px 5px 0px;
|
|
||||||
$welcomePageEnterRoomInputContainerBorderWidth: 0px 0px 2px 0px;
|
|
||||||
$welcomePageEnterRoomInputContainerBorderStyle: solid;
|
|
||||||
$welcomePageEnterRoomInputContainerBorderImage: linear-gradient(to right, #dee1e6, #fff) 1;
|
|
||||||
|
|
||||||
$welcomePageEnterRoomTitleDisplay: inherit;
|
|
||||||
|
|
||||||
$welcomePageTabContainerDisplay: flex;
|
$welcomePageTabContainerDisplay: flex;
|
||||||
$welcomePageTabContentDisplay: inherit;
|
$welcomePageTabContentDisplay: inherit;
|
||||||
$welcomePageTabButtonsDisplay: flex;
|
$welcomePageTabButtonsDisplay: flex;
|
||||||
$welcomePageTabDisplay: block;
|
$welcomePageTabDisplay: block;
|
||||||
|
|
||||||
$welcomePageButtonWidth: 51px;
|
|
||||||
$welcomePageButtonMinWidth: inherit;
|
|
||||||
$welcomePageButtonFontSize: 14px;
|
|
||||||
$welcomePageButtonHeight: 35px;
|
|
||||||
$welcomePageButtonFontWeight: inherit;
|
|
||||||
$welcomePageButtonBorderRadius: 4px;
|
|
||||||
$welcomePageButtonLineHeight: 35px;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Deep-linking page variables.
|
* Deep-linking page variables.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -5,6 +5,7 @@ body.welcome-page {
|
||||||
|
|
||||||
.welcome {
|
.welcome {
|
||||||
background-image: $welcomePageBackground;
|
background-image: $welcomePageBackground;
|
||||||
|
background-color: #fff;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
font-family: $welcomePageFontFamily;
|
font-family: $welcomePageFontFamily;
|
||||||
|
@ -18,21 +19,15 @@ body.welcome-page {
|
||||||
background-repeat: $welcomePageHeaderBackgroundRepeat;
|
background-repeat: $welcomePageHeaderBackgroundRepeat;
|
||||||
background-size: $welcomePageHeaderBackgroundSize;
|
background-size: $welcomePageHeaderBackgroundSize;
|
||||||
padding-bottom: $welcomePageHeaderPaddingBottom;
|
padding-bottom: $welcomePageHeaderPaddingBottom;
|
||||||
align-items: center;
|
background-color: #002637;
|
||||||
display: flex;
|
height: 480px;
|
||||||
flex-direction: column;
|
|
||||||
min-height: $welcomePageHeaderMinHeight;
|
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
position: relative;
|
position: relative;
|
||||||
text-align: center;
|
|
||||||
|
|
||||||
.header-text {
|
.header-container {
|
||||||
display: $welcomePageHeaderTextDisplay;
|
display: $welcomePageHeaderContainerDisplay;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
margin-top: $watermarkHeight + $welcomePageHeaderTextMarginTop;
|
margin: $welcomePageHeaderContainerMargin;
|
||||||
margin-bottom: $welcomePageHeaderTextMarginBottom;
|
|
||||||
max-width: calc(100% - 40px);
|
|
||||||
width: $welcomePageHeaderTextWidth;
|
|
||||||
z-index: $zindex2;
|
z-index: $zindex2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -42,50 +37,52 @@ body.welcome-page {
|
||||||
font-weight: $welcomePageHeaderTextTitleFontWeight;
|
font-weight: $welcomePageHeaderTextTitleFontWeight;
|
||||||
line-height: $welcomePageHeaderTextTitleLineHeight;
|
line-height: $welcomePageHeaderTextTitleLineHeight;
|
||||||
margin-bottom: $welcomePageHeaderTextTitleMarginBottom;
|
margin-bottom: $welcomePageHeaderTextTitleMarginBottom;
|
||||||
|
max-width: $welcomePageHeaderTitleMaxWidth;
|
||||||
opacity: $welcomePageHeaderTextTitleOpacity;
|
opacity: $welcomePageHeaderTextTitleOpacity;
|
||||||
|
text-align: $welcomePageHeaderTextAlign;
|
||||||
}
|
}
|
||||||
|
|
||||||
.header-text-description {
|
.header-text-subtitle {
|
||||||
display: $welcomePageHeaderTextDescriptionDisplay;
|
color: #fff;
|
||||||
color: $welcomePageDescriptionColor;
|
font-size: 20px;
|
||||||
font-size: $welcomePageHeaderTextDescriptionFontSize;
|
font-weight: 600;
|
||||||
font-weight: $welcomePageHeaderTextDescriptionFontWeight;
|
line-height: 26px;
|
||||||
line-height: $welcomePageHeaderTextDescriptionLineHeight;
|
margin: 16px 0 32px 0;
|
||||||
margin-bottom: $welcomePageHeaderTextDescriptionMarginBottom;
|
text-align: $welcomePageHeaderTextAlign;
|
||||||
align-self: $welcomePageHeaderTextDescriptionAlignSelf;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#enter_room {
|
#enter_room {
|
||||||
display: $welcomePageEnterRoomDisplay;
|
display: $welcomePageEnterRoomDisplay;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
max-width: calc(100% - 40px);
|
max-width: 480px;
|
||||||
width: $welcomePageEnterRoomWidth;
|
width: $welcomePageEnterRoomWidth;
|
||||||
z-index: $zindex2;
|
z-index: $zindex2;
|
||||||
background-color: #fff;
|
background-color: #fff;
|
||||||
padding: $welcomePageEnterRoomPadding;
|
padding: $welcomePageEnterRoomPadding;
|
||||||
border-radius: $welcomePageEnterRoomBorderRadius;
|
border-radius: 4px;
|
||||||
|
margin: $welcomePageEnterRoomMargin;
|
||||||
|
|
||||||
.enter-room-input-container {
|
.enter-room-input-container {
|
||||||
width: 100%;
|
|
||||||
padding: $welcomePageEnterRoomInputContainerPadding;
|
|
||||||
text-align: left;
|
text-align: left;
|
||||||
color: #253858;
|
color: #253858;
|
||||||
|
flex-grow: 1;
|
||||||
height: fit-content;
|
height: fit-content;
|
||||||
|
padding-right: 4px;
|
||||||
.enter-room-title {
|
position: relative;
|
||||||
display: $welcomePageEnterRoomTitleDisplay;
|
|
||||||
font-size: 18px;
|
|
||||||
font-weight: bold;
|
|
||||||
padding-bottom: 5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.enter-room-input {
|
.enter-room-input {
|
||||||
border-width: $welcomePageEnterRoomInputContainerBorderWidth;
|
border: 0;
|
||||||
border-style: $welcomePageEnterRoomInputContainerBorderStyle;
|
background: #fff;
|
||||||
border-image: $welcomePageEnterRoomInputContainerBorderImage;
|
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
|
height: 50px;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
|
padding-left: 10px;
|
||||||
|
|
||||||
|
&:focus {
|
||||||
|
outline: auto 2px #005fcc;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.insecure-room-name-warning {
|
.insecure-room-name-warning {
|
||||||
|
@ -109,16 +106,28 @@ body.welcome-page {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.warning-without-link {
|
||||||
|
position: absolute;
|
||||||
|
top: 44px;
|
||||||
|
left: -10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.warning-with-link {
|
||||||
|
position: absolute;
|
||||||
|
top: 84px;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#moderated-meetings {
|
#moderated-meetings {
|
||||||
max-width: calc(100% - 40px);
|
max-width: calc(100% - 40px);
|
||||||
padding: 16px 0 39px 0;
|
padding: 16px 0 39px 0;
|
||||||
|
margin: $welcomePageEnterRoomMargin;
|
||||||
width: $welcomePageEnterRoomWidth;
|
width: $welcomePageEnterRoomWidth;
|
||||||
|
|
||||||
p {
|
p {
|
||||||
color: $welcomePageDescriptionColor;
|
color: $welcomePageDescriptionColor;
|
||||||
text-align: left;
|
text-align: $welcomePageHeaderTextAlign;
|
||||||
|
|
||||||
a {
|
a {
|
||||||
color: inherit;
|
color: inherit;
|
||||||
|
@ -126,76 +135,70 @@ body.welcome-page {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.tab-container {
|
.tab-container {
|
||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
|
position: relative;
|
||||||
|
text-align: left;
|
||||||
|
display: $welcomePageTabContainerDisplay;
|
||||||
|
flex-direction: column;
|
||||||
|
|
||||||
|
.tab-content{
|
||||||
|
display: $welcomePageTabContentDisplay;
|
||||||
|
height: 250px;
|
||||||
|
margin: 5px 0px;
|
||||||
|
overflow: hidden;
|
||||||
|
flex-grow: 1;
|
||||||
position: relative;
|
position: relative;
|
||||||
text-align: left;
|
}
|
||||||
min-height: 354px;
|
|
||||||
width: 710px;
|
|
||||||
background: #75A7E7;
|
|
||||||
display: $welcomePageTabContainerDisplay;
|
|
||||||
flex-direction: column;
|
|
||||||
|
|
||||||
.tab-content{
|
.tab-buttons {
|
||||||
display: $welcomePageTabContentDisplay;
|
background-color: #c7ddff;
|
||||||
margin: 5px 0px;
|
border-radius: 6px;
|
||||||
overflow: hidden;
|
color: #0163FF;
|
||||||
|
font-size: 14px;
|
||||||
|
line-height: 18px;
|
||||||
|
margin: 4px;
|
||||||
|
display: $welcomePageTabButtonsDisplay;
|
||||||
|
|
||||||
|
.tab {
|
||||||
|
background-color: #c7ddff;
|
||||||
|
border-radius: 7px;
|
||||||
|
cursor: pointer;
|
||||||
|
display: $welcomePageTabDisplay;
|
||||||
flex-grow: 1;
|
flex-grow: 1;
|
||||||
position: relative;
|
margin: 2px;
|
||||||
|
padding: 7px 0;
|
||||||
|
text-align: center;
|
||||||
|
|
||||||
> * {
|
&.selected {
|
||||||
position: absolute;
|
background-color: #FFF;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.tab-buttons {
|
|
||||||
font-size: 18px;
|
|
||||||
color: #FFFFFF;
|
|
||||||
display: $welcomePageTabButtonsDisplay;
|
|
||||||
flex-grow: 0;
|
|
||||||
flex-direction: row;
|
|
||||||
min-height: 54px;
|
|
||||||
width: 100%;
|
|
||||||
|
|
||||||
.tab {
|
|
||||||
display: $welcomePageTabDisplay;
|
|
||||||
text-align: center;
|
|
||||||
background: rgba(9,30,66,0.37);
|
|
||||||
height: 55px;
|
|
||||||
line-height: 54px;
|
|
||||||
flex-grow: 1;
|
|
||||||
cursor: pointer;
|
|
||||||
|
|
||||||
&.selected, &:hover {
|
|
||||||
background: rgba(9,30,66,0.71);
|
|
||||||
}
|
|
||||||
|
|
||||||
&:last-child {
|
|
||||||
margin-left: 1px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.welcome-page-button {
|
.welcome-page-button {
|
||||||
width: $welcomePageButtonWidth;
|
border: 0;
|
||||||
min-width: $welcomePageButtonMinWidth;
|
font-size: 14px;
|
||||||
height: $welcomePageButtonHeight;
|
|
||||||
font-size: $welcomePageButtonFontSize;
|
|
||||||
font-weight: $welcomePageButtonFontWeight;
|
|
||||||
background: #0074E0;
|
background: #0074E0;
|
||||||
border-radius: $welcomePageButtonBorderRadius;
|
border-radius: 3px;
|
||||||
color: #FFFFFF;
|
color: #FFFFFF;
|
||||||
text-align: center;
|
|
||||||
vertical-align: middle;
|
|
||||||
line-height: $welcomePageButtonLineHeight;
|
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
|
padding: 16px 20px;
|
||||||
|
|
||||||
|
&:focus-within {
|
||||||
|
outline: auto 2px #022e61;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.welcome-page-settings {
|
.welcome-page-settings {
|
||||||
|
background: rgba(255, 255, 255, 0.38);
|
||||||
|
border-radius: 3px;
|
||||||
color: $welcomePageDescriptionColor;
|
color: $welcomePageDescriptionColor;
|
||||||
|
padding: 4px;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 32px;
|
top: 32px;
|
||||||
right: 32px;
|
right: 32px;
|
||||||
|
@ -217,4 +220,83 @@ body.welcome-page {
|
||||||
height: $welcomePageWatermarkHeight;
|
height: $welcomePageWatermarkHeight;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&.without-content {
|
||||||
|
.welcome-card {
|
||||||
|
min-width: 500px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.welcome-cards-container {
|
||||||
|
color:#131519;
|
||||||
|
padding-top: 40px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.welcome-card-row {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
padding: 0 32px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.welcome-card-text {
|
||||||
|
padding: 32px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.welcome-card {
|
||||||
|
width: 49%;
|
||||||
|
border-radius: 8px;
|
||||||
|
|
||||||
|
&--dark {
|
||||||
|
background: #444447;
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
&--blue {
|
||||||
|
background: #D5E5FF;
|
||||||
|
}
|
||||||
|
|
||||||
|
&--grey {
|
||||||
|
background: #F2F3F4;
|
||||||
|
}
|
||||||
|
|
||||||
|
&--shadow {
|
||||||
|
box-shadow: 0px 4px 30px rgba(0, 0, 0, 0.15);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.welcome-footer {
|
||||||
|
background: #131519;
|
||||||
|
color: #fff;
|
||||||
|
margin-top: 40px;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.welcome-footer-centered {
|
||||||
|
max-width: 688px;
|
||||||
|
margin: 0 auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.welcome-footer-padded {
|
||||||
|
padding: 0px 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.welcome-footer-row-block {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
border-bottom: 1px solid #424447;
|
||||||
|
|
||||||
|
&:last-child {
|
||||||
|
border-bottom: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.welcome-footer--row-1 {
|
||||||
|
padding: 40px 0 24px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.welcome-footer-row-1-text {
|
||||||
|
max-width: 200px;
|
||||||
|
margin-right: 16px;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
After Width: | Height: | Size: 2.0 KiB |
|
@ -0,0 +1,21 @@
|
||||||
|
<svg width="68" height="72" viewBox="0 0 68 72" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<rect x="1" y="5.64514" width="65.3548" height="65.3548" rx="7" stroke="#A4B8D1" stroke-width="2"/>
|
||||||
|
<rect y="23.2258" width="67.3548" height="2.0213" fill="#A4B8D1"/>
|
||||||
|
<rect x="14.5161" width="2.32258" height="14.5161" fill="#A4B8D1"/>
|
||||||
|
<rect x="11.6129" y="12.1935" width="8.12903" height="2.32258" fill="#A4B8D1"/>
|
||||||
|
<rect x="50.5161" width="2.32258" height="14.5161" fill="#A4B8D1"/>
|
||||||
|
<rect x="47.6129" y="12.1935" width="8.12903" height="2.32258" fill="#A4B8D1"/>
|
||||||
|
<circle cx="24.387" cy="37.7419" r="2.32258" fill="#A4B8D1"/>
|
||||||
|
<circle cx="33.6774" cy="37.7419" r="2.32258" fill="#A4B8D1"/>
|
||||||
|
<circle cx="42.9677" cy="37.7419" r="2.32258" fill="#A4B8D1"/>
|
||||||
|
<circle cx="52.258" cy="37.7419" r="2.32258" fill="#A4B8D1"/>
|
||||||
|
<circle cx="24.387" cy="47.0322" r="2.32258" fill="#A4B8D1"/>
|
||||||
|
<circle cx="15.0968" cy="47.0322" r="2.32258" fill="#A4B8D1"/>
|
||||||
|
<circle cx="33.6774" cy="47.0322" r="2.32258" fill="#A4B8D1"/>
|
||||||
|
<circle cx="42.9677" cy="47.0322" r="2.32258" fill="#A4B8D1"/>
|
||||||
|
<circle cx="24.387" cy="56.3226" r="2.32258" fill="#A4B8D1"/>
|
||||||
|
<circle cx="15.0968" cy="56.3226" r="2.32258" fill="#A4B8D1"/>
|
||||||
|
<circle cx="33.6774" cy="56.3226" r="2.32258" fill="#A4B8D1"/>
|
||||||
|
<circle cx="42.9677" cy="56.3226" r="2.32258" fill="#A4B8D1"/>
|
||||||
|
<circle cx="52.258" cy="47.0322" r="2.32258" fill="#A4B8D1"/>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 1.3 KiB |
After Width: | Height: | Size: 4.0 KiB |
After Width: | Height: | Size: 4.2 KiB |
Before Width: | Height: | Size: 33 KiB |
After Width: | Height: | Size: 12 KiB |
After Width: | Height: | Size: 290 KiB |
|
@ -182,6 +182,7 @@
|
||||||
<!--#include virtual="title.html" -->
|
<!--#include virtual="title.html" -->
|
||||||
<!--#include virtual="plugin.head.html" -->
|
<!--#include virtual="plugin.head.html" -->
|
||||||
<!--#include virtual="static/welcomePageAdditionalContent.html" -->
|
<!--#include virtual="static/welcomePageAdditionalContent.html" -->
|
||||||
|
<!--#include virtual="static/welcomePageAdditionalCard.html" -->
|
||||||
<!--#include virtual="static/settingsToolbarAdditionalContent.html" -->
|
<!--#include virtual="static/settingsToolbarAdditionalContent.html" -->
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
|
|
@ -46,9 +46,9 @@ var interfaceConfig = {
|
||||||
|
|
||||||
DEFAULT_BACKGROUND: '#474747',
|
DEFAULT_BACKGROUND: '#474747',
|
||||||
DEFAULT_LOCAL_DISPLAY_NAME: 'me',
|
DEFAULT_LOCAL_DISPLAY_NAME: 'me',
|
||||||
DEFAULT_LOGO_URL: 'images/watermark.png',
|
DEFAULT_LOGO_URL: 'images/watermark.svg',
|
||||||
DEFAULT_REMOTE_DISPLAY_NAME: 'Fellow Jitster',
|
DEFAULT_REMOTE_DISPLAY_NAME: 'Fellow Jitster',
|
||||||
DEFAULT_WELCOME_PAGE_LOGO_URL: 'images/watermark.png',
|
DEFAULT_WELCOME_PAGE_LOGO_URL: 'images/watermark.svg',
|
||||||
|
|
||||||
DISABLE_DOMINANT_SPEAKER_INDICATOR: false,
|
DISABLE_DOMINANT_SPEAKER_INDICATOR: false,
|
||||||
|
|
||||||
|
@ -86,7 +86,9 @@ var interfaceConfig = {
|
||||||
*/
|
*/
|
||||||
DISABLE_VIDEO_BACKGROUND: false,
|
DISABLE_VIDEO_BACKGROUND: false,
|
||||||
|
|
||||||
DISPLAY_WELCOME_PAGE_CONTENT: true,
|
DISPLAY_WELCOME_FOOTER: true,
|
||||||
|
DISPLAY_WELCOME_PAGE_ADDITIONAL_CARD: false,
|
||||||
|
DISPLAY_WELCOME_PAGE_CONTENT: false,
|
||||||
DISPLAY_WELCOME_PAGE_TOOLBAR_ADDITIONAL_CONTENT: false,
|
DISPLAY_WELCOME_PAGE_TOOLBAR_ADDITIONAL_CONTENT: false,
|
||||||
|
|
||||||
ENABLE_DIAL_OUT: true,
|
ENABLE_DIAL_OUT: true,
|
||||||
|
@ -136,6 +138,21 @@ var interfaceConfig = {
|
||||||
*/
|
*/
|
||||||
MOBILE_APP_PROMO: true,
|
MOBILE_APP_PROMO: true,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Specify custom URL for downloading android mobile app.
|
||||||
|
*/
|
||||||
|
MOBILE_DOWNLOAD_LINK_ANDROID: 'https://play.google.com/store/apps/details?id=org.jitsi.meet',
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Specify custom URL for downloading f droid app.
|
||||||
|
*/
|
||||||
|
MOBILE_DOWNLOAD_LINK_F_DROID: 'https://f-droid.org/en/packages/org.jitsi.meet/',
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Specify URL for downloading ios mobile app.
|
||||||
|
*/
|
||||||
|
MOBILE_DOWNLOAD_LINK_IOS: 'https://itunes.apple.com/us/app/jitsi-meet/id1165103905',
|
||||||
|
|
||||||
NATIVE_APP_NAME: 'Jitsi Meet',
|
NATIVE_APP_NAME: 'Jitsi Meet',
|
||||||
|
|
||||||
// Names of browsers which should show a warning stating the current browser
|
// Names of browsers which should show a warning stating the current browser
|
||||||
|
@ -234,16 +251,6 @@ var interfaceConfig = {
|
||||||
*/
|
*/
|
||||||
// TILE_VIEW_MAX_COLUMNS: 5,
|
// TILE_VIEW_MAX_COLUMNS: 5,
|
||||||
|
|
||||||
/**
|
|
||||||
* Specify custom URL for downloading android mobile app.
|
|
||||||
*/
|
|
||||||
// MOBILE_DOWNLOAD_LINK_ANDROID: 'https://play.google.com/store/apps/details?id=org.jitsi.meet',
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Specify URL for downloading ios mobile app.
|
|
||||||
*/
|
|
||||||
// MOBILE_DOWNLOAD_LINK_IOS: 'https://itunes.apple.com/us/app/jitsi-meet/id1165103905',
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Specify Firebase dynamic link properties for the mobile apps.
|
* Specify Firebase dynamic link properties for the mobile apps.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -878,6 +878,8 @@
|
||||||
"goSmall": "GO",
|
"goSmall": "GO",
|
||||||
"info": "Dial-in info",
|
"info": "Dial-in info",
|
||||||
"join": "CREATE / JOIN",
|
"join": "CREATE / JOIN",
|
||||||
|
"jitsiMeet": "Jitsi Meet",
|
||||||
|
"jitsiOnMobile": "Jitsi on mobile – download our apps and start a meeting from anywhere",
|
||||||
"moderatedMessage": "Or <a href=\"{{url}}\" rel=\"noopener noreferrer\" target=\"_blank\">book a meeting URL</a> in advance where you are the only moderator.",
|
"moderatedMessage": "Or <a href=\"{{url}}\" rel=\"noopener noreferrer\" target=\"_blank\">book a meeting URL</a> in advance where you are the only moderator.",
|
||||||
"privacy": "Privacy",
|
"privacy": "Privacy",
|
||||||
"recentList": "Recent",
|
"recentList": "Recent",
|
||||||
|
@ -888,6 +890,8 @@
|
||||||
"roomname": "Enter room name",
|
"roomname": "Enter room name",
|
||||||
"roomnameHint": "Enter the name or URL of the room you want to join. You may make a name up, just let the people you are meeting know it so that they enter the same name.",
|
"roomnameHint": "Enter the name or URL of the room you want to join. You may make a name up, just let the people you are meeting know it so that they enter the same name.",
|
||||||
"sendFeedback": "Send feedback",
|
"sendFeedback": "Send feedback",
|
||||||
|
"secureMeetings": "Secure and high quality meetings",
|
||||||
|
"startMeeting": "Start meeting",
|
||||||
"terms": "Terms",
|
"terms": "Terms",
|
||||||
"title": "Secure, fully featured, and completely free video conferencing"
|
"title": "Secure, fully featured, and completely free video conferencing"
|
||||||
},
|
},
|
||||||
|
|
|
@ -0,0 +1,3 @@
|
||||||
|
<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path fill-rule="evenodd" clip-rule="evenodd" d="M4.99996 2.50002C4.99996 2.03978 5.37306 1.66669 5.83329 1.66669C6.29353 1.66669 6.66663 2.03978 6.66663 2.50002V3.33335H13.3333V2.50002C13.3333 2.03978 13.7064 1.66669 14.1666 1.66669C14.6269 1.66669 15 2.03978 15 2.50002V3.33335H16.6666C17.5871 3.33335 18.3333 4.07955 18.3333 5.00002V16.6667C18.3333 17.5872 17.5871 18.3334 16.6666 18.3334H3.33329C2.41282 18.3334 1.66663 17.5872 1.66663 16.6667V5.00002C1.66663 4.07955 2.41282 3.33335 3.33329 3.33335H4.99996V2.50002ZM3.33329 16.6667V5.00002H16.6666V16.6667H3.33329ZM9.99996 6.66669C9.53972 6.66669 9.16663 7.03978 9.16663 7.50002V10H6.66662C6.20639 10 5.83329 10.3731 5.83329 10.8334C5.83329 11.2936 6.20639 11.6667 6.66662 11.6667H9.16663V14.1667C9.16663 14.6269 9.53972 15 9.99996 15C10.4602 15 10.8333 14.6269 10.8333 14.1667V11.6667H13.3333C13.7935 11.6667 14.1666 11.2936 14.1666 10.8334C14.1666 10.3731 13.7935 10 13.3333 10H10.8333V7.50002C10.8333 7.03978 10.4602 6.66669 9.99996 6.66669Z" fill="#0163FF"/>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 1.1 KiB |
|
@ -11,6 +11,7 @@ export { default as IconAudioOnly } from './visibility.svg';
|
||||||
export { default as IconAudioOnlyOff } from './visibility-off.svg';
|
export { default as IconAudioOnlyOff } from './visibility-off.svg';
|
||||||
export { default as IconAudioRoute } from './volume.svg';
|
export { default as IconAudioRoute } from './volume.svg';
|
||||||
export { default as IconBlurBackground } from './blur-background.svg';
|
export { default as IconBlurBackground } from './blur-background.svg';
|
||||||
|
export { default as IconPlusCalendar } from './calendar-plus.svg';
|
||||||
export { default as IconCamera } from './camera.svg';
|
export { default as IconCamera } from './camera.svg';
|
||||||
export { default as IconCameraDisabled } from './camera-disabled.svg';
|
export { default as IconCameraDisabled } from './camera-disabled.svg';
|
||||||
export { default as IconCancelSelection } from './cancel.svg';
|
export { default as IconCancelSelection } from './cancel.svg';
|
||||||
|
|
|
@ -6,6 +6,7 @@ import {
|
||||||
getLocalizedDateFormatter,
|
getLocalizedDateFormatter,
|
||||||
getLocalizedDurationFormatter
|
getLocalizedDurationFormatter
|
||||||
} from '../../../i18n';
|
} from '../../../i18n';
|
||||||
|
import { Icon, IconTrash } from '../../../icons';
|
||||||
|
|
||||||
import Container from './Container';
|
import Container from './Container';
|
||||||
import Text from './Text';
|
import Text from './Text';
|
||||||
|
@ -38,9 +39,9 @@ type Props = {
|
||||||
meetings: Array<Object>,
|
meetings: Array<Object>,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Defines what happens when an item in the section list is clicked
|
* Handler for deleting an item.
|
||||||
*/
|
*/
|
||||||
onItemClick: Function
|
onItemDelete?: Function
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -138,6 +139,25 @@ export default class MeetingsList extends Component<Props> {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_onDelete: Object => Function;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a function that is used on the onDelete callback.
|
||||||
|
*
|
||||||
|
* @param {Object} item - The item to be deleted.
|
||||||
|
* @private
|
||||||
|
* @returns {Function}
|
||||||
|
*/
|
||||||
|
_onDelete(item) {
|
||||||
|
const { onItemDelete } = this.props;
|
||||||
|
|
||||||
|
return evt => {
|
||||||
|
evt.stopPropagation();
|
||||||
|
|
||||||
|
onItemDelete && onItemDelete(item);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
_renderItem: (Object, number) => React$Node;
|
_renderItem: (Object, number) => React$Node;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -156,7 +176,7 @@ export default class MeetingsList extends Component<Props> {
|
||||||
title,
|
title,
|
||||||
url
|
url
|
||||||
} = meeting;
|
} = meeting;
|
||||||
const { hideURL = false } = this.props;
|
const { hideURL = false, onItemDelete } = this.props;
|
||||||
const onPress = this._onPress(url);
|
const onPress = this._onPress(url);
|
||||||
const rootClassName
|
const rootClassName
|
||||||
= `item ${
|
= `item ${
|
||||||
|
@ -168,10 +188,10 @@ export default class MeetingsList extends Component<Props> {
|
||||||
key = { index }
|
key = { index }
|
||||||
onClick = { onPress }>
|
onClick = { onPress }>
|
||||||
<Container className = 'left-column'>
|
<Container className = 'left-column'>
|
||||||
<Text className = 'date'>
|
<Text className = 'title'>
|
||||||
{ _toDateString(date) }
|
{ _toDateString(date) }
|
||||||
</Text>
|
</Text>
|
||||||
<Text>
|
<Text className = 'subtitle'>
|
||||||
{ _toTimeString(time) }
|
{ _toTimeString(time) }
|
||||||
</Text>
|
</Text>
|
||||||
</Container>
|
</Container>
|
||||||
|
@ -187,13 +207,18 @@ export default class MeetingsList extends Component<Props> {
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
typeof duration === 'number' ? (
|
typeof duration === 'number' ? (
|
||||||
<Text>
|
<Text className = 'subtitle'>
|
||||||
{ getLocalizedDurationFormatter(duration) }
|
{ getLocalizedDurationFormatter(duration) }
|
||||||
</Text>) : null
|
</Text>) : null
|
||||||
}
|
}
|
||||||
</Container>
|
</Container>
|
||||||
<Container className = 'actions'>
|
<Container className = 'actions'>
|
||||||
{ elementAfter || null }
|
{ elementAfter || null }
|
||||||
|
|
||||||
|
{ onItemDelete && <Icon
|
||||||
|
className = 'delete-meeting'
|
||||||
|
onClick = { this._onDelete(meeting) }
|
||||||
|
src = { IconTrash } />}
|
||||||
</Container>
|
</Container>
|
||||||
</Container>
|
</Container>
|
||||||
);
|
);
|
||||||
|
|
|
@ -8,6 +8,7 @@ import {
|
||||||
sendAnalytics
|
sendAnalytics
|
||||||
} from '../../analytics';
|
} from '../../analytics';
|
||||||
import { translate } from '../../base/i18n';
|
import { translate } from '../../base/i18n';
|
||||||
|
import { Icon, IconPlusCalendar } from '../../base/icons';
|
||||||
import { AbstractPage } from '../../base/react';
|
import { AbstractPage } from '../../base/react';
|
||||||
import { connect } from '../../base/redux';
|
import { connect } from '../../base/redux';
|
||||||
import { openSettingsDialog, SETTINGS_TABS } from '../../settings';
|
import { openSettingsDialog, SETTINGS_TABS } from '../../settings';
|
||||||
|
@ -185,16 +186,22 @@ class CalendarList extends AbstractPage<Props> {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className = 'meetings-list-empty'>
|
<div className = 'meetings-list-empty'>
|
||||||
<p className = 'description'>
|
<div className = 'meetings-list-empty-image'>
|
||||||
|
<img src = '/images/calendar.svg' />
|
||||||
|
</div>
|
||||||
|
<div className = 'description'>
|
||||||
{ t('welcomepage.connectCalendarText', {
|
{ t('welcomepage.connectCalendarText', {
|
||||||
app: interfaceConfig.APP_NAME,
|
app: interfaceConfig.APP_NAME,
|
||||||
provider: interfaceConfig.PROVIDER_NAME
|
provider: interfaceConfig.PROVIDER_NAME
|
||||||
}) }
|
}) }
|
||||||
</p>
|
</div>
|
||||||
<div
|
<div
|
||||||
className = 'button'
|
className = 'meetings-list-empty-button'
|
||||||
onClick = { this._onOpenSettings }>
|
onClick = { this._onOpenSettings }>
|
||||||
{ t('welcomepage.connectCalendarButton') }
|
<Icon
|
||||||
|
className = 'meetings-list-empty-icon'
|
||||||
|
src = { IconPlusCalendar } />
|
||||||
|
<span>{ t('welcomepage.connectCalendarButton') }</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
|
@ -4,6 +4,7 @@ import Tooltip from '@atlaskit/tooltip';
|
||||||
import React, { Component } from 'react';
|
import React, { Component } from 'react';
|
||||||
|
|
||||||
import { translate } from '../../base/i18n';
|
import { translate } from '../../base/i18n';
|
||||||
|
import { Icon, IconAdd } from '../../base/icons';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The type of the React {@code Component} props of {@link JoinButton}.
|
* The type of the React {@code Component} props of {@link JoinButton}.
|
||||||
|
@ -60,7 +61,9 @@ class JoinButton extends Component<Props> {
|
||||||
<div
|
<div
|
||||||
className = 'button join-button'
|
className = 'button join-button'
|
||||||
onClick = { this._onClick }>
|
onClick = { this._onClick }>
|
||||||
{ t('calendarSync.join') }
|
<Icon
|
||||||
|
size = '14'
|
||||||
|
src = { IconAdd } />
|
||||||
</div>
|
</div>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
);
|
);
|
||||||
|
|
|
@ -6,6 +6,7 @@ import type { Dispatch } from 'redux';
|
||||||
import { translate } from '../../base/i18n';
|
import { translate } from '../../base/i18n';
|
||||||
import { MeetingsList } from '../../base/react';
|
import { MeetingsList } from '../../base/react';
|
||||||
import { connect } from '../../base/redux';
|
import { connect } from '../../base/redux';
|
||||||
|
import { deleteRecentListEntry } from '../actions';
|
||||||
import { isRecentListEnabled, toDisplayableList } from '../functions';
|
import { isRecentListEnabled, toDisplayableList } from '../functions';
|
||||||
|
|
||||||
import AbstractRecentList from './AbstractRecentList';
|
import AbstractRecentList from './AbstractRecentList';
|
||||||
|
@ -55,6 +56,19 @@ class RecentList extends AbstractRecentList<Props> {
|
||||||
this._getRenderListEmptyComponent
|
this._getRenderListEmptyComponent
|
||||||
= this._getRenderListEmptyComponent.bind(this);
|
= this._getRenderListEmptyComponent.bind(this);
|
||||||
this._onPress = this._onPress.bind(this);
|
this._onPress = this._onPress.bind(this);
|
||||||
|
this._onItemDelete = this._onItemDelete.bind(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
_onItemDelete: Object => void;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deletes a recent entry.
|
||||||
|
*
|
||||||
|
* @param {Object} entry - The entry to be deleted.
|
||||||
|
* @inheritdoc
|
||||||
|
*/
|
||||||
|
_onItemDelete(entry) {
|
||||||
|
this.props.dispatch(deleteRecentListEntry(entry));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -78,6 +92,7 @@ class RecentList extends AbstractRecentList<Props> {
|
||||||
hideURL = { true }
|
hideURL = { true }
|
||||||
listEmptyComponent = { this._getRenderListEmptyComponent() }
|
listEmptyComponent = { this._getRenderListEmptyComponent() }
|
||||||
meetings = { recentList }
|
meetings = { recentList }
|
||||||
|
onItemDelete = { this._onItemDelete }
|
||||||
onPress = { this._onPress } />
|
onPress = { this._onPress } />
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,7 +12,7 @@ import { parseURIString, safeDecodeURIComponent } from '../base/util';
|
||||||
*/
|
*/
|
||||||
export function toDisplayableList(recentList) {
|
export function toDisplayableList(recentList) {
|
||||||
return (
|
return (
|
||||||
recentList.slice(-3).reverse()
|
recentList.reverse()
|
||||||
.map(item => {
|
.map(item => {
|
||||||
return {
|
return {
|
||||||
date: item.date,
|
date: item.date,
|
||||||
|
|
|
@ -47,9 +47,6 @@ export default class Tabs extends Component<Props> {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className = 'tab-container'>
|
<div className = 'tab-container'>
|
||||||
<div className = 'tab-content'>
|
|
||||||
{ content }
|
|
||||||
</div>
|
|
||||||
{ tabs.length > 1 ? (
|
{ tabs.length > 1 ? (
|
||||||
<div className = 'tab-buttons'>
|
<div className = 'tab-buttons'>
|
||||||
{
|
{
|
||||||
|
@ -64,6 +61,9 @@ export default class Tabs extends Component<Props> {
|
||||||
}
|
}
|
||||||
</div>) : null
|
</div>) : null
|
||||||
}
|
}
|
||||||
|
<div className = 'tab-content'>
|
||||||
|
{ content }
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,12 +20,6 @@ import Tabs from './Tabs';
|
||||||
*/
|
*/
|
||||||
export const ROOM_NAME_VALIDATE_PATTERN_STR = '^[^?&:\u0022\u0027%#]+$';
|
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.
|
* The Web container rendering the welcome page.
|
||||||
*
|
*
|
||||||
|
@ -78,6 +72,17 @@ class WelcomePage extends AbstractWelcomePage {
|
||||||
*/
|
*/
|
||||||
this._additionalToolbarContentRef = null;
|
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
|
* The template to use as the main content for the welcome page. If
|
||||||
* not found then only the welcome page head will display.
|
* 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.
|
// Bind event handlers so they are only bound once per instance.
|
||||||
this._onFormSubmit = this._onFormSubmit.bind(this);
|
this._onFormSubmit = this._onFormSubmit.bind(this);
|
||||||
this._onRoomChange = this._onRoomChange.bind(this);
|
this._onRoomChange = this._onRoomChange.bind(this);
|
||||||
|
this._setAdditionalCardRef = this._setAdditionalCardRef.bind(this);
|
||||||
this._setAdditionalContentRef
|
this._setAdditionalContentRef
|
||||||
= this._setAdditionalContentRef.bind(this);
|
= this._setAdditionalContentRef.bind(this);
|
||||||
this._setRoomInputRef = this._setRoomInputRef.bind(this);
|
this._setRoomInputRef = this._setRoomInputRef.bind(this);
|
||||||
this._setAdditionalToolbarContentRef
|
this._setAdditionalToolbarContentRef
|
||||||
= this._setAdditionalToolbarContentRef.bind(this);
|
= this._setAdditionalToolbarContentRef.bind(this);
|
||||||
this._onTabSelected = this._onTabSelected.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)
|
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() {
|
render() {
|
||||||
const { _moderatedRoomServiceUrl, t } = this.props;
|
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 showAdditionalContent = this._shouldShowAdditionalContent();
|
||||||
const showAdditionalToolbarContent = this._shouldShowAdditionalToolbarContent();
|
const showAdditionalToolbarContent = this._shouldShowAdditionalToolbarContent();
|
||||||
const showResponsiveText = this._shouldShowResponsiveText();
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
|
@ -172,6 +185,7 @@ class WelcomePage extends AbstractWelcomePage {
|
||||||
<div className = 'welcome-watermark'>
|
<div className = 'welcome-watermark'>
|
||||||
<Watermarks defaultJitsiLogoURL = { DEFAULT_WELCOME_PAGE_LOGO_URL } />
|
<Watermarks defaultJitsiLogoURL = { DEFAULT_WELCOME_PAGE_LOGO_URL } />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className = 'header'>
|
<div className = 'header'>
|
||||||
<div className = 'welcome-page-settings'>
|
<div className = 'welcome-page-settings'>
|
||||||
<SettingsButton
|
<SettingsButton
|
||||||
|
@ -184,64 +198,82 @@ class WelcomePage extends AbstractWelcomePage {
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
<div className = 'header-image' />
|
<div className = 'header-image' />
|
||||||
<div className = 'header-text'>
|
<div className = 'header-container'>
|
||||||
<h1 className = 'header-text-title'>
|
<h1 className = 'header-text-title'>
|
||||||
{ t('welcomepage.title') }
|
{ t('welcomepage.jitsiMeet') }
|
||||||
</h1>
|
</h1>
|
||||||
<p className = 'header-text-description'>
|
<span className = 'header-text-subtitle'>
|
||||||
{ t('welcomepage.appDescription',
|
{ t('welcomepage.secureMeetings')}
|
||||||
{ app: APP_NAME }) }
|
</span>
|
||||||
</p>
|
<div id = 'enter_room'>
|
||||||
</div>
|
<div className = 'enter-room-input-container'>
|
||||||
<div id = 'enter_room'>
|
<form onSubmit = { this._onFormSubmit }>
|
||||||
<div className = 'enter-room-input-container'>
|
<input
|
||||||
<div className = 'enter-room-title'>
|
aria-disabled = 'false'
|
||||||
{ t('welcomepage.enterRoomTitle') }
|
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() }
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
</div>
|
</div>
|
||||||
<form onSubmit = { this._onFormSubmit }>
|
<button
|
||||||
<input
|
aria-disabled = 'false'
|
||||||
autoFocus = { true }
|
aria-label = 'Start meeting'
|
||||||
className = 'enter-room-input'
|
className = 'welcome-page-button'
|
||||||
id = 'enter_room_field'
|
id = 'enter_room_button'
|
||||||
onChange = { this._onRoomChange }
|
onClick = { this._onFormSubmit }
|
||||||
pattern = { ROOM_NAME_VALIDATE_PATTERN_STR }
|
tabIndex = '0'
|
||||||
placeholder = { this.state.roomPlaceholder }
|
type = 'button'>
|
||||||
ref = { this._setRoomInputRef }
|
{ t('welcomepage.startMeeting') }
|
||||||
title = { t('welcomepage.roomNameAllowedChars') }
|
</button>
|
||||||
type = 'text'
|
|
||||||
value = { this.state.room } />
|
|
||||||
{ this._renderInsecureRoomNameWarning() }
|
|
||||||
</form>
|
|
||||||
</div>
|
</div>
|
||||||
<div
|
|
||||||
className = 'welcome-page-button'
|
{ _moderatedRoomServiceUrl && (
|
||||||
id = 'enter_room_button'
|
<div id = 'moderated-meetings'>
|
||||||
onClick = { this._onFormSubmit }>
|
<p>
|
||||||
{
|
{
|
||||||
showResponsiveText
|
translateToHTML(
|
||||||
? t('welcomepage.goSmall')
|
|
||||||
: t('welcomepage.go')
|
|
||||||
}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{ _moderatedRoomServiceUrl && (
|
|
||||||
<div id = 'moderated-meetings'>
|
|
||||||
<p>
|
|
||||||
{
|
|
||||||
translateToHTML(
|
|
||||||
t, 'welcomepage.moderatedMessage', { url: _moderatedRoomServiceUrl })
|
t, 'welcomepage.moderatedMessage', { url: _moderatedRoomServiceUrl })
|
||||||
}
|
}
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>)}
|
||||||
) }
|
</div>
|
||||||
{ this._renderTabs() }
|
|
||||||
</div>
|
</div>
|
||||||
{ showAdditionalContent
|
|
||||||
? <div
|
<div className = 'welcome-cards-container'>
|
||||||
className = 'welcome-page-content'
|
<div className = 'welcome-card-row'>
|
||||||
ref = { this._setAdditionalContentRef } />
|
<div className = 'welcome-tabs welcome-card welcome-card--blue'>
|
||||||
: null }
|
{ this._renderTabs() }
|
||||||
|
</div>
|
||||||
|
{ showAdditionalCard
|
||||||
|
? <div
|
||||||
|
className = 'welcome-card welcome-card--dark'
|
||||||
|
ref = { this._setAdditionalCardRef } />
|
||||||
|
: null }
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{ showAdditionalContent
|
||||||
|
? <div
|
||||||
|
className = 'welcome-page-content'
|
||||||
|
ref = { this._setAdditionalContentRef } />
|
||||||
|
: null }
|
||||||
|
</div>
|
||||||
|
{ DISPLAY_WELCOME_FOOTER && this._renderFooter()}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -302,6 +334,45 @@ class WelcomePage extends AbstractWelcomePage {
|
||||||
this.setState({ selectedTab: tabIndex });
|
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')}</div>
|
||||||
|
<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>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</footer>);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Renders tabs to show previous meetings and upcoming calendar events. The
|
* Renders tabs to show previous meetings and upcoming calendar events. The
|
||||||
* tabs are purposefully hidden on mobile browsers.
|
* tabs are purposefully hidden on mobile browsers.
|
||||||
|
@ -342,6 +413,19 @@ class WelcomePage extends AbstractWelcomePage {
|
||||||
tabs = { tabs } />);
|
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
|
* Sets the internal reference to the HTMLDivElement used to hold the
|
||||||
* welcome page content.
|
* welcome page content.
|
||||||
|
@ -380,6 +464,19 @@ class WelcomePage extends AbstractWelcomePage {
|
||||||
this._roomInputRef = el;
|
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
|
* Returns whether or not additional content should be displayed below
|
||||||
* the welcome page's header for entering a room name.
|
* the welcome page's header for entering a room name.
|
||||||
|
@ -407,20 +504,6 @@ class WelcomePage extends AbstractWelcomePage {
|
||||||
&& this._additionalToolbarContentTemplate.content
|
&& this._additionalToolbarContentTemplate.content
|
||||||
&& this._additionalToolbarContentTemplate.innerHTML.trim();
|
&& 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));
|
export default translate(connect(_mapStateToProps)(WelcomePage));
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
<template id = "welcome-page-additional-card-template"></template>
|