/*
Copyright 2018 Joseph Weston
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see .
*/
import React from 'react' ;
import AnimateHeight from 'react-animate-height'
import Spinner from 'react-spinkit'
import {
ComposableMap,
ZoomableGroup,
Geographies,
Geography,
} from "react-simple-maps"
import 'normalize.css/normalize.css'
import './static/styles.css'
// Import licence for GEOJSON so as to include it into the webpack output.
// This is necessary to avoid violating the license terms.
import './static/LICENSE'
import World from './static/world.geo.json'
const VPN = Object.freeze({
disconnected:1,
connecting:2,
connected:3,
disconnecting: 4,
error: 5,
}) ;
class Nord extends React.Component {
constructor(props) {
super(props) ;
this.state = {
enabled: false,
loading: true,
status: VPN.disconnected,
country: null,
host: null,
viewportWidth: null,
} ;
this.connection = null
this.connect = this.connect.bind(this) ;
this.updateDimensions = this.updateDimensions.bind(this) ;
this.disconnect = this.disconnect.bind(this) ;
this.handleData = this.handleData.bind(this) ;
}
updateDimensions() {
this.setState({
viewportWidth: Math.max(document.documentElement.clientWidth,
window.innerWidth || 0)
}) ;
}
componentWillMount() {
this.updateDimensions() ;
}
componentWillUnmount() {
window.removeEventListener("resize", this.updateDimensions) ;
}
componentDidMount() {
const upstream = location.hostname+(location.port ? ':'+location.port : '')
window.addEventListener("resize", this.updateDimensions) ;
this.setState({enabled: false, loading: true})
this.connection = new WebSocket('ws://'+upstream+'/api') ;
this.connection.onopen = () =>
this.setState({enabled: true, loading: false}) ;
this.connection.onerror = () =>
this.setState({enabled: false, loading: false}) ;
this.connection.onclose = () =>
this.setState({enabled: false, loading: false}) ;
this.connection.onmessage = this.handleData ;
}
handleData(msg) {
msg = JSON.parse(msg.data)
switch(msg.state) {
case "connected":
this.setState({
status: VPN.connected,
host: msg.host
}) ;
break ;
case "disconnected":
this.setState({
status: VPN.disconnected
}) ;
break ;
case "connecting":
this.setState({
status: VPN.connecting,
country: msg.country,
host: null,
}) ;
break ;
case "disconnecting":
this.setState({
status: VPN.disconnecting,
}) ;
break ;
case "error":
this.setState({
status: VPN.error,
error_message: msg.message
}) ;
break ;
}
}
connect(geography) {
const country_info = geography.properties ;
// this.setState({
// status: VPN.connecting,
// country: country_info.NAME,
// host: null,
// }) ;
this.connection.send(JSON.stringify({
method: 'connect',
country: country_info.ISO_A2
})) ;
}
disconnect() {
// this.setState((prev) => ({ ...prev, status: VPN.disconnecting })) ;
this.connection.send(JSON.stringify({
method: 'disconnect'
})) ;
}
render() {
return (