mirror of
https://github.com/zerotier/ZeroTierOne.git
synced 2024-12-30 09:48:54 +00:00
Merge branch 'adamierymenko-dev' into android-jni
This commit is contained in:
commit
8130b2a0de
15919
ui/JSXTransformer.js
15919
ui/JSXTransformer.js
File diff suppressed because one or more lines are too long
1820
ui/JSXTransformer.min.js
vendored
Normal file
1820
ui/JSXTransformer.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
80
ui/ZeroTierNetwork.jsx
Normal file
80
ui/ZeroTierNetwork.jsx
Normal file
@ -0,0 +1,80 @@
|
||||
var ZeroTierNetwork = React.createClass({
|
||||
getInitialState: function() {
|
||||
return {
|
||||
deleted: false
|
||||
};
|
||||
},
|
||||
|
||||
leaveNetwork: function(event) {
|
||||
Ajax.call({
|
||||
url: 'network/'+this.props.nwid+'?auth='+this.props.authToken,
|
||||
cache: false,
|
||||
type: 'DELETE',
|
||||
success: function(data) {
|
||||
this.setState({deleted: true});
|
||||
}.bind(this),
|
||||
error: function(error) {
|
||||
}.bind(this)
|
||||
});
|
||||
event.preventDefault();
|
||||
},
|
||||
|
||||
render: function() {
|
||||
return (
|
||||
<div className="zeroTierNetwork">
|
||||
{
|
||||
(this.state.deleted) ? (
|
||||
<div className="deletedOverlay"> </div>
|
||||
) : (null)
|
||||
}
|
||||
<div className="networkInfo">
|
||||
<span className="networkId">{this.props.nwid}</span>
|
||||
<span className="networkName">{this.props.name}</span>
|
||||
</div>
|
||||
<div className="networkProps">
|
||||
<div className="row">
|
||||
<div className="name">Status</div>
|
||||
<div className="value">{this.props['status']}</div>
|
||||
</div>
|
||||
<div className="row">
|
||||
<div className="name">Type</div>
|
||||
<div className="value">{this.props['type']}</div>
|
||||
</div>
|
||||
<div className="row">
|
||||
<div className="name">MAC</div>
|
||||
<div className="value zeroTierAddress">{this.props['mac']}</div>
|
||||
</div>
|
||||
<div className="row">
|
||||
<div className="name">MTU</div>
|
||||
<div className="value">{this.props['mtu']}</div>
|
||||
</div>
|
||||
<div className="row">
|
||||
<div className="name">Broadcast</div>
|
||||
<div className="value">{(this.props['broadcastEnabled']) ? 'ENABLED' : 'DISABLED'}</div>
|
||||
</div>
|
||||
<div className="row">
|
||||
<div className="name">Bridging</div>
|
||||
<div className="value">{(this.props['bridge']) ? 'ACTIVE' : 'DISABLED'}</div>
|
||||
</div>
|
||||
<div className="row">
|
||||
<div className="name">Device</div>
|
||||
<div className="value">{(this.props['portDeviceName']) ? this.props['portDeviceName'] : '(none)'}</div>
|
||||
</div>
|
||||
<div className="row">
|
||||
<div className="name">Managed IPs</div>
|
||||
<div className="value ipList">
|
||||
{
|
||||
this.props['assignedAddresses'].map(function(ipAssignment) {
|
||||
return (
|
||||
<div className="ipAddress">{ipAssignment}</div>
|
||||
);
|
||||
})
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<button className="leaveNetworkButton" onClick={this.leaveNetwork}>Leave Network</button>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
});
|
@ -3,46 +3,185 @@ var ZeroTierNode = React.createClass({
|
||||
return {
|
||||
address: '----------',
|
||||
online: false,
|
||||
version: '_._._'
|
||||
version: '_._._',
|
||||
_networks: [],
|
||||
_peers: []
|
||||
};
|
||||
},
|
||||
|
||||
ago: function(ms) {
|
||||
if (ms > 0) {
|
||||
var tmp = Math.round((Date.now() - ms) / 1000);
|
||||
return ((tmp > 0) ? tmp : 0);
|
||||
} else return 0;
|
||||
},
|
||||
|
||||
updatePeers: function() {
|
||||
Ajax.call({
|
||||
url: 'peer?auth='+this.props.authToken,
|
||||
cache: false,
|
||||
type: 'GET',
|
||||
success: function(data) {
|
||||
if (data) {
|
||||
var pl = JSON.parse(data);
|
||||
if (Array.isArray(pl)) {
|
||||
this.setState({_peers: pl});
|
||||
}
|
||||
}
|
||||
}.bind(this),
|
||||
error: function() {
|
||||
}.bind(this)
|
||||
});
|
||||
},
|
||||
updateNetworks: function() {
|
||||
Ajax.call({
|
||||
url: 'network?auth='+this.props.authToken,
|
||||
cache: false,
|
||||
type: 'GET',
|
||||
success: function(data) {
|
||||
if (data) {
|
||||
var nwl = JSON.parse(data);
|
||||
if (Array.isArray(nwl)) {
|
||||
this.setState({_networks: nwl});
|
||||
}
|
||||
}
|
||||
}.bind(this),
|
||||
error: function() {
|
||||
}.bind(this)
|
||||
});
|
||||
},
|
||||
updateAll: function() {
|
||||
Ajax.call({
|
||||
url: 'status?auth='+this.props.authToken,
|
||||
cache: false,
|
||||
type: 'GET',
|
||||
success: function(data) {
|
||||
if (data)
|
||||
this.setState(JSON.parse(data));
|
||||
if (data) {
|
||||
var status = JSON.parse(data);
|
||||
this.setState(status);
|
||||
document.title = 'ZeroTier One [' + status.address + ']';
|
||||
}
|
||||
this.updateNetworks();
|
||||
this.updatePeers();
|
||||
}.bind(this),
|
||||
error: function() {
|
||||
this.setState(this.getInitialState());
|
||||
this.setState({online: false});
|
||||
}.bind(this)
|
||||
})
|
||||
});
|
||||
},
|
||||
joinNetwork: function(event) {
|
||||
event.preventDefault();
|
||||
if ((this.networkToJoin)&&(this.networkToJoin.length === 16)) {
|
||||
Ajax.call({
|
||||
url: 'network/'+this.networkToJoin+'?auth='+this.props.authToken,
|
||||
cache: false,
|
||||
type: 'POST',
|
||||
success: function(data) {
|
||||
}.bind(this),
|
||||
error: function() {
|
||||
}.bind(this)
|
||||
});
|
||||
}
|
||||
},
|
||||
handleNetworkIdEntry: function(event) {
|
||||
var nid = event.target.value;
|
||||
if (nid) {
|
||||
nid = nid.toLowerCase();
|
||||
var nnid = '';
|
||||
for(var i=0;((i<nid.length)&&(i<16));++i) {
|
||||
if ("0123456789abcdef".indexOf(nid.charAt(i)) >= 0)
|
||||
nnid += nid.charAt(i);
|
||||
}
|
||||
this.networkToJoin = nnid;
|
||||
event.target.value = nnid;
|
||||
} else {
|
||||
this.networkToJoin = '';
|
||||
event.target.value = '';
|
||||
}
|
||||
},
|
||||
|
||||
componentDidMount: function() {
|
||||
this.tabIndex = 0;
|
||||
this.updateAll();
|
||||
// this.updateIntervalId = setInterval(this.updateAll,2500);
|
||||
this.updateIntervalId = setInterval(this.updateAll,2500);
|
||||
},
|
||||
componentWillUnmount: function() {
|
||||
// clearInterval(this.updateIntervalId);
|
||||
clearInterval(this.updateIntervalId);
|
||||
},
|
||||
render: function() {
|
||||
return (
|
||||
<div className="container-fluid zeroTierNode">
|
||||
<div className="row">
|
||||
<div className="zeroTierNode">
|
||||
<div className="top">
|
||||
<button disabled={this.tabIndex === 0} onClick={function() {this.tabIndex = 0; this.forceUpdate();}.bind(this)}>Networks</button>
|
||||
<button disabled={this.tabIndex === 1} onClick={function() {this.tabIndex = 1; this.forceUpdate();}.bind(this)}>Peers</button>
|
||||
</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'} {this.state.version}</span>
|
||||
<div className="middle">
|
||||
<div className="middleScroll">
|
||||
{
|
||||
(this.tabIndex === 1) ? (
|
||||
<div className="peers">
|
||||
<div className="peerHeader">
|
||||
<div className="f">Address</div>
|
||||
<div className="f">Version</div>
|
||||
<div className="f">Latency</div>
|
||||
<div className="f">Direct Paths</div>
|
||||
<div className="f">Role</div>
|
||||
</div>
|
||||
{
|
||||
this.state._peers.map(function(peer) {
|
||||
return (
|
||||
<div className="peer">
|
||||
<div className="f zeroTierAddress">{peer['address']}</div>
|
||||
<div className="f">{(peer['version'] === '-1.-1.-1') ? '-' : peer['version']}</div>
|
||||
<div className="f">{peer['latency']}</div>
|
||||
<div className="f">
|
||||
{
|
||||
(peer['paths'].length === 0) ? (
|
||||
<div className="peerPath"><i>(none)</i></div>
|
||||
) : (
|
||||
<div>
|
||||
{
|
||||
peer['paths'].map(function(path) {
|
||||
if ((path.active)||(path.fixed)) {
|
||||
return (
|
||||
<div className="peerPath">{path.address} {this.ago(path.lastSend)} {this.ago(path.lastReceive)}{path.preferred ? ' *' : ''}</div>
|
||||
);
|
||||
} else {
|
||||
return (
|
||||
<div className="peerPathInactive">{path.address} {this.ago(path.lastSend)} {this.ago(path.lastReceive)}</div>
|
||||
);
|
||||
}
|
||||
}.bind(this))
|
||||
}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
</div>
|
||||
<div className="f">{peer['role']}</div>
|
||||
</div>
|
||||
);
|
||||
}.bind(this))
|
||||
}
|
||||
</div>
|
||||
) : (
|
||||
<div className="networks">
|
||||
{
|
||||
this.state._networks.map(function(network) {
|
||||
network['authToken'] = this.props.authToken;
|
||||
return React.createElement('div',{className: 'network'},React.createElement(ZeroTierNetwork,network));
|
||||
}.bind(this))
|
||||
}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
</div>
|
||||
<div className="col-xs-4">
|
||||
<form>
|
||||
<input type="text"/>
|
||||
</form>
|
||||
</div>
|
||||
<div className="bottom">
|
||||
<div className="left">
|
||||
<span className="statusLine"><span className="zeroTierAddress">{this.state.address}</span> {this.state.online ? 'ONLINE' : 'OFFLINE'} {this.state.version}</span>
|
||||
</div>
|
||||
<div className="right">
|
||||
<form onSubmit={this.joinNetwork}><input type="text" placeholder="################" onChange={this.handleNetworkIdEntry} size="16"/><button type="submit">Join</button></form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
5
ui/bootstrap-theme.min.css
vendored
5
ui/bootstrap-theme.min.css
vendored
File diff suppressed because one or more lines are too long
5
ui/bootstrap.min.css
vendored
5
ui/bootstrap.min.css
vendored
File diff suppressed because one or more lines are too long
@ -4,14 +4,17 @@
|
||||
<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 src="JSXTransformer.min.js"></script>
|
||||
|
||||
<script type="text/jsx" src="ZeroTierNetwork.jsx"></script>
|
||||
<script type="text/jsx" src="ZeroTierNode.jsx"></script>
|
||||
|
||||
<script type="text/jsx" src="main.jsx"></script>
|
||||
|
262
ui/zerotier.css
262
ui/zerotier.css
@ -3,37 +3,253 @@
|
||||
* 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%;
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.zerotier-address {
|
||||
.zeroTierAddress {
|
||||
font-family: monospace;
|
||||
}
|
||||
.zerotier-node-statusline {
|
||||
font-size: smaller;
|
||||
padding: 0 0.75rem 0 0.75rem;
|
||||
|
||||
.zeroTierNode {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
max-height: 100%;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
display: table;
|
||||
}
|
||||
|
||||
.zeroTierNode > .top {
|
||||
width: 100%;
|
||||
overflow: hidden;
|
||||
display: table-row;
|
||||
white-space: nowrap;
|
||||
background: #234447;
|
||||
color: #ffffff;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
||||
.zeroTierNode > .top button {
|
||||
display: inline-block;
|
||||
padding: 0.25rem 0.75rem 0.25rem 0.75rem;
|
||||
color: #ffffff;
|
||||
margin: 0;
|
||||
border: 0;
|
||||
outline: none;
|
||||
background: #234447;
|
||||
font-size: 12pt;
|
||||
cursor: pointer;
|
||||
}
|
||||
.zeroTierNode > .top button:hover {
|
||||
background: #91a2a3;
|
||||
}
|
||||
.zeroTierNode > .top button:disabled {
|
||||
background: #91a2a3;
|
||||
}
|
||||
|
||||
.zeroTierNode > .middle {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
overflow: hidden;
|
||||
display: table-row;
|
||||
}
|
||||
.zeroTierNode > .middle > .middleScroll {
|
||||
display: block;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
overflow-x: hidden;
|
||||
overflow-y: scroll;
|
||||
background: #eeeeee;
|
||||
}
|
||||
.zeroTierNode > .middle > .middleScroll > .networks {
|
||||
display: block;
|
||||
width: auto;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
border: 0;
|
||||
border-collapse: collapse;
|
||||
}
|
||||
.zeroTierNode > .middle > .middleScroll > .networks > .network {
|
||||
padding: 0.5rem;
|
||||
margin: 0.25rem;
|
||||
float: left;
|
||||
display: inline-block;
|
||||
border: 1px solid #234447;
|
||||
background: #ffffff;
|
||||
}
|
||||
.zeroTierNode > .middle > .middleScroll > .peers {
|
||||
display: table;
|
||||
width: 100%;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
border-collapse: collapse;
|
||||
}
|
||||
.zeroTierNode > .middle > .middleScroll > .peers > .peer {
|
||||
width: 100%;
|
||||
display: table-row;
|
||||
background: #ffffff;
|
||||
}
|
||||
.zeroTierNode > .middle > .middleScroll > .peers > .peer .peerPath {
|
||||
font-size: 10pt;
|
||||
font-family: monospace;
|
||||
white-space: nowrap;
|
||||
}
|
||||
.zeroTierNode > .middle > .middleScroll > .peers > .peer .peerPathInactive {
|
||||
font-size: 10pt;
|
||||
font-family: monospace;
|
||||
color: #bbbbbb;
|
||||
text-decoration: line-through;
|
||||
white-space: nowrap;
|
||||
}
|
||||
.zeroTierNode > .middle > .middleScroll > .peers > .peer > .f {
|
||||
display: table-cell;
|
||||
font-size: 10pt;
|
||||
}
|
||||
.zeroTierNode > .middle > .middleScroll > .peers > .peerHeader {
|
||||
width: 100%;
|
||||
display: table-row;
|
||||
background: #ffffff;
|
||||
border-bottom: 1px solid #000000;
|
||||
}
|
||||
.zeroTierNode > .middle > .middleScroll > .peers > .peerHeader > .f {
|
||||
display: table-cell;
|
||||
font-size: 10pt;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.zeroTierNode > .bottom {
|
||||
width: 100%;
|
||||
overflow: hidden;
|
||||
display: table-row;
|
||||
background: #234447;
|
||||
color: #ffffff;
|
||||
}
|
||||
.zeroTierNode > .bottom > .left {
|
||||
text-align: left;
|
||||
white-space: nowrap;
|
||||
float: left;
|
||||
padding: 0 0 0 0.5rem;
|
||||
}
|
||||
.zeroTierNode > .bottom > .left > .statusLine {
|
||||
font-family: monospace;
|
||||
white-space: nowrap;
|
||||
font-size: 12pt;
|
||||
}
|
||||
.zeroTierNode > .bottom > .right {
|
||||
background: #91a2a3;
|
||||
text-align: right;
|
||||
white-space: nowrap;
|
||||
float: right;
|
||||
}
|
||||
.zeroTierNode > .bottom > .right input {
|
||||
font-family: monospace;
|
||||
font-size: 12pt;
|
||||
background: #91a2a3;
|
||||
color: #ffffff;
|
||||
outline: none;
|
||||
border: 0;
|
||||
margin: 0;
|
||||
padding: 0.05rem 0.25rem 0.05rem 0.25rem;
|
||||
height: 100%;
|
||||
display: inline-block;
|
||||
}
|
||||
.zeroTierNode > .bottom > .right button {
|
||||
display: inline-block;
|
||||
font-size: 12pt;
|
||||
background: #ffb354;
|
||||
border: 1px solid #ffb354;
|
||||
color: #000000;
|
||||
margin: 0;
|
||||
padding: 0.05rem 0.75rem 0.05rem 0.75rem;
|
||||
height: 100%;
|
||||
}
|
||||
.zeroTierNode > .bottom > .right button:hover {
|
||||
cursor: pointer;
|
||||
border: 1px solid #000000;
|
||||
}
|
||||
|
||||
.zeroTierNetwork {
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
display: inline-block;
|
||||
text-align: right;
|
||||
width: 100%;
|
||||
position: relative;
|
||||
}
|
||||
.zeroTierNetwork .deletedOverlay {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
position: absolute;
|
||||
background: rgba(255,255,255,0.8);
|
||||
display: block;
|
||||
top: 0;
|
||||
left: 0;
|
||||
z-index: 2;
|
||||
}
|
||||
.zeroTierNetwork .networkInfo {
|
||||
padding: 0 0 0.5rem 0;
|
||||
text-align: left;
|
||||
font-size: 12pt;
|
||||
}
|
||||
.zeroTierNetwork .networkInfo .networkId {
|
||||
font-size: 10pt;
|
||||
font-family: monospace;
|
||||
color: #91a2a3;
|
||||
}
|
||||
.zeroTierNetwork .networkInfo .networkName {
|
||||
padding: 0 0 0 1rem;
|
||||
float: right;
|
||||
font-size: 12pt;
|
||||
}
|
||||
.zeroTierNetwork .networkProps {
|
||||
width: 100%;
|
||||
display: table;
|
||||
padding: 0;
|
||||
margin: 0 auto 0 auto;
|
||||
border-top: 1px solid #999999;
|
||||
border-bottom: 1px solid #999999;
|
||||
}
|
||||
.zeroTierNetwork .networkProps > .row {
|
||||
display: table-row;
|
||||
}
|
||||
.zeroTierNetwork .networkProps > .row > .name {
|
||||
display: table-cell;
|
||||
font-size: 10pt;
|
||||
padding: 0.1rem 0.5rem 0.1rem 0.5rem;
|
||||
}
|
||||
.zeroTierNetwork .networkProps > .row > .value {
|
||||
font-size: 10pt;
|
||||
display: table-cell;
|
||||
padding: 0.1rem 0.5rem 0.1rem 0.5rem;
|
||||
background: #eeeeee;
|
||||
}
|
||||
.zeroTierNetwork .ipList {
|
||||
}
|
||||
.zeroTierNetwork .ipAddress {
|
||||
font-family: monospace;
|
||||
font-size: 10pt;
|
||||
}
|
||||
.zeroTierNetwork .leaveNetworkButton {
|
||||
padding: 0.25rem 0.5rem 0.25rem 0.5rem;
|
||||
margin: 0.5rem 0 0 0;
|
||||
font-size: 10pt;
|
||||
background: #ffffff;
|
||||
outline: none;
|
||||
background: #ffb354;
|
||||
border: 1px solid #ffb354;
|
||||
cursor: pointer;
|
||||
}
|
||||
.zeroTierNetwork .leaveNetworkButton:hover {
|
||||
border: 1px solid #000000;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user