Merge branch 'adamierymenko-dev' into android-jni

This commit is contained in:
Grant Limberg 2015-05-06 20:24:01 -07:00
commit 8130b2a0de
8 changed files with 2299 additions and 15970 deletions

File diff suppressed because one or more lines are too long

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
View 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">&nbsp;</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&nbsp;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&nbsp;Network</button>
</div>
);
}
});

View File

@ -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">&nbsp;&nbsp;
<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'}&nbsp;&nbsp;{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&nbsp;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}&nbsp;{this.ago(path.lastSend)}&nbsp;{this.ago(path.lastReceive)}{path.preferred ? ' *' : ''}</div>
);
} else {
return (
<div className="peerPathInactive">{path.address}&nbsp;{this.ago(path.lastSend)}&nbsp;{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>&nbsp;&nbsp;{this.state.online ? 'ONLINE' : 'OFFLINE'}&nbsp;&nbsp;{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>

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -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>

View File

@ -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;
}