wire up searchbox filtering, and some minor overall tweaks

pull/1402/head
Matthew Hodgson 2016-04-15 17:54:48 +01:00
parent 90ae024a4e
commit 26d12bebe4
5 changed files with 92 additions and 24 deletions

View File

@ -31,6 +31,7 @@ var LeftPanel = React.createClass({
getInitialState: function() { getInitialState: function() {
return { return {
showCallElement: null, showCallElement: null,
searchFilter: '',
}; };
}, },
@ -84,6 +85,10 @@ var LeftPanel = React.createClass({
} }
}, },
onSearch: function(term) {
this.setState({ searchFilter: term });
},
render: function() { render: function() {
var RoomList = sdk.getComponent('rooms.RoomList'); var RoomList = sdk.getComponent('rooms.RoomList');
var BottomLeftMenu = sdk.getComponent('structures.BottomLeftMenu'); var BottomLeftMenu = sdk.getComponent('structures.BottomLeftMenu');
@ -111,12 +116,13 @@ var LeftPanel = React.createClass({
return ( return (
<aside className={classes} style={{ opacity: this.props.opacity }}> <aside className={classes} style={{ opacity: this.props.opacity }}>
<SearchBox collapsed={ this.props.collapsed } /> <SearchBox collapsed={ this.props.collapsed } onSearch={ this.onSearch } />
{ collapseButton } { collapseButton }
{ callPreview } { callPreview }
<RoomList <RoomList
selectedRoom={this.props.selectedRoom} selectedRoom={this.props.selectedRoom}
collapsed={this.props.collapsed} collapsed={this.props.collapsed}
searchFilter={this.state.searchFilter}
ConferenceHandler={VectorConferenceHandler} /> ConferenceHandler={VectorConferenceHandler} />
<BottomLeftMenu collapsed={this.props.collapsed}/> <BottomLeftMenu collapsed={this.props.collapsed}/>
</aside> </aside>

View File

@ -65,16 +65,12 @@ var RoomSubList = React.createClass({
selectedRoom: React.PropTypes.string.isRequired, selectedRoom: React.PropTypes.string.isRequired,
startAsHidden: React.PropTypes.bool, startAsHidden: React.PropTypes.bool,
showSpinner: React.PropTypes.bool, // true to show a spinner if 0 elements when expanded showSpinner: React.PropTypes.bool, // true to show a spinner if 0 elements when expanded
collapsed: React.PropTypes.bool.isRequired, // is LeftPanel collapsed?
// TODO: Fix the name of this. This is too easily confused with the
// "hidden" state which is the expanded (or not) view of the list of rooms.
// What this prop *really* does is control whether the room name is displayed
// so it should be named as such.
collapsed: React.PropTypes.bool.isRequired,
onHeaderClick: React.PropTypes.func, onHeaderClick: React.PropTypes.func,
alwaysShowHeader: React.PropTypes.bool, alwaysShowHeader: React.PropTypes.bool,
incomingCall: React.PropTypes.object, incomingCall: React.PropTypes.object,
onShowMoreRooms: React.PropTypes.func onShowMoreRooms: React.PropTypes.func,
searchFilter: React.PropTypes.string,
}, },
getInitialState: function() { getInitialState: function() {
@ -93,13 +89,20 @@ var RoomSubList = React.createClass({
}, },
componentWillMount: function() { componentWillMount: function() {
this.sortList(this.props.list, this.props.order); this.sortList(this.applySearchFilter(this.props.list, this.props.searchFilter), this.props.order);
}, },
componentWillReceiveProps: function(newProps) { componentWillReceiveProps: function(newProps) {
// order the room list appropriately before we re-render // order the room list appropriately before we re-render
//if (debug) console.log("received new props, list = " + newProps.list); //if (debug) console.log("received new props, list = " + newProps.list);
this.sortList(newProps.list, newProps.order); this.sortList(this.applySearchFilter(newProps.list, newProps.searchFilter), newProps.order);
},
applySearchFilter: function(list, filter) {
if (filter === "") return list;
return list.filter((room) => {
return room.name && room.name.toLowerCase().indexOf(filter.toLowerCase()) >= 0
});
}, },
onClick: function(ev) { onClick: function(ev) {

View File

@ -19,32 +19,78 @@ limitations under the License.
var React = require('react'); var React = require('react');
var sdk = require('matrix-react-sdk') var sdk = require('matrix-react-sdk')
var dis = require('matrix-react-sdk/lib/dispatcher'); var dis = require('matrix-react-sdk/lib/dispatcher');
var rate_limited_func = require('matrix-react-sdk/lib/ratelimitedfunc');
module.exports = React.createClass({ module.exports = React.createClass({
displayName: 'SearchBox', displayName: 'SearchBox',
propTypes: {
collapsed: React.PropTypes.bool,
onSearch: React.PropTypes.func,
},
onChange: new rate_limited_func(
function() {
if (this.refs.search) {
this.props.onSearch(this.refs.search.value);
}
},
100
),
onToggleCollapse: function(show) {
if (show) {
dis.dispatch({
action: 'show_left_panel',
});
}
else {
dis.dispatch({
action: 'hide_left_panel',
});
}
},
render: function() { render: function() {
var TintableSvg = sdk.getComponent('elements.TintableSvg'); var TintableSvg = sdk.getComponent('elements.TintableSvg');
var toggleCollapse; var toggleCollapse;
if (this.props.collapsed) { if (this.props.collapsed) {
toggleCollapse = <img className="mx_SearchBox_maximise" src="img/maximise.svg" width="10" height="16" alt="&lt;"/>; toggleCollapse =
<div className="mx_SearchBox_maximise" onClick={ this.onToggleCollapse.bind(this, true) }>
<TintableSvg src="img/maximise.svg" width="10" height="16" alt="&lt;"/>
</div>
} }
else { else {
toggleCollapse = <img className="mx_SearchBox_minimise" src="img/minimise.svg" width="10" height="16" alt="&lt;"/>; toggleCollapse =
<div className="mx_SearchBox_minimise" onClick={ this.onToggleCollapse.bind(this, false) }>
<TintableSvg src="img/minimise.svg" width="10" height="16" alt="&lt;"/>
</div>
} }
var searchControls;
if (!this.props.collapsed) {
searchControls = [
<TintableSvg
key="button"
className="mx_SearchBox_searchButton"
src="img/search.svg" width="21" height="19"
/>,
<input
key="searchfield"
type="text"
ref="search"
className="mx_SearchBox_search"
onChange={ this.onChange }
placeholder="Search room names"
/>
];
}
var self = this;
return ( return (
<div className="mx_SearchBox"> <div className="mx_SearchBox">
<TintableSvg { searchControls }
className="mx_SearchBox_searchButton"
src="img/search.svg" width="21" height="19"
/>
<input
type="text"
className="mx_SearchBox_search"
placeholder="Search Vector"
/>
{ toggleCollapse } { toggleCollapse }
</div> </div>
); );

View File

@ -15,9 +15,9 @@ limitations under the License.
*/ */
.mx_RoomStatusBar { .mx_RoomStatusBar {
margin-top: 12px; margin-top: 15px;
margin-left: 65px; margin-left: 65px;
min-height: 37px; min-height: 34px;
} }
/* position the indicator in the same place horizontally as .mx_EventTile_avatar. */ /* position the indicator in the same place horizontally as .mx_EventTile_avatar. */
@ -33,8 +33,9 @@ limitations under the License.
.mx_RoomStatusBar_placeholderIndicator span { .mx_RoomStatusBar_placeholderIndicator span {
color: #4a4a4a; color: #4a4a4a;
opacity: 0.5; opacity: 0.5;
/*
position: relative; position: relative;
top: -4px;
/*
animation-duration: 1s; animation-duration: 1s;
animation-name: bounce; animation-name: bounce;
animation-direction: alternate; animation-direction: alternate;

View File

@ -45,5 +45,17 @@ limitations under the License.
.mx_SearchBox_minimise, .mx_SearchBox_minimise,
.mx_SearchBox_maximise { .mx_SearchBox_maximise {
cursor: pointer;
}
.mx_SearchBox_minimise {
margin-left: 10px; margin-left: 10px;
} }
.mx_SearchBox_maximise {
margin-left: 6px;
}
.mx_SearchBox object {
pointer-events: none;
}