Merge pull request #71 from Mikunj/ui/registration

Registration UI
pull/74/head
Beaudan Campbell-Brown 7 years ago committed by GitHub
commit b0cec76fbb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -1669,5 +1669,10 @@
"editDisplayName": {
"message": "Edit display name",
"description": "Button action that the user can click to edit their display name"
},
"copiedMnemonic": {
"message": "Copied mnemonic to clipboard",
"description": "A toast message telling the user that the mnemonic was copied"
}
}

@ -598,27 +598,46 @@
</script>
<script type='text/x-tmpl-mustache' id='standalone'>
<div class='step'>
<div id='standalone' class='step'>
<div class='inner'>
<div class='step-body'>
<div class='header'>Create your Loki Messenger Account</div>
<div class='display-name-header'>Enter a name that will be shown to all your contacts</div>
<input class='form-control' type='text' id='display-name' placeholder='Display Name (optional)' autocomplete='off' spellcheck='false' maxlength='25'>
<hr>
<input class='form-control' type='text' id='mnemonic' placeholder='Mnemonic' autocomplete='off' spellcheck='false'>
<select id='mnemonic-language'></select>
<div class='clearfix'>
<a class='button' id='register-mnemonic'>Register using mnenomic</a>
<h4 class='section-toggle'>Restore using seed</h4>
<div class='standalone-mnemonic section-content'>
<div class='standalone-mnemonic-inputs'>
<input class='form-control' type='text' id='mnemonic' placeholder='Mnemonic Seed' autocomplete='off' spellcheck='false' />
<div class='select-container'>
<select id='mnemonic-language'></select>
</div>
</div>
<a class='button' id='register-mnemonic'>Restore</a>
<div id='error' class='collapse'></div>
<div id=status></div>
</div>
<h4 class='section-toggle section-toggle-visible'>Register a new account</h4>
<div class='standalone-register section-content'>
<div class='standalone-register-warning'>
Please save the seed below in a safe location.
</br>
They can be used to restore your account if you lose access or migrate to a new device.
</div>
<div class='standalone-register-language'>
<span>Language:</span>
<div class='select-container'>
<select id='mnemonic-display-language'></select>
</div>
</div>
<div id='mnemonic-display' />
<div class='standalone-register-buttons'>
<a class='button' id='generate-mnemonic'>Generate Seed</a>
<a class='button' id='copy-mnemonic'>Copy Seed</a>
<a class='button' id='register' data-loading-text='Please wait...'>Register</a>
</div>
</div>
<div id='error' class='collapse'></div>
<div id=status></div>
<hr>
</div>
<div class='nav'>
<a class='button' id='register' data-loading-text='Please wait...'>Register</a>
</div>
</div>
</div>

@ -1,4 +1,4 @@
/* global Whisper, $, getAccountManager, textsecure, storage, ConversationController */
/* global Whisper, $, getAccountManager, textsecure, i18n, storage, ConversationController */
/* eslint-disable more/no-then */
@ -10,7 +10,7 @@
Whisper.StandaloneRegistrationView = Whisper.View.extend({
templateName: 'standalone',
className: 'full-screen-flow',
className: 'full-screen-flow standalone-fullscreen',
initialize() {
this.accountManager = getAccountManager();
@ -25,28 +25,34 @@
});
this.$('#error').hide();
window.mnemonic.get_languages().forEach(language => {
this.$('#mnemonic-language').append(
$('<option>', {
value: language,
text: language.charAt(0).toUpperCase() + language.slice(1),
})
);
this.$('.standalone-mnemonic').hide();
this.onGenerateMnemonic();
const options = window.mnemonic.get_languages().map(language => {
const text = language.charAt(0).toUpperCase() + language.slice(1);
return `<option value="${language}">${text}</option>`;
});
this.$('#mnemonic-language').append(options);
this.$('#mnemonic-display-language').append(options);
},
events: {
'validation input.number': 'onValidation',
'click #request-voice': 'requestVoice',
'click #request-sms': 'requestSMSVerification',
'change #code': 'onChangeCode',
'click #register': 'register',
'click #register': 'registerWithoutMnemonic',
'click #register-mnemonic': 'registerWithMnemonic',
'change #mnemonic': 'onChangeMnemonic',
'click #generate-mnemonic': 'onGenerateMnemonic',
'change #mnemonic-display-language': 'onGenerateMnemonic',
'click #copy-mnemonic': 'onCopyMnemonic',
'click .section-toggle': 'toggleSection',
},
register() {
register(mnemonic) {
this.accountManager
.registerSingleDevice(
this.$('#mnemonic').val(),
mnemonic,
this.$('#mnemonic-language').val(),
this.$('#display-name').val()
)
@ -55,17 +61,35 @@
})
.catch(this.log.bind(this));
},
registerWithoutMnemonic() {
const mnemonic = this.$('#mnemonic-display').text();
this.register(mnemonic);
},
registerWithMnemonic() {
const words = this.$('#mnemonic').val();
if (!words) {
const mnemonic = this.$('#mnemonic').val();
if (!mnemonic) {
this.log('Please provide a mnemonic word list');
} else {
this.register();
this.register(mnemonic);
}
},
onChangeMnemonic() {
this.$('#status').html('');
},
async onGenerateMnemonic() {
const language = this.$('#mnemonic-display-language').val();
const mnemonic = await this.accountManager.generateMnemonic(language);
this.$('#mnemonic-display').text(mnemonic)
},
onCopyMnemonic() {
window.clipboard.writeText(this.$('#mnemonic-display').text());
const toast = new Whisper.MessageToastView({
message: i18n('copiedMnemonic'),
});
toast.$el.appendTo(this.$el);
toast.render();
},
log(s) {
window.log.info(s);
this.$('#status').text(s);
@ -121,5 +145,18 @@
this.$('#number-container').addClass('invalid');
}
},
toggleSection(e) {
// Expand or collapse this panel
const $target = this.$(e.target);
const $next = $target.next();
// Toggle section visibility
$next.slideToggle('fast');
$target.toggleClass('section-toggle-visible');
// Hide the other sections
this.$('.section-toggle').not($target).removeClass('section-toggle-visible')
this.$('.section-content').not($next).slideUp('fast');
},
});
})();

@ -2,7 +2,7 @@
window,
textsecure,
libsignal,
WebSocketResource,
mnemonic,
btoa,
getString,
Event,
@ -446,6 +446,11 @@
);
});
},
async generateMnemonic(language = 'english') {
const keys = await libsignal.KeyHelper.generateIdentityKeyPair();
const hex = StringView.arrayBufferToHex(keys.privKey);
return mnemonic.mn_encode(hex, language);
},
async registrationDone(number, profileName) {
window.log.info('registration done');

@ -276,7 +276,7 @@
display: block;
max-height: 100px;
padding: 10px;
border-radius: 2px;
border-radius: 4px;
background-color: $color-loki-light-gray;
color: $color-light-90;
border: 1px solid rgba(0, 0, 0, 0.2);
@ -368,19 +368,20 @@
box-shadow: 0px 0px 15px 0px rgba(0, 0, 0, 0.3);
.buttons {
margin-top: 10px;
button {
float: right;
margin-left: 10px;
background-color: $grey_l;
border-radius: $border-radius;
padding: 5px 8px;
border: 1px solid $grey_l2;
background-color: $color-loki-green;
border-radius: 100px;
padding: 5px 15px;
border: 1px solid $color-loki-green;
color: white;
outline: none;
&:hover {
background-color: $grey_l2;
border-color: $grey_l3;
background-color: $color-loki-green-dark;
border-color: $color-loki-green-dark;
}
}
}
@ -388,10 +389,16 @@
input {
width: 100%;
padding: 8px;
margin-bottom: 4px;
margin-bottom: 15px;
border: 0;
outline: none;
border-radius: 4px;
background-color: $color-loki-light-gray;
}
h4 {
margin-top: 8px;
margin-bottom: 16px;
white-space: -moz-pre-wrap; /* Mozilla */
white-space: -hp-pre-wrap; /* HP printers */
white-space: -o-pre-wrap; /* Opera 7 */
@ -406,6 +413,7 @@
font-style: italic;
color: $grey;
font-size: 12px;
margin-bottom: 16px;
}
}
}

