added /api/info/:id route
This commit is contained in:
parent
81534d2c13
commit
97ad674be2
20 changed files with 74 additions and 38 deletions
|
@ -1,6 +0,0 @@
|
|||
const html = require('choo/html');
|
||||
|
||||
module.exports = function() {
|
||||
const div = html`<div></div>`;
|
||||
return div;
|
||||
};
|
|
@ -1,34 +0,0 @@
|
|||
const html = require('choo/html');
|
||||
const progress = require('./progress');
|
||||
const { fadeOut } = require('../utils');
|
||||
|
||||
module.exports = function(state, emit) {
|
||||
const div = html`
|
||||
<div id="page-one">
|
||||
<div id="download" class="fadeIn">
|
||||
<div id="download-progress">
|
||||
<div id="dl-title" class="title">
|
||||
${state.translate('downloadFinish')}
|
||||
</div>
|
||||
<div class="description"></div>
|
||||
${progress(1)}
|
||||
<div class="upload">
|
||||
<div class="progress-text"></div>
|
||||
</div>
|
||||
</div>
|
||||
<a class="send-new"
|
||||
data-state="completed"
|
||||
href="/"
|
||||
onclick=${sendNew}>${state.translate('sendYourFilesLink')}</a>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
async function sendNew(e) {
|
||||
e.preventDefault();
|
||||
await fadeOut('download');
|
||||
emit('pushState', '/');
|
||||
}
|
||||
|
||||
return div;
|
||||
};
|
|
@ -1,43 +0,0 @@
|
|||
const html = require('choo/html');
|
||||
const progress = require('./progress');
|
||||
const { bytes } = require('../utils');
|
||||
|
||||
module.exports = function(state, emit) {
|
||||
const transfer = state.transfer;
|
||||
const div = html`
|
||||
<div id="page-one">
|
||||
<div id="download">
|
||||
<div id="download-progress" class="fadeIn">
|
||||
<div id="dl-title" 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)}
|
||||
<div class="upload">
|
||||
<div class="progress-text">${state.translate(
|
||||
transfer.msg,
|
||||
transfer.sizes
|
||||
)}</div>
|
||||
<button
|
||||
id="cancel-upload"
|
||||
title="${state.translate('deletePopupCancel')}"
|
||||
onclick=${cancel}>${state.translate('deletePopupCancel')}</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
function cancel() {
|
||||
const btn = document.getElementById('cancel-upload');
|
||||
btn.remove();
|
||||
emit('cancel');
|
||||
}
|
||||
return div;
|
||||
};
|
|
@ -1,10 +0,0 @@
|
|||
const html = require('choo/html');
|
||||
const assets = require('../../common/assets');
|
||||
|
||||
module.exports = function(state) {
|
||||
return html`
|
||||
<div id="upload-error">
|
||||
<div class="title">${state.translate('errorPageHeader')}</div>
|
||||
<img id="upload-error-img" src="${assets.get('illustration_error.svg')}"/>
|
||||
</div>`;
|
||||
};
|
|
@ -1,34 +0,0 @@
|
|||
const html = require('choo/html');
|
||||
|
||||
function replaceLinks(str, urls) {
|
||||
let i = -1;
|
||||
const s = str.replace(/<a>([^<]+)<\/a>/g, (m, v) => {
|
||||
i++;
|
||||
return `<a href="${urls[i]}">${v}</a>`;
|
||||
});
|
||||
return [`<div class="description">${s}</div>`];
|
||||
}
|
||||
|
||||
module.exports = function(state) {
|
||||
const div = html`
|
||||
<div id="page-one">
|
||||
<div id="legal">
|
||||
<div class="title">${state.translate('legalHeader')}</div>
|
||||
${html(
|
||||
replaceLinks(state.translate('legalNoticeTestPilot'), [
|
||||
'https://testpilot.firefox.com/terms',
|
||||
'https://testpilot.firefox.com/privacy',
|
||||
'https://testpilot.firefox.com/experiments/send'
|
||||
])
|
||||
)}
|
||||
${html(
|
||||
replaceLinks(state.translate('legalNoticeMozilla'), [
|
||||
'https://www.mozilla.org/privacy/websites/',
|
||||
'https://www.mozilla.org/about/legal/terms/mozilla/'
|
||||
])
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
return div;
|
||||
};
|
|
@ -1,21 +0,0 @@
|
|||
const html = require('choo/html');
|
||||
const assets = require('../../common/assets');
|
||||
|
||||
module.exports = function(state) {
|
||||
const div = html`
|
||||
<div id="page-one">
|
||||
<div id="download">
|
||||
<div class="title">${state.translate('expiredPageHeader')}</div>
|
||||
<div class="share-window">
|
||||
<img src="${assets.get('illustration_expired.svg')}" id="expired-img">
|
||||
</div>
|
||||
<div class="expired-description">
|
||||
${state.translate('uploadPageExplainer')}
|
||||
</div>
|
||||
<a class="send-new" href="/" data-state="notfound">
|
||||
${state.translate('sendYourFilesLink')}
|
||||
</a>
|
||||
</div>
|
||||
</div>`;
|
||||
return div;
|
||||
};
|
|
@ -1,37 +0,0 @@
|
|||
const html = require('choo/html');
|
||||
const assets = require('../../common/assets');
|
||||
const { bytes } = require('../utils');
|
||||
|
||||
module.exports = function(state, pageAction) {
|
||||
const fileInfo = state.fileInfo;
|
||||
const size = fileInfo.size
|
||||
? state.translate('downloadFileSize', { size: bytes(fileInfo.size) })
|
||||
: '';
|
||||
|
||||
const title = fileInfo.name
|
||||
? state.translate('downloadFileName', { filename: fileInfo.name })
|
||||
: state.translate('downloadFileTitle');
|
||||
const div = html`
|
||||
<div id="page-one">
|
||||
<div id="download">
|
||||
<div id="download-page-one">
|
||||
<div class="title">
|
||||
<span id="dl-file"
|
||||
data-nonce="${fileInfo.nonce}"
|
||||
data-requires-password="${fileInfo.requiresPassword}"
|
||||
>${title}</span>
|
||||
<span id="dl-filesize">${' ' + size}</span>
|
||||
</div>
|
||||
<div class="description">${state.translate('downloadMessage')}</div>
|
||||
<img
|
||||
src="${assets.get('illustration_download.svg')}"
|
||||
id="download-img"
|
||||
alt="${state.translate('downloadAltText')}"/>
|
||||
${pageAction}
|
||||
</div>
|
||||
<a class="send-new" href="/">${state.translate('sendYourFilesLink')}</a>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
return div;
|
||||
};
|
|
@ -1,126 +0,0 @@
|
|||
/* global EXPIRE_SECONDS */
|
||||
const html = require('choo/html');
|
||||
const assets = require('../../common/assets');
|
||||
const notFound = require('./notFound');
|
||||
const uploadPasswordSet = require('./uploadPasswordSet');
|
||||
const uploadPasswordUnset = require('./uploadPasswordUnset');
|
||||
const selectbox = require('./selectbox');
|
||||
const { allowedCopy, delay, fadeOut } = require('../utils');
|
||||
|
||||
function expireInfo(file, translate, emit) {
|
||||
const hours = Math.floor(EXPIRE_SECONDS / 60 / 60);
|
||||
const el = html([
|
||||
`<div>${translate('expireInfo', {
|
||||
downloadCount: '<select></select>',
|
||||
timespan: translate('timespanHours', { num: hours })
|
||||
})}</div>`
|
||||
]);
|
||||
const select = el.querySelector('select');
|
||||
const options = [1, 2, 3, 4, 5, 20];
|
||||
const t = num => translate('downloadCount', { num });
|
||||
const changed = value => emit('changeLimit', { file, value });
|
||||
select.parentNode.replaceChild(
|
||||
selectbox(file.dlimit || 1, options, t, changed),
|
||||
select
|
||||
);
|
||||
return el;
|
||||
}
|
||||
|
||||
module.exports = function(state, emit) {
|
||||
const file = state.storage.getFileById(state.params.id);
|
||||
if (!file) {
|
||||
return notFound(state, emit);
|
||||
}
|
||||
|
||||
const passwordSection = file.hasPassword()
|
||||
? uploadPasswordSet(state, emit)
|
||||
: uploadPasswordUnset(state, emit);
|
||||
const div = html`
|
||||
<div id="share-link" class="fadeIn">
|
||||
<div class="title">${expireInfo(file, state.translate, emit)}</div>
|
||||
<div id="share-window">
|
||||
<div id="copy-text">
|
||||
${state.translate('copyUrlFormLabelWithName', { filename: file.name })}
|
||||
</div>
|
||||
<div id="copy">
|
||||
<input id="link" type="url" value="${file.url}" readonly="true"/>
|
||||
<button id="copy-btn"
|
||||
class="btn"
|
||||
title="${state.translate('copyUrlFormButton')}"
|
||||
onclick=${copyLink}>${state.translate('copyUrlFormButton')}</button>
|
||||
</div>
|
||||
${passwordSection}
|
||||
<button id="delete-file"
|
||||
class="btn"
|
||||
title="${state.translate('deleteFileButton')}"
|
||||
onclick=${showPopup}>${state.translate('deleteFileButton')}
|
||||
</button>
|
||||
<div id="deletePopup" class="popup">
|
||||
<div class="popuptext" onblur=${cancel} tabindex="-1">
|
||||
<div class="popup-message">${state.translate('deletePopupText')}
|
||||
</div>
|
||||
<div class="popup-action">
|
||||
<span class="popup-no" onclick=${cancel}>
|
||||
${state.translate('deletePopupCancel')}
|
||||
</span>
|
||||
<span class="popup-yes" onclick=${deleteFile}>
|
||||
${state.translate('deletePopupYes')}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<a class="send-new"
|
||||
data-state="completed"
|
||||
href="/"
|
||||
onclick=${sendNew}>${state.translate('sendAnotherFileLink')}</a>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
function showPopup() {
|
||||
const popupText = document.querySelector('.popuptext');
|
||||
popupText.classList.add('show');
|
||||
popupText.focus();
|
||||
}
|
||||
|
||||
function cancel(e) {
|
||||
e.stopPropagation();
|
||||
const popupText = document.querySelector('.popuptext');
|
||||
popupText.classList.remove('show');
|
||||
}
|
||||
|
||||
async function sendNew(e) {
|
||||
e.preventDefault();
|
||||
await fadeOut('share-link');
|
||||
emit('pushState', '/');
|
||||
}
|
||||
|
||||
async function copyLink() {
|
||||
if (allowedCopy()) {
|
||||
emit('copy', { url: file.url, location: 'success-screen' });
|
||||
const input = document.getElementById('link');
|
||||
input.disabled = true;
|
||||
const copyBtn = document.getElementById('copy-btn');
|
||||
copyBtn.disabled = true;
|
||||
copyBtn.classList.add('success');
|
||||
copyBtn.replaceChild(
|
||||
html`<img src="${assets.get('check-16.svg')}" class="icon-check">`,
|
||||
copyBtn.firstChild
|
||||
);
|
||||
await delay(2000);
|
||||
input.disabled = false;
|
||||
if (!copyBtn.parentNode.classList.contains('wait-password')) {
|
||||
copyBtn.disabled = false;
|
||||
}
|
||||
copyBtn.classList.remove('success');
|
||||
copyBtn.textContent = state.translate('copyUrlFormButton');
|
||||
}
|
||||
}
|
||||
|
||||
async function deleteFile() {
|
||||
emit('delete', { file, location: 'success-screen' });
|
||||
await fadeOut('share-link');
|
||||
emit('pushState', '/');
|
||||
}
|
||||
return div;
|
||||
};
|
|
@ -1,52 +0,0 @@
|
|||
const html = require('choo/html');
|
||||
const assets = require('../../common/assets');
|
||||
|
||||
module.exports = function(state) {
|
||||
const msg =
|
||||
state.params.reason === 'outdated'
|
||||
? html`
|
||||
<div id="unsupported-browser">
|
||||
<div class="title">${state.translate('notSupportedHeader')}</div>
|
||||
<div class="description">
|
||||
${state.translate('notSupportedOutdatedDetail')}
|
||||
</div>
|
||||
<a
|
||||
id="update-firefox"
|
||||
href="https://support.mozilla.org/kb/update-firefox-latest-version">
|
||||
<img
|
||||
src="${assets.get('firefox_logo-only.svg')}"
|
||||
class="firefox-logo"
|
||||
alt="Firefox"/>
|
||||
<div class="unsupported-button-text">
|
||||
${state.translate('updateFirefox')}
|
||||
</div>
|
||||
</a>
|
||||
<div class="unsupported-description">
|
||||
${state.translate('uploadPageExplainer')}
|
||||
</div>
|
||||
</div>`
|
||||
: html`
|
||||
<div id="unsupported-browser">
|
||||
<div class="title">${state.translate('notSupportedHeader')}</div>
|
||||
<div class="description">${state.translate('notSupportedDetail')}</div>
|
||||
<div class="description">
|
||||
<a href="https://github.com/mozilla/send/blob/master/docs/faq.md#why-is-my-browser-not-supported">
|
||||
${state.translate('notSupportedLink')}
|
||||
</a>
|
||||
</div>
|
||||
<a id="dl-firefox" href="https://www.mozilla.org/firefox/new/?utm_campaign=send-acquisition&utm_medium=referral&utm_source=send.firefox.com">
|
||||
<img
|
||||
src="${assets.get('firefox_logo-only.svg')}"
|
||||
class="firefox-logo"
|
||||
alt="Firefox"/>
|
||||
<div class="unsupported-button-text">Firefox<br>
|
||||
<span>${state.translate('downloadFirefoxButtonSub')}</span>
|
||||
</div>
|
||||
</a>
|
||||
<div class="unsupported-description">
|
||||
${state.translate('uploadPageExplainer')}
|
||||
</div>
|
||||
</div>`;
|
||||
const div = html`<div id="page-one">${msg}</div>`;
|
||||
return div;
|
||||
};
|
|
@ -1,41 +0,0 @@
|
|||
const html = require('choo/html');
|
||||
const progress = require('./progress');
|
||||
const { bytes } = require('../utils');
|
||||
|
||||
module.exports = function(state, emit) {
|
||||
const transfer = state.transfer;
|
||||
|
||||
const div = html`
|
||||
<div id="download">
|
||||
<div id="upload-progress" class="fadeIn">
|
||||
<div class="title" id="upload-filename">
|
||||
${state.translate('uploadingPageProgress', {
|
||||
filename: transfer.file.name,
|
||||
size: bytes(transfer.file.size)
|
||||
})}
|
||||
</div>
|
||||
<div class="description"></div>
|
||||
${progress(transfer.progressRatio)}
|
||||
<div class="upload">
|
||||
<div class="progress-text">
|
||||
${state.translate(transfer.msg, transfer.sizes)}
|
||||
</div>
|
||||
<button
|
||||
id="cancel-upload"
|
||||
title="${state.translate('uploadingPageCancel')}"
|
||||
onclick=${cancel}>
|
||||
${state.translate('uploadingPageCancel')}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
function cancel() {
|
||||
const btn = document.getElementById('cancel-upload');
|
||||
btn.disabled = true;
|
||||
btn.textContent = state.translate('uploadCancelNotification');
|
||||
emit('cancel');
|
||||
}
|
||||
return div;
|
||||
};
|
|
@ -1,82 +0,0 @@
|
|||
/* global MAXFILESIZE */
|
||||
const html = require('choo/html');
|
||||
const assets = require('../../common/assets');
|
||||
const fileList = require('./fileList');
|
||||
const { bytes, fadeOut } = require('../utils');
|
||||
|
||||
module.exports = function(state, emit) {
|
||||
const div = html`
|
||||
<div id="page-one" class="fadeIn">
|
||||
<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="upload-window"
|
||||
ondragover=${dragover}
|
||||
ondragleave=${dragleave}>
|
||||
<div id="upload-img">
|
||||
<img
|
||||
src="${assets.get('upload.svg')}"
|
||||
title="${state.translate('uploadSvgAlt')}"/>
|
||||
</div>
|
||||
<div id="upload-text">${state.translate('uploadPageDropMessage')}</div>
|
||||
<span id="file-size-msg">
|
||||
<em>${state.translate('uploadPageSizeMessage')}</em>
|
||||
</span>
|
||||
<input id="file-upload"
|
||||
type="file"
|
||||
name="fileUploaded"
|
||||
onfocus=${onfocus}
|
||||
onblur=${onblur}
|
||||
onchange=${upload} />
|
||||
<label for="file-upload"
|
||||
id="browse"
|
||||
class="btn browse"
|
||||
title="${state.translate('uploadPageBrowseButton1')}">
|
||||
${state.translate('uploadPageBrowseButton1')}
|
||||
</label>
|
||||
</div>
|
||||
${fileList(state, emit)}
|
||||
</div>
|
||||
`;
|
||||
|
||||
function dragover(event) {
|
||||
const div = document.querySelector('.upload-window');
|
||||
div.classList.add('ondrag');
|
||||
}
|
||||
|
||||
function dragleave(event) {
|
||||
const div = document.querySelector('.upload-window');
|
||||
div.classList.remove('ondrag');
|
||||
}
|
||||
|
||||
function onfocus(event) {
|
||||
event.target.classList.add('has-focus');
|
||||
}
|
||||
|
||||
function onblur(event) {
|
||||
event.target.classList.remove('has-focus');
|
||||
}
|
||||
|
||||
async function upload(event) {
|
||||
event.preventDefault();
|
||||
const target = event.target;
|
||||
const file = target.files[0];
|
||||
if (file.size === 0) {
|
||||
return;
|
||||
}
|
||||
if (file.size > MAXFILESIZE) {
|
||||
window.alert(state.translate('fileTooBig', { size: bytes(MAXFILESIZE) }));
|
||||
return;
|
||||
}
|
||||
|
||||
await fadeOut('page-one');
|
||||
emit('upload', { file, type: 'click' });
|
||||
}
|
||||
return div;
|
||||
};
|
Loading…
Add table
Add a link
Reference in a new issue