basic implementation of search
parent
0ade5ff640
commit
2ee840922d
|
@ -14,6 +14,7 @@ See the License for the specific language governing permissions and
|
||||||
limitations under the License.
|
limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
var Matrix = require("matrix-js-sdk");
|
||||||
var MatrixClientPeg = require("matrix-react-sdk/lib/MatrixClientPeg");
|
var MatrixClientPeg = require("matrix-react-sdk/lib/MatrixClientPeg");
|
||||||
var React = require("react");
|
var React = require("react");
|
||||||
var q = require("q");
|
var q = require("q");
|
||||||
|
@ -38,7 +39,8 @@ module.exports = {
|
||||||
uploadingRoomSettings: false,
|
uploadingRoomSettings: false,
|
||||||
numUnreadMessages: 0,
|
numUnreadMessages: 0,
|
||||||
draggingFile: false,
|
draggingFile: false,
|
||||||
searchResults: [],
|
searching: false,
|
||||||
|
searchResults: null,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -357,9 +359,23 @@ module.exports = {
|
||||||
return WhoIsTyping.whoIsTypingString(this.state.room);
|
return WhoIsTyping.whoIsTypingString(this.state.room);
|
||||||
},
|
},
|
||||||
|
|
||||||
onSearch: function(term) {
|
onSearch: function(term, scope) {
|
||||||
MatrixClientPeg.get().searchMessageText(term).then(function(data) {
|
var self = this;
|
||||||
|
MatrixClientPeg.get().search({
|
||||||
|
body: {
|
||||||
|
search_categories: {
|
||||||
|
room_events: {
|
||||||
|
search_term: term,
|
||||||
|
event_context: {
|
||||||
|
before_limit: 1,
|
||||||
|
after_limit: 1,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}).then(function(data) {
|
||||||
self.setState({
|
self.setState({
|
||||||
|
searchTerm: term,
|
||||||
searchResults: data,
|
searchResults: data,
|
||||||
});
|
});
|
||||||
}, function(error) {
|
}, function(error) {
|
||||||
|
@ -375,7 +391,27 @@ module.exports = {
|
||||||
|
|
||||||
var EventTile = sdk.getComponent('molecules.EventTile');
|
var EventTile = sdk.getComponent('molecules.EventTile');
|
||||||
|
|
||||||
if (this.state.searchResults.length) {
|
if (this.state.searchResults) {
|
||||||
|
// XXX: this dance is foul, due to the results API not returning sorted results
|
||||||
|
var results = this.state.searchResults.search_categories.room_events.results;
|
||||||
|
var eventIds = Object.keys(results);
|
||||||
|
// XXX: todo: merge overlapping results somehow?
|
||||||
|
// XXX: why doesn't searching on name work?
|
||||||
|
var resultList = eventIds.map(function(key) { return results[key]; }).sort(function(a, b) { b.rank - a.rank });
|
||||||
|
for (var i = 0; i < resultList.length; i++) {
|
||||||
|
var ts1 = resultList[i].result.origin_server_ts;
|
||||||
|
ret.push(<li key={ts1}><DateSeparator ts={ts1}/></li>); // Rank: {resultList[i].rank}
|
||||||
|
var mxEv = new Matrix.MatrixEvent(resultList[i].result);
|
||||||
|
if (resultList[i].context.events_before[0]) {
|
||||||
|
var mxEv2 = new Matrix.MatrixEvent(resultList[i].context.events_before[0]);
|
||||||
|
ret.push(<li key={mxEv.getId() + "," + mxEv2.getId()}><EventTile mxEvent={mxEv2} contextual={true} /></li>);
|
||||||
|
}
|
||||||
|
ret.push(<li key={mxEv.getId()}><EventTile mxEvent={mxEv} searchTerm={this.state.searchTerm}/></li>);
|
||||||
|
if (resultList[i].context.events_after[0]) {
|
||||||
|
var mxEv2 = new Matrix.MatrixEvent(resultList[i].context.events_after[0]);
|
||||||
|
ret.push(<li key={mxEv.getId() + "," + mxEv2.getId()}><EventTile mxEvent={mxEv2} contextual={true} /></li>);
|
||||||
|
}
|
||||||
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -44,14 +44,14 @@ module.exports = React.createClass({
|
||||||
|
|
||||||
onSearchChange: function(e) {
|
onSearchChange: function(e) {
|
||||||
if (e.keyCode === 13) {
|
if (e.keyCode === 13) {
|
||||||
this.props.onSearch(this.refs.search_term.getDOMNode().value);
|
this.props.onSearch(this.refs.search_term.getDOMNode().value, this.state.scope);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
render: function() {
|
render: function() {
|
||||||
return (
|
return (
|
||||||
<div className="mx_SearchBar">
|
<div className="mx_SearchBar">
|
||||||
<input ref="search_term" className="mx_SearchBar_input" type="text" placeholder="Search..." onChange={this.onSearchChange}/>
|
<input ref="search_term" className="mx_SearchBar_input" type="text" autoFocus={true} placeholder="Search..." onKeyDown={this.onSearchChange}/>
|
||||||
<div className={"mx_SearchBar_button" + (this.state.scope !== this.Scope.Room ? " mx_SearchBar_unselected" : "")} onClick={this.onThisRoomClick}>This Room</div>
|
<div className={"mx_SearchBar_button" + (this.state.scope !== this.Scope.Room ? " mx_SearchBar_unselected" : "")} onClick={this.onThisRoomClick}>This Room</div>
|
||||||
<div className={"mx_SearchBar_button" + (this.state.scope !== this.Scope.All ? " mx_SearchBar_unselected" : "")} onClick={this.onAllRoomsClick}>All Rooms</div>
|
<div className={"mx_SearchBar_button" + (this.state.scope !== this.Scope.All ? " mx_SearchBar_unselected" : "")} onClick={this.onAllRoomsClick}>All Rooms</div>
|
||||||
<img className="mx_SearchBar_cancel" src="img/cancel-black.png" width="18" height="18" onClick={this.props.onCancelClick} />
|
<img className="mx_SearchBar_cancel" src="img/cancel-black.png" width="18" height="18" onClick={this.props.onCancelClick} />
|
||||||
|
|
|
@ -63,6 +63,10 @@ module.exports = React.createClass({
|
||||||
this.setState(this.getInitialState());
|
this.setState(this.getInitialState());
|
||||||
},
|
},
|
||||||
|
|
||||||
|
onSearchClick: function() {
|
||||||
|
this.setState({ searching: true });
|
||||||
|
},
|
||||||
|
|
||||||
onConferenceNotificationClick: function() {
|
onConferenceNotificationClick: function() {
|
||||||
dis.dispatch({
|
dis.dispatch({
|
||||||
action: 'place_call',
|
action: 'place_call',
|
||||||
|
|
Loading…
Reference in New Issue