+
${state.translate('copyUrlFormLabelWithName', { filename: file.name })}
-
-
-
${passwordSection}
-
${state.translate('deleteFileButton')}
-
@@ -79,48 +78,40 @@ module.exports = function(state, emit) {
`;
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');
+ const popup = document.querySelector('.popup');
+ popup.classList.add('popup--show');
+ popup.focus();
}
async function sendNew(e) {
e.preventDefault();
- await fadeOut('share-link');
+ await fadeOut('#shareWrapper');
emit('pushState', '/');
}
async function copyLink() {
if (allowedCopy()) {
emit('copy', { url: file.url, location: 'success-screen' });
- const input = document.getElementById('link');
+ const input = document.getElementById('fileUrl');
input.disabled = true;
- const copyBtn = document.getElementById('copy-btn');
+ const copyBtn = document.getElementById('copyBtn');
copyBtn.disabled = true;
- copyBtn.classList.add('success');
+ copyBtn.classList.add('inputBtn--copied');
copyBtn.replaceChild(
- html`
`,
+ html`
`,
copyBtn.firstChild
);
await delay(2000);
input.disabled = false;
- if (!copyBtn.parentNode.classList.contains('wait-password')) {
- copyBtn.disabled = false;
- }
- copyBtn.classList.remove('success');
+ copyBtn.disabled = false;
+ copyBtn.classList.remove('inputBtn--copied');
copyBtn.textContent = state.translate('copyUrlFormButton');
}
}
async function deleteFile() {
emit('delete', { file, location: 'success-screen' });
- await fadeOut('share-link');
+ await fadeOut('#shareWrapper');
emit('pushState', '/');
}
return div;
diff --git a/app/pages/share/share.css b/app/pages/share/share.css
new file mode 100644
index 00000000..84d3af2e
--- /dev/null
+++ b/app/pages/share/share.css
@@ -0,0 +1,109 @@
+.sharePage {
+ margin: 0 auto;
+ display: flex;
+ justify-content: center;
+ flex-direction: column;
+ width: 100%;
+ max-width: 640px;
+}
+
+.sharePage__copyText {
+ align-self: flex-start;
+ margin-top: 60px;
+ margin-bottom: 10px;
+ color: var(--textColor);
+ max-width: 614px;
+ word-wrap: break-word;
+}
+
+.sharePage__deletePopup {
+ position: relative;
+ align-self: center;
+ bottom: 50px;
+}
+
+.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);
+ font-family: 'SF Pro Text', sans-serif;
+ letter-spacing: 0;
+ line-height: 23px;
+ font-weight: 300;
+ padding-left: 10px;
+ padding-right: 10px;
+}
+
+.copySection__url:disabled {
+ border: 1px solid var(--successControlBGColor);
+ background: var(--successControlFGColor);
+}
+
+.inputBtn--copy {
+ flex: 0 1 165px;
+ padding-bottom: 4px;
+}
+
+.inputBtn--copied,
+.inputBtn--copied:hover {
+ background: var(--successControlBGColor);
+ border: 1px solid var(--successControlBGColor);
+ color: var(--successControlFGColor);
+}
+
+.btn--delete {
+ 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;
+}
+
+.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;
+ }
+}
diff --git a/app/pages/unsupported.js b/app/pages/unsupported.js
deleted file mode 100644
index 03a55883..00000000
--- a/app/pages/unsupported.js
+++ /dev/null
@@ -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`
-
`
- : html`
-
`;
- const div = html`
${msg}
`;
- return div;
-};
diff --git a/app/pages/unsupported/index.js b/app/pages/unsupported/index.js
new file mode 100644
index 00000000..7f70311c
--- /dev/null
+++ b/app/pages/unsupported/index.js
@@ -0,0 +1,68 @@
+const html = require('choo/html');
+const assets = require('../../../common/assets');
+
+function outdatedStrings(state) {
+ return {
+ title: state.translate('notSupportedHeader'),
+ description: state.translate('notSupportedOutdatedDetail'),
+ button: state.translate('updateFirefox'),
+ explainer: state.translate('uploadPageExplainer')
+ };
+}
+
+function unsupportedStrings(state) {
+ return {
+ title: state.translate('notSupportedHeader'),
+ description: state.translate('notSupportedDetail'),
+ button: state.translate('downloadFirefoxButtonSub'),
+ explainer: state.translate('uploadPageExplainer')
+ };
+}
+
+module.exports = function(state) {
+ let strings = {};
+ let why = '';
+ let url = '';
+ let buttonAction = '';
+ if (state.params.reason !== 'outdated') {
+ strings = unsupportedStrings(state);
+ why = html`
+
`;
+ url =
+ 'https://www.mozilla.org/firefox/new/?utm_campaign=send-acquisition&utm_medium=referral&utm_source=send.firefox.com';
+ buttonAction = html`
+
+ Firefox
${strings.button}
+
`;
+ } else {
+ strings = outdatedStrings(state);
+ url = 'https://support.mozilla.org/kb/update-firefox-latest-version';
+ buttonAction = html`
+
+ ${strings.button}
+
`;
+ }
+ const div = html`
+
+
${strings.title}
+
+ ${strings.description}
+
+ ${why}
+
+
+ ${buttonAction}
+
+
+ ${strings.explainer}
+
+
`;
+ return div;
+};
diff --git a/app/pages/unsupported/unsupported.css b/app/pages/unsupported/unsupported.css
new file mode 100644
index 00000000..c4c9cb91
--- /dev/null
+++ b/app/pages/unsupported/unsupported.css
@@ -0,0 +1,49 @@
+.unsupportedPage {
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ flex-direction: column;
+}
+
+.unsupportedPage__info {
+ font-size: 13px;
+ line-height: 23px;
+ text-align: center;
+ color: #7d7d7d;
+ margin: 0 auto 23px;
+}
+
+.firefoxDownload {
+ margin-bottom: 181px;
+ height: 80px;
+ background: #98e02b;
+ 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: #fff;
+ font-size: 26px;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ line-height: 1;
+ padding: 0 25px;
+}
+
+.firefoxDownload__logo {
+ width: 70px;
+}
+
+.firefoxDownload__action {
+ text-align: left;
+ margin-left: 20.4px;
+}
+
+.firefoxDownload__text {
+ font-family: 'Fira Sans', 'segoe ui', sans-serif;
+ font-weight: 300;
+ font-size: 18px;
+ letter-spacing: -0.69px;
+}
diff --git a/app/pages/upload.js b/app/pages/upload.js
deleted file mode 100644
index 7a21bd3b..00000000
--- a/app/pages/upload.js
+++ /dev/null
@@ -1,41 +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 div = html`
-
-
-
- ${state.translate('uploadingPageProgress', {
- filename: transfer.file.name,
- size: bytes(transfer.file.size)
- })}
-
-
- ${progress(transfer.progressRatio)}
-
-
- ${state.translate(transfer.msg, transfer.sizes)}
-
-
- ${state.translate('uploadingPageCancel')}
-
-
-
-
- `;
-
- function cancel() {
- const btn = document.getElementById('cancel-upload');
- btn.disabled = true;
- btn.textContent = state.translate('uploadCancelNotification');
- emit('cancel');
- }
- return div;
-};
diff --git a/app/pages/upload/index.js b/app/pages/upload/index.js
new file mode 100644
index 00000000..15e5d81f
--- /dev/null
+++ b/app/pages/upload/index.js
@@ -0,0 +1,40 @@
+const html = require('choo/html');
+const progress = require('../../templates/progress');
+const { bytes } = require('../../utils');
+
+module.exports = function(state, emit) {
+ const transfer = state.transfer;
+
+ const div = html`
+
+
+ ${state.translate('uploadingPageProgress', {
+ filename: transfer.file.name,
+ size: bytes(transfer.file.size)
+ })}
+
+
+ ${progress(transfer.progressRatio)}
+
+
+ ${state.translate(transfer.msg, transfer.sizes)}
+
+
+ ${state.translate('uploadingPageCancel')}
+
+
+
+ `;
+
+ function cancel() {
+ const btn = document.getElementById('cancel-upload');
+ btn.disabled = true;
+ btn.textContent = state.translate('uploadCancelNotification');
+ emit('cancel');
+ }
+ return div;
+};
diff --git a/app/pages/welcome.js b/app/pages/welcome/index.js
similarity index 63%
rename from app/pages/welcome.js
rename to app/pages/welcome/index.js
index ab5df408..af24dad8 100644
--- a/app/pages/welcome.js
+++ b/app/pages/welcome/index.js
@@ -1,12 +1,12 @@
/* global MAXFILESIZE */
const html = require('choo/html');
-const assets = require('../../common/assets');
-const fileList = require('../templates/fileList');
-const { bytes, fadeOut } = require('../utils');
+const assets = require('../../../common/assets');
+const fileList = require('../../templates/fileList');
+const { bytes, fadeOut } = require('../../utils');
module.exports = function(state, emit) {
- // the page flickers if both the server and browser set 'fadeIn'
- const fade = state.layout ? '' : 'fadeIn';
+ // the page flickers if both the server and browser set 'effect--fadeIn'
+ const fade = state.layout ? '' : 'effect--fadeIn';
const div = html`
${state.translate('uploadPageHeader')}
@@ -18,7 +18,7 @@ module.exports = function(state, emit) {
${state.translate('uploadPageLearnMore')}
-
@@ -26,19 +26,21 @@ module.exports = function(state, emit) {
src="${assets.get('upload.svg')}"
title="${state.translate('uploadSvgAlt')}"/>
-
${state.translate('uploadPageDropMessage')}
-
- ${state.translate('uploadPageSizeMessage')}
+
+ ${state.translate('uploadPageDropMessage')}
+
+
+ ${state.translate('uploadPageSizeMessage')}
@@ -48,21 +50,21 @@ module.exports = function(state, emit) {
`;
function dragover(event) {
- const div = document.querySelector('.upload-window');
- div.classList.add('ondrag');
+ const div = document.querySelector('.uploadArea');
+ div.classList.add('uploadArea--dragging');
}
function dragleave(event) {
- const div = document.querySelector('.upload-window');
- div.classList.remove('ondrag');
+ const div = document.querySelector('.uploadArea');
+ div.classList.remove('uploadArea--dragging');
}
function onfocus(event) {
- event.target.classList.add('has-focus');
+ event.target.classList.add('inputFile--focused');
}
function onblur(event) {
- event.target.classList.remove('has-focus');
+ event.target.classList.remove('inputFile--focused');
}
async function upload(event) {
@@ -77,7 +79,7 @@ module.exports = function(state, emit) {
return;
}
- await fadeOut('page-one');
+ await fadeOut('#page-one');
emit('upload', { file, type: 'click' });
}
return div;
diff --git a/app/pages/welcome/welcome.css b/app/pages/welcome/welcome.css
new file mode 100644
index 00000000..298c1a3a
--- /dev/null
+++ b/app/pages/welcome/welcome.css
@@ -0,0 +1,71 @@
+.uploadArea {
+ border: 3px dashed rgba(0, 148, 251, 0.5);
+ margin: 0 auto 10px;
+ height: 255px;
+ border-radius: 4px;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ flex-direction: column;
+ text-align: center;
+ transition: transform 150ms;
+ padding: 15px;
+}
+
+.uploadArea__msg {
+ font-size: 22px;
+ color: var(--lightTextColor);
+ margin: 20px 0 10px;
+ font-family: 'SF Pro Text', sans-serif;
+}
+
+.uploadArea__sizeMsg {
+ font-style: italic;
+ font-size: 12px;
+ line-height: 16px;
+ color: var(--lightTextColor);
+ margin-bottom: 22px;
+}
+
+.uploadArea--dragging {
+ border: 5px dashed rgba(0, 148, 251, 0.5);
+ height: 251px;
+ transform: scale(1.04);
+ border-radius: 4.2px;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ flex-direction: column;
+ text-align: center;
+}
+
+.uploadArea--dragging * {
+ pointer-events: none;
+}
+
+.btn--file {
+ font-size: 20px;
+ min-width: 240px;
+ height: 60px;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ padding: 0 10px;
+}
+
+.btn--file:hover {
+ background-color: var(--primaryControlHoverColor);
+}
+
+.inputFile {
+ opacity: 0;
+ overflow: hidden;
+ position: absolute;
+ z-index: -1;
+}
+
+.btn--file .inputFile--focused {
+ background-color: var(--primaryControlHoverColor);
+ outline: 1px dotted #000;
+ outline: -webkit-focus-ring-color auto 5px;
+}
diff --git a/app/templates/changePasswordSection/changePasswordSection.css b/app/templates/changePasswordSection/changePasswordSection.css
new file mode 100644
index 00000000..fea7c090
--- /dev/null
+++ b/app/templates/changePasswordSection/changePasswordSection.css
@@ -0,0 +1,29 @@
+.changePasswordSection {
+ padding: 10px 0;
+ align-self: left;
+ max-width: 100%;
+ overflow-wrap: break-word;
+}
+
+.btn--reset {
+ width: 80px;
+ height: 30px;
+ background: #fff;
+ border-color: rgba(12, 12, 13, 0.3);
+ margin-top: 5px;
+ margin-left: 15px;
+ margin-bottom: 12px;
+ line-height: 24px;
+ color: #313131;
+}
+
+.btn--reset:hover {
+ background: #efeff1;
+}
+
+@media (max-device-width: 520px), (max-width: 520px) {
+ .changePasswordSection {
+ align-self: center;
+ min-width: 95%;
+ }
+}
diff --git a/app/templates/changePasswordSection/index.js b/app/templates/changePasswordSection/index.js
new file mode 100644
index 00000000..82746dbe
--- /dev/null
+++ b/app/templates/changePasswordSection/index.js
@@ -0,0 +1,52 @@
+const html = require('choo/html');
+const raw = require('choo/html/raw');
+const passwordInput = require('../passwordInput');
+
+module.exports = function(state, emit) {
+ const file = state.storage.getFileById(state.params.id);
+
+ return html`
+ ${passwordSpan(file.password)}
+ ${state.translate('changePasswordButton')}
+ ${passwordInput(
+ state.translate('unlockInputPlaceholder'),
+ state.translate('changePasswordButton'),
+ changePassword
+ )}
+
`;
+
+ function passwordSpan(password) {
+ password = password || '●●●●●';
+ const span = html`${raw(
+ state.translate('passwordResult', {
+ password: ''
+ })
+ )}`;
+ const masked = span.querySelector('.passwordMask');
+ masked.textContent = password.replace(/./g, '●');
+ return span;
+ }
+
+ function changePassword(event) {
+ event.preventDefault();
+ const password = document.getElementById('password-input').value;
+ if (password.length > 0) {
+ emit('password', { password, file });
+ }
+ return false;
+ }
+
+ function toggleResetInput(event) {
+ const form = event.target.parentElement.querySelector('form.passwordInput');
+ const input = document.getElementById('password-input');
+ if (form.style.visibility === 'hidden' || form.style.visibility === '') {
+ form.style.visibility = 'visible';
+ input.focus();
+ } else {
+ form.style.visibility = 'hidden';
+ }
+ }
+};
diff --git a/app/templates/downloadButton/downloadButton.css b/app/templates/downloadButton/downloadButton.css
new file mode 100644
index 00000000..834dc76f
--- /dev/null
+++ b/app/templates/downloadButton/downloadButton.css
@@ -0,0 +1,10 @@
+.btn--download {
+ width: 180px;
+ height: 44px;
+ margin-top: 20px;
+ margin-bottom: 30px;
+}
+
+.btn--download:hover {
+ background-color: var(--primaryControlHoverColor);
+}
diff --git a/app/templates/downloadButton.js b/app/templates/downloadButton/index.js
similarity index 86%
rename from app/templates/downloadButton.js
rename to app/templates/downloadButton/index.js
index be01333f..ff95c0e3 100644
--- a/app/templates/downloadButton.js
+++ b/app/templates/downloadButton/index.js
@@ -8,8 +8,7 @@ module.exports = function(state, emit) {
return html`
- ${state.translate('downloadButtonLabel')}
`;
diff --git a/app/templates/downloadPassword/downloadPassword.css b/app/templates/downloadPassword/downloadPassword.css
new file mode 100644
index 00000000..f6272f4f
--- /dev/null
+++ b/app/templates/downloadPassword/downloadPassword.css
@@ -0,0 +1,30 @@
+.passwordSection {
+ text-align: left;
+ padding: 40px;
+}
+
+.passwordForm {
+ display: flex;
+ flex-wrap: nowrap;
+ width: 100%;
+ padding: 10px 0;
+}
+
+.input--password {
+ flex: 1;
+}
+
+.inputBtn--password {
+ flex: 0 1 165px;
+}
+
+.red {
+ color: red;
+}
+
+@media (max-device-width: 520px), (max-width: 520px) {
+ .passwordForm {
+ flex-direction: column;
+ padding-left: 0;
+ }
+}
diff --git a/app/templates/downloadPassword.js b/app/templates/downloadPassword/index.js
similarity index 54%
rename from app/templates/downloadPassword.js
rename to app/templates/downloadPassword/index.js
index bca7ccf1..08e41d5c 100644
--- a/app/templates/downloadPassword.js
+++ b/app/templates/downloadPassword/index.js
@@ -5,52 +5,52 @@ module.exports = function(state, emit) {
const label =
fileInfo.password === null
? html`
-