aboutsummaryrefslogtreecommitdiffstats
path: root/web/src/js/components/ProxyApp.js
diff options
context:
space:
mode:
Diffstat (limited to 'web/src/js/components/ProxyApp.js')
-rw-r--r--web/src/js/components/ProxyApp.js163
1 files changed, 163 insertions, 0 deletions
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 (
+ <div id="container" tabIndex="0" onKeyDown={this.onKeydown}>
+ <Header ref="header" settings={settings} updateLocation={this.updateLocation} query={query} />
+ {React.cloneElement(
+ children,
+ { ref: "view", location, query, updateLocation: this.updateLocation }
+ )}
+ {showEventLog && [
+ <Splitter key="splitter" axis="y"/>,
+ <EventLog key="eventlog"/>
+ ]}
+ <Footer settings={settings}/>
+ </div>
+ )
+ }
+})
+
+export default connect(
+ state => ({
+ showEventLog: state.eventLog.visible
+ })
+)(ProxyAppMain)