Fix vector-im/vector-web#851 by truncating the search results

This commit is contained in:
Kegan Dougal 2016-02-05 15:24:51 +00:00
parent ef9b4ab1e6
commit a0c5b30fd6
2 changed files with 49 additions and 8 deletions

View file

@ -24,6 +24,7 @@ var sdk = require('../../../index');
var GeminiScrollbar = require('react-gemini-scrollbar'); var GeminiScrollbar = require('react-gemini-scrollbar');
var rate_limited_func = require('../../../ratelimitedfunc'); var rate_limited_func = require('../../../ratelimitedfunc');
var INITIAL_SEARCH_RESULTS_COUNT = 10;
var INITIAL_LOAD_NUM_MEMBERS = 30; var INITIAL_LOAD_NUM_MEMBERS = 30;
var SHARE_HISTORY_WARNING = "Newly invited users will see the history of this room. "+ var SHARE_HISTORY_WARNING = "Newly invited users will see the history of this room. "+
"If you'd prefer invited users not to see messages that were sent before they joined, "+ "If you'd prefer invited users not to see messages that were sent before they joined, "+
@ -420,12 +421,12 @@ module.exports = React.createClass({
entities.unshift(this._emailEntity); entities.unshift(this._emailEntity);
} }
return ( return (
<SearchableEntityList searchPlaceholderText={"Invite / Search"} <SearchableEntityList searchPlaceholderText={"Invite / Search"}
onSubmit={this.onInvite} onSubmit={this.onInvite}
onQueryChanged={this.onSearchQueryChanged} onQueryChanged={this.onSearchQueryChanged}
entities={entities} /> entities={entities}
truncateAt={INITIAL_SEARCH_RESULTS_COUNT}/>
); );
} }
}, },

View file

@ -16,6 +16,7 @@ limitations under the License.
var React = require('react'); var React = require('react');
var MatrixClientPeg = require("../../../MatrixClientPeg"); var MatrixClientPeg = require("../../../MatrixClientPeg");
var Modal = require("../../../Modal"); var Modal = require("../../../Modal");
var sdk = require("../../../index");
var GeminiScrollbar = require('react-gemini-scrollbar'); var GeminiScrollbar = require('react-gemini-scrollbar');
// A list capable of displaying entities which conform to the SearchableEntity // A list capable of displaying entities which conform to the SearchableEntity
@ -29,7 +30,8 @@ var SearchableEntityList = React.createClass({
showInputBox: React.PropTypes.bool, showInputBox: React.PropTypes.bool,
onQueryChanged: React.PropTypes.func, // fn(inputText) onQueryChanged: React.PropTypes.func, // fn(inputText)
onSubmit: React.PropTypes.func, // fn(inputText) onSubmit: React.PropTypes.func, // fn(inputText)
entities: React.PropTypes.array entities: React.PropTypes.array,
truncateAt: React.PropTypes.number
}, },
getDefaultProps: function() { getDefaultProps: function() {
@ -46,6 +48,7 @@ var SearchableEntityList = React.createClass({
getInitialState: function() { getInitialState: function() {
return { return {
query: "", query: "",
truncateAt: this.props.truncateAt,
results: this.getSearchResults("", this.props.entities) results: this.getSearchResults("", this.props.entities)
}; };
}, },
@ -103,6 +106,24 @@ var SearchableEntityList = React.createClass({
}); });
}, },
_showAll: function() {
this.setState({
truncateAt: -1
});
},
_createOverflowEntity: function(overflowCount, totalCount) {
var EntityTile = sdk.getComponent("rooms.EntityTile");
var BaseAvatar = sdk.getComponent("avatars.BaseAvatar");
var text = "and " + overflowCount + " other" + (overflowCount > 1 ? "s" : "") + "...";
return (
<EntityTile className="mx_EntityTile_ellipsis" avatarJsx={
<BaseAvatar url="img/ellipsis.svg" name="..." width={36} height={36} />
} name={text} presenceState="online" suppressOnHover={true}
onClick={this._showAll} />
);
},
render: function() { render: function() {
var inputBox; var inputBox;
@ -116,15 +137,34 @@ var SearchableEntityList = React.createClass({
); );
} }
return ( var list;
<div className={ "mx_SearchableEntityList " + (this.state.query.length ? "mx_SearchableEntityList_expanded" : "") }> if (this.props.truncateAt) { // caller wants list truncated
{inputBox} var TruncatedList = sdk.getComponent("elements.TruncatedList");
<GeminiScrollbar autoshow={true} className="mx_SearchableEntityList_listWrapper"> list = (
<TruncatedList className="mx_SearchableEntityList_list"
truncateAt={this.state.truncateAt} // use state truncation as it may be expanded
createOverflowElement={this._createOverflowEntity}>
{this.state.results.map((entity) => {
return entity.getJsx();
})}
</TruncatedList>
);
}
else {
list = (
<div className="mx_SearchableEntityList_list"> <div className="mx_SearchableEntityList_list">
{this.state.results.map((entity) => { {this.state.results.map((entity) => {
return entity.getJsx(); return entity.getJsx();
})} })}
</div> </div>
);
}
return (
<div className={ "mx_SearchableEntityList " + (this.state.query.length ? "mx_SearchableEntityList_expanded" : "") }>
{inputBox}
<GeminiScrollbar autoshow={true} className="mx_SearchableEntityList_listWrapper">
{ list }
</GeminiScrollbar> </GeminiScrollbar>
{ this.state.query.length ? <div className="mx_SearchableEntityList_hrWrapper"><hr/></div> : '' } { this.state.query.length ? <div className="mx_SearchableEntityList_hrWrapper"><hr/></div> : '' }
</div> </div>