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

This commit is contained in:
sachaaaaa 2019-08-30 11:29:53 +10:00
parent 1d4c98adf0
commit 3a78f47cd7
3 changed files with 70 additions and 15 deletions

View File

@ -658,8 +658,9 @@
<div class='standalone-secondary-device-inputs'>
<input class='form-control' type='text' id='primary-pubkey' placeholder='Primary Account Public Key' autocomplete='off' spellcheck='false' />
</div>
<div id='pubkey' 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>

View File

@ -13,6 +13,8 @@
className: 'full-screen-flow standalone-fullscreen',
initialize() {
this.accountManager = getAccountManager();
// Clean status in case the app closed unexpectedly
textsecure.storage.remove('secondaryDeviceStatus');
this.render();
@ -50,12 +52,14 @@
this.registrationParams = {};
this.$pages = this.$('.page');
this.pairingTimeout = null;
this.pairingInterval = null;
this.showRegisterPage();
this.onValidatePassword();
this.onSecondaryDeviceRegistered = this.onSecondaryDeviceRegistered.bind(this);
this.onSecondaryDeviceRegistered = this.onSecondaryDeviceRegistered.bind(
this
);
},
events: {
'validation input.number': 'onValidation',
@ -108,6 +112,9 @@
const input = this.trim(this.$passwordInput.val());
// Ensure we clear the secondary device registration status
textsecure.storage.remove('secondaryDeviceStatus');
try {
await window.setPassword(input);
await this.accountManager.registerSingleDevice(
@ -129,11 +136,19 @@
this.showProfilePage(mnemonic, language);
},
onSecondaryDeviceRegistered() {
clearInterval(this.pairingInterval);
// Ensure the left menu is updated
Whisper.events.trigger('userChanged', { isSecondaryDevice: true });
this.$el.trigger('openInbox');
},
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 language = this.$('#mnemonic-display-language').val();
const primaryPubKey = this.$('#primary-pubkey').val();
@ -147,26 +162,57 @@
'secondaryDeviceRegistration',
this.onSecondaryDeviceRegistered
);
clearTimeout(this.pairingTimeout);
this.pairingTimeout = setTimeout(() => {
this.$('.standalone-secondary-device #error').text(
'The primary device has not responded within 1 minute. Ensure it is connected.'
clearInterval(this.pairingInterval);
let countDown = 60;
const onError = async error => {
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 {
await this.accountManager.registerSingleDevice(
mnemonic,
language,
'John Smith'
null
);
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) {
textsecure.storage.remove('secondaryDeviceStatus');
this.$('.standalone-secondary-device #error').text(e);
this.$('.standalone-secondary-device #error').show();
clearTimeout(this.pairingTimeout);
onError(e);
}
},
registerWithMnemonic() {

View File

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