diff --git a/src/boundThreepids.js b/src/boundThreepids.js
new file mode 100644
index 0000000000..799728f801
--- /dev/null
+++ b/src/boundThreepids.js
@@ -0,0 +1,52 @@
+/*
+Copyright 2019 The Matrix.org Foundation C.I.C.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+import IdentityAuthClient from './IdentityAuthClient';
+
+export async function getThreepidBindStatus(client, filterMedium) {
+ const userId = client.getUserId();
+
+ let { threepids } = await client.getThreePids();
+ if (filterMedium) {
+ threepids = threepids.filter((a) => a.medium === filterMedium);
+ }
+
+ if (threepids.length > 0) {
+ // TODO: Handle terms agreement
+ // See https://github.com/vector-im/riot-web/issues/10522
+ const authClient = new IdentityAuthClient();
+ const identityAccessToken = await authClient.getAccessToken();
+
+ // Restructure for lookup query
+ const query = threepids.map(({ medium, address }) => [medium, address]);
+ const lookupResults = await client.bulkLookupThreePids(query, identityAccessToken);
+
+ // Record which are already bound
+ for (const [medium, address, mxid] of lookupResults.threepids) {
+ if (mxid !== userId) {
+ continue;
+ }
+ if (filterMedium && medium !== filterMedium) {
+ continue;
+ }
+ const threepid = threepids.find(e => e.medium === medium && e.address === address);
+ if (!threepid) continue;
+ threepid.bound = true;
+ }
+ }
+
+ return threepids;
+}
diff --git a/src/components/views/settings/SetIdServer.js b/src/components/views/settings/SetIdServer.js
index beea3f878f..096222f124 100644
--- a/src/components/views/settings/SetIdServer.js
+++ b/src/components/views/settings/SetIdServer.js
@@ -22,6 +22,7 @@ import MatrixClientPeg from "../../../MatrixClientPeg";
import SdkConfig from "../../../SdkConfig";
import Modal from '../../../Modal';
import dis from "../../../dispatcher";
+import { getThreepidBindStatus } from '../../../boundThreepids';
import IdentityAuthClient from "../../../IdentityAuthClient";
import {SERVICE_TYPES} from "matrix-js-sdk";
@@ -100,6 +101,7 @@ export default class SetIdServer extends React.Component {
idServer: defaultIdServer,
error: null,
busy: false,
+ disconnectBusy: false,
checking: false,
};
}
@@ -193,24 +195,45 @@ export default class SetIdServer extends React.Component {
});
};
- _onDisconnectClicked = () => {
- const QuestionDialog = sdk.getComponent("dialogs.QuestionDialog");
- Modal.createTrackedDialog('Identity Server Disconnect Warning', '', QuestionDialog, {
- title: _t("Disconnect Identity Server"),
- description:
-
- {_t(
- "Disconnect from the identity server ?", {},
- {idserver: sub => {abbreviateUrl(this.state.currentClientIdServer)}},
- )},
-
,
- button: _t("Disconnect"),
- onFinished: (confirmed) => {
- if (confirmed) {
- this._disconnectIdServer();
- }
- },
- });
+ _onDisconnectClicked = async () => {
+ this.setState({disconnectBusy: true});
+ try {
+ const threepids = await getThreepidBindStatus(MatrixClientPeg.get());
+
+ const boundThreepids = threepids.filter(tp => tp.bound);
+ let message;
+ if (boundThreepids.length) {
+ message = _t(
+ "You are currently sharing email addresses or phone numbers on the identity " +
+ "server . You will need to reconnect to to stop " +
+ "sharing them.", {},
+ {
+ idserver: sub => {abbreviateUrl(this.state.currentClientIdServer)},
+ // XXX: https://github.com/vector-im/riot-web/issues/9086
+ idserver2: sub => {abbreviateUrl(this.state.currentClientIdServer)},
+ },
+ );
+ } else {
+ message = _t(
+ "Disconnect from the identity server ?", {},
+ {idserver: sub => {abbreviateUrl(this.state.currentClientIdServer)}},
+ );
+ }
+
+ const QuestionDialog = sdk.getComponent("dialogs.QuestionDialog");
+ Modal.createTrackedDialog('Identity Server Disconnect Warning', '', QuestionDialog, {
+ title: _t("Disconnect Identity Server"),
+ description: message,
+ button: _t("Disconnect"),
+ onFinished: (confirmed) => {
+ if (confirmed) {
+ this._disconnectIdServer();
+ }
+ },
+ });
+ } finally {
+ this.setState({disconnectBusy: false});
+ }
};
_disconnectIdServer = () => {
@@ -258,6 +281,11 @@ export default class SetIdServer extends React.Component {
let discoSection;
if (idServerUrl) {
+ let discoButtonContent = _t("Disconnect");
+ if (this.state.disconnectBusy) {
+ const InlineSpinner = sdk.getComponent('views.elements.InlineSpinner');
+ discoButtonContent = ;
+ }
discoSection =
{_t(
"Disconnecting from your identity server will mean you " +
@@ -265,7 +293,7 @@ export default class SetIdServer extends React.Component {
"able to invite others by email or phone.",
)}
- {_t("Disconnect")}
+ {discoButtonContent}
;
}
diff --git a/src/components/views/settings/discovery/EmailAddresses.js b/src/components/views/settings/discovery/EmailAddresses.js
index 7862eda61e..4d18c1d355 100644
--- a/src/components/views/settings/discovery/EmailAddresses.js
+++ b/src/components/views/settings/discovery/EmailAddresses.js
@@ -22,8 +22,8 @@ import { _t } from "../../../../languageHandler";
import MatrixClientPeg from "../../../../MatrixClientPeg";
import sdk from '../../../../index';
import Modal from '../../../../Modal';
-import IdentityAuthClient from '../../../../IdentityAuthClient';
import AddThreepid from '../../../../AddThreepid';
+import { getThreepidBindStatus } from '../../../../boundThreepids';
/*
TODO: Improve the UX for everything in here.
@@ -198,31 +198,8 @@ export default class EmailAddresses extends React.Component {
async componentWillMount() {
const client = MatrixClientPeg.get();
- const userId = client.getUserId();
- const { threepids } = await client.getThreePids();
- const emails = threepids.filter((a) => a.medium === 'email');
-
- if (emails.length > 0) {
- // TODO: Handle terms agreement
- // See https://github.com/vector-im/riot-web/issues/10522
- const authClient = new IdentityAuthClient();
- const identityAccessToken = await authClient.getAccessToken();
-
- // Restructure for lookup query
- const query = emails.map(({ medium, address }) => [medium, address]);
- const lookupResults = await client.bulkLookupThreePids(query, identityAccessToken);
-
- // Record which are already bound
- for (const [medium, address, mxid] of lookupResults.threepids) {
- if (medium !== "email" || mxid !== userId) {
- continue;
- }
- const email = emails.find(e => e.address === address);
- if (!email) continue;
- email.bound = true;
- }
- }
+ const emails = await getThreepidBindStatus(client, 'email');
this.setState({ emails });
}
diff --git a/src/components/views/settings/discovery/PhoneNumbers.js b/src/components/views/settings/discovery/PhoneNumbers.js
index 3930277aea..fdebac5d22 100644
--- a/src/components/views/settings/discovery/PhoneNumbers.js
+++ b/src/components/views/settings/discovery/PhoneNumbers.js
@@ -22,8 +22,8 @@ import { _t } from "../../../../languageHandler";
import MatrixClientPeg from "../../../../MatrixClientPeg";
import sdk from '../../../../index';
import Modal from '../../../../Modal';
-import IdentityAuthClient from '../../../../IdentityAuthClient';
import AddThreepid from '../../../../AddThreepid';
+import { getThreepidBindStatus } from '../../../../boundThreepids';
/*
TODO: Improve the UX for everything in here.
@@ -217,31 +217,8 @@ export default class PhoneNumbers extends React.Component {
async componentWillMount() {
const client = MatrixClientPeg.get();
- const userId = client.getUserId();
- const { threepids } = await client.getThreePids();
- const msisdns = threepids.filter((a) => a.medium === 'msisdn');
-
- if (msisdns.length > 0) {
- // TODO: Handle terms agreement
- // See https://github.com/vector-im/riot-web/issues/10522
- const authClient = new IdentityAuthClient();
- const identityAccessToken = await authClient.getAccessToken();
-
- // Restructure for lookup query
- const query = msisdns.map(({ medium, address }) => [medium, address]);
- const lookupResults = await client.bulkLookupThreePids(query, identityAccessToken);
-
- // Record which are already bound
- for (const [medium, address, mxid] of lookupResults.threepids) {
- if (medium !== "msisdn" || mxid !== userId) {
- continue;
- }
- const msisdn = msisdns.find(e => e.address === address);
- if (!msisdn) continue;
- msisdn.bound = true;
- }
- }
+ const msisdns = await getThreepidBindStatus(client, 'msisdn');
this.setState({ msisdns });
}
diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json
index 09337fc7fc..8e49de48d3 100644
--- a/src/i18n/strings/en_EN.json
+++ b/src/i18n/strings/en_EN.json
@@ -548,12 +548,13 @@
"Not a valid Identity Server (status code %(code)s)": "Not a valid Identity Server (status code %(code)s)",
"Could not connect to Identity Server": "Could not connect to Identity Server",
"Checking server": "Checking server",
+ "You are currently sharing email addresses or phone numbers on the identity server . You will need to reconnect to to stop sharing them.": "You are currently sharing email addresses or phone numbers on the identity server . You will need to reconnect to to stop sharing them.",
+ "Disconnect from the identity server ?": "Disconnect from the identity server ?",
"Identity server has no terms of service": "Identity server has no terms of service",
"The identity server you have chosen does not have any terms of service.": "The identity server you have chosen does not have any terms of service.",
"Only continue if you trust the owner of the server.": "Only continue if you trust the owner of the server.",
"Terms of service not accepted or the identity server is invalid.": "Terms of service not accepted or the identity server is invalid.",
"Disconnect Identity Server": "Disconnect Identity Server",
- "Disconnect from the identity server ?": "Disconnect from the identity server ?",
"Disconnect": "Disconnect",
"Identity Server (%(server)s)": "Identity Server (%(server)s)",
"You are currently using to discover and be discoverable by existing contacts you know. You can change your identity server below.": "You are currently using to discover and be discoverable by existing contacts you know. You can change your identity server below.",