From 00cc2535941d5e009a25f40a53a9f704e8601e51 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Thu, 20 Feb 2020 10:50:35 -0700 Subject: [PATCH 1/5] Always suggest a pill for MXID-looking users Part of https://github.com/vector-im/riot-web/issues/12440 --- src/components/views/dialogs/InviteDialog.js | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/components/views/dialogs/InviteDialog.js b/src/components/views/dialogs/InviteDialog.js index 8c9c5f75ef..ce653d38ae 100644 --- a/src/components/views/dialogs/InviteDialog.js +++ b/src/components/views/dialogs/InviteDialog.js @@ -645,6 +645,13 @@ export default class InviteDialog extends React.PureComponent { } catch (e) { console.warn("Non-fatal error trying to make an invite for a user ID"); console.warn(e); + + // Add a result anyways, just without a profile + r.results.push({ + user_id: term, + display_name: term, + avatar_url: null, + }); } } From 62aaa0db9a115a434728ed719476fa0dbe95b52a Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Thu, 20 Feb 2020 23:01:50 -0700 Subject: [PATCH 2/5] Always insert suggestions for user IDs Fixes https://github.com/vector-im/riot-web/issues/12419 --- src/components/views/dialogs/InviteDialog.js | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/components/views/dialogs/InviteDialog.js b/src/components/views/dialogs/InviteDialog.js index ce653d38ae..3920cfd249 100644 --- a/src/components/views/dialogs/InviteDialog.js +++ b/src/components/views/dialogs/InviteDialog.js @@ -630,13 +630,14 @@ export default class InviteDialog extends React.PureComponent { // While we're here, try and autocomplete a search result for the mxid itself // if there's no matches (and the input looks like a mxid). - if (term[0] === '@' && term.indexOf(':') > 1 && r.results.length === 0) { + if (term[0] === '@' && term.indexOf(':') > 1) { try { const profile = await MatrixClientPeg.get().getProfileInfo(term); if (profile) { // If we have a profile, we have enough information to assume that - // the mxid can be invited - add it to the list - r.results.push({ + // the mxid can be invited - add it to the list. We stick it at the + // top so it is most obviously presented to the user. + r.results.splice(0, 0, { user_id: term, display_name: profile['displayname'], avatar_url: profile['avatar_url'], @@ -646,8 +647,9 @@ export default class InviteDialog extends React.PureComponent { console.warn("Non-fatal error trying to make an invite for a user ID"); console.warn(e); - // Add a result anyways, just without a profile - r.results.push({ + // Add a result anyways, just without a profile. We stick it at the + // top so it is most obviously presented to the user. + r.results.splice(0, 0,{ user_id: term, display_name: term, avatar_url: null, From f491e4222a5aa9f7eb1a87c9cc7634bd5ef7e267 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Thu, 20 Feb 2020 23:10:43 -0700 Subject: [PATCH 3/5] Convert the user's last filter into a selection if possible Fixes https://github.com/vector-im/riot-web/issues/12440 --- src/components/views/dialogs/InviteDialog.js | 26 +++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-) diff --git a/src/components/views/dialogs/InviteDialog.js b/src/components/views/dialogs/InviteDialog.js index 3920cfd249..fa12f5393a 100644 --- a/src/components/views/dialogs/InviteDialog.js +++ b/src/components/views/dialogs/InviteDialog.js @@ -512,9 +512,26 @@ export default class InviteDialog extends React.PureComponent { return false; } + _convertFilter(): Member[] { + if (!this.state.filterText || !this.state.filterText.includes('@')) return; // nothing to convert + + let newMember: Member; + if (this.state.filterText.startsWith('@')) { + // Assume mxid + newMember = new DirectoryMember({user_id: this.state.filterText, display_name: null, avatar_url: null}); + } else { + // Assume email + newMember = new ThreepidMember(this.state.filterText); + } + const newTargets = [...this.state.targets, newMember]; + this.setState({targets: newTargets, filterText: ''}); + return newTargets; + } + _startDm = async () => { this.setState({busy: true}); - const targetIds = this.state.targets.map(t => t.userId); + const targets = this._convertFilter(); + const targetIds = targets.map(t => t.userId); // Check if there is already a DM with these people and reuse it if possible. const existingRoom = DMRoomMap.shared().getDMRoomForIdentifiers(targetIds); @@ -573,7 +590,9 @@ export default class InviteDialog extends React.PureComponent { _inviteUsers = () => { this.setState({busy: true}); - const targetIds = this.state.targets.map(t => t.userId); + this._convertFilter(); + const targets = this._convertFilter(); + const targetIds = targets.map(t => t.userId); const room = MatrixClientPeg.get().getRoom(this.props.roomId); if (!room) { @@ -1038,6 +1057,7 @@ export default class InviteDialog extends React.PureComponent { goButtonFn = this._inviteUsers; } + const hasSelection = this.state.targets.length > 0 || (this.state.filterText && this.state.filterText.includes('@')); return ( {buttonText} From 8ba274a38263fa500f2a01992919bb8a2c7492eb Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Thu, 20 Feb 2020 23:16:21 -0700 Subject: [PATCH 4/5] Allow creating a room with only yourself in it Fixes https://github.com/vector-im/riot-web/issues/12092 --- src/components/views/dialogs/InviteDialog.js | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/components/views/dialogs/InviteDialog.js b/src/components/views/dialogs/InviteDialog.js index fa12f5393a..03ec242a2e 100644 --- a/src/components/views/dialogs/InviteDialog.js +++ b/src/components/views/dialogs/InviteDialog.js @@ -513,7 +513,8 @@ export default class InviteDialog extends React.PureComponent { } _convertFilter(): Member[] { - if (!this.state.filterText || !this.state.filterText.includes('@')) return; // nothing to convert + // Check to see if there's anything to convert first + if (!this.state.filterText || !this.state.filterText.includes('@')) return this.state.targets || []; let newMember: Member; if (this.state.filterText.startsWith('@')) { @@ -523,7 +524,7 @@ export default class InviteDialog extends React.PureComponent { // Assume email newMember = new ThreepidMember(this.state.filterText); } - const newTargets = [...this.state.targets, newMember]; + const newTargets = [...(this.state.targets || []), newMember]; this.setState({targets: newTargets, filterText: ''}); return newTargets; } @@ -561,9 +562,12 @@ export default class InviteDialog extends React.PureComponent { // Check if it's a traditional DM and create the room if required. // TODO: [Canonical DMs] Remove this check and instead just create the multi-person DM let createRoomPromise = Promise.resolve(); - if (targetIds.length === 1) { + const isSelf = targetIds.length === 1 && targetIds[0] === MatrixClientPeg.get().getUserId(); + if (targetIds.length === 1 && !isSelf) { createRoomOptions.dmUserId = targetIds[0]; createRoomPromise = createRoom(createRoomOptions); + } else if (isSelf) { + createRoomPromise = createRoom(createRoomOptions); } else { // Create a boring room and try to invite the targets manually. createRoomPromise = createRoom(createRoomOptions).then(roomId => { From bcb1d73c3cfb09a2c953aeb716e4a1ad981b73b4 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Thu, 20 Feb 2020 23:21:35 -0700 Subject: [PATCH 5/5] Appease the linter --- src/components/views/dialogs/InviteDialog.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/components/views/dialogs/InviteDialog.js b/src/components/views/dialogs/InviteDialog.js index 03ec242a2e..5c222182de 100644 --- a/src/components/views/dialogs/InviteDialog.js +++ b/src/components/views/dialogs/InviteDialog.js @@ -672,7 +672,7 @@ export default class InviteDialog extends React.PureComponent { // Add a result anyways, just without a profile. We stick it at the // top so it is most obviously presented to the user. - r.results.splice(0, 0,{ + r.results.splice(0, 0, { user_id: term, display_name: term, avatar_url: null, @@ -1061,7 +1061,8 @@ export default class InviteDialog extends React.PureComponent { goButtonFn = this._inviteUsers; } - const hasSelection = this.state.targets.length > 0 || (this.state.filterText && this.state.filterText.includes('@')); + const hasSelection = this.state.targets.length > 0 + || (this.state.filterText && this.state.filterText.includes('@')); return (