2016-09-15 11:29:27 +01:00
|
|
|
/*
|
|
|
|
|
Copyright 2016 OpenMarket Ltd
|
|
|
|
|
|
|
|
|
|
Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
|
|
you may not use this file except in compliance with the License.
|
|
|
|
|
You may obtain a copy of the License at
|
|
|
|
|
|
|
|
|
|
http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
|
|
|
|
|
|
Unless required by applicable law or agreed to in writing, software
|
|
|
|
|
distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
|
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
|
See the License for the specific language governing permissions and
|
|
|
|
|
limitations under the License.
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
import React from 'react';
|
|
|
|
|
|
|
|
|
|
export default class NetworkDropdown extends React.Component {
|
|
|
|
|
constructor() {
|
|
|
|
|
super();
|
|
|
|
|
|
|
|
|
|
this.dropdownRootElement = null;
|
|
|
|
|
this.ignoreEvent = null;
|
|
|
|
|
|
2016-09-15 15:18:12 +01:00
|
|
|
this.onInputClick = this.onInputClick.bind(this);
|
2016-09-15 11:29:27 +01:00
|
|
|
this.onRootClick = this.onRootClick.bind(this);
|
|
|
|
|
this.onDocumentClick = this.onDocumentClick.bind(this);
|
|
|
|
|
this.onNetworkClick = this.onNetworkClick.bind(this);
|
|
|
|
|
this.collectRoot = this.collectRoot.bind(this);
|
|
|
|
|
|
|
|
|
|
this.state = {
|
|
|
|
|
expanded: false,
|
2016-09-15 15:18:12 +01:00
|
|
|
selectedNetwork: null,
|
2016-09-15 11:29:27 +01:00
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
componentWillMount() {
|
|
|
|
|
// Listen for all clicks on the document so we can close the
|
|
|
|
|
// menu when the user clicks somewhere else
|
|
|
|
|
document.addEventListener('click', this.onDocumentClick, false);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
componentWillUnmount() {
|
|
|
|
|
document.removeEventListener('click', this.onDocumentClick, false);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
onDocumentClick(ev) {
|
|
|
|
|
// Close the dropdown if the user clicks anywhere that isn't
|
|
|
|
|
// within our root element
|
|
|
|
|
if (ev !== this.ignoreEvent) {
|
|
|
|
|
this.setState({
|
|
|
|
|
expanded: false,
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
onRootClick(ev) {
|
|
|
|
|
// This captures any clicks that happen within our elements,
|
|
|
|
|
// such that we can then ignore them when they're seen by the
|
|
|
|
|
// click listener on the document handler, ie. not close the
|
|
|
|
|
// dropdown immediately after opening it.
|
|
|
|
|
// NB. We can't just stopPropagation() because then the event
|
|
|
|
|
// doesn't reach the React onClick().
|
|
|
|
|
this.ignoreEvent = ev;
|
|
|
|
|
}
|
|
|
|
|
|
2016-09-15 15:18:12 +01:00
|
|
|
onInputClick(ev) {
|
2016-09-15 11:29:27 +01:00
|
|
|
this.setState({
|
|
|
|
|
expanded: !this.state.expanded,
|
|
|
|
|
});
|
2016-09-15 15:18:12 +01:00
|
|
|
ev.preventDefault();
|
2016-09-15 11:29:27 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
onNetworkClick(network, ev) {
|
|
|
|
|
this.setState({
|
|
|
|
|
expanded: false,
|
|
|
|
|
selectedNetwork: network,
|
|
|
|
|
});
|
2016-09-15 15:18:12 +01:00
|
|
|
this.props.onNetworkChange(network);
|
2016-09-15 11:29:27 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
collectRoot(e) {
|
|
|
|
|
if (this.dropdownRootElement) {
|
|
|
|
|
this.dropdownRootElement.removeEventListener('click', this.onRootClick, false);
|
|
|
|
|
}
|
|
|
|
|
if (e) {
|
|
|
|
|
e.addEventListener('click', this.onRootClick, false);
|
|
|
|
|
}
|
|
|
|
|
this.dropdownRootElement = e;
|
|
|
|
|
}
|
|
|
|
|
|
2016-09-15 15:18:12 +01:00
|
|
|
_optionForNetwork(network, wire_onclick) {
|
|
|
|
|
if (wire_onclick === undefined) wire_onclick = true;
|
2016-09-15 11:29:27 +01:00
|
|
|
let icon;
|
|
|
|
|
let name;
|
2016-09-15 15:18:12 +01:00
|
|
|
let span_class;
|
2016-09-15 11:29:27 +01:00
|
|
|
|
2016-09-15 15:18:12 +01:00
|
|
|
if (network === null) {
|
2016-09-15 11:29:27 +01:00
|
|
|
name = 'All networks';
|
2016-09-15 15:18:12 +01:00
|
|
|
span_class = 'mx_NetworkDropdown_menu_all';
|
2016-09-15 11:29:27 +01:00
|
|
|
} else {
|
2016-09-15 17:20:13 +01:00
|
|
|
name = this.props.config.networkNames[network];
|
|
|
|
|
icon = <img src={this.props.config.networkIcons[network]} />;
|
2016-09-15 15:18:12 +01:00
|
|
|
span_class = 'mx_NetworkDropdown_menu_network';
|
2016-09-15 11:29:27 +01:00
|
|
|
}
|
|
|
|
|
|
2016-09-15 15:18:12 +01:00
|
|
|
const click_handler = wire_onclick ? this.onNetworkClick.bind(this, network) : null;
|
|
|
|
|
|
|
|
|
|
return <div key={network} className="mx_NetworkDropdown_networkoption" onClick={click_handler}>
|
2016-09-15 11:29:27 +01:00
|
|
|
{icon}
|
2016-09-15 15:18:12 +01:00
|
|
|
<span className={span_class}>{name}</span>
|
2016-09-15 11:29:27 +01:00
|
|
|
</div>;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
render() {
|
2016-09-15 15:18:12 +01:00
|
|
|
const current_value = this._optionForNetwork(this.state.selectedNetwork, false);
|
2016-09-15 11:29:27 +01:00
|
|
|
|
|
|
|
|
let menu;
|
|
|
|
|
if (this.state.expanded) {
|
2016-09-15 15:18:12 +01:00
|
|
|
const menu_options = [this._optionForNetwork(null)];
|
2016-09-15 17:20:13 +01:00
|
|
|
for (const network of this.props.config.networks) {
|
2016-09-15 15:18:12 +01:00
|
|
|
menu_options.push(this._optionForNetwork(network));
|
2016-09-15 11:29:27 +01:00
|
|
|
}
|
|
|
|
|
menu = <div className="mx_NetworkDropdown_menu">
|
2016-09-15 15:18:12 +01:00
|
|
|
{menu_options}
|
2016-09-15 11:29:27 +01:00
|
|
|
</div>;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return <div className="mx_NetworkDropdown" ref={this.collectRoot}>
|
2016-09-15 15:18:12 +01:00
|
|
|
<div className="mx_NetworkDropdown_input" onClick={this.onInputClick}>
|
|
|
|
|
{current_value}
|
2016-09-15 11:29:27 +01:00
|
|
|
<span className="mx_NetworkDropdown_arrow"></span>
|
|
|
|
|
{menu}
|
|
|
|
|
</div>
|
|
|
|
|
</div>;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2016-09-15 15:18:12 +01:00
|
|
|
NetworkDropdown.propTypes = {
|
|
|
|
|
onNetworkChange: React.PropTypes.func.isRequired,
|
2016-09-15 17:20:13 +01:00
|
|
|
config: React.PropTypes.object,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
NetworkDropdown.defaultProps = {
|
|
|
|
|
config: {
|
|
|
|
|
networks: [],
|
|
|
|
|
}
|
2016-09-15 15:18:12 +01:00
|
|
|
};
|
|
|
|
|
|