From 851bb4bf68c20f22c195a4397dacb8cdfdb65fba Mon Sep 17 00:00:00 2001 From: Jason Date: Thu, 9 Jun 2016 13:35:41 +0800 Subject: [web] rewrite ProxyApp and MainView with es6 --- web/src/js/components/ProxyApp.js | 163 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 163 insertions(+) create mode 100644 web/src/js/components/ProxyApp.js (limited to 'web/src/js/components/ProxyApp.js') diff --git a/web/src/js/components/ProxyApp.js b/web/src/js/components/ProxyApp.js new file mode 100644 index 00000000..33443dcd --- /dev/null +++ b/web/src/js/components/ProxyApp.js @@ -0,0 +1,163 @@ +import React, { Component, PropTypes } from "react" +import ReactDOM from "react-dom" +import _ from "lodash" +import { connect } from 'react-redux' + +import { Splitter } from "./common.js" +import { Header, MainMenu } from "./header.js" +import EventLog from "./eventlog.js" +import Footer from "./footer.js" +import { SettingsStore } from "../store/store.js" +import { Key } from "../utils.js" + +class ProxyAppMain extends Component { + + static childContextTypes = { + returnFocus: PropTypes.func.isRequired, + location: PropTypes.object.isRequired, + } + + static contextTypes = { + router: PropTypes.object.isRequired, + } + + constructor() { + this.settingsStore = new SettingsStore() + + // Default Settings before fetch + _.extend(this.settingsStore.dict, {}) + + this.state = { settings: this.settingsStore.dict } + } + + /** + * @todo move to actions + */ + updateLocation(pathname, queryUpdate) { + if (pathname === undefined) { + pathname = this.props.location.pathname + } + const query = this.props.location.query + for (const key of Object.keys(queryUpdate || {})) { + query[i] = queryUpdate[i] || undefined + } + this.context.router.replace({pathname, query}) + } + + /** + * @todo pass in with props + */ + getQuery() { + // For whatever reason, react-router always returns the same object, which makes comparing + // the current props with nextProps impossible. As a workaround, we just clone the query object. + return _.clone(this.props.location.query) + } + + /** + * @todo remove settings store + * @todo connect websocket here + * @todo listen to window's key events + */ + componentDidMount() { + this.focus() + this.settingsStore.addListener("recalculate", this.onSettingsChange) + } + + /** + * @todo remove settings store + * @todo disconnect websocket here + * @todo stop listening to window's key events + */ + componentWillUnmount() { + this.settingsStore.removeListener("recalculate", this.onSettingsChange) + } + + /** + * @todo move to actions + */ + onSettingsChange() { + this.setState({ settings: this.settingsStore.dict }) + } + + /** + * @todo use props + */ + getChildContext() { + return { + returnFocus: this.focus, + location: this.props.location + } + } + + /** + * @todo remove it + */ + focus() { + document.activeElement.blur() + window.getSelection().removeAllRanges() + ReactDOM.findDOMNode(this).focus() + } + + /** + * @todo move to actions + */ + onKeydown(e) { + let name = null + + switch (e.keyCode) { + case Key.I: + name = "intercept" + break + case Key.L: + name = "search" + break + case Key.H: + name = "highlight" + break + default: + let main = this.refs.view + if (this.refs.view.getWrappedInstance) { + main = this.refs.view.getWrappedInstance() + } + if (main.onMainKeyDown) { + main.onMainKeyDown(e) + } + return // don't prevent default then + } + + if (name) { + const headerComponent = this.refs.header + headerComponent.setState({active: MainMenu}, function () { + headerComponent.refs.active.refs[name].select() + }) + } + + e.preventDefault() + } + + render() { + const { showEventLog, location, children } = this.props + const { settings } = this.state + const query = this.getQuery() + return ( +
+
+ {React.cloneElement( + children, + { ref: "view", location, query, updateLocation: this.updateLocation } + )} + {showEventLog && [ + , + + ]} +
+ ) + } +}) + +export default connect( + state => ({ + showEventLog: state.eventLog.visible + }) +)(ProxyAppMain) -- cgit v1.2.3