From e1e87807b52ca7233eb0ec331aec6078c022c9aa Mon Sep 17 00:00:00 2001 From: David Baker Date: Wed, 25 Jan 2017 18:51:28 +0000 Subject: [PATCH 1/4] Look up email addresses in ChatInviteDialog So email addresses known to the IS get a display name & avatar --- .../views/dialogs/ChatInviteDialog.js | 73 +++++++++++++++---- src/components/views/elements/AddressTile.js | 22 ++++-- 2 files changed, 73 insertions(+), 22 deletions(-) diff --git a/src/components/views/dialogs/ChatInviteDialog.js b/src/components/views/dialogs/ChatInviteDialog.js index 61503196e5..4fadad5f84 100644 --- a/src/components/views/dialogs/ChatInviteDialog.js +++ b/src/components/views/dialogs/ChatInviteDialog.js @@ -14,17 +14,18 @@ See the License for the specific language governing permissions and limitations under the License. */ -var React = require("react"); -var classNames = require('classnames'); -var sdk = require("../../../index"); -var Invite = require("../../../Invite"); -var createRoom = require("../../../createRoom"); -var MatrixClientPeg = require("../../../MatrixClientPeg"); -var DMRoomMap = require('../../../utils/DMRoomMap'); -var rate_limited_func = require("../../../ratelimitedfunc"); -var dis = require("../../../dispatcher"); -var Modal = require('../../../Modal'); +import React from 'react'; +import classNames from 'classnames'; +import sdk from '../../../index'; +import { getAddressType } from '../../../Invite'; +import createRoom from '../../../createRoom'; +import MatrixClientPeg from '../../../MatrixClientPeg'; +import DMRoomMap from '../../../utils/DMRoomMap'; +import rate_limited_func from '../../../ratelimitedfunc'; +import dis from '../../../dispatcher'; +import Modal from '../../../Modal'; import AccessibleButton from '../elements/AccessibleButton'; +import q from 'q'; const TRUNCATE_QUERY_LIST = 40; @@ -186,13 +187,22 @@ module.exports = React.createClass({ // If the query isn't a user we know about, but is a // valid address, add an entry for that if (queryList.length == 0) { - const addrType = Invite.getAddressType(query); + const addrType = getAddressType(query); if (addrType !== null) { - queryList.push({ + queryList[0] = { addressType: addrType, address: query, isKnown: false, - }); + }; + if (addrType == 'email') { + this._lookupThreepid(addrType, query).then((res) => { + if (res !== null) { + this.setState({ + queryList: [res] + }); + } + }).done(); + } } } } @@ -380,7 +390,7 @@ module.exports = React.createClass({ }, _isDmChat: function(addrs) { - if (addrs.length === 1 && Invite.getAddressType(addrs[0]) === "mx" && !this.props.roomId) { + if (addrs.length === 1 && getAddressType(addrs[0]) === "mx" && !this.props.roomId) { return true; } else { return false; @@ -408,7 +418,7 @@ module.exports = React.createClass({ _addInputToList: function() { const addressText = this.refs.textinput.value.trim(); - const addrType = Invite.getAddressType(addressText); + const addrType = getAddressType(addressText); const addrObj = { addressType: addrType, address: addressText, @@ -435,6 +445,39 @@ module.exports = React.createClass({ return inviteList; }, + _lookupThreepid(medium, address) { + // wait a bit to let the user finish typing + return q.delay(500).then(() => { + // If the query has changed, forget it + if (this.state.queryList[0] && this.state.queryList[0].address !== address) { + return null; + } + return MatrixClientPeg.get().lookupThreePid(medium, address); + }).then((res) => { + if (res === null || !res.mxid) return null; + // If the query has changed now, drop the response + if (this.state.queryList[0] && this.state.queryList[0].address !== address) { + return null; + } + + return MatrixClientPeg.get().getProfileInfo(res.mxid); + }).then((res) => { + if (res === null) return null; + // If the query has changed now, drop the response + if (this.state.queryList[0] && this.state.queryList[0].address !== address) { + return null; + } + // return an InviteAddressType + return { + addressType: medium, + address: address, + displayName: res.displayname, + avatarMxc: res.avatar_url, + isKnown: true, + } + }); + }, + render: function() { const TintableSvg = sdk.getComponent("elements.TintableSvg"); const AddressSelector = sdk.getComponent("elements.AddressSelector"); diff --git a/src/components/views/elements/AddressTile.js b/src/components/views/elements/AddressTile.js index 01c1ed3255..18492d8ae6 100644 --- a/src/components/views/elements/AddressTile.js +++ b/src/components/views/elements/AddressTile.js @@ -94,14 +94,14 @@ export default React.createClass({ const BaseAvatar = sdk.getComponent('avatars.BaseAvatar'); const TintableSvg = sdk.getComponent("elements.TintableSvg"); + const nameClasses = classNames({ + "mx_AddressTile_name": true, + "mx_AddressTile_justified": this.props.justified, + }); + let info; let error = false; if (address.addressType === "mx" && address.isKnown) { - const nameClasses = classNames({ - "mx_AddressTile_name": true, - "mx_AddressTile_justified": this.props.justified, - }); - const idClasses = classNames({ "mx_AddressTile_id": true, "mx_AddressTile_justified": this.props.justified, @@ -123,13 +123,21 @@ export default React.createClass({
{ this.props.address.address }
); } else if (address.addressType === "email") { - var emailClasses = classNames({ + const emailClasses = classNames({ "mx_AddressTile_email": true, "mx_AddressTile_justified": this.props.justified, }); + let nameNode = null; + if (address.displayName) { + nameNode =
{ address.displayName }
+ } + info = ( -
{ address.address }
+
+
{ address.address }
+ {nameNode} +
); } else { error = true; From bf66f77acb79d5bad1a354f43e290930e2947731 Mon Sep 17 00:00:00 2001 From: David Baker Date: Thu, 26 Jan 2017 10:08:44 +0000 Subject: [PATCH 2/4] Set state in _lookupThreepid --- .../views/dialogs/ChatInviteDialog.js | 26 ++++++++----------- 1 file changed, 11 insertions(+), 15 deletions(-) diff --git a/src/components/views/dialogs/ChatInviteDialog.js b/src/components/views/dialogs/ChatInviteDialog.js index 4fadad5f84..09a18e5208 100644 --- a/src/components/views/dialogs/ChatInviteDialog.js +++ b/src/components/views/dialogs/ChatInviteDialog.js @@ -195,13 +195,7 @@ module.exports = React.createClass({ isKnown: false, }; if (addrType == 'email') { - this._lookupThreepid(addrType, query).then((res) => { - if (res !== null) { - this.setState({ - queryList: [res] - }); - } - }).done(); + this._lookupThreepid(addrType, query).done(); } } } @@ -467,14 +461,16 @@ module.exports = React.createClass({ if (this.state.queryList[0] && this.state.queryList[0].address !== address) { return null; } - // return an InviteAddressType - return { - addressType: medium, - address: address, - displayName: res.displayname, - avatarMxc: res.avatar_url, - isKnown: true, - } + this.setState({ + queryList: [{ + // an InviteAddressType + addressType: medium, + address: address, + displayName: res.displayname, + avatarMxc: res.avatar_url, + isKnown: true, + }] + }); }); }, From 23a25e550dcc08993f87ddc6f04fc4d33698dd78 Mon Sep 17 00:00:00 2001 From: David Baker Date: Thu, 26 Jan 2017 10:09:33 +0000 Subject: [PATCH 3/4] Missed a `function` --- src/components/views/dialogs/ChatInviteDialog.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/views/dialogs/ChatInviteDialog.js b/src/components/views/dialogs/ChatInviteDialog.js index 09a18e5208..e172ddd657 100644 --- a/src/components/views/dialogs/ChatInviteDialog.js +++ b/src/components/views/dialogs/ChatInviteDialog.js @@ -439,7 +439,7 @@ module.exports = React.createClass({ return inviteList; }, - _lookupThreepid(medium, address) { + _lookupThreepid: function(medium, address) { // wait a bit to let the user finish typing return q.delay(500).then(() => { // If the query has changed, forget it From c42b705497d6ee0ea29da0540b4dcf917c210fea Mon Sep 17 00:00:00 2001 From: David Baker Date: Thu, 26 Jan 2017 10:54:07 +0000 Subject: [PATCH 4/4] Use a cancel function rather than checking queryList each time --- .../views/dialogs/ChatInviteDialog.js | 28 +++++++++++-------- 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/src/components/views/dialogs/ChatInviteDialog.js b/src/components/views/dialogs/ChatInviteDialog.js index e172ddd657..fa7b30aa17 100644 --- a/src/components/views/dialogs/ChatInviteDialog.js +++ b/src/components/views/dialogs/ChatInviteDialog.js @@ -194,6 +194,7 @@ module.exports = React.createClass({ address: query, isKnown: false, }; + if (this._cancelThreepidLookup) this._cancelThreepidLookup(); if (addrType == 'email') { this._lookupThreepid(addrType, query).done(); } @@ -216,6 +217,7 @@ module.exports = React.createClass({ inviteList: inviteList, queryList: [], }); + if (this._cancelThreepidLookup) this._cancelThreepidLookup(); }; }, @@ -233,6 +235,7 @@ module.exports = React.createClass({ inviteList: inviteList, queryList: [], }); + if (this._cancelThreepidLookup) this._cancelThreepidLookup(); }, _getDirectMessageRoom: function(addr) { @@ -436,31 +439,32 @@ module.exports = React.createClass({ inviteList: inviteList, queryList: [], }); + if (this._cancelThreepidLookup) this._cancelThreepidLookup(); return inviteList; }, _lookupThreepid: function(medium, address) { + let cancelled = false; + // Note that we can't safely remove this after we're done + // because we don't know that it's the same one, so we just + // leave it: it's replacing the old one each time so it's + // not like they leak. + this._cancelThreepidLookup = function() { + cancelled = true; + } + // wait a bit to let the user finish typing return q.delay(500).then(() => { - // If the query has changed, forget it - if (this.state.queryList[0] && this.state.queryList[0].address !== address) { - return null; - } + if (cancelled) return null; return MatrixClientPeg.get().lookupThreePid(medium, address); }).then((res) => { if (res === null || !res.mxid) return null; - // If the query has changed now, drop the response - if (this.state.queryList[0] && this.state.queryList[0].address !== address) { - return null; - } + if (cancelled) return null; return MatrixClientPeg.get().getProfileInfo(res.mxid); }).then((res) => { if (res === null) return null; - // If the query has changed now, drop the response - if (this.state.queryList[0] && this.state.queryList[0].address !== address) { - return null; - } + if (cancelled) return null; this.setState({ queryList: [{ // an InviteAddressType