Merge pull request #509 from sachaaaaa/show_paired_devices

[multi-device] Display list of paired device in modal
pull/519/head
sachaaaaa 6 years ago committed by GitHub
commit ea17437a0c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -926,6 +926,30 @@
"cancel": { "cancel": {
"message": "Cancel" "message": "Cancel"
}, },
"skip": {
"message": "Skip"
},
"close": {
"message": "Close"
},
"pairNewDevice": {
"message": "Pair new Device"
},
"devicePairingAccepted": {
"message": "Device Pairing Accepted"
},
"devicePairingReceived": {
"message": "Device Pairing Received"
},
"waitingForDeviceToRegister": {
"message": "Waiting for device to register..."
},
"pairedDevices": {
"message": "Paired Devices"
},
"allowPairing": {
"message": "Allow Pairing"
},
"clear": { "clear": {
"message": "Clear" "message": "Clear"
}, },

@ -247,8 +247,21 @@
</script> </script>
<script type='text/x-tmpl-mustache' id='device-pairing-dialog'> <script type='text/x-tmpl-mustache' id='device-pairing-dialog'>
<div class="content"> <div class="content">
<!-- Default view -->
<div class="defaultView">
<h4>{{ defaultTitle }}</h4>
<ul id="pairedPubKeys">
<li>No paired devices</li>
</ul>
<div class='buttons'>
<button id='close' tabindex='2'>{{ closeText }}</button>
<button id="startPairing" tabindex='1'>{{ startPairingText }}</button>
</div>
</div>
<!-- Waiting for request --> <!-- Waiting for request -->
<div class="waitingForRequestView"> <div class="waitingForRequestView" style="display: none;">
<h4>{{ waitingForRequestTitle }}</h4> <h4>{{ waitingForRequestTitle }}</h4>
<div class='buttons'> <div class='buttons'>
<button class="cancel">{{ cancelText }}</button> <button class="cancel">{{ cancelText }}</button>
@ -269,7 +282,6 @@
<!-- Request accepted --> <!-- Request accepted -->
<div class="requestAcceptedView" style="display: none;"> <div class="requestAcceptedView" style="display: none;">
<h4>{{ requestAcceptedTitle }}</h4> <h4>{{ requestAcceptedTitle }}</h4>
Sending pairing authorisation to:
<p class="secretWords"></p> <p class="secretWords"></p>
<p class="transmissionStatus">Please be patient...</p> <p class="transmissionStatus">Please be patient...</p>
<div class='buttons'> <div class='buttons'>
@ -660,7 +672,7 @@
</br> </br>
Open the Loki Messenger App on your Primary Device Open the Loki Messenger App on your Primary Device
</br> </br>
and select "Pair New Device" in the main menu. and select "Device Pairing" in the main menu.
</p> </p>
<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' />

@ -202,12 +202,17 @@
}, },
showDevicePairingDialog() { showDevicePairingDialog() {
const dialog = new Whisper.DevicePairingDialogView(); const dialog = new Whisper.DevicePairingDialogView();
// remove all listeners for this events is fine since the
// only listener is right below. dialog.on('startReceivingRequests', () => {
Whisper.events.off('devicePairingRequestReceived'); Whisper.events.on('devicePairingRequestReceived', pubKey =>
Whisper.events.on('devicePairingRequestReceived', pubKey => dialog.requestReceived(pubKey)
dialog.requestReceived(pubKey) );
); });
dialog.on('stopReceivingRequests', () => {
Whisper.events.off('devicePairingRequestReceived');
});
dialog.once('devicePairingRequestAccepted', (pubKey, cb) => dialog.once('devicePairingRequestAccepted', (pubKey, cb) =>
Whisper.events.trigger('devicePairingRequestAccepted', pubKey, cb) Whisper.events.trigger('devicePairingRequestAccepted', pubKey, cb)
); );

