Merge pull request #761 from mozilla/i741

added maxPasswordLength and passwordError messages
This commit is contained in:
Danny Coates 2018-02-22 09:10:26 -08:00 committed by GitHub
commit b39bbaf6fb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 81 additions and 56 deletions

View File

@ -106,6 +106,10 @@ a {
padding-right: 10px;
}
.input--error {
border-color: var(--errorColor);
}
.input--noBtn {
border-radius: 6px;
}
@ -215,6 +219,10 @@ a {
}
}
.error {
color: var(--errorColor);
}
.title {
font-size: 33px;
line-height: 40px;

View File

@ -135,9 +135,11 @@ export default function(state, emitter) {
state.storage.writeFile(file);
metrics.addedPassword({ size: file.size });
await delay(1000);
state.settingPassword = false;
} catch (err) {
console.error(err);
state.passwordSetError = err;
} finally {
state.settingPassword = false;
}
render();
});

View File

@ -21,11 +21,17 @@ export default class OwnedFile {
}
async setPassword(password) {
this.password = password;
this._hasPassword = true;
this.keychain.setPassword(password, this.url);
const result = await setPassword(this.id, this.ownerToken, this.keychain);
return result;
try {
this.password = password;
this._hasPassword = true;
this.keychain.setPassword(password, this.url);
const result = await setPassword(this.id, this.ownerToken, this.keychain);
return result;
} catch (e) {
this.password = null;
this._hasPassword = false;
throw e;
}
}
del() {

View File

@ -21,11 +21,9 @@ module.exports = function(state, emit) {
<div class="uploadArea"
ondragover=${dragover}
ondragleave=${dragleave}>
<div id="upload-img">
<img
src="${assets.get('upload.svg')}"
title="${state.translate('uploadSvgAlt')}"/>
</div>
<img
src="${assets.get('upload.svg')}"
title="${state.translate('uploadSvgAlt')}"/>
<div class="uploadArea__msg">
${state.translate('uploadPageDropMessage')}
</div>

View File

@ -11,14 +11,6 @@
padding: 10px 0;
}
.error {
color: var(--errorColor);
}
.input--error {
border-color: var(--errorColor);
}
@media (max-device-width: 520px), (max-width: 520px) {
.passwordSection {
width: 100%;

View File

@ -1,11 +1,13 @@
const html = require('choo/html');
const MAX_LENGTH = 32;
module.exports = function(file, state, emit) {
const loading = state.settingPassword;
const pwd = file.hasPassword;
const formClass = pwd
? 'passwordInput'
: 'passwordInput passwordInput--hidden';
const sectionClass =
pwd || state.passwordSetError
? 'passwordInput'
: 'passwordInput passwordInput--hidden';
const inputClass = loading || pwd ? 'input' : 'input input--noBtn';
let btnClass = 'inputBtn inputBtn--password inputBtn--hidden';
if (loading) {
@ -13,26 +15,25 @@ module.exports = function(file, state, emit) {
} else if (pwd) {
btnClass = 'inputBtn inputBtn--password';
}
const action = pwd
? state.translate('changePasswordButton')
: state.translate('addPasswordButton');
return html`
<div>
<div class="${sectionClass}">
<form
class="${formClass}"
class="passwordInput__form"
onsubmit=${setPassword}
data-no-csrf>
<input id="password-input"
${loading ? 'disabled' : ''}
class="${inputClass}"
maxlength="32"
maxlength="${MAX_LENGTH}"
autocomplete="off"
type="password"
oninput=${inputChanged}
onfocus=${focused}
placeholder="${
pwd
pwd && !state.passwordSetError
? passwordPlaceholder(file.password)
: state.translate('unlockInputPlaceholder')
}">
@ -42,22 +43,28 @@ module.exports = function(file, state, emit) {
class="${btnClass}"
value="${loading ? '' : action}">
</form>
<div class="passwordInput__msg">${message(
loading,
pwd,
state.translate('passwordIsSet')
)}</div>
</div>
`;
<label
class="passwordInput__msg ${
state.passwordSetError ? 'passwordInput__msg--error' : ''
}"
for="password-input">${message(state, pwd)}</label>
</div>`;
function inputChanged() {
const pwdmsg = document.querySelector('.passwordInput__msg');
if (pwdmsg) {
pwdmsg.textContent = '';
}
state.passwordSetError = null;
const resetInput = document.getElementById('password-input');
const resetBtn = document.getElementById('password-btn');
if (resetInput.value.length > 0) {
const pwdmsg = document.querySelector('.passwordInput__msg');
const length = resetInput.value.length;
if (length === MAX_LENGTH) {
pwdmsg.textContent = state.translate('maxPasswordLength', {
length: MAX_LENGTH
});
} else {
pwdmsg.textContent = '';
}
if (length > 0) {
resetBtn.classList.remove('inputBtn--hidden');
resetInput.classList.remove('input--noBtn');
} else {
@ -91,9 +98,12 @@ function passwordPlaceholder(password) {
return password ? password.replace(/./g, '●') : '●●●●●●●●●●●●';
}
function message(loading, pwd, deflt) {
if (loading || !pwd) {
function message(state, pwd) {
if (state.passwordSetError) {
return state.translate('passwordSetError');
}
if (state.settingPassword || !pwd) {
return '';
}
return deflt;
return state.translate('passwordIsSet');
}

View File

@ -1,21 +1,28 @@
.passwordInput {
display: flex;
flex-wrap: nowrap;
width: 80%;
padding: 10px 5px 5px;
}
.passwordInput__msg {
width: 90%;
height: 100px;
margin: 0 5px;
font-size: 15px;
color: var(--lightTextColor);
padding: 10px 5px 5px;
}
.passwordInput--hidden {
visibility: hidden;
}
.passwordInput__form {
display: flex;
flex-wrap: nowrap;
padding-bottom: 5px;
}
.passwordInput__msg {
font-size: 15px;
color: var(--lightTextColor);
}
.passwordInput__msg--error {
color: var(--errorColor);
}
.inputBtn--loading {
background-image: url('../assets/spinner.svg');
background-position: center;

View File

@ -9,7 +9,7 @@ module.exports = function(state, emit) {
<div class="checkbox">
<input
${file.hasPassword ? 'disabled' : ''}
${file.hasPassword ? 'checked' : ''}
${file.hasPassword || state.passwordSetError ? 'checked' : ''}
class="checkbox__input"
id="add-password"
type="checkbox"
@ -26,7 +26,7 @@ module.exports = function(state, emit) {
const unlockInput = document.getElementById('password-input');
const boxChecked = e.target.checked;
document
.querySelector('form.passwordInput')
.querySelector('.passwordInput')
.classList.toggle('passwordInput--hidden', !boxChecked);
if (boxChecked) {
unlockInput.focus();

View File

@ -103,8 +103,6 @@ requirePasswordCheckbox = Require a password to download this file
addPasswordButton = Add password
changePasswordButton = Change
passwordTryAgain = Incorrect password. Try again.
# This label is followed by the password needed to download a file
passwordResult = Password: { $password }
reportIPInfringement = Report IP Infringement
javascriptRequired = Firefox Send requires JavaScript
whyJavascript = Why does Firefox Send require JavaScript?
@ -115,3 +113,7 @@ expiresHoursMinutes = { $hours }h { $minutes }m
expiresMinutes = { $minutes }m
# A short status message shown when a password is successfully set
passwordIsSet = Password set
# A short status message shown when the user enters a long password
maxPasswordLength = Maximum password length: { $length }
# A short status message shown when there was an error setting the password
passwordSetError = This password could not be set