Skip to content

Commit d051340

Browse files
committed
Pass filter text when clicking explore/dm prompt
1 parent a481f3b commit d051340

File tree

6 files changed

+149
-124
lines changed

6 files changed

+149
-124
lines changed

src/RoomInvite.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,11 +40,11 @@ export function inviteMultipleToRoom(roomId, addrs) {
4040
return inviter.invite(addrs).then(states => Promise.resolve({states, inviter}));
4141
}
4242

43-
export function showStartChatInviteDialog() {
43+
export function showStartChatInviteDialog(initialText) {
4444
// This dialog handles the room creation internally - we don't need to worry about it.
4545
const InviteDialog = sdk.getComponent("dialogs.InviteDialog");
4646
Modal.createTrackedDialog(
47-
'Start DM', '', InviteDialog, {kind: KIND_DM},
47+
'Start DM', '', InviteDialog, {kind: KIND_DM, initialText},
4848
/*className=*/null, /*isPriority=*/false, /*isStatic=*/true,
4949
);
5050
}

src/components/structures/MatrixChat.tsx

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -653,8 +653,9 @@ export default class MatrixChat extends React.PureComponent<IProps, IState> {
653653
}
654654
case Action.ViewRoomDirectory: {
655655
const RoomDirectory = sdk.getComponent("structures.RoomDirectory");
656-
Modal.createTrackedDialog('Room directory', '', RoomDirectory, {},
657-
'mx_RoomDirectory_dialogWrapper', false, true);
656+
Modal.createTrackedDialog('Room directory', '', RoomDirectory, {
657+
initialText: payload.initialText,
658+
}, 'mx_RoomDirectory_dialogWrapper', false, true);
658659

659660
// View the welcome or home page if we need something to look at
660661
this.viewSomethingBehindModal();
@@ -677,7 +678,7 @@ export default class MatrixChat extends React.PureComponent<IProps, IState> {
677678
this.chatCreateOrReuse(payload.user_id);
678679
break;
679680
case 'view_create_chat':
680-
showStartChatInviteDialog();
681+
showStartChatInviteDialog(payload.initialText || "");
681682
break;
682683
case 'view_invite':
683684
showRoomInviteDialog(payload.roomId);

src/components/structures/RoomDirectory.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ function track(action) {
4444

4545
export default class RoomDirectory extends React.Component {
4646
static propTypes = {
47+
initialText: PropTypes.string,
4748
onFinished: PropTypes.func.isRequired,
4849
};
4950

@@ -61,7 +62,7 @@ export default class RoomDirectory extends React.Component {
6162
error: null,
6263
instanceId: undefined,
6364
roomServer: MatrixClientPeg.getHomeserverName(),
64-
filterString: null,
65+
filterString: this.props.initialText || "",
6566
selectedCommunityId: SettingsStore.getValue("feature_communities_v2_prototypes")
6667
? selectedCommunityId
6768
: null,
@@ -686,6 +687,7 @@ export default class RoomDirectory extends React.Component {
686687
onJoinClick={this.onJoinFromSearchClick}
687688
placeholder={placeholder}
688689
showJoinButton={showJoinButton}
690+
initialText={this.props.initialText}
689691
/>
690692
{dropdown}
691693
</div>;

src/components/views/dialogs/InviteDialog.js

Lines changed: 118 additions & 104 deletions
Original file line numberDiff line numberDiff line change
@@ -308,10 +308,14 @@ export default class InviteDialog extends React.PureComponent {
308308

309309
// The room ID this dialog is for. Only required for KIND_INVITE.
310310
roomId: PropTypes.string,
311+
312+
// Initial value to populate the filter with
313+
initialText: PropTypes.string,
311314
};
312315

313316
static defaultProps = {
314317
kind: KIND_DM,
318+
initialText: "",
315319
};
316320

317321
_debounceTimer: number = null;
@@ -338,7 +342,7 @@ export default class InviteDialog extends React.PureComponent {
338342

339343
this.state = {
340344
targets: [], // array of Member objects (see interface above)
341-
filterText: "",
345+
filterText: this.props.initialText,
342346
recents: InviteDialog.buildRecents(alreadyInvited),
343347
numRecentsShown: INITIAL_ROOMS_SHOWN,
344348
suggestions: this._buildSuggestions(alreadyInvited),
@@ -356,6 +360,12 @@ export default class InviteDialog extends React.PureComponent {
356360
this._editorRef = createRef();
357361
}
358362

363+
componentDidMount() {
364+
if (this.props.initialText) {
365+
this._updateSuggestions(this.props.initialText);
366+
}
367+
}
368+
359369
static buildRecents(excludedTargetIds: Set<string>): {userId: string, user: RoomMember, lastActive: number} {
360370
const rooms = DMRoomMap.shared().getUniqueRoomsWithIndividuals(); // map of userId => js-sdk Room
361371

@@ -687,123 +697,127 @@ export default class InviteDialog extends React.PureComponent {
687697
}
688698
};
689699

690-
_updateFilter = (e) => {
691-
const term = e.target.value;
692-
this.setState({filterText: term});
700+
_updateSuggestions = async (term) => {
701+
MatrixClientPeg.get().searchUserDirectory({term}).then(async r => {
702+
if (term !== this.state.filterText) {
703+
// Discard the results - we were probably too slow on the server-side to make
704+
// these results useful. This is a race we want to avoid because we could overwrite
705+
// more accurate results.
706+
return;
707+
}
693708

694-
// Debounce server lookups to reduce spam. We don't clear the existing server
695-
// results because they might still be vaguely accurate, likewise for races which
696-
// could happen here.
697-
if (this._debounceTimer) {
698-
clearTimeout(this._debounceTimer);
699-
}
700-
this._debounceTimer = setTimeout(async () => {
701-
MatrixClientPeg.get().searchUserDirectory({term}).then(async r => {
702-
if (term !== this.state.filterText) {
703-
// Discard the results - we were probably too slow on the server-side to make
704-
// these results useful. This is a race we want to avoid because we could overwrite
705-
// more accurate results.
706-
return;
707-
}
709+
if (!r.results) r.results = [];
708710

709-
if (!r.results) r.results = [];
710-
711-
// While we're here, try and autocomplete a search result for the mxid itself
712-
// if there's no matches (and the input looks like a mxid).
713-
if (term[0] === '@' && term.indexOf(':') > 1) {
714-
try {
715-
const profile = await MatrixClientPeg.get().getProfileInfo(term);
716-
if (profile) {
717-
// If we have a profile, we have enough information to assume that
718-
// the mxid can be invited - add it to the list. We stick it at the
719-
// top so it is most obviously presented to the user.
720-
r.results.splice(0, 0, {
721-
user_id: term,
722-
display_name: profile['displayname'],
723-
avatar_url: profile['avatar_url'],
724-
});
725-
}
726-
} catch (e) {
727-
console.warn("Non-fatal error trying to make an invite for a user ID");
728-
console.warn(e);
729-
730-
// Add a result anyways, just without a profile. We stick it at the
711+
// While we're here, try and autocomplete a search result for the mxid itself
712+
// if there's no matches (and the input looks like a mxid).
713+
if (term[0] === '@' && term.indexOf(':') > 1) {
714+
try {
715+
const profile = await MatrixClientPeg.get().getProfileInfo(term);
716+
if (profile) {
717+
// If we have a profile, we have enough information to assume that
718+
// the mxid can be invited - add it to the list. We stick it at the
731719
// top so it is most obviously presented to the user.
732720
r.results.splice(0, 0, {
733721
user_id: term,
734-
display_name: term,
735-
avatar_url: null,
722+
display_name: profile['displayname'],
723+
avatar_url: profile['avatar_url'],
736724
});
737725
}
726+
} catch (e) {
727+
console.warn("Non-fatal error trying to make an invite for a user ID");
728+
console.warn(e);
729+
730+
// Add a result anyways, just without a profile. We stick it at the
731+
// top so it is most obviously presented to the user.
732+
r.results.splice(0, 0, {
733+
user_id: term,
734+
display_name: term,
735+
avatar_url: null,
736+
});
738737
}
738+
}
739739

740-
this.setState({
741-
serverResultsMixin: r.results.map(u => ({
742-
userId: u.user_id,
743-
user: new DirectoryMember(u),
744-
})),
745-
});
746-
}).catch(e => {
747-
console.error("Error searching user directory:");
748-
console.error(e);
749-
this.setState({serverResultsMixin: []}); // clear results because it's moderately fatal
740+
this.setState({
741+
serverResultsMixin: r.results.map(u => ({
742+
userId: u.user_id,
743+
user: new DirectoryMember(u),
744+
})),
750745
});
746+
}).catch(e => {
747+
console.error("Error searching user directory:");
748+
console.error(e);
749+
this.setState({serverResultsMixin: []}); // clear results because it's moderately fatal
750+
});
751751

752-
// Whenever we search the directory, also try to search the identity server. It's
753-
// all debounced the same anyways.
754-
if (!this.state.canUseIdentityServer) {
755-
// The user doesn't have an identity server set - warn them of that.
756-
this.setState({tryingIdentityServer: true});
757-
return;
758-
}
759-
if (term.indexOf('@') > 0 && Email.looksValid(term) && SettingsStore.getValue(UIFeature.IdentityServer)) {
760-
// Start off by suggesting the plain email while we try and resolve it
761-
// to a real account.
762-
this.setState({
763-
// per above: the userId is a lie here - it's just a regular identifier
764-
threepidResultsMixin: [{user: new ThreepidMember(term), userId: term}],
765-
});
766-
try {
767-
const authClient = new IdentityAuthClient();
768-
const token = await authClient.getAccessToken();
769-
if (term !== this.state.filterText) return; // abandon hope
770-
771-
const lookup = await MatrixClientPeg.get().lookupThreePid(
772-
'email',
773-
term,
774-
undefined, // callback
775-
token,
776-
);
777-
if (term !== this.state.filterText) return; // abandon hope
778-
779-
if (!lookup || !lookup.mxid) {
780-
// We weren't able to find anyone - we're already suggesting the plain email
781-
// as an alternative, so do nothing.
782-
return;
783-
}
752+
// Whenever we search the directory, also try to search the identity server. It's
753+
// all debounced the same anyways.
754+
if (!this.state.canUseIdentityServer) {
755+
// The user doesn't have an identity server set - warn them of that.
756+
this.setState({tryingIdentityServer: true});
757+
return;
758+
}
759+
if (term.indexOf('@') > 0 && Email.looksValid(term) && SettingsStore.getValue(UIFeature.IdentityServer)) {
760+
// Start off by suggesting the plain email while we try and resolve it
761+
// to a real account.
762+
this.setState({
763+
// per above: the userId is a lie here - it's just a regular identifier
764+
threepidResultsMixin: [{user: new ThreepidMember(term), userId: term}],
765+
});
766+
try {
767+
const authClient = new IdentityAuthClient();
768+
const token = await authClient.getAccessToken();
769+
if (term !== this.state.filterText) return; // abandon hope
770+
771+
const lookup = await MatrixClientPeg.get().lookupThreePid(
772+
'email',
773+
term,
774+
undefined, // callback
775+
token,
776+
);
777+
if (term !== this.state.filterText) return; // abandon hope
784778

785-
// We append the user suggestion to give the user an option to click
786-
// the email anyways, and so we don't cause things to jump around. In
787-
// theory, the user would see the user pop up and think "ah yes, that
788-
// person!"
789-
const profile = await MatrixClientPeg.get().getProfileInfo(lookup.mxid);
790-
if (term !== this.state.filterText || !profile) return; // abandon hope
791-
this.setState({
792-
threepidResultsMixin: [...this.state.threepidResultsMixin, {
793-
user: new DirectoryMember({
794-
user_id: lookup.mxid,
795-
display_name: profile.displayname,
796-
avatar_url: profile.avatar_url,
797-
}),
798-
userId: lookup.mxid,
799-
}],
800-
});
801-
} catch (e) {
802-
console.error("Error searching identity server:");
803-
console.error(e);
804-
this.setState({threepidResultsMixin: []}); // clear results because it's moderately fatal
779+
if (!lookup || !lookup.mxid) {
780+
// We weren't able to find anyone - we're already suggesting the plain email
781+
// as an alternative, so do nothing.
782+
return;
805783
}
784+
785+
// We append the user suggestion to give the user an option to click
786+
// the email anyways, and so we don't cause things to jump around. In
787+
// theory, the user would see the user pop up and think "ah yes, that
788+
// person!"
789+
const profile = await MatrixClientPeg.get().getProfileInfo(lookup.mxid);
790+
if (term !== this.state.filterText || !profile) return; // abandon hope
791+
this.setState({
792+
threepidResultsMixin: [...this.state.threepidResultsMixin, {
793+
user: new DirectoryMember({
794+
user_id: lookup.mxid,
795+
display_name: profile.displayname,
796+
avatar_url: profile.avatar_url,
797+
}),
798+
userId: lookup.mxid,
799+
}],
800+
});
801+
} catch (e) {
802+
console.error("Error searching identity server:");
803+
console.error(e);
804+
this.setState({threepidResultsMixin: []}); // clear results because it's moderately fatal
806805
}
806+
}
807+
};
808+
809+
_updateFilter = (e) => {
810+
const term = e.target.value;
811+
this.setState({filterText: term});
812+
813+
// Debounce server lookups to reduce spam. We don't clear the existing server
814+
// results because they might still be vaguely accurate, likewise for races which
815+
// could happen here.
816+
if (this._debounceTimer) {
817+
clearTimeout(this._debounceTimer);
818+
}
819+
this._debounceTimer = setTimeout(() => {
820+
this._updateSuggestions(term);
807821
}, 150); // 150ms debounce (human reaction time + some)
808822
};
809823

src/components/views/elements/DirectorySearchBox.js

Lines changed: 18 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,8 @@ import * as sdk from '../../../index';
2020
import { _t } from '../../../languageHandler';
2121

2222
export default class DirectorySearchBox extends React.Component {
23-
constructor() {
24-
super();
23+
constructor(props) {
24+
super(props);
2525
this._collectInput = this._collectInput.bind(this);
2626
this._onClearClick = this._onClearClick.bind(this);
2727
this._onChange = this._onChange.bind(this);
@@ -31,7 +31,7 @@ export default class DirectorySearchBox extends React.Component {
3131
this.input = null;
3232

3333
this.state = {
34-
value: '',
34+
value: this.props.initialText || '',
3535
};
3636
}
3737

@@ -90,15 +90,20 @@ export default class DirectorySearchBox extends React.Component {
9090
}
9191

9292
return <div className={`mx_DirectorySearchBox ${this.props.className} mx_textinput`}>
93-
<input type="text" name="dirsearch" value={this.state.value}
94-
className="mx_textinput_icon mx_textinput_search"
95-
ref={this._collectInput}
96-
onChange={this._onChange} onKeyUp={this._onKeyUp}
97-
placeholder={this.props.placeholder} autoFocus
98-
/>
99-
{ joinButton }
100-
<AccessibleButton className="mx_DirectorySearchBox_clear" onClick={this._onClearClick}></AccessibleButton>
101-
</div>;
93+
<input
94+
type="text"
95+
name="dirsearch"
96+
value={this.state.value}
97+
className="mx_textinput_icon mx_textinput_search"
98+
ref={this._collectInput}
99+
onChange={this._onChange}
100+
onKeyUp={this._onKeyUp}
101+
placeholder={this.props.placeholder}
102+
autoFocus
103+
/>
104+
{ joinButton }
105+
<AccessibleButton className="mx_DirectorySearchBox_clear" onClick={this._onClearClick} />
106+
</div>;
102107
}
103108
}
104109

@@ -109,4 +114,5 @@ DirectorySearchBox.propTypes = {
109114
onJoinClick: PropTypes.func,
110115
placeholder: PropTypes.string,
111116
showJoinButton: PropTypes.bool,
117+
initialText: PropTypes.string,
112118
};

src/components/views/rooms/RoomList.tsx

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -285,11 +285,13 @@ export default class RoomList extends React.PureComponent<IProps, IState> {
285285
};
286286

287287
private onStartChat = () => {
288-
dis.dispatch({action: "view_create_chat"});
288+
const initialText = RoomListStore.instance.getFirstNameFilterCondition()?.search;
289+
dis.dispatch({ action: "view_create_chat", initialText });
289290
};
290291

291292
private onExplore = () => {
292-
dis.fire(Action.ViewRoomDirectory);
293+
const initialText = RoomListStore.instance.getFirstNameFilterCondition()?.search;
294+
dis.dispatch({ action: Action.ViewRoomDirectory, initialText });
293295
};
294296

295297
private renderCommunityInvites(): TemporaryTile[] {

0 commit comments

Comments
 (0)