updated password input UI
This commit is contained in:
parent
8d41111cd6
commit
346e604f34
14
app/base.css
14
app/base.css
|
@ -34,7 +34,6 @@ body {
|
||||||
position: relative;
|
position: relative;
|
||||||
}
|
}
|
||||||
|
|
||||||
pre,
|
|
||||||
input,
|
input,
|
||||||
select,
|
select,
|
||||||
textarea,
|
textarea,
|
||||||
|
@ -43,13 +42,6 @@ button {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
pre {
|
|
||||||
font-family: monospace;
|
|
||||||
font-size: 18px;
|
|
||||||
font-weight: 600;
|
|
||||||
display: inline-block;
|
|
||||||
}
|
|
||||||
|
|
||||||
a {
|
a {
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
}
|
}
|
||||||
|
@ -69,7 +61,7 @@ a {
|
||||||
.btn {
|
.btn {
|
||||||
font-size: 15px;
|
font-size: 15px;
|
||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
color: white;
|
color: var(--primaryControlFGColor);
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
background: var(--primaryControlBGColor);
|
background: var(--primaryControlBGColor);
|
||||||
|
@ -113,7 +105,7 @@ a {
|
||||||
background: var(--primaryControlBGColor);
|
background: var(--primaryControlBGColor);
|
||||||
border-radius: 0 6px 6px 0;
|
border-radius: 0 6px 6px 0;
|
||||||
border: 1px solid var(--primaryControlBGColor);
|
border: 1px solid var(--primaryControlBGColor);
|
||||||
color: white;
|
color: var(--primaryControlFGColor);
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
|
|
||||||
/* Force flat button look */
|
/* Force flat button look */
|
||||||
|
@ -177,7 +169,7 @@ a {
|
||||||
}
|
}
|
||||||
|
|
||||||
.progressSection__text {
|
.progressSection__text {
|
||||||
color: rgba(0, 0, 0, 0.5);
|
color: var(--lightTextColor);
|
||||||
letter-spacing: -0.4px;
|
letter-spacing: -0.4px;
|
||||||
margin-top: 24px;
|
margin-top: 24px;
|
||||||
margin-bottom: 74px;
|
margin-bottom: 74px;
|
||||||
|
|
|
@ -130,9 +130,13 @@ export default function(state, emitter) {
|
||||||
|
|
||||||
emitter.on('password', async ({ password, file }) => {
|
emitter.on('password', async ({ password, file }) => {
|
||||||
try {
|
try {
|
||||||
|
state.settingPassword = true;
|
||||||
|
render();
|
||||||
await file.setPassword(password);
|
await file.setPassword(password);
|
||||||
state.storage.writeFile(file);
|
state.storage.writeFile(file);
|
||||||
metrics.addedPassword({ size: file.size });
|
metrics.addedPassword({ size: file.size });
|
||||||
|
await delay(1000);
|
||||||
|
state.settingPassword = false;
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error(err);
|
console.error(err);
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,6 @@
|
||||||
@import './templates/passwordInput/passwordInput.css';
|
@import './templates/passwordInput/passwordInput.css';
|
||||||
@import './templates/downloadPassword/downloadPassword.css';
|
@import './templates/downloadPassword/downloadPassword.css';
|
||||||
@import './templates/setPasswordSection/setPasswordSection.css';
|
@import './templates/setPasswordSection/setPasswordSection.css';
|
||||||
@import './templates/changePasswordSection/changePasswordSection.css';
|
|
||||||
@import './templates/footer/footer.css';
|
@import './templates/footer/footer.css';
|
||||||
@import './templates/fxPromo/fxPromo.css';
|
@import './templates/fxPromo/fxPromo.css';
|
||||||
@import './templates/selectbox/selectbox.css';
|
@import './templates/selectbox/selectbox.css';
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
const html = require('choo/html');
|
const html = require('choo/html');
|
||||||
|
|
||||||
module.exports = function() {
|
module.exports = function() {
|
||||||
const div = html`<div></div>`;
|
return html`<div></div>`;
|
||||||
return div;
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -3,7 +3,7 @@ const progress = require('../../templates/progress');
|
||||||
const { fadeOut } = require('../../utils');
|
const { fadeOut } = require('../../utils');
|
||||||
|
|
||||||
module.exports = function(state, emit) {
|
module.exports = function(state, emit) {
|
||||||
const div = html`
|
return html`
|
||||||
<div class="page effect--fadeIn">
|
<div class="page effect--fadeIn">
|
||||||
<div class="title">
|
<div class="title">
|
||||||
${state.translate('downloadFinish')}
|
${state.translate('downloadFinish')}
|
||||||
|
@ -23,6 +23,4 @@ module.exports = function(state, emit) {
|
||||||
await fadeOut('.page');
|
await fadeOut('.page');
|
||||||
emit('pushState', '/');
|
emit('pushState', '/');
|
||||||
}
|
}
|
||||||
|
|
||||||
return div;
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -13,7 +13,7 @@ module.exports = function(state, emit) {
|
||||||
${state.translate('deletePopupCancel')}
|
${state.translate('deletePopupCancel')}
|
||||||
</button>`;
|
</button>`;
|
||||||
|
|
||||||
const div = html`
|
return html`
|
||||||
<div class="page effect--fadeIn">
|
<div class="page effect--fadeIn">
|
||||||
<div class="title">
|
<div class="title">
|
||||||
${state.translate('downloadingPageProgress', {
|
${state.translate('downloadingPageProgress', {
|
||||||
|
@ -39,5 +39,4 @@ module.exports = function(state, emit) {
|
||||||
btn.remove();
|
btn.remove();
|
||||||
emit('cancel');
|
emit('cancel');
|
||||||
}
|
}
|
||||||
return div;
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,17 +1,8 @@
|
||||||
const html = require('choo/html');
|
const html = require('choo/html');
|
||||||
const raw = require('choo/html/raw');
|
const raw = require('choo/html/raw');
|
||||||
|
|
||||||
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) {
|
module.exports = function(state) {
|
||||||
const div = html`
|
return html`
|
||||||
<div id="legal">
|
<div id="legal">
|
||||||
<div class="title">${state.translate('legalHeader')}</div>
|
<div class="title">${state.translate('legalHeader')}</div>
|
||||||
${raw(
|
${raw(
|
||||||
|
@ -29,5 +20,13 @@ module.exports = function(state) {
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
`;
|
`;
|
||||||
return div;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
function replaceLinks(str, urls) {
|
||||||
|
let i = 0;
|
||||||
|
const s = str.replace(
|
||||||
|
/<a>([^<]+)<\/a>/g,
|
||||||
|
(m, v) => `<a href="${urls[i++]}">${v}</a>`
|
||||||
|
);
|
||||||
|
return `<div class="description">${s}</div>`;
|
||||||
|
}
|
||||||
|
|
|
@ -2,7 +2,7 @@ const html = require('choo/html');
|
||||||
const assets = require('../../../common/assets');
|
const assets = require('../../../common/assets');
|
||||||
|
|
||||||
module.exports = function(state) {
|
module.exports = function(state) {
|
||||||
const div = html`
|
return html`
|
||||||
<div class="notFoundPage">
|
<div class="notFoundPage">
|
||||||
<div class="title">${state.translate('expiredPageHeader')}</div>
|
<div class="title">${state.translate('expiredPageHeader')}</div>
|
||||||
<div class="notFoundPage__img">
|
<div class="notFoundPage__img">
|
||||||
|
@ -15,5 +15,4 @@ module.exports = function(state) {
|
||||||
${state.translate('sendYourFilesLink')}
|
${state.translate('sendYourFilesLink')}
|
||||||
</a>
|
</a>
|
||||||
</div>`;
|
</div>`;
|
||||||
return div;
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -20,7 +20,7 @@ module.exports = function(state, pageAction) {
|
||||||
if (!pageAction) {
|
if (!pageAction) {
|
||||||
return info;
|
return info;
|
||||||
}
|
}
|
||||||
const div = html`
|
return html`
|
||||||
<div class="page">
|
<div class="page">
|
||||||
<div class="title">
|
<div class="title">
|
||||||
<span>${title}</span>
|
<span>${title}</span>
|
||||||
|
@ -38,5 +38,4 @@ module.exports = function(state, pageAction) {
|
||||||
${info}
|
${info}
|
||||||
</div>
|
</div>
|
||||||
`;
|
`;
|
||||||
return div;
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -3,41 +3,18 @@ const html = require('choo/html');
|
||||||
const raw = require('choo/html/raw');
|
const raw = require('choo/html/raw');
|
||||||
const assets = require('../../../common/assets');
|
const assets = require('../../../common/assets');
|
||||||
const notFound = require('../notFound');
|
const notFound = require('../notFound');
|
||||||
const changePasswordSection = require('../../templates/changePasswordSection');
|
|
||||||
const setPasswordSection = require('../../templates/setPasswordSection');
|
const setPasswordSection = require('../../templates/setPasswordSection');
|
||||||
const selectbox = require('../../templates/selectbox');
|
const selectbox = require('../../templates/selectbox');
|
||||||
const deletePopup = require('../../templates/popup');
|
const deletePopup = require('../../templates/popup');
|
||||||
const { allowedCopy, delay, fadeOut } = require('../../utils');
|
const { allowedCopy, delay, fadeOut } = require('../../utils');
|
||||||
|
|
||||||
function expireInfo(file, translate, emit) {
|
|
||||||
const hours = Math.floor(EXPIRE_SECONDS / 60 / 60);
|
|
||||||
const el = html`<div>${raw(
|
|
||||||
translate('expireInfo', {
|
|
||||||
downloadCount: '<select></select>',
|
|
||||||
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 });
|
|
||||||
select.parentNode.replaceChild(
|
|
||||||
selectbox(file.dlimit || 1, options, t, changed),
|
|
||||||
select
|
|
||||||
);
|
|
||||||
return el;
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports = function(state, emit) {
|
module.exports = function(state, emit) {
|
||||||
const file = state.storage.getFileById(state.params.id);
|
const file = state.storage.getFileById(state.params.id);
|
||||||
if (!file) {
|
if (!file) {
|
||||||
return notFound(state, emit);
|
return notFound(state, emit);
|
||||||
}
|
}
|
||||||
|
|
||||||
const passwordSection = file.hasPassword
|
return html`
|
||||||
? changePasswordSection(state, emit)
|
|
||||||
: setPasswordSection(state, emit);
|
|
||||||
const div = html`
|
|
||||||
<div id="shareWrapper" class="effect--fadeIn">
|
<div id="shareWrapper" class="effect--fadeIn">
|
||||||
<div class="title">${expireInfo(file, state.translate, emit)}</div>
|
<div class="title">${expireInfo(file, state.translate, emit)}</div>
|
||||||
<div class="sharePage">
|
<div class="sharePage">
|
||||||
|
@ -56,7 +33,7 @@ module.exports = function(state, emit) {
|
||||||
title="${state.translate('copyUrlFormButton')}"
|
title="${state.translate('copyUrlFormButton')}"
|
||||||
onclick=${copyLink}>${state.translate('copyUrlFormButton')}</button>
|
onclick=${copyLink}>${state.translate('copyUrlFormButton')}</button>
|
||||||
</div>
|
</div>
|
||||||
${passwordSection}
|
${setPasswordSection(state, emit)}
|
||||||
<button
|
<button
|
||||||
class="btn btn--delete"
|
class="btn btn--delete"
|
||||||
title="${state.translate('deleteFileButton')}"
|
title="${state.translate('deleteFileButton')}"
|
||||||
|
@ -94,6 +71,7 @@ module.exports = function(state, emit) {
|
||||||
emit('copy', { url: file.url, location: 'success-screen' });
|
emit('copy', { url: file.url, location: 'success-screen' });
|
||||||
const input = document.getElementById('fileUrl');
|
const input = document.getElementById('fileUrl');
|
||||||
input.disabled = true;
|
input.disabled = true;
|
||||||
|
input.classList.add('input--copied');
|
||||||
const copyBtn = document.getElementById('copyBtn');
|
const copyBtn = document.getElementById('copyBtn');
|
||||||
copyBtn.disabled = true;
|
copyBtn.disabled = true;
|
||||||
copyBtn.classList.add('inputBtn--copied');
|
copyBtn.classList.add('inputBtn--copied');
|
||||||
|
@ -103,6 +81,7 @@ module.exports = function(state, emit) {
|
||||||
);
|
);
|
||||||
await delay(2000);
|
await delay(2000);
|
||||||
input.disabled = false;
|
input.disabled = false;
|
||||||
|
input.classList.remove('input--copied');
|
||||||
copyBtn.disabled = false;
|
copyBtn.disabled = false;
|
||||||
copyBtn.classList.remove('inputBtn--copied');
|
copyBtn.classList.remove('inputBtn--copied');
|
||||||
copyBtn.textContent = state.translate('copyUrlFormButton');
|
copyBtn.textContent = state.translate('copyUrlFormButton');
|
||||||
|
@ -114,5 +93,23 @@ module.exports = function(state, emit) {
|
||||||
await fadeOut('#shareWrapper');
|
await fadeOut('#shareWrapper');
|
||||||
emit('pushState', '/');
|
emit('pushState', '/');
|
||||||
}
|
}
|
||||||
return div;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
function expireInfo(file, translate, emit) {
|
||||||
|
const hours = Math.floor(EXPIRE_SECONDS / 60 / 60);
|
||||||
|
const el = html`<div>${raw(
|
||||||
|
translate('expireInfo', {
|
||||||
|
downloadCount: '<select></select>',
|
||||||
|
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 });
|
||||||
|
select.parentNode.replaceChild(
|
||||||
|
selectbox(file.dlimit || 1, options, t, changed),
|
||||||
|
select
|
||||||
|
);
|
||||||
|
return el;
|
||||||
|
}
|
||||||
|
|
|
@ -40,7 +40,6 @@
|
||||||
line-height: 23px;
|
line-height: 23px;
|
||||||
font-weight: 300;
|
font-weight: 300;
|
||||||
padding-left: 10px;
|
padding-left: 10px;
|
||||||
padding-right: 10px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.copySection__url:disabled {
|
.copySection__url:disabled {
|
||||||
|
@ -53,6 +52,10 @@
|
||||||
padding-bottom: 4px;
|
padding-bottom: 4px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.input--copied {
|
||||||
|
border-color: var(--successControlBGColor);
|
||||||
|
}
|
||||||
|
|
||||||
.inputBtn--copied,
|
.inputBtn--copied,
|
||||||
.inputBtn--copied:hover {
|
.inputBtn--copied:hover {
|
||||||
background: var(--successControlBGColor);
|
background: var(--successControlBGColor);
|
||||||
|
|
|
@ -1,24 +1,6 @@
|
||||||
const html = require('choo/html');
|
const html = require('choo/html');
|
||||||
const assets = require('../../../common/assets');
|
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) {
|
module.exports = function(state) {
|
||||||
let strings = {};
|
let strings = {};
|
||||||
let why = '';
|
let why = '';
|
||||||
|
@ -46,7 +28,7 @@ module.exports = function(state) {
|
||||||
${strings.button}
|
${strings.button}
|
||||||
</div>`;
|
</div>`;
|
||||||
}
|
}
|
||||||
const div = html`
|
return html`
|
||||||
<div class="unsupportedPage">
|
<div class="unsupportedPage">
|
||||||
<div class="title">${strings.title}</div>
|
<div class="title">${strings.title}</div>
|
||||||
<div class="description">
|
<div class="description">
|
||||||
|
@ -64,5 +46,22 @@ module.exports = function(state) {
|
||||||
${strings.explainer}
|
${strings.explainer}
|
||||||
</div>
|
</div>
|
||||||
</div>`;
|
</div>`;
|
||||||
return div;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
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')
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
font-size: 13px;
|
font-size: 13px;
|
||||||
line-height: 23px;
|
line-height: 23px;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
color: #7d7d7d;
|
color: var(--lightTextColor);
|
||||||
margin: 0 auto 23px;
|
margin: 0 auto 23px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -23,7 +23,7 @@
|
||||||
box-shadow: 0 5px 3px rgb(234, 234, 234);
|
box-shadow: 0 5px 3px rgb(234, 234, 234);
|
||||||
font-family: 'Fira Sans', 'segoe ui', sans-serif;
|
font-family: 'Fira Sans', 'segoe ui', sans-serif;
|
||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
color: #fff;
|
color: var(--primaryControlFGColor);
|
||||||
font-size: 26px;
|
font-size: 26px;
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
|
|
|
@ -5,7 +5,7 @@ const { bytes } = require('../../utils');
|
||||||
module.exports = function(state, emit) {
|
module.exports = function(state, emit) {
|
||||||
const transfer = state.transfer;
|
const transfer = state.transfer;
|
||||||
|
|
||||||
const div = html`
|
return html`
|
||||||
<div class="page effect--fadeIn">
|
<div class="page effect--fadeIn">
|
||||||
<div class="title">
|
<div class="title">
|
||||||
${state.translate('uploadingPageProgress', {
|
${state.translate('uploadingPageProgress', {
|
||||||
|
@ -36,5 +36,4 @@ module.exports = function(state, emit) {
|
||||||
btn.textContent = state.translate('uploadCancelNotification');
|
btn.textContent = state.translate('uploadCancelNotification');
|
||||||
emit('cancel');
|
emit('cancel');
|
||||||
}
|
}
|
||||||
return div;
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -7,7 +7,7 @@ const { bytes, fadeOut } = require('../../utils');
|
||||||
module.exports = function(state, emit) {
|
module.exports = function(state, emit) {
|
||||||
// the page flickers if both the server and browser set 'effect--fadeIn'
|
// the page flickers if both the server and browser set 'effect--fadeIn'
|
||||||
const fade = state.layout ? '' : 'effect--fadeIn';
|
const fade = state.layout ? '' : 'effect--fadeIn';
|
||||||
const div = html`
|
return html`
|
||||||
<div id="page-one" class="${fade}">
|
<div id="page-one" class="${fade}">
|
||||||
<div class="title">${state.translate('uploadPageHeader')}</div>
|
<div class="title">${state.translate('uploadPageHeader')}</div>
|
||||||
<div class="description">
|
<div class="description">
|
||||||
|
@ -82,5 +82,4 @@ module.exports = function(state, emit) {
|
||||||
await fadeOut('#page-one');
|
await fadeOut('#page-one');
|
||||||
emit('upload', { file, type: 'click' });
|
emit('upload', { file, type: 'click' });
|
||||||
}
|
}
|
||||||
return div;
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,29 +0,0 @@
|
||||||
.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%;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,52 +0,0 @@
|
||||||
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`<div class="changePasswordSection">
|
|
||||||
${passwordSpan(file.password)}
|
|
||||||
<button
|
|
||||||
class="btn btn--reset"
|
|
||||||
onclick=${toggleResetInput}
|
|
||||||
>${state.translate('changePasswordButton')}</button>
|
|
||||||
${passwordInput(
|
|
||||||
state.translate('unlockInputPlaceholder'),
|
|
||||||
state.translate('changePasswordButton'),
|
|
||||||
changePassword
|
|
||||||
)}
|
|
||||||
</div>`;
|
|
||||||
|
|
||||||
function passwordSpan(password) {
|
|
||||||
password = password || '●●●●●';
|
|
||||||
const span = html`<span>${raw(
|
|
||||||
state.translate('passwordResult', {
|
|
||||||
password: '<pre class="passwordMask"></pre>'
|
|
||||||
})
|
|
||||||
)}</span>`;
|
|
||||||
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';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
|
@ -1,15 +1,13 @@
|
||||||
const html = require('choo/html');
|
const html = require('choo/html');
|
||||||
|
|
||||||
module.exports = function(state, emit) {
|
module.exports = function(state, emit) {
|
||||||
|
return html`
|
||||||
|
<button class="btn btn--download"
|
||||||
|
onclick=${download}>${state.translate('downloadButtonLabel')}
|
||||||
|
</button>`;
|
||||||
|
|
||||||
function download(event) {
|
function download(event) {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
emit('download', state.fileInfo);
|
emit('download', state.fileInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
return html`
|
|
||||||
<div>
|
|
||||||
<button class="btn btn--download"
|
|
||||||
onclick=${download}>${state.translate('downloadButtonLabel')}
|
|
||||||
</button>
|
|
||||||
</div>`;
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
.fileData {
|
.fileData {
|
||||||
font-size: 15px;
|
font-size: 15px;
|
||||||
vertical-align: top;
|
vertical-align: top;
|
||||||
color: #4a4a4a;
|
color: var(--lightTextColor);
|
||||||
padding: 17px 19px 0;
|
padding: 17px 19px 0;
|
||||||
line-height: 23px;
|
line-height: 23px;
|
||||||
position: relative;
|
position: relative;
|
||||||
|
|
|
@ -3,30 +3,13 @@ const assets = require('../../../common/assets');
|
||||||
const number = require('../../utils').number;
|
const number = require('../../utils').number;
|
||||||
const deletePopup = require('../popup');
|
const deletePopup = require('../popup');
|
||||||
|
|
||||||
function timeLeft(milliseconds, state) {
|
|
||||||
const minutes = Math.floor(milliseconds / 1000 / 60);
|
|
||||||
const hours = Math.floor(minutes / 60);
|
|
||||||
if (hours >= 1) {
|
|
||||||
return state.translate('expiresHoursMinutes', {
|
|
||||||
hours,
|
|
||||||
minutes: minutes % 60
|
|
||||||
});
|
|
||||||
} else if (hours === 0) {
|
|
||||||
if (minutes === 0) {
|
|
||||||
return state.translate('expiresMinutes', { minutes: '< 1' });
|
|
||||||
}
|
|
||||||
return state.translate('expiresMinutes', { minutes });
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports = function(file, state, emit) {
|
module.exports = function(file, state, emit) {
|
||||||
const ttl = file.expiresAt - Date.now();
|
const ttl = file.expiresAt - Date.now();
|
||||||
const remainingTime =
|
const remainingTime =
|
||||||
timeLeft(ttl, state) || state.translate('linkExpiredAlt');
|
timeLeft(ttl, state) || state.translate('linkExpiredAlt');
|
||||||
const downloadLimit = file.dlimit || 1;
|
const downloadLimit = file.dlimit || 1;
|
||||||
const totalDownloads = file.dtotal || 0;
|
const totalDownloads = file.dtotal || 0;
|
||||||
const row = html`
|
return html`
|
||||||
<tr id="${file.id}">
|
<tr id="${file.id}">
|
||||||
<td class="fileData fileData--overflow" title="${file.name}">
|
<td class="fileData fileData--overflow" title="${file.name}">
|
||||||
<a class="link" href="/share/${file.id}">${file.name}</a>
|
<a class="link" href="/share/${file.id}">${file.name}</a>
|
||||||
|
@ -84,6 +67,21 @@ module.exports = function(file, state, emit) {
|
||||||
emit('delete', { file, location: 'upload-list' });
|
emit('delete', { file, location: 'upload-list' });
|
||||||
emit('render');
|
emit('render');
|
||||||
}
|
}
|
||||||
|
|
||||||
return row;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
function timeLeft(milliseconds, state) {
|
||||||
|
const minutes = Math.floor(milliseconds / 1000 / 60);
|
||||||
|
const hours = Math.floor(minutes / 60);
|
||||||
|
if (hours >= 1) {
|
||||||
|
return state.translate('expiresHoursMinutes', {
|
||||||
|
hours,
|
||||||
|
minutes: minutes % 60
|
||||||
|
});
|
||||||
|
} else if (hours === 0) {
|
||||||
|
if (minutes === 0) {
|
||||||
|
return state.translate('expiresMinutes', { minutes: '< 1' });
|
||||||
|
}
|
||||||
|
return state.translate('expiresMinutes', { minutes });
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
|
|
||||||
.fileList__header {
|
.fileList__header {
|
||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
color: #858585;
|
color: var(--lightTextColor);
|
||||||
font-weight: lighter;
|
font-weight: lighter;
|
||||||
text-align: left;
|
text-align: left;
|
||||||
background: rgba(0, 148, 251, 0.05);
|
background: rgba(0, 148, 251, 0.05);
|
||||||
|
|
|
@ -2,9 +2,8 @@ const html = require('choo/html');
|
||||||
const file = require('../file');
|
const file = require('../file');
|
||||||
|
|
||||||
module.exports = function(state, emit) {
|
module.exports = function(state, emit) {
|
||||||
let table = '';
|
|
||||||
if (state.storage.files.length) {
|
if (state.storage.files.length) {
|
||||||
table = html`
|
return html`
|
||||||
<table class="fileList">
|
<table class="fileList">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
|
@ -31,5 +30,4 @@ module.exports = function(state, emit) {
|
||||||
</table>
|
</table>
|
||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
return table;
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -20,7 +20,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.legalSection__link {
|
.legalSection__link {
|
||||||
color: #858585;
|
color: var(--lightTextColor);
|
||||||
opacity: 0.9;
|
opacity: 0.9;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
margin-right: 2vw;
|
margin-right: 2vw;
|
||||||
|
@ -31,7 +31,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.legalSection__link:visited {
|
.legalSection__link:visited {
|
||||||
color: #858585;
|
color: var(--lightTextColor);
|
||||||
}
|
}
|
||||||
|
|
||||||
.legalSection__mozLogo {
|
.legalSection__mozLogo {
|
||||||
|
|
|
@ -2,9 +2,6 @@ const html = require('choo/html');
|
||||||
const assets = require('../../../common/assets');
|
const assets = require('../../../common/assets');
|
||||||
|
|
||||||
module.exports = function(state, emit) {
|
module.exports = function(state, emit) {
|
||||||
function clicked() {
|
|
||||||
emit('experiment', { cd3: 'promo' });
|
|
||||||
}
|
|
||||||
let classes = 'fxPromo';
|
let classes = 'fxPromo';
|
||||||
switch (state.promo) {
|
switch (state.promo) {
|
||||||
case 'blue':
|
case 'blue':
|
||||||
|
@ -30,4 +27,8 @@ module.exports = function(state, emit) {
|
||||||
>Download Firefox now ≫</a></span>
|
>Download Firefox now ≫</a></span>
|
||||||
</div>
|
</div>
|
||||||
</div>`;
|
</div>`;
|
||||||
|
|
||||||
|
function clicked() {
|
||||||
|
emit('experiment', { cd3: 'promo' });
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -59,7 +59,7 @@
|
||||||
border-radius: 3px;
|
border-radius: 3px;
|
||||||
border: 1px solid var(--primaryControlBGColor);
|
border: 1px solid var(--primaryControlBGColor);
|
||||||
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1);
|
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1);
|
||||||
color: #fff;
|
color: var(--primaryControlFGColor);
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
display: block;
|
display: block;
|
||||||
float: right;
|
float: right;
|
||||||
|
@ -85,7 +85,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.feedback:active {
|
.feedback:active {
|
||||||
background-color: #0277d8;
|
background-color: var(--primaryControlHoverColor);
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (max-device-width: 520px), (max-width: 520px) {
|
@media (max-device-width: 520px), (max-width: 520px) {
|
||||||
|
|
|
@ -11,6 +11,28 @@ const assets = require('../../../common/assets');
|
||||||
string with the value from package.json. 🤢
|
string with the value from package.json. 🤢
|
||||||
*/
|
*/
|
||||||
const version = require('../../../package.json').version || 'VERSION';
|
const version = require('../../../package.json').version || 'VERSION';
|
||||||
|
const browser = browserName();
|
||||||
|
|
||||||
|
module.exports = function(state) {
|
||||||
|
return html`<header class="header">
|
||||||
|
<div class="logo">
|
||||||
|
<a class="logo__link" href="/">
|
||||||
|
<img
|
||||||
|
src="${assets.get('send_logo.svg')}"
|
||||||
|
alt="Send"/>
|
||||||
|
<h1 class="logo__title">Send</h1>
|
||||||
|
</a>
|
||||||
|
<div class="logo__subtitle">
|
||||||
|
<a class="logo__subtitle-link" href="https://testpilot.firefox.com">Firefox Test Pilot</a>
|
||||||
|
<div>${state.translate('siteSubtitle')}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<a href="https://qsurvey.mozilla.com/s3/txp-firefox-send?ver=${version}&browser=${browser}"
|
||||||
|
rel="noreferrer noopener"
|
||||||
|
class="feedback"
|
||||||
|
target="_blank">${state.translate('siteFeedback')}</a>
|
||||||
|
</header>`;
|
||||||
|
};
|
||||||
|
|
||||||
function browserName() {
|
function browserName() {
|
||||||
try {
|
try {
|
||||||
|
@ -34,26 +56,3 @@ function browserName() {
|
||||||
return 'unknown';
|
return 'unknown';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const browser = browserName();
|
|
||||||
|
|
||||||
module.exports = function(state) {
|
|
||||||
return html`<header class="header">
|
|
||||||
<div class="logo">
|
|
||||||
<a class="logo__link" href="/">
|
|
||||||
<img
|
|
||||||
src="${assets.get('send_logo.svg')}"
|
|
||||||
alt="Send"/>
|
|
||||||
<h1 class="logo__title">Send</h1>
|
|
||||||
</a>
|
|
||||||
<div class="logo__subtitle">
|
|
||||||
<a class="logo__subtitle-link" href="https://testpilot.firefox.com">Firefox Test Pilot</a>
|
|
||||||
<div>${state.translate('siteSubtitle')}</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<a href="https://qsurvey.mozilla.com/s3/txp-firefox-send?ver=${version}&browser=${browser}"
|
|
||||||
rel="noreferrer noopener"
|
|
||||||
class="feedback"
|
|
||||||
target="_blank">${state.translate('siteFeedback')}</a>
|
|
||||||
</header>`;
|
|
||||||
};
|
|
||||||
|
|
|
@ -1,26 +1,54 @@
|
||||||
const html = require('choo/html');
|
const html = require('choo/html');
|
||||||
|
|
||||||
module.exports = function(placeholder, action, submit) {
|
module.exports = function(file, state, emit) {
|
||||||
|
const setting = state.settingPassword;
|
||||||
|
const formClass = file.hasPassword
|
||||||
|
? 'passwordInput'
|
||||||
|
: 'passwordInput passwordInput--hidden';
|
||||||
|
const inputClass = setting ? 'input input--copied' : 'input input--noBtn';
|
||||||
|
const btnClass = setting
|
||||||
|
? 'inputBtn inputBtn--loading'
|
||||||
|
: 'inputBtn inputBtn--hidden';
|
||||||
|
const action = file.hasPassword
|
||||||
|
? state.translate('changePasswordButton')
|
||||||
|
: state.translate('addPasswordButton');
|
||||||
return html`
|
return html`
|
||||||
|
<div>
|
||||||
<form
|
<form
|
||||||
class="passwordInput passwordInput--hidden"
|
class="${formClass}"
|
||||||
onsubmit=${submit}
|
onsubmit=${setPassword}
|
||||||
data-no-csrf>
|
data-no-csrf>
|
||||||
<input id="password-input"
|
<input id="password-input"
|
||||||
class="input input--noBtn"
|
${setting ? 'disabled' : ''}
|
||||||
|
class="${inputClass}"
|
||||||
maxlength="32"
|
maxlength="32"
|
||||||
autocomplete="off"
|
autocomplete="off"
|
||||||
type="password"
|
type="password"
|
||||||
oninput=${inputChanged}
|
oninput=${inputChanged}
|
||||||
placeholder="${placeholder}">
|
placeholder="${
|
||||||
|
file.hasPassword
|
||||||
|
? passwordPlaceholder(file.password)
|
||||||
|
: state.translate('unlockInputPlaceholder')
|
||||||
|
}">
|
||||||
<input type="submit"
|
<input type="submit"
|
||||||
id="password-btn"
|
id="password-btn"
|
||||||
class="inputBtn inputBtn--hidden"
|
${setting ? 'disabled' : ''}
|
||||||
value="${action}"/>
|
class="${btnClass}"
|
||||||
|
value="${setting ? '' : action}">
|
||||||
</form>
|
</form>
|
||||||
|
<div class="passwordInput__msg">${message(
|
||||||
|
setting,
|
||||||
|
file.hasPassword,
|
||||||
|
state.translate('passwordIsSet')
|
||||||
|
)}</div>
|
||||||
|
</div>
|
||||||
`;
|
`;
|
||||||
|
|
||||||
function inputChanged() {
|
function inputChanged() {
|
||||||
|
const pwdmsg = document.querySelector('.passwordInput__msg');
|
||||||
|
if (pwdmsg) {
|
||||||
|
pwdmsg.textContent = '';
|
||||||
|
}
|
||||||
const resetInput = document.getElementById('password-input');
|
const resetInput = document.getElementById('password-input');
|
||||||
const resetBtn = document.getElementById('password-btn');
|
const resetBtn = document.getElementById('password-btn');
|
||||||
if (resetInput.value.length > 0) {
|
if (resetInput.value.length > 0) {
|
||||||
|
@ -31,4 +59,24 @@ module.exports = function(placeholder, action, submit) {
|
||||||
resetInput.classList.add('input--noBtn');
|
resetInput.classList.add('input--noBtn');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function setPassword(event) {
|
||||||
|
event.preventDefault();
|
||||||
|
const password = document.getElementById('password-input').value;
|
||||||
|
if (password.length > 0) {
|
||||||
|
emit('password', { password, file });
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
function passwordPlaceholder(password) {
|
||||||
|
return password ? password.replace(/./g, '●') : '●●●●●●●●●●●●';
|
||||||
|
}
|
||||||
|
|
||||||
|
function message(setting, pwd, deflt) {
|
||||||
|
if (setting || !pwd) {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
return deflt;
|
||||||
|
}
|
||||||
|
|
|
@ -3,16 +3,42 @@
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-wrap: nowrap;
|
flex-wrap: nowrap;
|
||||||
width: 80%;
|
width: 80%;
|
||||||
padding: 10px 5px;
|
padding: 10px 5px 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.passwordInput__msg {
|
||||||
|
height: 100px;
|
||||||
|
margin: 0 5px;
|
||||||
|
font-size: 15px;
|
||||||
|
color: var(--lightTextColor);
|
||||||
}
|
}
|
||||||
|
|
||||||
.passwordInput--hidden {
|
.passwordInput--hidden {
|
||||||
visibility: hidden;
|
visibility: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.inputBtn--loading {
|
||||||
|
background-image: url('../assets/spinner.svg');
|
||||||
|
background-position: center;
|
||||||
|
background-size: 30px 30px;
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
background-color: var(--successControlBGColor);
|
||||||
|
border: 1px solid var(--successControlBGColor);
|
||||||
|
color: var(--successControlFGColor);
|
||||||
|
width: 10em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.inputBtn--loading:hover {
|
||||||
|
background-color: var(--successControlBGColor);
|
||||||
|
}
|
||||||
|
|
||||||
@media (max-device-width: 520px), (max-width: 520px) {
|
@media (max-device-width: 520px), (max-width: 520px) {
|
||||||
.passwordInput {
|
.passwordInput {
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
width: inherit;
|
width: inherit;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.inputBtn--loading {
|
||||||
|
width: inherit;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,14 +1,6 @@
|
||||||
const html = require('choo/html');
|
const html = require('choo/html');
|
||||||
|
|
||||||
module.exports = function(msg, confirmText, cancelText, confirmCallback) {
|
module.exports = function(msg, confirmText, cancelText, confirmCallback) {
|
||||||
function hide(e) {
|
|
||||||
e.stopPropagation();
|
|
||||||
const popup = document.querySelector('.popup.popup--show');
|
|
||||||
if (popup) {
|
|
||||||
popup.classList.remove('popup--show');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return html`
|
return html`
|
||||||
<div class="popup__wrapper">
|
<div class="popup__wrapper">
|
||||||
<div class="popup" onblur=${hide} tabindex="-1">
|
<div class="popup" onblur=${hide} tabindex="-1">
|
||||||
|
@ -23,4 +15,12 @@ module.exports = function(msg, confirmText, cancelText, confirmCallback) {
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>`;
|
</div>`;
|
||||||
|
|
||||||
|
function hide(e) {
|
||||||
|
e.stopPropagation();
|
||||||
|
const popup = document.querySelector('.popup.popup--show');
|
||||||
|
if (popup) {
|
||||||
|
popup.classList.remove('popup--show');
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -2,8 +2,8 @@
|
||||||
visibility: hidden;
|
visibility: hidden;
|
||||||
min-width: 204px;
|
min-width: 204px;
|
||||||
min-height: 105px;
|
min-height: 105px;
|
||||||
background-color: #fff;
|
background-color: var(--pageBGColor);
|
||||||
color: #000;
|
color: var(--textColor);
|
||||||
border: 1px solid #d7d7db;
|
border: 1px solid #d7d7db;
|
||||||
padding: 15px 24px;
|
padding: 15px 24px;
|
||||||
box-sizing: content-box;
|
box-sizing: content-box;
|
||||||
|
@ -82,7 +82,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.popup__yes {
|
.popup__yes {
|
||||||
color: #fff;
|
color: var(--primaryControlFGColor);
|
||||||
background-color: var(--primaryControlBGColor);
|
background-color: var(--primaryControlBGColor);
|
||||||
border-radius: 5px;
|
border-radius: 5px;
|
||||||
padding: 5px 25px;
|
padding: 5px 25px;
|
||||||
|
|
|
@ -9,7 +9,7 @@ const circumference = 2 * Math.PI * radius;
|
||||||
module.exports = function(progressRatio) {
|
module.exports = function(progressRatio) {
|
||||||
const dashOffset = (1 - progressRatio) * circumference;
|
const dashOffset = (1 - progressRatio) * circumference;
|
||||||
const percentComplete = percent(progressRatio);
|
const percentComplete = percent(progressRatio);
|
||||||
const div = html`
|
return html`
|
||||||
<div class="progress">
|
<div class="progress">
|
||||||
<svg
|
<svg
|
||||||
width="${oDiameter}"
|
width="${oDiameter}"
|
||||||
|
@ -37,5 +37,4 @@ module.exports = function(progressRatio) {
|
||||||
</svg>
|
</svg>
|
||||||
</div>
|
</div>
|
||||||
`;
|
`;
|
||||||
return div;
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -5,6 +5,25 @@ module.exports = function(selected, options, translate, changed) {
|
||||||
const id = `select-${Math.random()}`;
|
const id = `select-${Math.random()}`;
|
||||||
let x = selected;
|
let x = selected;
|
||||||
|
|
||||||
|
return html`
|
||||||
|
<div class="selectbox">
|
||||||
|
<div onclick=${toggle}>
|
||||||
|
<span class="link">${translate(selected)}</span>
|
||||||
|
<svg width="32" height="32">
|
||||||
|
<polygon points="8 18 17 28 26 18" fill="#0094fb"/>
|
||||||
|
</svg>
|
||||||
|
</div>
|
||||||
|
<ul id="${id}" class="selectbox__options">
|
||||||
|
${options.map(
|
||||||
|
i => html`
|
||||||
|
<li
|
||||||
|
class="selectbox__option"
|
||||||
|
onclick=${choose}
|
||||||
|
data-value="${i}">${number(i)}</li>`
|
||||||
|
)}
|
||||||
|
</ul>
|
||||||
|
</div>`;
|
||||||
|
|
||||||
function close() {
|
function close() {
|
||||||
const ul = document.getElementById(id);
|
const ul = document.getElementById(id);
|
||||||
const body = document.querySelector('body');
|
const body = document.querySelector('body');
|
||||||
|
@ -37,21 +56,4 @@ module.exports = function(selected, options, translate, changed) {
|
||||||
}
|
}
|
||||||
close();
|
close();
|
||||||
}
|
}
|
||||||
return html`
|
|
||||||
<div class="selectbox">
|
|
||||||
<div onclick=${toggle}>
|
|
||||||
<span class="link">${translate(selected)}</span>
|
|
||||||
<svg width="32" height="32">
|
|
||||||
<polygon points="8 18 17 28 26 18" fill="#0094fb"/>
|
|
||||||
</svg>
|
|
||||||
</div>
|
|
||||||
<ul id="${id}" class="selectbox__options">
|
|
||||||
${options.map(
|
|
||||||
i =>
|
|
||||||
html`<li class="selectbox__option" onclick=${choose} data-value="${i}">${number(
|
|
||||||
i
|
|
||||||
)}</li>`
|
|
||||||
)}
|
|
||||||
</ul>
|
|
||||||
</div>`;
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
left: 0;
|
left: 0;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
margin: 40px 0;
|
margin: 40px 0;
|
||||||
background-color: white;
|
background-color: var(--pageBGColor);
|
||||||
border: 1px solid rgba(12, 12, 13, 0.3);
|
border: 1px solid rgba(12, 12, 13, 0.3);
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
box-shadow: 1px 2px 4px rgba(12, 12, 13, 0.3);
|
box-shadow: 1px 2px 4px rgba(12, 12, 13, 0.3);
|
||||||
|
|
|
@ -3,10 +3,13 @@ const passwordInput = require('../passwordInput');
|
||||||
|
|
||||||
module.exports = function(state, emit) {
|
module.exports = function(state, emit) {
|
||||||
const file = state.storage.getFileById(state.params.id);
|
const file = state.storage.getFileById(state.params.id);
|
||||||
const div = html`
|
|
||||||
|
return html`
|
||||||
<div class="setPasswordSection">
|
<div class="setPasswordSection">
|
||||||
<div class="checkbox">
|
<div class="checkbox">
|
||||||
<input
|
<input
|
||||||
|
${file.hasPassword ? 'disabled' : ''}
|
||||||
|
${file.hasPassword ? 'checked' : ''}
|
||||||
class="checkbox__input"
|
class="checkbox__input"
|
||||||
id="add-password"
|
id="add-password"
|
||||||
type="checkbox"
|
type="checkbox"
|
||||||
|
@ -16,22 +19,9 @@ module.exports = function(state, emit) {
|
||||||
${state.translate('requirePasswordCheckbox')}
|
${state.translate('requirePasswordCheckbox')}
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
${passwordInput(
|
${passwordInput(file, state, emit)}
|
||||||
state.translate('unlockInputPlaceholder'),
|
|
||||||
state.translate('addPasswordButton'),
|
|
||||||
addPassword
|
|
||||||
)}
|
|
||||||
</div>`;
|
</div>`;
|
||||||
|
|
||||||
function addPassword(event) {
|
|
||||||
event.preventDefault();
|
|
||||||
const password = document.getElementById('password-input').value;
|
|
||||||
if (password.length > 0) {
|
|
||||||
emit('password', { password, file });
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
function togglePasswordInput(e) {
|
function togglePasswordInput(e) {
|
||||||
const unlockInput = document.getElementById('password-input');
|
const unlockInput = document.getElementById('password-input');
|
||||||
const boxChecked = e.target.checked;
|
const boxChecked = e.target.checked;
|
||||||
|
@ -44,6 +34,4 @@ module.exports = function(state, emit) {
|
||||||
unlockInput.value = '';
|
unlockInput.value = '';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return div;
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -11,7 +11,7 @@
|
||||||
|
|
||||||
.checkbox__input {
|
.checkbox__input {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
visibility: collapse;
|
opacity: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.checkbox__label {
|
.checkbox__label {
|
||||||
|
@ -31,12 +31,13 @@
|
||||||
border-radius: 2px;
|
border-radius: 2px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.checkbox__input:focus + .checkbox__label::before,
|
||||||
.checkbox:hover .checkbox__label::before {
|
.checkbox:hover .checkbox__label::before {
|
||||||
border: 1px solid var(--primaryControlBGColor);
|
border: 1px solid var(--primaryControlBGColor);
|
||||||
}
|
}
|
||||||
|
|
||||||
.checkbox__input:checked + .checkbox__label {
|
.checkbox__input:checked + .checkbox__label {
|
||||||
color: #000;
|
color: var(--textColor);
|
||||||
}
|
}
|
||||||
|
|
||||||
.checkbox__input:checked + .checkbox__label::before {
|
.checkbox__input:checked + .checkbox__label::before {
|
||||||
|
@ -44,6 +45,19 @@
|
||||||
background-position: 2px 1px;
|
background-position: 2px 1px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.checkbox__input:disabled + .checkbox__label {
|
||||||
|
cursor: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.checkbox__input:disabled + .checkbox__label::before {
|
||||||
|
background-image: url('../assets/check-16.svg');
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
background-size: 18px 18px;
|
||||||
|
border-color: var(--successControlBGColor);
|
||||||
|
background-color: var(--successControlBGColor);
|
||||||
|
cursor: auto;
|
||||||
|
}
|
||||||
|
|
||||||
@media (max-device-width: 520px), (max-width: 520px) {
|
@media (max-device-width: 520px), (max-width: 520px) {
|
||||||
.setPasswordSection {
|
.setPasswordSection {
|
||||||
align-self: center;
|
align-self: center;
|
||||||
|
|
|
@ -0,0 +1,17 @@
|
||||||
|
<!-- By Sam Herbert (@sherb), for everyone. More @ http://goo.gl/7AJzbL -->
|
||||||
|
<svg width="38" height="38" viewBox="0 0 38 38" xmlns="http://www.w3.org/2000/svg" stroke="#fff">
|
||||||
|
<g fill="none" fill-rule="evenodd">
|
||||||
|
<g transform="translate(1 1)" stroke-width="2">
|
||||||
|
<circle stroke-opacity=".5" cx="18" cy="18" r="18"/>
|
||||||
|
<path d="M36 18c0-9.94-8.06-18-18-18">
|
||||||
|
<animateTransform
|
||||||
|
attributeName="transform"
|
||||||
|
type="rotate"
|
||||||
|
from="0 18 18"
|
||||||
|
to="360 18 18"
|
||||||
|
dur="1s"
|
||||||
|
repeatCount="indefinite"/>
|
||||||
|
</path>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 694 B |
|
@ -113,3 +113,5 @@ enableJavascript = Please enable JavaScript and try again.
|
||||||
expiresHoursMinutes = { $hours }h { $minutes }m
|
expiresHoursMinutes = { $hours }h { $minutes }m
|
||||||
# A short representation of a countdown timer containing the number of minutes remaining as digits, example "56m"
|
# A short representation of a countdown timer containing the number of minutes remaining as digits, example "56m"
|
||||||
expiresMinutes = { $minutes }m
|
expiresMinutes = { $minutes }m
|
||||||
|
# A short status message shown when a password is successfully set
|
||||||
|
passwordIsSet = Password set
|
||||||
|
|
Loading…
Reference in New Issue