diff --git a/cmd/server_amd64.go b/cmd/server_amd64.go index 50dc5b25a..e467a0295 100644 --- a/cmd/server_amd64.go +++ b/cmd/server_amd64.go @@ -195,7 +195,7 @@ func init() { } } - s, e := backend.MakeAPIServer(kos, *options.horizonTestnetURI, apiTestNet, *options.horizonPubnetURI, apiPubNet, *rootCcxtRestURL, *options.noHeaders) + s, e := backend.MakeAPIServer(kos, *options.horizonTestnetURI, apiTestNet, *options.horizonPubnetURI, apiPubNet, *rootCcxtRestURL, *options.noHeaders, quit) if e != nil { panic(e) } diff --git a/gui/backend/api_server.go b/gui/backend/api_server.go index 34d6c7595..c4e94febb 100644 --- a/gui/backend/api_server.go +++ b/gui/backend/api_server.go @@ -26,6 +26,7 @@ type APIServer struct { apiTestNet *horizonclient.Client apiPubNet *horizonclient.Client noHeaders bool + quitFn func() cachedOptionsMetadata metadata } @@ -39,6 +40,7 @@ func MakeAPIServer( apiPubNet *horizonclient.Client, ccxtRestUrl string, noHeaders bool, + quitFn func(), ) (*APIServer, error) { binPath, e := filepath.Abs(os.Args[0]) if e != nil { @@ -67,6 +69,7 @@ func MakeAPIServer( apiPubNet: apiPubNet, noHeaders: noHeaders, cachedOptionsMetadata: optionsMetadata, + quitFn: quitFn, }, nil } diff --git a/gui/backend/quit.go b/gui/backend/quit.go new file mode 100644 index 000000000..bbba96d65 --- /dev/null +++ b/gui/backend/quit.go @@ -0,0 +1,15 @@ +package backend + +import ( + "net/http" + "time" +) + +func (s *APIServer) quit(w http.ResponseWriter, r *http.Request) { + go func() { + // sleep so we can respond to the request + time.Sleep(1 * time.Second) + s.quitFn() + }() + w.WriteHeader(http.StatusOK) +} diff --git a/gui/backend/routes.go b/gui/backend/routes.go index 564744d8a..cfdb7d0e8 100644 --- a/gui/backend/routes.go +++ b/gui/backend/routes.go @@ -10,6 +10,7 @@ import ( func SetRoutes(r *chi.Mux, s *APIServer) { r.Route("/api/v1", func(r chi.Router) { r.Get("/version", http.HandlerFunc(s.version)) + r.Get("/quit", http.HandlerFunc(s.quit)) r.Get("/listBots", http.HandlerFunc(s.listBots)) r.Get("/autogenerate", http.HandlerFunc(s.autogenerateBot)) r.Get("/genBotName", http.HandlerFunc(s.generateBotName)) diff --git a/gui/web/src/App.js b/gui/web/src/App.js index ced84a02e..b7de76707 100644 --- a/gui/web/src/App.js +++ b/gui/web/src/App.js @@ -2,14 +2,15 @@ import React, { Component } from 'react'; import { BrowserRouter as Router, Route } from "react-router-dom"; import styles from './App.module.scss'; import Header from './components/molecules/Header/Header'; +import Button from './components/atoms/Button/Button'; import Bots from './components/screens/Bots/Bots'; import NewBot from './components/screens/NewBot/NewBot'; +import version from './kelp-ops-api/version'; +import quit from './kelp-ops-api/quit'; // import Welcome from './components/molecules/Welcome/Welcome'; // import Modal from './components/molecules/Modal/Modal'; -import version from './kelp-ops-api/version'; - -let baseUrl = function() { +let baseUrl = function () { let origin = window.location.origin if (process.env.REACT_APP_API_PORT) { let parts = origin.split(":") @@ -26,6 +27,7 @@ class App extends Component { }; this.setVersion = this.setVersion.bind(this); + this.quit = this.quit.bind(this); this._asyncRequests = {}; } @@ -43,13 +45,28 @@ class App extends Component { delete _this._asyncRequests["version"]; if (!resp.includes("error")) { - _this.setState({version: resp}); + _this.setState({ version: resp }); } else { setTimeout(_this.setVersion, 30000); } }); } + quit() { + var _this = this + this._asyncRequests["quit"] = quit(baseUrl).then(resp => { + if (!_this._asyncRequests["quit"]) { + // if it has been deleted it means we don't want to process the result + return + } + delete _this._asyncRequests["quit"]; + + if (resp.status === 200) { + window.close(); + } + }); + } + componentWillUnmount() { if (this._asyncRequests["version"]) { delete this._asyncRequests["version"]; @@ -57,7 +74,16 @@ class App extends Component { } render() { - let banner = (
Kelp UI is only available on the Stellar Test Network
); + let banner = (
+ + Kelp UI is only available on the Stellar Test Network +
); return (
diff --git a/gui/web/src/App.module.scss b/gui/web/src/App.module.scss index 3c2f2d865..a45d271ef 100644 --- a/gui/web/src/App.module.scss +++ b/gui/web/src/App.module.scss @@ -6,4 +6,12 @@ text-align: center; vertical-align: middle; color: $color-contrast-2; +} + +.quit { + height: 8px; + background-color: $color-primary; + vertical-align: middle; + color: $color-danger; + float: left; } \ No newline at end of file diff --git a/gui/web/src/kelp-ops-api/quit.js b/gui/web/src/kelp-ops-api/quit.js new file mode 100644 index 000000000..8ce3a5d8f --- /dev/null +++ b/gui/web/src/kelp-ops-api/quit.js @@ -0,0 +1,3 @@ +export default (baseUrl) => { + return fetch(baseUrl + "/api/v1/quit"); +}; \ No newline at end of file