Pass filter text when clicking explore/dm prompt

pull/21833/head
Michael Telatynski 2020-11-11 13:36:17 +00:00
parent a481f3bdf1
commit d0513406ee
6 changed files with 153 additions and 128 deletions

View File

@ -40,11 +40,11 @@ export function inviteMultipleToRoom(roomId, addrs) {
return inviter.invite(addrs).then(states => Promise.resolve({states, inviter})); return inviter.invite(addrs).then(states => Promise.resolve({states, inviter}));
} }
export function showStartChatInviteDialog() { export function showStartChatInviteDialog(initialText) {
// This dialog handles the room creation internally - we don't need to worry about it. // This dialog handles the room creation internally - we don't need to worry about it.
const InviteDialog = sdk.getComponent("dialogs.InviteDialog"); const InviteDialog = sdk.getComponent("dialogs.InviteDialog");
Modal.createTrackedDialog( Modal.createTrackedDialog(
'Start DM', '', InviteDialog, {kind: KIND_DM}, 'Start DM', '', InviteDialog, {kind: KIND_DM, initialText},
/*className=*/null, /*isPriority=*/false, /*isStatic=*/true, /*className=*/null, /*isPriority=*/false, /*isStatic=*/true,
); );
} }

View File

@ -653,8 +653,9 @@ export default class MatrixChat extends React.PureComponent<IProps, IState> {
} }
case Action.ViewRoomDirectory: { case Action.ViewRoomDirectory: {
const RoomDirectory = sdk.getComponent("structures.RoomDirectory"); const RoomDirectory = sdk.getComponent("structures.RoomDirectory");
Modal.createTrackedDialog('Room directory', '', RoomDirectory, {}, Modal.createTrackedDialog('Room directory', '', RoomDirectory, {
'mx_RoomDirectory_dialogWrapper', false, true); initialText: payload.initialText,
}, 'mx_RoomDirectory_dialogWrapper', false, true);
// View the welcome or home page if we need something to look at // View the welcome or home page if we need something to look at
this.viewSomethingBehindModal(); this.viewSomethingBehindModal();
@ -677,7 +678,7 @@ export default class MatrixChat extends React.PureComponent<IProps, IState> {
this.chatCreateOrReuse(payload.user_id); this.chatCreateOrReuse(payload.user_id);
break; break;
case 'view_create_chat': case 'view_create_chat':
showStartChatInviteDialog(); showStartChatInviteDialog(payload.initialText || "");
break; break;
case 'view_invite': case 'view_invite':
showRoomInviteDialog(payload.roomId); showRoomInviteDialog(payload.roomId);

View File

@ -44,6 +44,7 @@ function track(action) {
export default class RoomDirectory extends React.Component { export default class RoomDirectory extends React.Component {
static propTypes = { static propTypes = {
initialText: PropTypes.string,
onFinished: PropTypes.func.isRequired, onFinished: PropTypes.func.isRequired,
}; };
@ -61,7 +62,7 @@ export default class RoomDirectory extends React.Component {
error: null, error: null,
instanceId: undefined, instanceId: undefined,
roomServer: MatrixClientPeg.getHomeserverName(), roomServer: MatrixClientPeg.getHomeserverName(),
filterString: null, filterString: this.props.initialText || "",
selectedCommunityId: SettingsStore.getValue("feature_communities_v2_prototypes") selectedCommunityId: SettingsStore.getValue("feature_communities_v2_prototypes")
? selectedCommunityId ? selectedCommunityId
: null, : null,
@ -686,6 +687,7 @@ export default class RoomDirectory extends React.Component {
onJoinClick={this.onJoinFromSearchClick} onJoinClick={this.onJoinFromSearchClick}
placeholder={placeholder} placeholder={placeholder}
showJoinButton={showJoinButton} showJoinButton={showJoinButton}
initialText={this.props.initialText}
/> />
{dropdown} {dropdown}
</div>; </div>;

View File

@ -308,10 +308,14 @@ export default class InviteDialog extends React.PureComponent {
// The room ID this dialog is for. Only required for KIND_INVITE. // The room ID this dialog is for. Only required for KIND_INVITE.
roomId: PropTypes.string, roomId: PropTypes.string,
// Initial value to populate the filter with
initialText: PropTypes.string,
}; };
static defaultProps = { static defaultProps = {
kind: KIND_DM, kind: KIND_DM,
initialText: "",
}; };
_debounceTimer: number = null; _debounceTimer: number = null;
@ -338,7 +342,7 @@ export default class InviteDialog extends React.PureComponent {
this.state = { this.state = {
targets: [], // array of Member objects (see interface above) targets: [], // array of Member objects (see interface above)
filterText: "", filterText: this.props.initialText,
recents: InviteDialog.buildRecents(alreadyInvited), recents: InviteDialog.buildRecents(alreadyInvited),
numRecentsShown: INITIAL_ROOMS_SHOWN, numRecentsShown: INITIAL_ROOMS_SHOWN,
suggestions: this._buildSuggestions(alreadyInvited), suggestions: this._buildSuggestions(alreadyInvited),
@ -356,6 +360,12 @@ export default class InviteDialog extends React.PureComponent {
this._editorRef = createRef(); this._editorRef = createRef();
} }
componentDidMount() {
if (this.props.initialText) {
this._updateSuggestions(this.props.initialText);
}
}
static buildRecents(excludedTargetIds: Set<string>): {userId: string, user: RoomMember, lastActive: number} { static buildRecents(excludedTargetIds: Set<string>): {userId: string, user: RoomMember, lastActive: number} {
const rooms = DMRoomMap.shared().getUniqueRoomsWithIndividuals(); // map of userId => js-sdk Room const rooms = DMRoomMap.shared().getUniqueRoomsWithIndividuals(); // map of userId => js-sdk Room
@ -687,17 +697,7 @@ export default class InviteDialog extends React.PureComponent {
} }
}; };
_updateFilter = (e) => { _updateSuggestions = async (term) => {
const term = e.target.value;
this.setState({filterText: term});
// Debounce server lookups to reduce spam. We don't clear the existing server
// results because they might still be vaguely accurate, likewise for races which
// could happen here.
if (this._debounceTimer) {
clearTimeout(this._debounceTimer);
}
this._debounceTimer = setTimeout(async () => {
MatrixClientPeg.get().searchUserDirectory({term}).then(async r => { MatrixClientPeg.get().searchUserDirectory({term}).then(async r => {
if (term !== this.state.filterText) { if (term !== this.state.filterText) {
// Discard the results - we were probably too slow on the server-side to make // Discard the results - we were probably too slow on the server-side to make
@ -804,6 +804,20 @@ export default class InviteDialog extends React.PureComponent {
this.setState({threepidResultsMixin: []}); // clear results because it's moderately fatal this.setState({threepidResultsMixin: []}); // clear results because it's moderately fatal
} }
} }
};
_updateFilter = (e) => {
const term = e.target.value;
this.setState({filterText: term});
// Debounce server lookups to reduce spam. We don't clear the existing server
// results because they might still be vaguely accurate, likewise for races which
// could happen here.
if (this._debounceTimer) {
clearTimeout(this._debounceTimer);
}
this._debounceTimer = setTimeout(() => {
this._updateSuggestions(term);
}, 150); // 150ms debounce (human reaction time + some) }, 150); // 150ms debounce (human reaction time + some)
}; };

View File

@ -20,8 +20,8 @@ import * as sdk from '../../../index';
import { _t } from '../../../languageHandler'; import { _t } from '../../../languageHandler';
export default class DirectorySearchBox extends React.Component { export default class DirectorySearchBox extends React.Component {
constructor() { constructor(props) {
super(); super(props);
this._collectInput = this._collectInput.bind(this); this._collectInput = this._collectInput.bind(this);
this._onClearClick = this._onClearClick.bind(this); this._onClearClick = this._onClearClick.bind(this);
this._onChange = this._onChange.bind(this); this._onChange = this._onChange.bind(this);
@ -31,7 +31,7 @@ export default class DirectorySearchBox extends React.Component {
this.input = null; this.input = null;
this.state = { this.state = {
value: '', value: this.props.initialText || '',
}; };
} }
@ -90,14 +90,19 @@ export default class DirectorySearchBox extends React.Component {
} }
return <div className={`mx_DirectorySearchBox ${this.props.className} mx_textinput`}> return <div className={`mx_DirectorySearchBox ${this.props.className} mx_textinput`}>
<input type="text" name="dirsearch" value={this.state.value} <input
type="text"
name="dirsearch"
value={this.state.value}
className="mx_textinput_icon mx_textinput_search" className="mx_textinput_icon mx_textinput_search"
ref={this._collectInput} ref={this._collectInput}
onChange={this._onChange} onKeyUp={this._onKeyUp} onChange={this._onChange}
placeholder={this.props.placeholder} autoFocus onKeyUp={this._onKeyUp}
placeholder={this.props.placeholder}
autoFocus
/> />
{ joinButton } { joinButton }
<AccessibleButton className="mx_DirectorySearchBox_clear" onClick={this._onClearClick}></AccessibleButton> <AccessibleButton className="mx_DirectorySearchBox_clear" onClick={this._onClearClick} />
</div>; </div>;
} }
} }
@ -109,4 +114,5 @@ DirectorySearchBox.propTypes = {
onJoinClick: PropTypes.func, onJoinClick: PropTypes.func,
placeholder: PropTypes.string, placeholder: PropTypes.string,
showJoinButton: PropTypes.bool, showJoinButton: PropTypes.bool,
initialText: PropTypes.string,
}; };

View File

@ -285,11 +285,13 @@ export default class RoomList extends React.PureComponent<IProps, IState> {
}; };
private onStartChat = () => { private onStartChat = () => {
dis.dispatch({action: "view_create_chat"}); const initialText = RoomListStore.instance.getFirstNameFilterCondition()?.search;
dis.dispatch({ action: "view_create_chat", initialText });
}; };
private onExplore = () => { private onExplore = () => {
dis.fire(Action.ViewRoomDirectory); const initialText = RoomListStore.instance.getFirstNameFilterCondition()?.search;
dis.dispatch({ action: Action.ViewRoomDirectory, initialText });
}; };
private renderCommunityInvites(): TemporaryTile[] { private renderCommunityInvites(): TemporaryTile[] {