diff --git a/src/components/structures/RoomDirectory.js b/src/components/structures/RoomDirectory.js index a60f96d6..35194883 100644 --- a/src/components/structures/RoomDirectory.js +++ b/src/components/structures/RoomDirectory.js @@ -32,6 +32,13 @@ var sanitizeHtml = require('sanitize-html'); linkifyMatrix(linkify); +const NETWORK_PATTERNS = { + 'gitter': /#gitter_.*/, + 'irc:freenode': /#freenode_.*:.*/, + 'irc:mozilla': /#mozilla_.*:.*/, + 'irc:w3c': /@w3c_.*:.*/, +}; + module.exports = React.createClass({ displayName: 'RoomDirectory', @@ -40,6 +47,7 @@ module.exports = React.createClass({ publicRooms: [], roomAlias: '', loading: true, + filterByNetwork: null, } }, @@ -143,6 +151,12 @@ module.exports = React.createClass({ } }, + onNetworkChange: function(network) { + this.setState({ + filterByNetwork: network, + }); + }, + showRoomAlias: function(alias) { this.showRoom(null, alias); }, @@ -192,9 +206,13 @@ module.exports = React.createClass({ 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 // 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) || (a.aliases && a.aliases[0].toLowerCase().search(filter.toLowerCase()) >= 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() { if (this.state.loading) { var Loader = sdk.getComponent("elements.Spinner"); @@ -284,7 +318,7 @@ module.exports = React.createClass({
- +
diff --git a/src/components/views/directory/NetworkDropdown.js b/src/components/views/directory/NetworkDropdown.js index eacb0fff..1ffa9c94 100644 --- a/src/components/views/directory/NetworkDropdown.js +++ b/src/components/views/directory/NetworkDropdown.js @@ -23,7 +23,7 @@ export default class NetworkDropdown extends React.Component { this.dropdownRootElement = null; this.ignoreEvent = null; - this.onClick = this.onClick.bind(this); + this.onInputClick = this.onInputClick.bind(this); this.onRootClick = this.onRootClick.bind(this); this.onDocumentClick = this.onDocumentClick.bind(this); this.onNetworkClick = this.onNetworkClick.bind(this); @@ -31,24 +31,30 @@ export default class NetworkDropdown extends React.Component { this.state = { expanded: false, - selectedNetwork: 'all', + selectedNetwork: null, }; this.networks = [ - 'matrix_org', - 'freenode', + 'matrix:matrix_org', 'gitter', + 'irc:freenode', + 'irc:mozilla', + 'irc:w3c', ]; this.networkNames = { - 'matrix_org': 'matrix.org', - 'freenode': 'Freenode', + 'matrix:matrix_org': 'matrix.org', + 'irc:freenode': 'Freenode', + 'irc:mozilla': 'Mozilla', + 'irc:w3c': 'W3C', 'gitter': 'Gitter', }; this.networkIcons = { - 'matrix_org': '//matrix.org/favicon.ico', - 'freenode': '//matrix.org/_matrix/media/v1/download/matrix.org/DHLHpDDgWNNejFmrewvwEAHX', + 'matrix:matrix_org': '//matrix.org/favicon.ico', + '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', }; } @@ -83,10 +89,11 @@ export default class NetworkDropdown extends React.Component { this.ignoreEvent = ev; } - onClick(ev) { + onInputClick(ev) { this.setState({ expanded: !this.state.expanded, }); + ev.preventDefault(); } onNetworkClick(network, ev) { @@ -94,6 +101,7 @@ export default class NetworkDropdown extends React.Component { expanded: false, selectedNetwork: network, }); + this.props.onNetworkChange(network); } collectRoot(e) { @@ -106,43 +114,46 @@ export default class NetworkDropdown extends React.Component { this.dropdownRootElement = e; } - _optionForNetwork(network) { + _optionForNetwork(network, wire_onclick) { + if (wire_onclick === undefined) wire_onclick = true; let icon; let name; - let spanClass; + let span_class; - if (network == 'all') { + if (network === null) { name = 'All networks'; - spanClass = 'mx_NetworkDropdown_menu_all'; + span_class = 'mx_NetworkDropdown_menu_all'; } else { name = this.networkNames[network]; icon = ; - spanClass = 'mx_NetworkDropdown_menu_network'; + span_class = 'mx_NetworkDropdown_menu_network'; } - return
+ const click_handler = wire_onclick ? this.onNetworkClick.bind(this, network) : null; + + return
{icon} - {name} + {name}
; } render() { - const currentValue = this._optionForNetwork(this.state.selectedNetwork); + const current_value = this._optionForNetwork(this.state.selectedNetwork, false); let menu; if (this.state.expanded) { - const menuOptions = [this._optionForNetwork('all')]; + const menu_options = [this._optionForNetwork(null)]; for (const network of this.networks) { - menuOptions.push(this._optionForNetwork(network)); + menu_options.push(this._optionForNetwork(network)); } menu =
- {menuOptions} + {menu_options}
; } return
-
- {currentValue} +
+ {current_value} {menu}
@@ -150,3 +161,7 @@ export default class NetworkDropdown extends React.Component { } } +NetworkDropdown.propTypes = { + onNetworkChange: React.PropTypes.func.isRequired, +}; + diff --git a/src/skins/vector/css/vector-web/views/directory/NetworkDropdown.css b/src/skins/vector/css/vector-web/views/directory/NetworkDropdown.css index 6380a7a1..3bf4bb34 100644 --- a/src/skins/vector/css/vector-web/views/directory/NetworkDropdown.css +++ b/src/skins/vector/css/vector-web/views/directory/NetworkDropdown.css @@ -26,6 +26,7 @@ limitations under the License. font-size: 13px; margin-top: 12px; margin-bottom: 12px; + user-select: none; } .mx_NetworkDropdown_arrow {