hook multifile to ui
This commit is contained in:
parent
e42ad175db
commit
c9ae76b209
77 changed files with 1528 additions and 1111 deletions
|
@ -1,26 +0,0 @@
|
|||
const html = require('choo/html');
|
||||
const progress = require('../../templates/progress');
|
||||
const { fadeOut } = require('../../utils');
|
||||
|
||||
module.exports = function(state, emit) {
|
||||
return html`
|
||||
<div class="page effect--fadeIn">
|
||||
<div class="title">
|
||||
${state.translate('downloadFinish')}
|
||||
</div>
|
||||
<div class="description"></div>
|
||||
${progress(1)}
|
||||
<div class="progressSection">
|
||||
<div class="progressSection__text"></div>
|
||||
</div>
|
||||
<a class="link link--action"
|
||||
href="/"
|
||||
onclick=${sendNew}>${state.translate('sendYourFilesLink')}</a>
|
||||
</div>`;
|
||||
|
||||
async function sendNew(e) {
|
||||
e.preventDefault();
|
||||
await fadeOut('.page');
|
||||
emit('pushState', '/');
|
||||
}
|
||||
};
|
|
@ -1,42 +0,0 @@
|
|||
const html = require('choo/html');
|
||||
const progress = require('../../templates/progress');
|
||||
const { bytes } = require('../../utils');
|
||||
|
||||
module.exports = function(state, emit) {
|
||||
const transfer = state.transfer;
|
||||
const cancelBtn = html`
|
||||
<button
|
||||
id="cancel"
|
||||
class="btn btn--cancel"
|
||||
title="${state.translate('deletePopupCancel')}"
|
||||
onclick=${cancel}>
|
||||
${state.translate('deletePopupCancel')}
|
||||
</button>`;
|
||||
|
||||
return html`
|
||||
<div class="page effect--fadeIn">
|
||||
<div class="title">
|
||||
${state.translate('downloadingPageProgress', {
|
||||
filename: state.fileInfo.name,
|
||||
size: bytes(state.fileInfo.size)
|
||||
})}
|
||||
</div>
|
||||
<div class="description">
|
||||
${state.translate('downloadingPageMessage')}
|
||||
</div>
|
||||
${progress(transfer.progressRatio, transfer.progressIndefinite)}
|
||||
<div class="progressSection">
|
||||
<div class="progressSection__text">
|
||||
${state.translate(transfer.msg, transfer.sizes)}
|
||||
</div>
|
||||
${transfer.state === 'downloading' ? cancelBtn : null}
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
function cancel() {
|
||||
const btn = document.getElementById('cancel');
|
||||
btn.remove();
|
||||
emit('cancel');
|
||||
}
|
||||
};
|
|
@ -1,10 +1,22 @@
|
|||
const html = require('choo/html');
|
||||
const assets = require('../../../common/assets');
|
||||
const title = require('../../templates/title');
|
||||
|
||||
module.exports = function(state) {
|
||||
return html`
|
||||
<div class="page">
|
||||
<div class="title">${state.translate('errorPageHeader')}</div>
|
||||
<img src="${assets.get('illustration_error.svg')}"/>
|
||||
|
||||
${title(state)}
|
||||
|
||||
<div class="error">${state.translate('errorPageHeader')}</div>
|
||||
<img class="flexible" src="${assets.get('illustration_error.svg')}"/>
|
||||
|
||||
<div class="description">
|
||||
${state.translate('uploadPageExplainer')}
|
||||
</div>
|
||||
<a class="link link--action" href="/">
|
||||
${state.translate('sendYourFilesLink')}
|
||||
</a>
|
||||
|
||||
</div>`;
|
||||
};
|
||||
|
|
|
@ -1,11 +1,17 @@
|
|||
const html = require('choo/html');
|
||||
const assets = require('../../../common/assets');
|
||||
const title = require('../../templates/title');
|
||||
|
||||
module.exports = function(state) {
|
||||
return html`
|
||||
<div class="page">
|
||||
<div class="title">${state.translate('expiredPageHeader')}</div>
|
||||
<img src="${assets.get('illustration_expired.svg')}" id="expired-img">
|
||||
|
||||
${title(state)}
|
||||
|
||||
<div class="error">${state.translate('expiredPageHeader')}</div>
|
||||
<img src="${assets.get(
|
||||
'illustration_expired.svg'
|
||||
)}" class="flexible" id="expired-img">
|
||||
<div class="description">
|
||||
${state.translate('uploadPageExplainer')}
|
||||
</div>
|
||||
|
|
19
app/pages/password/index.js
Normal file
19
app/pages/password/index.js
Normal file
|
@ -0,0 +1,19 @@
|
|||
const html = require('choo/html');
|
||||
const titleSection = require('../../templates/title');
|
||||
const downloadPassword = require('../../templates/downloadPassword');
|
||||
|
||||
module.exports = function(state, emit) {
|
||||
return html`
|
||||
<div class="page">
|
||||
${titleSection(state)}
|
||||
|
||||
<div class="description">${state.translate('downloadMessage2')}</div>
|
||||
${downloadPassword(state, emit)}
|
||||
|
||||
<a class="link link--action" href="/">
|
||||
${state.translate('sendYourFilesLink')}
|
||||
</a>
|
||||
|
||||
</div>
|
||||
`;
|
||||
};
|
|
@ -1,40 +1,25 @@
|
|||
const html = require('choo/html');
|
||||
const assets = require('../../../common/assets');
|
||||
const { bytes } = require('../../utils');
|
||||
const titleSection = require('../../templates/title');
|
||||
const downloadButton = require('../../templates/downloadButton');
|
||||
const downloadedFiles = require('../../templates/uploadedFileList');
|
||||
|
||||
module.exports = function(state, pageAction) {
|
||||
const fileInfo = state.fileInfo;
|
||||
module.exports = function(state, emit) {
|
||||
const storageFile = state.storage.getFileById(state.params.id);
|
||||
|
||||
const size = fileInfo.size
|
||||
? state.translate('downloadFileSize', { size: bytes(fileInfo.size) })
|
||||
: '';
|
||||
const multifiles = Array.from(storageFile.manifest.files);
|
||||
|
||||
const title = fileInfo.name
|
||||
? state.translate('downloadFileName', { filename: fileInfo.name })
|
||||
: state.translate('downloadFileTitle');
|
||||
|
||||
const info = html`
|
||||
<div id="dl-file"
|
||||
data-nonce="${fileInfo.nonce}"
|
||||
data-requires-password="${fileInfo.requiresPassword}"></div>`;
|
||||
if (!pageAction) {
|
||||
return info;
|
||||
}
|
||||
return html`
|
||||
<div class="page">
|
||||
<div class="title">
|
||||
<span>${title}</span>
|
||||
<span>${' ' + size}</span>
|
||||
</div>
|
||||
<div class="description">${state.translate('downloadMessage')}</div>
|
||||
<img
|
||||
src="${assets.get('illustration_download.svg')}"
|
||||
title="${state.translate('downloadAltText')}"/>
|
||||
${pageAction}
|
||||
${titleSection(state)}
|
||||
|
||||
${downloadedFiles(multifiles, state, emit)}
|
||||
<div class="description">${state.translate('downloadMessage2')}</div>
|
||||
${downloadButton(state, emit)}
|
||||
|
||||
<a class="link link--action" href="/">
|
||||
${state.translate('sendYourFilesLink')}
|
||||
</a>
|
||||
${info}
|
||||
|
||||
</div>
|
||||
`;
|
||||
};
|
||||
|
|
|
@ -3,42 +3,51 @@ const html = require('choo/html');
|
|||
const raw = require('choo/html/raw');
|
||||
const assets = require('../../../common/assets');
|
||||
const notFound = require('../notFound');
|
||||
const setPasswordSection = require('../../templates/setPasswordSection');
|
||||
const selectbox = require('../../templates/selectbox');
|
||||
const deletePopup = require('../../templates/popup');
|
||||
const uploadedFiles = require('../../templates/uploadedFileList');
|
||||
const { allowedCopy, delay, fadeOut } = require('../../utils');
|
||||
|
||||
module.exports = function(state, emit) {
|
||||
const file = state.storage.getFileById(state.params.id);
|
||||
if (!file) {
|
||||
return notFound(state, emit);
|
||||
return notFound(state);
|
||||
}
|
||||
|
||||
const passwordReminderClass = file._hasPassword
|
||||
? ''
|
||||
: 'passwordReminder--hidden';
|
||||
|
||||
const multifiles = Array.from(file.manifest.files);
|
||||
|
||||
return html`
|
||||
<div id="shareWrapper" class="effect--fadeIn">
|
||||
${expireInfo(file, state.translate, emit)}
|
||||
<div class="sharePage">
|
||||
|
||||
<div class="page effect--fadeIn" id="shareWrapper">
|
||||
<a href="/" class="goBackButton">
|
||||
<img src="${assets.get('back-arrow.svg')}"/>
|
||||
</a>
|
||||
${expireInfo(file, state.translate)}
|
||||
|
||||
${uploadedFiles(multifiles, state, emit)}
|
||||
|
||||
|
||||
<div class="sharePage__copyText">
|
||||
${state.translate('copyUrlFormLabelWithName', { filename: file.name })}
|
||||
${state.translate('copyUrlFormLabelWithName', { filename: '' })}
|
||||
<div class="sharePage__passwordReminder ${passwordReminderClass}">(don't forget the password too)</div>
|
||||
</div>
|
||||
<div class="copySection">
|
||||
<input
|
||||
id="fileUrl"
|
||||
class="copySection__url"
|
||||
type="url"
|
||||
value="${file.url}"
|
||||
readonly="true"/>
|
||||
<button id="copyBtn"
|
||||
class="inputBtn inputBtn--copy"
|
||||
title="${state.translate('copyUrlFormButton')}"
|
||||
onclick=${copyLink}>${state.translate('copyUrlFormButton')}</button>
|
||||
</div>
|
||||
${setPasswordSection(state, emit)}
|
||||
<button
|
||||
class="btn btn--delete"
|
||||
title="${state.translate('deleteFileButton')}"
|
||||
onclick=${showPopup}>${state.translate('deleteFileButton')}
|
||||
|
||||
<input
|
||||
id="fileUrl"
|
||||
class="copySection__url"
|
||||
type="url"
|
||||
value="${file.url}"
|
||||
readonly="true"/>
|
||||
|
||||
<button id="copyBtn"
|
||||
class="btn copyBtn"
|
||||
title="${state.translate('copyUrlFormButton')}"
|
||||
onclick=${copyLink}>${state.translate('copyUrlFormButton')}
|
||||
</button>
|
||||
|
||||
<div class="sharePage__deletePopup">
|
||||
${deletePopup(
|
||||
state.translate('deletePopupText'),
|
||||
|
@ -47,11 +56,15 @@ module.exports = function(state, emit) {
|
|||
deleteFile
|
||||
)}
|
||||
</div>
|
||||
<a class="link link--action"
|
||||
href="/"
|
||||
onclick=${sendNew}>${state.translate('sendAnotherFileLink')}</a>
|
||||
|
||||
<a
|
||||
class="error btn--delete"
|
||||
title="${state.translate('deleteFileButton')}"
|
||||
onclick=${showPopup}>${state.translate('deleteFileButton')}
|
||||
</a>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
`;
|
||||
|
||||
function showPopup() {
|
||||
|
@ -60,30 +73,22 @@ module.exports = function(state, emit) {
|
|||
popup.focus();
|
||||
}
|
||||
|
||||
async function sendNew(e) {
|
||||
e.preventDefault();
|
||||
await fadeOut('#shareWrapper');
|
||||
emit('pushState', '/');
|
||||
}
|
||||
|
||||
async function copyLink() {
|
||||
if (allowedCopy()) {
|
||||
emit('copy', { url: file.url, location: 'success-screen' });
|
||||
const input = document.getElementById('fileUrl');
|
||||
input.disabled = true;
|
||||
input.classList.add('input--copied');
|
||||
const copyBtn = document.getElementById('copyBtn');
|
||||
copyBtn.disabled = true;
|
||||
copyBtn.classList.add('inputBtn--copied');
|
||||
copyBtn.classList.add('copyBtn--copied');
|
||||
copyBtn.replaceChild(
|
||||
html`<img src="${assets.get('check-16.svg')}" class="cursor--pointer">`,
|
||||
html`<label>${state.translate('copiedUrl')}</label>`,
|
||||
copyBtn.firstChild
|
||||
);
|
||||
await delay(2000);
|
||||
input.disabled = false;
|
||||
input.classList.remove('input--copied');
|
||||
copyBtn.disabled = false;
|
||||
copyBtn.classList.remove('inputBtn--copied');
|
||||
copyBtn.classList.remove('copyBtn--copied');
|
||||
copyBtn.textContent = state.translate('copyUrlFormButton');
|
||||
}
|
||||
}
|
||||
|
@ -95,18 +100,14 @@ module.exports = function(state, emit) {
|
|||
}
|
||||
};
|
||||
|
||||
function expireInfo(file, translate, emit) {
|
||||
function expireInfo(file, translate) {
|
||||
const hours = Math.floor(EXPIRE_SECONDS / 60 / 60);
|
||||
const el = html`<div class="title">${raw(
|
||||
const el = html`<div class="shareTitle">${raw(
|
||||
translate('expireInfo', {
|
||||
downloadCount: '<select></select>',
|
||||
downloadCount: translate('downloadCount', { num: file.dlimit }),
|
||||
timespan: translate('timespanHours', { num: hours })
|
||||
})
|
||||
)}</div>`;
|
||||
const select = el.querySelector('select');
|
||||
const options = [1, 2, 3, 4, 5, 20].filter(i => i > (file.dtotal || 0));
|
||||
const t = num => translate('downloadCount', { num });
|
||||
const changed = value => emit('changeLimit', { file, value });
|
||||
el.replaceChild(selectbox(file.dlimit || 1, options, t, changed), select);
|
||||
|
||||
return el;
|
||||
}
|
||||
|
|
|
@ -1,112 +1,86 @@
|
|||
.sharePage {
|
||||
margin: 0 auto;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
flex-direction: column;
|
||||
width: 100%;
|
||||
max-width: 640px;
|
||||
.sharePage__copyText {
|
||||
margin: 8px 0 8px;
|
||||
word-wrap: break-word;
|
||||
font-size: 15px;
|
||||
color: var(--lightTextColor);
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.sharePage__copyText {
|
||||
align-self: flex-start;
|
||||
margin-top: 60px;
|
||||
margin-bottom: 10px;
|
||||
color: var(--textColor);
|
||||
max-width: 614px;
|
||||
word-wrap: break-word;
|
||||
.sharePage__passwordReminder {
|
||||
font-size: 11px;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.passwordReminder--hidden {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.sharePage__deletePopup {
|
||||
position: relative;
|
||||
align-self: center;
|
||||
bottom: 50px;
|
||||
margin-top: -70px;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.shareTitle {
|
||||
color: var(--textColor);
|
||||
margin: 8px auto 15px;
|
||||
text-align: center;
|
||||
font-family: 'SF Pro Text', sans-serif;
|
||||
font-size: 12px;
|
||||
font-style: italic;
|
||||
width: 280px;
|
||||
}
|
||||
|
||||
.copySection {
|
||||
display: flex;
|
||||
flex-wrap: nowrap;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.copySection__url {
|
||||
flex: 1;
|
||||
height: 56px;
|
||||
border: 1px solid var(--primaryControlBGColor);
|
||||
border-radius: 6px 0 0 6px;
|
||||
font-size: 20px;
|
||||
color: var(--inputTextColor);
|
||||
box-sizing: border-box;
|
||||
height: 30px;
|
||||
border: 1px solid var(--lightBorderColor);
|
||||
border-radius: 4px;
|
||||
font-size: 15px;
|
||||
color: var(--primaryControlBGColor);
|
||||
margin: 0 0 6px;
|
||||
padding: 6px;
|
||||
font-family: 'SF Pro Text', sans-serif;
|
||||
letter-spacing: 0;
|
||||
line-height: 23px;
|
||||
font-weight: 300;
|
||||
padding-left: 10px;
|
||||
line-height: 18px;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.copySection__url:disabled {
|
||||
border: 1px solid var(--successControlBGColor);
|
||||
background: var(--successControlFGColor);
|
||||
}
|
||||
|
||||
.inputBtn--copy {
|
||||
flex: 0 1 165px;
|
||||
padding-bottom: 4px;
|
||||
}
|
||||
|
||||
.input--copied {
|
||||
border-color: var(--successControlBGColor);
|
||||
}
|
||||
|
||||
.inputBtn--copied,
|
||||
.inputBtn--copied:hover {
|
||||
.copyBtn {
|
||||
transition: background 0.5s;
|
||||
}
|
||||
|
||||
.copyBtn--copied,
|
||||
.copyBtn--copied:hover {
|
||||
background: var(--successControlBGColor);
|
||||
border: 1px solid var(--successControlBGColor);
|
||||
color: var(--successControlFGColor);
|
||||
transition: background 0s;
|
||||
}
|
||||
|
||||
.btn--delete {
|
||||
border: none;
|
||||
align-self: center;
|
||||
width: 176px;
|
||||
height: 44px;
|
||||
background: #fff;
|
||||
border-color: rgba(12, 12, 13, 0.3);
|
||||
margin-top: 50px;
|
||||
margin-bottom: 12px;
|
||||
color: #313131;
|
||||
margin: 10px 0 0;
|
||||
font-size: 14px;
|
||||
line-height: 16px;
|
||||
color: var(--errorColor);
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.btn--delete:hover {
|
||||
background: #efeff1;
|
||||
}
|
||||
|
||||
@media (max-device-width: 768px), (max-width: 768px) {
|
||||
.copySection {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.copySection__url {
|
||||
font-size: 18px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-device-width: 520px), (max-width: 520px) {
|
||||
.copySection {
|
||||
width: 100%;
|
||||
flex-direction: column;
|
||||
padding-left: 0;
|
||||
}
|
||||
|
||||
.copySection__url {
|
||||
font-size: 22px;
|
||||
padding: 15px 10px;
|
||||
border-radius: 6px 6px 0 0;
|
||||
}
|
||||
|
||||
.sharePage__copyText {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.inputBtn--copy {
|
||||
border-radius: 0 0 6px 6px;
|
||||
flex: 0 1 65px;
|
||||
}
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
|
60
app/pages/signin/index.js
Normal file
60
app/pages/signin/index.js
Normal file
|
@ -0,0 +1,60 @@
|
|||
const html = require('choo/html');
|
||||
const assets = require('../../../common/assets');
|
||||
const title = require('../../templates/title');
|
||||
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
module.exports = function(state, emit) {
|
||||
return html`
|
||||
|
||||
<div class="page signInPage">
|
||||
<a href="/" class="goBackButton">
|
||||
<img src="${assets.get('back-arrow.svg')}"/>
|
||||
</a>
|
||||
${title(state)}
|
||||
|
||||
<div class="signIn__info flexible">
|
||||
${state.translate('accountBenefitTitle')}
|
||||
<ul>
|
||||
<li>${state.translate('accountBenefitMultiFile')}</li>
|
||||
<li>${state.translate('accountBenefitLargeFiles')}</li>
|
||||
<li>${state.translate('accountBenefitExpiry')}</li>
|
||||
<li>${state.translate('accountBenefitSync')}</li>
|
||||
<li>${state.translate('accountBenefitNotify')}</li>
|
||||
<li>${state.translate('accountBenefitMore')}</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="signIn__form flexible">
|
||||
|
||||
<img class="signIn__firefoxLogo"
|
||||
src="${assets.get('firefox_logo-only.svg')}"
|
||||
width=56 height=56
|
||||
alt="Firefox logo"/>
|
||||
|
||||
<div class="signIn__emailLabel">
|
||||
${state.translate('signInEmailEnter')}
|
||||
</div>
|
||||
${state.translate('signInContinueMessage')}
|
||||
|
||||
<form
|
||||
data-no-csrf>
|
||||
<input
|
||||
type="text"
|
||||
class="signIn__emailInput"
|
||||
placeholder=${state.translate('emailEntryPlaceholder')}/>
|
||||
|
||||
<input
|
||||
class='noDisplay'
|
||||
id="emailSubmit"
|
||||
type="submit"/>
|
||||
</form>
|
||||
|
||||
</div>
|
||||
|
||||
<label class="btn" for="emailSubmit">
|
||||
${state.translate('signInContinueButton')}
|
||||
</label>
|
||||
|
||||
</div>
|
||||
`;
|
||||
};
|
33
app/pages/signin/signin.css
Normal file
33
app/pages/signin/signin.css
Normal file
|
@ -0,0 +1,33 @@
|
|||
.signInPage {
|
||||
font-size: 13px;
|
||||
line-height: 18px;
|
||||
color: var(--lightTextColor);
|
||||
}
|
||||
|
||||
.signIn__info {
|
||||
width: 308px;
|
||||
margin: 16px auto 0;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.signIn__firefoxLogo {
|
||||
display: block;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.signIn__emailLabel {
|
||||
font-size: 22px;
|
||||
margin: 8px 0;
|
||||
}
|
||||
|
||||
.signIn__emailInput {
|
||||
box-sizing: border-box;
|
||||
width: 310px;
|
||||
height: 40px;
|
||||
border: 1px solid rgba(0, 0, 0, 0.2);
|
||||
border-radius: 4px;
|
||||
margin: 0;
|
||||
padding: 0 8px;
|
||||
font-size: 18px;
|
||||
color: var(--lightTextColor);
|
||||
}
|
|
@ -1,11 +1,13 @@
|
|||
const html = require('choo/html');
|
||||
const assets = require('../../../common/assets');
|
||||
const title = require('../../templates/title');
|
||||
|
||||
module.exports = function(state) {
|
||||
let strings = {};
|
||||
let why = '';
|
||||
let url = '';
|
||||
let buttonAction = '';
|
||||
|
||||
if (state.params.reason !== 'outdated') {
|
||||
strings = unsupportedStrings(state);
|
||||
why = html`
|
||||
|
@ -28,20 +30,26 @@ module.exports = function(state) {
|
|||
${strings.button}
|
||||
</div>`;
|
||||
}
|
||||
|
||||
return html`
|
||||
<div class="unsupportedPage">
|
||||
<div class="title">${strings.title}</div>
|
||||
<div class="description">
|
||||
<div class="page unsupportedPage">
|
||||
${title(state)}
|
||||
<div class="error unsupportedPage__error">${strings.header}</div>
|
||||
<div class="description flexible">
|
||||
${strings.description}
|
||||
${why}
|
||||
</div>
|
||||
${why}
|
||||
<a href="${url}" class="firefoxDownload">
|
||||
<img
|
||||
src="${assets.get('firefox_logo-only.svg')}"
|
||||
class="firefoxDownload__logo"
|
||||
alt="Firefox"/>
|
||||
${buttonAction}
|
||||
</a>
|
||||
|
||||
<div class="flexible firefoxDownload">
|
||||
<a href="${url}" class="firefoxDownload__button">
|
||||
<img
|
||||
src="${assets.get('firefox_logo-only.svg')}"
|
||||
class="firefoxDownload__logo"
|
||||
alt="Firefox"/>
|
||||
${buttonAction}
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div class="unsupportedPage__info">
|
||||
${strings.explainer}
|
||||
</div>
|
||||
|
@ -50,7 +58,7 @@ module.exports = function(state) {
|
|||
|
||||
function outdatedStrings(state) {
|
||||
return {
|
||||
title: state.translate('notSupportedHeader'),
|
||||
header: state.translate('notSupportedHeader'),
|
||||
description: state.translate('notSupportedOutdatedDetail'),
|
||||
button: state.translate('updateFirefox'),
|
||||
explainer: state.translate('uploadPageExplainer')
|
||||
|
@ -59,7 +67,7 @@ function outdatedStrings(state) {
|
|||
|
||||
function unsupportedStrings(state) {
|
||||
return {
|
||||
title: state.translate('notSupportedHeader'),
|
||||
header: state.translate('notSupportedHeader'),
|
||||
description: state.translate('notSupportedDetail'),
|
||||
button: state.translate('downloadFirefoxButtonSub'),
|
||||
explainer: state.translate('uploadPageExplainer')
|
||||
|
|
|
@ -1,26 +1,30 @@
|
|||
.unsupportedPage {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.unsupportedPage__error {
|
||||
margin: 10px 0 20px;
|
||||
}
|
||||
|
||||
.unsupportedPage__info {
|
||||
font-size: 13px;
|
||||
line-height: 23px;
|
||||
text-align: center;
|
||||
color: var(--lightTextColor);
|
||||
margin: 0 auto 23px;
|
||||
margin: 0 auto 10px;
|
||||
}
|
||||
|
||||
.firefoxDownload {
|
||||
margin-bottom: 181px;
|
||||
height: 80px;
|
||||
background: #98e02b;
|
||||
flex: 2;
|
||||
}
|
||||
|
||||
.firefoxDownload__button {
|
||||
margin: 0 auto 20px;
|
||||
height: 70px;
|
||||
width: 250px;
|
||||
background: #12bc00;
|
||||
border-radius: 3px;
|
||||
cursor: pointer;
|
||||
border: 0;
|
||||
box-shadow: 0 5px 3px rgb(234, 234, 234);
|
||||
font-family: 'Fira Sans', 'segoe ui', sans-serif;
|
||||
font-weight: 500;
|
||||
color: var(--primaryControlFGColor);
|
||||
|
@ -29,21 +33,22 @@
|
|||
justify-content: center;
|
||||
align-items: center;
|
||||
line-height: 1;
|
||||
padding: 0 25px;
|
||||
padding: 8px;
|
||||
}
|
||||
|
||||
.firefoxDownload__logo {
|
||||
width: 70px;
|
||||
width: 55px;
|
||||
}
|
||||
|
||||
.firefoxDownload__action {
|
||||
text-align: left;
|
||||
margin-left: 20.4px;
|
||||
text-transform: uppercase;
|
||||
margin-left: 20px;
|
||||
}
|
||||
|
||||
.firefoxDownload__text {
|
||||
text-transform: none;
|
||||
font-family: 'Fira Sans', 'segoe ui', sans-serif;
|
||||
font-weight: 300;
|
||||
font-size: 18px;
|
||||
letter-spacing: -0.69px;
|
||||
font-size: 17px;
|
||||
}
|
||||
|
|
|
@ -1,39 +0,0 @@
|
|||
const html = require('choo/html');
|
||||
const progress = require('../../templates/progress');
|
||||
const { bytes } = require('../../utils');
|
||||
|
||||
module.exports = function(state, emit) {
|
||||
const transfer = state.transfer;
|
||||
|
||||
return html`
|
||||
<div class="page effect--fadeIn">
|
||||
<div class="title">
|
||||
${state.translate('uploadingPageProgress', {
|
||||
filename: transfer.file.name,
|
||||
size: bytes(transfer.file.size)
|
||||
})}
|
||||
</div>
|
||||
<div class="description"></div>
|
||||
${progress(transfer.progressRatio, transfer.progressIndefinite)}
|
||||
<div class="progressSection">
|
||||
<div class="progressSection__text">
|
||||
${state.translate(transfer.msg, transfer.sizes)}
|
||||
</div>
|
||||
<button
|
||||
id="cancel-upload"
|
||||
class="btn btn--cancel"
|
||||
title="${state.translate('uploadingPageCancel')}"
|
||||
onclick=${cancel}>
|
||||
${state.translate('uploadingPageCancel')}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
function cancel() {
|
||||
const btn = document.getElementById('cancel-upload');
|
||||
btn.disabled = true;
|
||||
btn.textContent = state.translate('uploadCancelNotification');
|
||||
emit('cancel');
|
||||
}
|
||||
};
|
|
@ -1,50 +1,86 @@
|
|||
/* global MAXFILESIZE */
|
||||
const html = require('choo/html');
|
||||
const assets = require('../../../common/assets');
|
||||
const fileList = require('../../templates/fileList');
|
||||
const { bytes, fadeOut } = require('../../utils');
|
||||
const { checkSize } = require('../../utils');
|
||||
const title = require('../../templates/title');
|
||||
const setPasswordSection = require('../../templates/setPasswordSection');
|
||||
const uploadBox = require('../../templates/uploadedFileList');
|
||||
const expireInfo = require('../../templates/expireInfo');
|
||||
|
||||
module.exports = function(state, emit) {
|
||||
// the page flickers if both the server and browser set 'effect--fadeIn'
|
||||
const fade = state.layout ? '' : 'effect--fadeIn';
|
||||
const files = state.files ? state.files : [];
|
||||
|
||||
const optionClass = state.uploading ? 'uploadOptions--faded' : '';
|
||||
const btnUploading = state.uploading ? 'btn--stripes' : '';
|
||||
const faded = files.length > 0 ? 'uploadArea--faded' : '';
|
||||
const selectFileClass = files.length > 0 ? 'btn--hidden' : '';
|
||||
const sendFileClass = files.length > 0 ? '' : 'btn--hidden';
|
||||
|
||||
let btnText = '';
|
||||
|
||||
if (state.encrypting) {
|
||||
btnText = state.translate('encryptingFile');
|
||||
} else if (state.uploading) {
|
||||
btnText = `sending... ${Math.floor(state.transfer.progressRatio * 100)}%`;
|
||||
} else {
|
||||
//default pre-upload text
|
||||
btnText = state.translate('uploadSuccessConfirmHeader');
|
||||
}
|
||||
|
||||
return html`
|
||||
<div id="page-one" class="${fade}">
|
||||
<div class="title">${state.translate('uploadPageHeader')}</div>
|
||||
<div class="description">
|
||||
<div>${state.translate('uploadPageExplainer')}</div>
|
||||
<a
|
||||
href="https://testpilot.firefox.com/experiments/send"
|
||||
class="link">
|
||||
${state.translate('uploadPageLearnMore')}
|
||||
</a>
|
||||
</div>
|
||||
<div class="uploadArea"
|
||||
<div id="page-one" class="page ${fade}">
|
||||
${title(state)}
|
||||
|
||||
<label class="uploadArea"
|
||||
ondragover=${dragover}
|
||||
ondragleave=${dragleave}>
|
||||
<img
|
||||
src="${assets.get('upload.svg')}"
|
||||
title="${state.translate('uploadSvgAlt')}"/>
|
||||
<div class="uploadArea__msg">
|
||||
${state.translate('uploadPageDropMessage')}
|
||||
|
||||
${uploadBox(files, state, emit)}
|
||||
|
||||
<div class="uploadedFilesWrapper ${faded}">
|
||||
<img
|
||||
class="uploadArea__icon"
|
||||
src="${assets.get('addfile.svg')}"
|
||||
title="${state.translate('uploadSvgAlt')}"/>
|
||||
<div class="uploadArea__msg">
|
||||
${state.translate('uploadDropDragMessage')}
|
||||
</div>
|
||||
|
||||
<span class="uploadArea__clickMsg">
|
||||
${state.translate('uploadDropClickMessage')}
|
||||
</span>
|
||||
</div>
|
||||
<span class="uploadArea__sizeMsg">
|
||||
${state.translate('uploadPageSizeMessage')}
|
||||
</span>
|
||||
|
||||
<input id="file-upload"
|
||||
class="inputFile"
|
||||
class="inputFile fileBox"
|
||||
type="file"
|
||||
multiple
|
||||
name="fileUploaded"
|
||||
onfocus=${onfocus}
|
||||
onblur=${onblur}
|
||||
onchange=${upload} />
|
||||
<label for="file-upload"
|
||||
class="btn btn--file"
|
||||
title="${state.translate('uploadPageBrowseButton1')}">
|
||||
${state.translate('uploadPageBrowseButton1')}
|
||||
</label>
|
||||
onchange=${addFiles} />
|
||||
|
||||
</label>
|
||||
|
||||
<div class="uploadOptions ${optionClass}">
|
||||
${expireInfo(state)}
|
||||
${setPasswordSection(state)}
|
||||
</div>
|
||||
${fileList(state, emit)}
|
||||
|
||||
<label for="file-upload"
|
||||
class="btn btn--file ${selectFileClass}"
|
||||
title="${state.translate('uploadPageBrowseButton1')}">
|
||||
${state.translate('uploadPageBrowseButton1')}
|
||||
</label>
|
||||
|
||||
<button
|
||||
class="btn ${btnUploading} ${sendFileClass}"
|
||||
onclick=${upload}
|
||||
title="${btnText}">
|
||||
${btnText}
|
||||
</button>
|
||||
|
||||
</div>
|
||||
`;
|
||||
|
||||
|
@ -66,22 +102,23 @@ module.exports = function(state, emit) {
|
|||
event.target.classList.remove('inputFile--focused');
|
||||
}
|
||||
|
||||
async function addFiles(event) {
|
||||
event.preventDefault();
|
||||
const target = event.target;
|
||||
checkSize(target.files, state.files);
|
||||
emit('addFiles', { files: target.files });
|
||||
}
|
||||
|
||||
async function upload(event) {
|
||||
event.preventDefault();
|
||||
const Archive = require('../../archive').default;
|
||||
const target = event.target;
|
||||
const file = new Archive(target.files);
|
||||
|
||||
if (file.size === 0) {
|
||||
return;
|
||||
if (files.length > 0) {
|
||||
emit('upload', {
|
||||
files,
|
||||
type: 'click',
|
||||
dlCount: state.downloadCount,
|
||||
password: state.password
|
||||
});
|
||||
}
|
||||
if (file.size > MAXFILESIZE) {
|
||||
// eslint-disable-next-line no-alert
|
||||
alert(state.translate('fileTooBig', { size: bytes(MAXFILESIZE) }));
|
||||
return;
|
||||
}
|
||||
|
||||
await fadeOut('#page-one');
|
||||
emit('upload', { file, type: 'click' });
|
||||
}
|
||||
};
|
||||
|
|
|
@ -1,61 +1,64 @@
|
|||
.uploadArea {
|
||||
border: 3px dashed rgba(0, 148, 251, 0.5);
|
||||
margin: 0 auto 10px;
|
||||
height: 255px;
|
||||
border-radius: 4px;
|
||||
position: relative;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
text-align: center;
|
||||
border: 1px dashed rgba(12, 12, 13, 0.2);
|
||||
margin: 0 0 10px;
|
||||
height: 400px;
|
||||
border-radius: 4px;
|
||||
overflow: scroll;
|
||||
transition: transform 150ms;
|
||||
padding: 15px;
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.uploadArea__msg {
|
||||
font-size: 22px;
|
||||
font-size: 15px;
|
||||
color: var(--lightTextColor);
|
||||
margin: 20px 0 10px;
|
||||
margin: 12px 0 0;
|
||||
font-family: 'SF Pro Text', sans-serif;
|
||||
text-transform: uppercase;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.uploadArea__sizeMsg {
|
||||
.uploadArea__clickMsg {
|
||||
font-style: italic;
|
||||
font-size: 12px;
|
||||
line-height: 16px;
|
||||
line-height: 12px;
|
||||
color: var(--lightTextColor);
|
||||
margin-bottom: 22px;
|
||||
margin: 5px;
|
||||
}
|
||||
|
||||
.uploadArea--dragging {
|
||||
border: 5px dashed rgba(0, 148, 251, 0.5);
|
||||
height: 251px;
|
||||
border: 1px dashed rgba(12, 12, 13, 0.4);
|
||||
transform: scale(1.04);
|
||||
border-radius: 4.2px;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
flex-direction: column;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.uploadArea--dragging * {
|
||||
.uploadArea--faded * {
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
.uploadArea--noEvents,
|
||||
.uploadArea--noEvents * {
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.btn--file {
|
||||
font-size: 20px;
|
||||
min-width: 240px;
|
||||
height: 60px;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
padding: 0 10px;
|
||||
display: inline-block;
|
||||
background-color: #737373;
|
||||
}
|
||||
|
||||
.btn--file:hover {
|
||||
background-color: #636363;
|
||||
}
|
||||
|
||||
.btn--hidden {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.inputFile {
|
||||
opacity: 0;
|
||||
position: absolute;
|
||||
display: none;
|
||||
}
|
||||
|
||||
.inputFile--focused + .btn--file {
|
||||
|
@ -63,3 +66,24 @@
|
|||
outline: 1px dotted #000;
|
||||
outline: -webkit-focus-ring-color auto 5px;
|
||||
}
|
||||
|
||||
.uploadArea > .uploadedFiles {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
flex: none;
|
||||
width: 100%;
|
||||
border: none;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.uploadOptions {
|
||||
text-align: left;
|
||||
font-size: 13px;
|
||||
color: var(--lightTextColor);
|
||||
}
|
||||
|
||||
.uploadOptions--faded {
|
||||
opacity: 0.5;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue