Secondary device registration: UX changes (show countdown, disable button, etc.)

pull/456/head
sachaaaaa 6 years ago
parent 1d4c98adf0
commit 3a78f47cd7

@ -658,8 +658,9 @@
<div class='standalone-secondary-device-inputs'> <div class='standalone-secondary-device-inputs'>
<input class='form-control' type='text' id='primary-pubkey' placeholder='Primary Account Public Key' autocomplete='off' spellcheck='false' /> <input class='form-control' type='text' id='primary-pubkey' placeholder='Primary Account Public Key' autocomplete='off' spellcheck='false' />
</div> </div>
<div id='pubkey' class='collapse'></div>
<div id='error' class='collapse'></div> <div id='error' class='collapse'></div>
<a class='button' id='register-secondary-device'>Link</a> <button type='button' class='button' id='register-secondary-device'>Link</button>
</div> </div>
</div> </div>

@ -13,6 +13,8 @@
className: 'full-screen-flow standalone-fullscreen', className: 'full-screen-flow standalone-fullscreen',
initialize() { initialize() {
this.accountManager = getAccountManager(); this.accountManager = getAccountManager();
// Clean status in case the app closed unexpectedly
textsecure.storage.remove('secondaryDeviceStatus');
this.render(); this.render();
@ -50,12 +52,14 @@
this.registrationParams = {}; this.registrationParams = {};
this.$pages = this.$('.page'); this.$pages = this.$('.page');
this.pairingTimeout = null; this.pairingInterval = null;
this.showRegisterPage(); this.showRegisterPage();
this.onValidatePassword(); this.onValidatePassword();
this.onSecondaryDeviceRegistered = this.onSecondaryDeviceRegistered.bind(this); this.onSecondaryDeviceRegistered = this.onSecondaryDeviceRegistered.bind(
this
);
}, },
events: { events: {
'validation input.number': 'onValidation', 'validation input.number': 'onValidation',
@ -108,6 +112,9 @@
const input = this.trim(this.$passwordInput.val()); const input = this.trim(this.$passwordInput.val());
// Ensure we clear the secondary device registration status
textsecure.storage.remove('secondaryDeviceStatus');
try { try {
await window.setPassword(input); await window.setPassword(input);
await this.accountManager.registerSingleDevice( await this.accountManager.registerSingleDevice(
@ -129,11 +136,19 @@
this.showProfilePage(mnemonic, language); this.showProfilePage(mnemonic, language);
}, },
onSecondaryDeviceRegistered() { onSecondaryDeviceRegistered() {
clearInterval(this.pairingInterval);
// Ensure the left menu is updated // Ensure the left menu is updated
Whisper.events.trigger('userChanged', { isSecondaryDevice: true }); Whisper.events.trigger('userChanged', { isSecondaryDevice: true });
this.$el.trigger('openInbox'); this.$el.trigger('openInbox');
}, },
async registerSecondaryDevice() { async registerSecondaryDevice() {
if (textsecure.storage.get('secondaryDeviceStatus') === 'ongoing') {
return;
}
textsecure.storage.put('secondaryDeviceStatus', 'ongoing');
this.$('#register-secondary-device')
.attr('disabled', 'disabled')
.text('Sending...');
const mnemonic = this.$('#mnemonic-display').text(); const mnemonic = this.$('#mnemonic-display').text();
const language = this.$('#mnemonic-display-language').val(); const language = this.$('#mnemonic-display-language').val();
const primaryPubKey = this.$('#primary-pubkey').val(); const primaryPubKey = this.$('#primary-pubkey').val();
@ -147,26 +162,57 @@
'secondaryDeviceRegistration', 'secondaryDeviceRegistration',
this.onSecondaryDeviceRegistered this.onSecondaryDeviceRegistered
); );
clearTimeout(this.pairingTimeout); clearInterval(this.pairingInterval);
this.pairingTimeout = setTimeout(() => { let countDown = 60;
this.$('.standalone-secondary-device #error').text( const onError = async error => {
'The primary device has not responded within 1 minute. Ensure it is connected.' clearInterval(this.pairingInterval);
this.$('.standalone-secondary-device #error')
.text(error)
.show();
const sleep = ms => new Promise(resolve => setTimeout(resolve, ms));
// If the registration started, ensure it's finished
while (
textsecure.storage.protocol.getIdentityKeyPair() &&
!Whisper.Registration.isDone()
) {
// eslint-disable-next-line no-await-in-loop
await sleep(100);
}
Whisper.Registration.remove();
Whisper.RotateSignedPreKeyListener.stop();
textsecure.storage.remove('secondaryDeviceStatus');
window.ConversationController.reset();
this.$('#register-secondary-device')
.removeAttr('disabled')
.text('Link');
};
const countDownCallBack = () => {
if (countDown > 0) {
this.$('#register-secondary-device').text(
`Waiting for Primary Device... (${countDown})`
);
countDown -= 1;
return;
}
onError(
'The primary device has not responded within 1 minute. Ensure that you accept the pairing on the primary device.'
); );
this.$('.standalone-secondary-device #error').show(); };
}, 60000);
textsecure.storage.put('secondaryDeviceStatus', 'ongoing');
try { try {
await this.accountManager.registerSingleDevice( await this.accountManager.registerSingleDevice(
mnemonic, mnemonic,
language, language,
'John Smith' null
); );
await this.accountManager.requestPairing(primaryPubKey); await this.accountManager.requestPairing(primaryPubKey);
countDownCallBack();
this.pairingInterval = setInterval(countDownCallBack, 1000);
const pubkey = textsecure.storage.user.getNumber();
this.$('.standalone-secondary-device #pubkey').text(
`Here is your pubkey:\n${pubkey}`
);
} catch (e) { } catch (e) {
textsecure.storage.remove('secondaryDeviceStatus'); onError(e);
this.$('.standalone-secondary-device #error').text(e);
this.$('.standalone-secondary-device #error').show();
clearTimeout(this.pairingTimeout);
} }
}, },
registerWithMnemonic() { registerWithMnemonic() {

@ -714,6 +714,14 @@ $loading-height: 16px;
.button { .button {
background: $color-loki-green-gradient; background: $color-loki-green-gradient;
border-radius: 100px; border-radius: 100px;
&[disabled='disabled'] {
&,
&:hover {
background: $color-loki-dark-gray;
cursor: default;
}
}
} }
#mnemonic-display { #mnemonic-display {

Loading…
Cancel
Save