@ -1,4 +1,4 @@
/* global Whisper, i18n */ /* global Whisper, i18n, libloki, textsecure */
// eslint-disable-next-line func-names // eslint-disable-next-line func-names
(function() { (function() {
@ -13,27 +13,43 @@
this.pubKeyRequests = []; this.pubKeyRequests = [];
this.pubKey = null; this.pubKey = null;
this.accepted = false; this.accepted = false;
this.isListening = false;
this.view = ''; this.view = '';
this.render(); this.render();
this.showView(); this.showView();
}, },
events: { events: {
'click .waitingForRequestView .cancel': 'close', 'click #startPairing': 'startReceivingRequests',
'click #close': 'close',
'click .waitingForRequestView .cancel': 'stopReceivingRequests',
'click .requestReceivedView .skip': 'skipDevice', 'click .requestReceivedView .skip': 'skipDevice',
'click #allowPairing': 'allowDevice', 'click #allowPairing': 'allowDevice',
'click .requestAcceptedView .ok': 'close', 'click .requestAcceptedView .ok': 'stopReceivingRequests',
}, },
render_attributes() { render_attributes() {
return { return {
waitingForRequestTitle: 'Waiting for device to register...', defaultTitle: i18n('pairedDevices'),
requestReceivedTitle: 'Device Pairing Received', waitingForRequestTitle: i18n('waitingForDeviceToRegister'),
requestAcceptedTitle: 'Device Pairing Accepted', requestReceivedTitle: i18n('devicePairingReceived'),
requestAcceptedTitle: i18n('devicePairingAccepted'),
startPairingText: i18n('pairNewDevice'),
cancelText: i18n('cancel'), cancelText: i18n('cancel'),
skipText: 'Skip', closeText: i18n('close'),
skipText: i18n('skip'),
okText: i18n('ok'), okText: i18n('ok'),
allowPairingText: 'Allow Pairing', allowPairingText: i18n('allowPairing'),
}; };
}, },
startReceivingRequests() {
this.trigger('startReceivingRequests');
this.isListening = true;
this.showView();
},
stopReceivingRequests() {
this.trigger('stopReceivingRequests');
this.isListening = false;
this.showView();
},
requestReceived(secondaryDevicePubKey) { requestReceived(secondaryDevicePubKey) {
// FIFO: push at the front of the array with unshift() // FIFO: push at the front of the array with unshift()
this.pubKeyRequests.unshift(secondaryDevicePubKey); this.pubKeyRequests.unshift(secondaryDevicePubKey);
@ -51,7 +67,7 @@
}, },
transmisssionCB(errors) { transmisssionCB(errors) {
if (!errors) { if (!errors) {
this.$('.transmissionStatus').text('Sent successfully'); this.$('.transmissionStatus').text(i18n('sent'));
} else { } else {
this.$('.transmissionStatus').text(errors); this.$('.transmissionStatus').text(errors);
} }
@ -66,11 +82,26 @@
// FIFO: pop at the back of the array using pop() // FIFO: pop at the back of the array using pop()
this.pubKey = this.pubKeyRequests.pop(); this.pubKey = this.pubKeyRequests.pop();
}, },
showView() { async showView() {
const defaultView = this.$('.defaultView');
const waitingForRequestView = this.$('.waitingForRequestView'); const waitingForRequestView = this.$('.waitingForRequestView');
const requestReceivedView = this.$('.requestReceivedView'); const requestReceivedView = this.$('.requestReceivedView');
const requestAcceptedView = this.$('.requestAcceptedView'); const requestAcceptedView = this.$('.requestAcceptedView');
if (this.accepted) { if (!this.isListening) {
const ourPubKey = textsecure.storage.user.getNumber();
defaultView.show();
requestReceivedView.hide();
waitingForRequestView.hide();
requestAcceptedView.hide();
const pubKeys = await libloki.storage.getSecondaryDevicesFor(ourPubKey);
if (pubKeys && pubKeys.length > 0) {
this.$('#pairedPubKeys').empty();
pubKeys.forEach(x => {
this.$('#pairedPubKeys').append(`<li>${x}</li>`);
});
}
} else if (this.accepted) {
defaultView.hide();
requestReceivedView.hide(); requestReceivedView.hide();
waitingForRequestView.hide(); waitingForRequestView.hide();
requestAcceptedView.show(); requestAcceptedView.show();
@ -84,10 +115,12 @@
requestReceivedView.show(); requestReceivedView.show();
waitingForRequestView.hide(); waitingForRequestView.hide();
requestAcceptedView.hide(); requestAcceptedView.hide();
defaultView.hide();
} else { } else {
waitingForRequestView.show(); waitingForRequestView.show();
requestReceivedView.hide(); requestReceivedView.hide();
requestAcceptedView.hide(); requestAcceptedView.hide();
defaultView.hide();
} }
}, },
close() { close() {

@ -125,10 +125,13 @@
return window.Signal.Data.getAuthorisationForPubKey(secondaryPubKey); return window.Signal.Data.getAuthorisationForPubKey(secondaryPubKey);
} }
function getSecondaryDevicesFor(primaryDevicePubKey) {
return window.Signal.Data.getSecondaryDevicesFor(primaryDevicePubKey);
}
async function getAllDevicePubKeysForPrimaryPubKey(primaryDevicePubKey) { async function getAllDevicePubKeysForPrimaryPubKey(primaryDevicePubKey) {
const secondaryPubKeys = const secondaryPubKeys =
(await window.Signal.Data.getSecondaryDevicesFor(primaryDevicePubKey)) || (await getSecondaryDevicesFor(primaryDevicePubKey)) || [];
[];
return secondaryPubKeys.concat(primaryDevicePubKey); return secondaryPubKeys.concat(primaryDevicePubKey);
} }
@ -141,6 +144,7 @@
getGrantAuthorisationForSecondaryPubKey, getGrantAuthorisationForSecondaryPubKey,
getAuthorisationForSecondaryPubKey, getAuthorisationForSecondaryPubKey,
getAllDevicePubKeysForPrimaryPubKey, getAllDevicePubKeysForPrimaryPubKey,
getSecondaryDevicesFor,
}; };
// Libloki protocol store // Libloki protocol store

@ -369,7 +369,7 @@ export class MainHeader extends React.Component<Props, any> {
if (!isSecondaryDevice) { if (!isSecondaryDevice) {
menuItems.push({ menuItems.push({
id: 'pairNewDevice', id: 'pairNewDevice',
name: 'Pair new Device', name: 'Device Pairing',
onClick: () => { onClick: () => {
trigger('showDevicePairingDialog'); trigger('showDevicePairingDialog');
}, },

Loading…
Cancel
Save