@ -533,7 +533,7 @@ textarea {
font-size: 10pt;
input {
margin-top: 1em;
margin-bottom: 1em;
font-size: 12pt;
font-family: roboto-light;
border: 2px solid $blue;
@ -647,10 +647,6 @@ textarea {
max-width: 35em;
}
#display-name {
margin-bottom: 12px;
}
.inner {
display: flex;
align-items: center;
@ -723,14 +719,12 @@ textarea {
border: none;
min-width: 300px;
padding: 0.75em;
margin-top: 1em;
margin-left: 0.5em;
margin-right: 0.5em;
color: white;
background: $blue;
box-shadow: 2px 2px 4px rgba(0, 0, 0, 0.5);
user-select: none;
font-size: 12pt;
margin-top: 4px;
&.neutral {
color: black;
@ -806,6 +800,194 @@ textarea {
}
}
.standalone-fullscreen {
background: $color-dark-85;
overflow-y: auto;
}
#standalone {
color: $color-dark-05;
height: auto;
padding: 0;
::-webkit-scrollbar-track {
background: $color-dark-85;
}
::-webkit-scrollbar-thumb {
border: 2px solid $color-dark-85;
}
.step-body {
width: 80%;
min-width: 100px;
max-width: none;
}
.section-toggle {
background: $color-dark-75;
&:first-of-type {
border-radius: 8px 8px 0 0;
}
&:last-of-type {
border-radius: 0 0 8px 8px;
}
}
.section-toggle-visible:last-of-type {
border-bottom-left-radius: 0;
border-bottom-right-radius: 0;
}
.section-content {
padding: 1em 0;
background-color: $color-dark-72;
&:last-of-type {
border-radius: 0 0 8px 8px;
}
}
#display-name {
font-weight: bold;
font-size: 25px;
border-radius: 100px;
&:focus {
outline: none;
}
}
#status {
margin-top: 12px;
}
.standalone-mnemonic-inputs {
display: flex;
flex-direction: row;
align-items: center;
margin: 1em 8px;
margin-top: 0;
input {
flex: 1;
margin: 0;
margin-right: 12px;
}
}
input {
border: 1px solid $color-light-60;
border-radius: 4px;
&:focus {
outline: solid 1px $blue;
}
}
.button {
background: $color-loki-green-gradient;
border-radius: 100px;
}
#mnemonic-display {
margin: 2em 8px;
font-size: 16px;
font-style: italic;
}
.standalone-register-warning {
font-weight: bold;
font-size: 16px;
margin: 0px 8px;
}
.standalone-register-language {
display: flex;
align-items: center;
justify-content: center;
margin-top: 2em;
span {
margin-right: 8px;
}
}
.display-name-header {
margin-bottom: 8px;
font-size: 14px;
}
#generate-mnemonic, #copy-mnemonic {
background: $grey;
}
.select-container {
position: relative;
display: block;
width: 10em;
line-height: 2.8;
background: white;
overflow: hidden;
border-radius: .25em;
select {
// Reset select
-webkit-appearance: none;
-moz-appearance: none;
-ms-appearance: none;
appearance: none;
outline: 0;
box-shadow: none;
border: 0 !important;
background: white;
background-image: none;
// Our own stlying
width: 100%;
height: 100%;
margin: 0;
padding: 0 0 0 .5em;
color: black;
cursor: pointer;
::-ms-expand {
display: none;
}
}
&:after {
content: '\25BC';
position: absolute;
top: 0;
right: 0;
bottom: 0;
padding: 0 1em;
background: $color-dark-85;
pointer-events: none;
-webkit-transition: .25s all ease;
-o-transition: .25s all ease;
transition: .25s all ease;
}
}
@media (min-height: 750px) and (min-width: 700px) {
.display-name-header {
font-size: 18px;
}
.standalone-register-warning {
font-size: 20px;
}
#mnemonic-display {
font-size: 20px;
}
}
}
//yellow border fix
.inbox:focus {
outline: none;

@ -6,6 +6,7 @@
flex-direction: column;
align-items: flex-start;
margin-right: 8px;
overflow-x: hidden;
}
.module-contact-name span {
@ -13,6 +14,7 @@
overflow-x: hidden;
width: 100%;
text-align: left;
user-select: none;
}
.module-contact-name__profile-number {
@ -1979,9 +1981,9 @@
.module-conversation-list-item__message__status-icon {
flex-shrink: 0;
margin-top: 2px;
margin-top: 1px;
width: 12px;
height: 12px;
height: 13px;
display: inline-block;
margin-left: 6px;
}
@ -2198,7 +2200,7 @@
div {
padding: 12px;
background-color: $color-dark-90;
user-select: none;
cursor: pointer;
&:hover {

@ -30,6 +30,8 @@ $color-loki-light-gray: #e9e9e9;
$color-loki-dark-gray: #323232;
$color-loki-extra-dark-gray: #101010;
$color-loki-green: #3bd110;
$color-loki-green-dark: #32b10e;
$color-loki-green-gradient: linear-gradient(to right, rgb(120, 190, 32) 0%, rgb(0, 133, 34) 100%);
// New colors
@ -113,6 +115,7 @@ $color-dark-30: #a8a9aa;
$color-dark-55: #88898c;
$color-dark-60: #797a7c;
$color-dark-70: #414347;
$color-dark-72: #31343c;
$color-dark-75: #292c33;
$color-dark-85: #1a1c20;
$color-dark-90: #121417;

@ -107,7 +107,7 @@ export class ConversationHeader extends React.Component<Props> {
profileName={profileName}
i18n={i18n}
/>
{isKeysPending ? ' (pending)' : null}
{isKeysPending ? '(pending)' : null}
</div>
);
}

Loading…
Cancel
Save