Make the network dropdown work

This commit is contained in:
David Baker 2016-09-15 15:18:12 +01:00
parent 43b87e1f82
commit f3cbb9fe90
3 changed files with 74 additions and 24 deletions

View File

@ -32,6 +32,13 @@ var sanitizeHtml = require('sanitize-html');
linkifyMatrix(linkify); linkifyMatrix(linkify);
const NETWORK_PATTERNS = {
'gitter': /#gitter_.*/,
'irc:freenode': /#freenode_.*:.*/,
'irc:mozilla': /#mozilla_.*:.*/,
'irc:w3c': /@w3c_.*:.*/,
};
module.exports = React.createClass({ module.exports = React.createClass({
displayName: 'RoomDirectory', displayName: 'RoomDirectory',
@ -40,6 +47,7 @@ module.exports = React.createClass({
publicRooms: [], publicRooms: [],
roomAlias: '', roomAlias: '',
loading: true, loading: true,
filterByNetwork: null,
} }
}, },
@ -143,6 +151,12 @@ module.exports = React.createClass({
} }
}, },
onNetworkChange: function(network) {
this.setState({
filterByNetwork: network,
});
},
showRoomAlias: function(alias) { showRoomAlias: function(alias) {
this.showRoom(null, alias); this.showRoom(null, alias);
}, },
@ -192,9 +206,13 @@ module.exports = React.createClass({
if (!this.state.publicRooms) return []; if (!this.state.publicRooms) return [];
var rooms = this.state.publicRooms.filter(function(a) { var rooms = this.state.publicRooms.filter((a) => {
// FIXME: if incrementally typing, keep narrowing down the search set // FIXME: if incrementally typing, keep narrowing down the search set
// incrementally rather than starting over each time. // incrementally rather than starting over each time.
if (this.state.filterByNetwork) {
if (this._networkForRoom(a) != this.state.filterByNetwork) return false;
}
return (((a.name && a.name.toLowerCase().search(filter.toLowerCase()) >= 0) || return (((a.name && a.name.toLowerCase().search(filter.toLowerCase()) >= 0) ||
(a.aliases && a.aliases[0].toLowerCase().search(filter.toLowerCase()) >= 0)) && (a.aliases && a.aliases[0].toLowerCase().search(filter.toLowerCase()) >= 0)) &&
a.num_joined_members > 0); a.num_joined_members > 0);
@ -266,6 +284,22 @@ module.exports = React.createClass({
} }
}, },
/**
* Terrible temporary function that guess what network a public room
* entry is in, until synapse is able to tell us
*/
_networkForRoom(room) {
if (room.aliases) {
for (const alias of room.aliases) {
for (const network of Object.keys(NETWORK_PATTERNS)) {
if (NETWORK_PATTERNS[network].test(alias)) return network;
}
}
}
return 'matrix:matrix_org';
},
render: function() { render: function() {
if (this.state.loading) { if (this.state.loading) {
var Loader = sdk.getComponent("elements.Spinner"); var Loader = sdk.getComponent("elements.Spinner");
@ -284,7 +318,7 @@ module.exports = React.createClass({
<div className="mx_RoomDirectory_list"> <div className="mx_RoomDirectory_list">
<div className="mx_RoomDirectory_listheader"> <div className="mx_RoomDirectory_listheader">
<input ref="roomAlias" placeholder="Join a room (e.g. #foo:domain.com)" className="mx_RoomDirectory_input" size="64" onKeyUp={ this.onKeyUp }/> <input ref="roomAlias" placeholder="Join a room (e.g. #foo:domain.com)" className="mx_RoomDirectory_input" size="64" onKeyUp={ this.onKeyUp }/>
<NetworkDropdown /> <NetworkDropdown onNetworkChange={this.onNetworkChange} />
</div> </div>
<GeminiScrollbar className="mx_RoomDirectory_tableWrapper"> <GeminiScrollbar className="mx_RoomDirectory_tableWrapper">
<table ref="directory_table" className="mx_RoomDirectory_table"> <table ref="directory_table" className="mx_RoomDirectory_table">

View File

@ -23,7 +23,7 @@ export default class NetworkDropdown extends React.Component {
this.dropdownRootElement = null; this.dropdownRootElement = null;
this.ignoreEvent = null; this.ignoreEvent = null;
this.onClick = this.onClick.bind(this); this.onInputClick = this.onInputClick.bind(this);
this.onRootClick = this.onRootClick.bind(this); this.onRootClick = this.onRootClick.bind(this);
this.onDocumentClick = this.onDocumentClick.bind(this); this.onDocumentClick = this.onDocumentClick.bind(this);
this.onNetworkClick = this.onNetworkClick.bind(this); this.onNetworkClick = this.onNetworkClick.bind(this);
@ -31,24 +31,30 @@ export default class NetworkDropdown extends React.Component {
this.state = { this.state = {
expanded: false, expanded: false,
selectedNetwork: 'all', selectedNetwork: null,
}; };
this.networks = [ this.networks = [
'matrix_org', 'matrix:matrix_org',
'freenode',
'gitter', 'gitter',
'irc:freenode',
'irc:mozilla',
'irc:w3c',
]; ];
this.networkNames = { this.networkNames = {
'matrix_org': 'matrix.org', 'matrix:matrix_org': 'matrix.org',
'freenode': 'Freenode', 'irc:freenode': 'Freenode',
'irc:mozilla': 'Mozilla',
'irc:w3c': 'W3C',
'gitter': 'Gitter', 'gitter': 'Gitter',
}; };
this.networkIcons = { this.networkIcons = {
'matrix_org': '//matrix.org/favicon.ico', 'matrix:matrix_org': '//matrix.org/favicon.ico',
'freenode': '//matrix.org/_matrix/media/v1/download/matrix.org/DHLHpDDgWNNejFmrewvwEAHX', 'irc:freenode': '//matrix.org/_matrix/media/v1/download/matrix.org/DHLHpDDgWNNejFmrewvwEAHX',
'irc:mozilla': '//matrix.org/_matrix/media/v1/download/matrix.org/DHLHpDDgWNNejFmrewvwEAHX',
'irc:w3c': '//matrix.org/_matrix/media/v1/download/matrix.org/DHLHpDDgWNNejFmrewvwEAHX',
'gitter': '//gitter.im/favicon.ico', 'gitter': '//gitter.im/favicon.ico',
}; };
} }
@ -83,10 +89,11 @@ export default class NetworkDropdown extends React.Component {
this.ignoreEvent = ev; this.ignoreEvent = ev;
} }
onClick(ev) { onInputClick(ev) {
this.setState({ this.setState({
expanded: !this.state.expanded, expanded: !this.state.expanded,
}); });
ev.preventDefault();
} }
onNetworkClick(network, ev) { onNetworkClick(network, ev) {
@ -94,6 +101,7 @@ export default class NetworkDropdown extends React.Component {
expanded: false, expanded: false,
selectedNetwork: network, selectedNetwork: network,
}); });
this.props.onNetworkChange(network);
} }
collectRoot(e) { collectRoot(e) {
@ -106,43 +114,46 @@ export default class NetworkDropdown extends React.Component {
this.dropdownRootElement = e; this.dropdownRootElement = e;
} }
_optionForNetwork(network) { _optionForNetwork(network, wire_onclick) {
if (wire_onclick === undefined) wire_onclick = true;
let icon; let icon;
let name; let name;
let spanClass; let span_class;
if (network == 'all') { if (network === null) {
name = 'All networks'; name = 'All networks';
spanClass = 'mx_NetworkDropdown_menu_all'; span_class = 'mx_NetworkDropdown_menu_all';
} else { } else {
name = this.networkNames[network]; name = this.networkNames[network];
icon = <img src={this.networkIcons[network]} />; icon = <img src={this.networkIcons[network]} />;
spanClass = 'mx_NetworkDropdown_menu_network'; span_class = 'mx_NetworkDropdown_menu_network';
} }
return <div key={network} className="mx_NetworkDropdown_networkoption" onClick={this.onNetworkClick.bind(this, network)}> const click_handler = wire_onclick ? this.onNetworkClick.bind(this, network) : null;
return <div key={network} className="mx_NetworkDropdown_networkoption" onClick={click_handler}>
{icon} {icon}
<span className={spanClass}>{name}</span> <span className={span_class}>{name}</span>
</div>; </div>;
} }
render() { render() {
const currentValue = this._optionForNetwork(this.state.selectedNetwork); const current_value = this._optionForNetwork(this.state.selectedNetwork, false);
let menu; let menu;
if (this.state.expanded) { if (this.state.expanded) {
const menuOptions = [this._optionForNetwork('all')]; const menu_options = [this._optionForNetwork(null)];
for (const network of this.networks) { for (const network of this.networks) {
menuOptions.push(this._optionForNetwork(network)); menu_options.push(this._optionForNetwork(network));
} }
menu = <div className="mx_NetworkDropdown_menu"> menu = <div className="mx_NetworkDropdown_menu">
{menuOptions} {menu_options}
</div>; </div>;
} }
return <div className="mx_NetworkDropdown" ref={this.collectRoot}> return <div className="mx_NetworkDropdown" ref={this.collectRoot}>
<div className="mx_NetworkDropdown_input" onClick={this.onClick}> <div className="mx_NetworkDropdown_input" onClick={this.onInputClick}>
{currentValue} {current_value}
<span className="mx_NetworkDropdown_arrow"></span> <span className="mx_NetworkDropdown_arrow"></span>
{menu} {menu}
</div> </div>
@ -150,3 +161,7 @@ export default class NetworkDropdown extends React.Component {
} }
} }
NetworkDropdown.propTypes = {
onNetworkChange: React.PropTypes.func.isRequired,
};

View File

@ -26,6 +26,7 @@ limitations under the License.
font-size: 13px; font-size: 13px;
margin-top: 12px; margin-top: 12px;
margin-bottom: 12px; margin-bottom: 12px;
user-select: none;
} }
.mx_NetworkDropdown_arrow { .mx_NetworkDropdown_arrow {