فهرست منبع

Beginning of HTML+Bootstrap+React UI for new desktop client -- looking like it will be easier than retrofitting the old Qt client for the new API.

Adam Ierymenko 10 سال پیش
والد
کامیت
b2b32e5969
12فایلهای تغییر یافته به همراه2777 افزوده شده و 31 حذف شده
  1. 32 29
      service/ControlPlane.cpp
  2. 2 1
      service/ControlPlane.hpp
  3. 1 1
      service/OneService.cpp
  4. 2606 0
      ui/JSXTransformer.js
  5. 51 0
      ui/ZeroTierNode.jsx
  6. 4 0
      ui/bootstrap-theme.min.css
  7. 4 0
      ui/bootstrap.min.css
  8. 22 0
      ui/index.html
  9. 4 0
      ui/main.jsx
  10. 11 0
      ui/react.min.js
  11. 1 0
      ui/simpleajax.min.js
  12. 39 0
      ui/zerotier.css

+ 32 - 29
service/ControlPlane.cpp

@@ -37,8 +37,7 @@
 #include "../node/InetAddress.hpp"
 #include "../node/Node.hpp"
 #include "../node/Utils.hpp"
-
-#define ZT_BUILD_IN_WEB_UI
+#include "../osdep/OSUtils.hpp"
 
 namespace ZeroTier {
 
@@ -242,9 +241,10 @@ static void _jsonAppend(unsigned int depth,std::string &buf,const ZT1_Peer *peer
 	buf.append(json);
 }
 
-ControlPlane::ControlPlane(OneService *svc,Node *n) :
+ControlPlane::ControlPlane(OneService *svc,Node *n,const char *uiStaticPath) :
 	_svc(svc),
-	_node(n)
+	_node(n),
+	_uiStaticPath((uiStaticPath) ? uiStaticPath : "")
 {
 }
 
@@ -316,31 +316,34 @@ unsigned int ControlPlane::handleRequest(
 			 * dot in the first path element (e.g. foo.html) is considered a static page,
 			 * as nothing in the API is so named. */
 
-#ifdef ZT_BUILD_IN_WEB_UI
-			if (ext == ".html")
-				responseContentType = "text/html";
-			else if (ext == ".js")
-				responseContentType = "application/javascript";
-			else if (ext == ".json")
-				responseContentType = "application/json";
-			else if (ext == ".css")
-				responseContentType = "text/css";
-			else if (ext == ".png")
-				responseContentType = "image/png";
-			else if (ext == ".jpg")
-				responseContentType = "image/jpeg";
-			else if (ext == ".gif")
-				responseContentType = "image/gif";
-			else if (ext == ".txt")
-				responseContentType = "text/plain";
-			else if (ext == ".xml")
-				responseContentType = "text/xml";
-			else if (ext == ".svg")
-				responseContentType = "image/svg+xml";
-			else responseContentType = "application/octet-stream";
-			responseBody = "<html><body>Hello World!</body></html>";
-			scode = 200;
-#endif // ZT_BUILD_IN_WEB_UI
+			if (_uiStaticPath.length() > 0) {
+				if (ext == ".html")
+					responseContentType = "text/html";
+				else if (ext == ".js")
+					responseContentType = "application/javascript";
+				else if (ext == ".jsx")
+					responseContentType = "text/jsx";
+				else if (ext == ".json")
+					responseContentType = "application/json";
+				else if (ext == ".css")
+					responseContentType = "text/css";
+				else if (ext == ".png")
+					responseContentType = "image/png";
+				else if (ext == ".jpg")
+					responseContentType = "image/jpeg";
+				else if (ext == ".gif")
+					responseContentType = "image/gif";
+				else if (ext == ".txt")
+					responseContentType = "text/plain";
+				else if (ext == ".xml")
+					responseContentType = "text/xml";
+				else if (ext == ".svg")
+					responseContentType = "image/svg+xml";
+				else responseContentType = "application/octet-stream";
+				scode = OSUtils::readFile((_uiStaticPath + ZT_PATH_SEPARATOR_S + ps[0]).c_str(),responseBody) ? 200 : 404;
+			} else {
+				scode = 404;
+			}
 
 		} else if (isAuth) {
 			/* Things that require authentication -- a.k.a. everything but static web app pages. */

+ 2 - 1
service/ControlPlane.hpp

@@ -49,7 +49,7 @@ struct InetAddress;
 class ControlPlane
 {
 public:
-	ControlPlane(OneService *svc,Node *n);
+	ControlPlane(OneService *svc,Node *n,const char *uiStaticPath);
 	~ControlPlane();
 
 	/**
@@ -102,6 +102,7 @@ public:
 private:
 	OneService *const _svc;
 	Node *const _node;
+	std::string _uiStaticPath;
 	std::set<std::string> _authTokens;
 	std::map<std::string,ControlPlaneSubsystem *> _subsystems;
 	Mutex _lock;

+ 1 - 1
service/OneService.cpp

@@ -226,7 +226,7 @@ public:
 			if (_master)
 				_node->setNetconfMaster((void *)_master);
 
-			_controlPlane = new ControlPlane(this,_node);
+			_controlPlane = new ControlPlane(this,_node,(_homePath + ZT_PATH_SEPARATOR_S + "ui").c_str());
 			_controlPlane->addAuthToken(authToken.c_str());
 			if (_master)
 				_controlPlane->mount("controller",reinterpret_cast<ControlPlaneSubsystem *>(_master));

تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 2606 - 0
ui/JSXTransformer.js


+ 51 - 0
ui/ZeroTierNode.jsx

@@ -0,0 +1,51 @@
+var ZeroTierNode = React.createClass({
+	getInitialState: function() {
+		return {
+			address: '----------',
+			online: false,
+			version: '_._._'
+		};
+	},
+
+	updateAll: function() {
+		Ajax.call({
+			url: 'status?auth='+this.props.authToken,
+			cache: false,
+			type: 'GET',
+			success: function(data) {
+				if (data)
+					this.setState(JSON.parse(data));
+			}.bind(this),
+			error: function() {
+				this.setState(this.getInitialState());
+			}.bind(this)
+		})
+	},
+
+	componentDidMount: function() {
+		this.updateAll();
+//		this.updateIntervalId = setInterval(this.updateAll,2500);
+	},
+	componentWillUnmount: function() {
+//		clearInterval(this.updateIntervalId);
+	},
+	render: function() {
+		return (
+			<div className="container-fluid zeroTierNode">
+				<div className="row">
+				</div>
+				<div className="row">
+					<div className="col-xs-8">
+						<span className="zerotier-address">{this.state.address}</span>
+						<span className="zerotier-node-statusline">{this.state.online ? 'ONLINE' : 'OFFLINE'}&nbsp;&nbsp;{this.state.version}</span>
+					</div>
+					<div className="col-xs-4">
+						<form>
+							<input type="text"/>
+						</form>
+					</div>
+				</div>
+			</div>
+		);
+	}
+});

تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 4 - 0
ui/bootstrap-theme.min.css


تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 4 - 0
ui/bootstrap.min.css


+ 22 - 0
ui/index.html

@@ -0,0 +1,22 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+	<title>ZeroTier One</title>
+	<meta http-equiv="X-UA-Compatible" content="IE=edge"/>
+	<meta name="viewport" content="width=device-width, initial-scale=1">
+	<link rel="stylesheet" href="bootstrap.min.css">
+	<link rel="stylesheet" href="bootstrap-theme.min.css">
+	<link rel="stylesheet" href="zerotier.css">
+
+	<script src="simpleajax.min.js"></script>
+	<script src="react.min.js"></script>
+	<script src="JSXTransformer.js"></script>
+
+	<script type="text/jsx" src="ZeroTierNode.jsx"></script>
+
+	<script type="text/jsx" src="main.jsx"></script>
+</head>
+<body>
+<div style="width: 100%; height: 100%;" id="main"></div>
+</body>
+</html>

+ 4 - 0
ui/main.jsx

@@ -0,0 +1,4 @@
+React.render(
+	<ZeroTierNode authToken={'5d6181b71fae2684f9cc64ed'} />,
+	document.getElementById('main')
+);

تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 11 - 0
ui/react.min.js


تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 1 - 0
ui/simpleajax.min.js


+ 39 - 0
ui/zerotier.css

@@ -0,0 +1,39 @@
+/* Dark blue-grey: #234447
+ * Light blue-grey: #91a2a3
+ * Light yellow: #ffffcc
+ * Orange: #ffb354 */
+
+/*
+@font-face {
+	font-family: 'Clear Sans Thin';
+	src: url('fonts/clearsans_thin/ClearSans-Thin-webfont.eot');
+	src: url('fonts/clearsans_thin/ClearSans-Thin-webfont.eot?#iefix') format('embedded-opentype'), url('fonts/clearsans_thin/ClearSans-Thin-webfont.woff') format('woff'), url('fonts/clearsans_thin/ClearSans-Thin-webfont.ttf') format('truetype'), url('fonts/clearsans_thin/ClearSans-Thin-webfont.svg#clear_sans_thinregular') format('svg');
+	font-weight: normal;
+	font-style: normal;
+}
+*/
+/*
+@font-face {
+	font-family: 'Clear Sans Regular';
+	src: url('ClearSans-Regular-webfont.eot');
+	src: url('ClearSans-Regular-webfont.eot?#iefix') format('embedded-opentype'), url('ClearSans-Regular-webfont.woff') format('woff'), url('ClearSans-Regular-webfont.ttf') format('truetype'), url('ClearSans-Regular-webfont.svg#clear_sansregular') format('svg');
+	font-weight: normal;
+	font-style: normal;
+}
+*/
+
+html,body {
+	font-family: "Helvetica Neue","Lucida Sans Unicode",sans-serif;
+	font-size: 12pt;
+	margin: 0;
+	padding: 0;
+	width: 100%;
+}
+
+.zerotier-address {
+	font-family: monospace;
+}
+.zerotier-node-statusline {
+	font-size: smaller;
+	padding: 0 0.75rem 0 0.75rem;
+}

برخی فایل ها در این مقایسه diff نمایش داده نمی شوند زیرا تعداد فایل ها بسیار زیاد است