commit
e5fc76f170
14
app.js
14
app.js
@ -34,13 +34,15 @@ api.on('connection', function(spark) {
|
|||||||
console.log(spark.address);
|
console.log(spark.address);
|
||||||
console.log(spark.query);
|
console.log(spark.query);
|
||||||
|
|
||||||
spark.on('hello', function(data) {
|
spark.on('hello', function(data)
|
||||||
|
{
|
||||||
console.log('got hello data from ', spark.id);
|
console.log('got hello data from ', spark.id);
|
||||||
console.log(data);
|
console.log(data);
|
||||||
|
|
||||||
if(typeof data.id !== 'undefined' && typeof data.info !== 'undefined')
|
if(typeof data.id !== 'undefined' && typeof data.info !== 'undefined')
|
||||||
{
|
{
|
||||||
data.ip = spark.address.ip;
|
data.ip = spark.address.ip;
|
||||||
|
data.spark = spark.id;
|
||||||
|
|
||||||
var info = Nodes.add(data);
|
var info = Nodes.add(data);
|
||||||
spark.emit('ready');
|
spark.emit('ready');
|
||||||
@ -49,7 +51,8 @@ api.on('connection', function(spark) {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
spark.on('update', function(data) {
|
spark.on('update', function(data)
|
||||||
|
{
|
||||||
console.log('got update from ' + spark.id);
|
console.log('got update from ' + spark.id);
|
||||||
console.log(data);
|
console.log(data);
|
||||||
|
|
||||||
@ -61,8 +64,11 @@ api.on('connection', function(spark) {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
spark.on('end', function(data) {
|
spark.on('end', function(data)
|
||||||
//
|
{
|
||||||
|
var stats = Nodes.inactive(spark.id);
|
||||||
|
|
||||||
|
client.write({action: 'inactive', data: stats});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -28,6 +28,18 @@ Collection.prototype.update = function(id, stats)
|
|||||||
return node.getStats();
|
return node.getStats();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Collection.prototype.inactive = function(id)
|
||||||
|
{
|
||||||
|
var node = this.getNode({ spark: id });
|
||||||
|
|
||||||
|
if(!node)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
node.stats.active = false;
|
||||||
|
|
||||||
|
return node.getStats();
|
||||||
|
}
|
||||||
|
|
||||||
Collection.prototype.getIndex = function(search)
|
Collection.prototype.getIndex = function(search)
|
||||||
{
|
{
|
||||||
return _.findIndex(this._list, search);
|
return _.findIndex(this._list, search);
|
||||||
|
@ -36,6 +36,9 @@ var Node = function Node(data)
|
|||||||
this.setGeo(data.ip);
|
this.setGeo(data.ip);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(typeof data.spark !== 'undefined')
|
||||||
|
this.spark = data.spark;
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -53,6 +56,9 @@ Node.prototype.setInfo = function(data)
|
|||||||
this.info.ip = data.ip;
|
this.info.ip = data.ip;
|
||||||
this.setGeo(data.ip);
|
this.setGeo(data.ip);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(typeof data.spark !== 'undefined')
|
||||||
|
this.spark = data.spark;
|
||||||
}
|
}
|
||||||
|
|
||||||
Node.prototype.getInfo = function()
|
Node.prototype.getInfo = function()
|
||||||
|
20
public/css/minimal-icons-codes.css
Normal file
20
public/css/minimal-icons-codes.css
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
|
||||||
|
.icon-truck:before { content: '\e800'; } /* '' */
|
||||||
|
.icon-database:before { content: '\e801'; } /* '' */
|
||||||
|
.icon-mining:before { content: '\e802'; } /* '' */
|
||||||
|
.icon-check:before { content: '\e803'; } /* '' */
|
||||||
|
.icon-cancel:before { content: '\e804'; } /* '' */
|
||||||
|
.icon-loader:before { content: '\e805'; } /* '' */
|
||||||
|
.icon-check-o:before { content: '\e806'; } /* '' */
|
||||||
|
.icon-cancel-o:before { content: '\e807'; } /* '' */
|
||||||
|
.icon-warning-o:before { content: '\e808'; } /* '' */
|
||||||
|
.icon-network:before { content: '\e809'; } /* '' */
|
||||||
|
.icon-block:before { content: '\e80a'; } /* '' */
|
||||||
|
.icon-bulb:before { content: '\e80b'; } /* '' */
|
||||||
|
.icon-node:before { content: '\e80c'; } /* '' */
|
||||||
|
.icon-laptop:before { content: '\e80d'; } /* '' */
|
||||||
|
.icon-time:before { content: '\e80e'; } /* '' */
|
||||||
|
.icon-clock:before { content: '\e80f'; } /* '' */
|
||||||
|
.icon-group:before { content: '\e810'; } /* '' */
|
||||||
|
.icon-gas:before { content: '\e811'; } /* '' */
|
||||||
|
.icon-difficulty:before { content: '\e812'; } /* '' */
|
73
public/css/minimal-icons-embedded.css
Normal file
73
public/css/minimal-icons-embedded.css
Normal file
File diff suppressed because one or more lines are too long
20
public/css/minimal-icons-ie7-codes.css
Normal file
20
public/css/minimal-icons-ie7-codes.css
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
|
||||||
|
.icon-truck { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
|
||||||
|
.icon-database { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
|
||||||
|
.icon-mining { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
|
||||||
|
.icon-check { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
|
||||||
|
.icon-cancel { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
|
||||||
|
.icon-loader { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
|
||||||
|
.icon-check-o { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
|
||||||
|
.icon-cancel-o { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
|
||||||
|
.icon-warning-o { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
|
||||||
|
.icon-network { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
|
||||||
|
.icon-block { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
|
||||||
|
.icon-bulb { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
|
||||||
|
.icon-node { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
|
||||||
|
.icon-laptop { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
|
||||||
|
.icon-time { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
|
||||||
|
.icon-clock { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
|
||||||
|
.icon-group { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
|
||||||
|
.icon-gas { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
|
||||||
|
.icon-difficulty { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
|
@ -27,3 +27,5 @@
|
|||||||
.icon-time { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
|
.icon-time { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
|
||||||
.icon-clock { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
|
.icon-clock { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
|
||||||
.icon-group { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
|
.icon-group { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
|
||||||
|
.icon-gas { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
|
||||||
|
.icon-difficulty { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
|
@ -1,10 +1,10 @@
|
|||||||
@font-face {
|
@font-face {
|
||||||
font-family: 'minimal-icons';
|
font-family: 'minimal-icons';
|
||||||
src: url('../fonts/minimal-icons.eot?18158983');
|
src: url('../fonts/minimal-icons.eot?55431205');
|
||||||
src: url('../fonts/minimal-icons.eot?18158983#iefix') format('embedded-opentype'),
|
src: url('../fonts/minimal-icons.eot?55431205#iefix') format('embedded-opentype'),
|
||||||
url('../fonts/minimal-icons.woff?18158983') format('woff'),
|
url('../fonts/minimal-icons.woff?55431205') format('woff'),
|
||||||
url('../fonts/minimal-icons.ttf?18158983') format('truetype'),
|
url('../fonts/minimal-icons.ttf?55431205') format('truetype'),
|
||||||
url('../fonts/minimal-icons.svg?18158983#minimal-icons') format('svg');
|
url('../fonts/minimal-icons.svg?55431205#minimal-icons') format('svg');
|
||||||
font-weight: normal;
|
font-weight: normal;
|
||||||
font-style: normal;
|
font-style: normal;
|
||||||
}
|
}
|
||||||
@ -14,7 +14,7 @@
|
|||||||
@media screen and (-webkit-min-device-pixel-ratio:0) {
|
@media screen and (-webkit-min-device-pixel-ratio:0) {
|
||||||
@font-face {
|
@font-face {
|
||||||
font-family: 'minimal-icons';
|
font-family: 'minimal-icons';
|
||||||
src: url('../fonts/minimal-icons.svg?18158983#minimal-icons') format('svg');
|
src: url('../fonts/minimal-icons.svg?55431205#minimal-icons') format('svg');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
@ -67,3 +67,5 @@
|
|||||||
.icon-time:before { content: '\e80e'; } /* '' */
|
.icon-time:before { content: '\e80e'; } /* '' */
|
||||||
.icon-clock:before { content: '\e80f'; } /* '' */
|
.icon-clock:before { content: '\e80f'; } /* '' */
|
||||||
.icon-group:before { content: '\e810'; } /* '' */
|
.icon-group:before { content: '\e810'; } /* '' */
|
||||||
|
.icon-gas:before { content: '\e811'; } /* '' */
|
||||||
|
.icon-difficulty:before { content: '\e812'; } /* '' */
|
Binary file not shown.
@ -1,7 +1,7 @@
|
|||||||
<?xml version="1.0" standalone="no"?>
|
<?xml version="1.0" standalone="no"?>
|
||||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||||
<svg xmlns="http://www.w3.org/2000/svg">
|
<svg xmlns="http://www.w3.org/2000/svg">
|
||||||
<metadata>Copyright (C) 2014 by original authors @ fontello.com</metadata>
|
<metadata>Copyright (C) 2015 by original authors @ fontello.com</metadata>
|
||||||
<defs>
|
<defs>
|
||||||
<font id="minimal-icons" horiz-adv-x="1000" >
|
<font id="minimal-icons" horiz-adv-x="1000" >
|
||||||
<font-face font-family="minimal-icons" font-weight="400" font-stretch="normal" units-per-em="1000" ascent="1000" descent="0" />
|
<font-face font-family="minimal-icons" font-weight="400" font-stretch="normal" units-per-em="1000" ascent="1000" descent="0" />
|
||||||
@ -23,6 +23,8 @@
|
|||||||
<glyph glyph-name="time" unicode="" d="m823 968h-646v-30h52c-14-76-42-354 266-452 300-96 257-367 244-425h-479c-6 33-23 137 19 236l-28 12c-43-103-30-206-22-248h-52v-30h646v30h-54c14 75 45 355-265 454-297 94-257 363-244 423h479c12-57 50-305-206-409l12-28c264 108 238 364 225 437h53v30z" horiz-adv-x="1000" />
|
<glyph glyph-name="time" unicode="" d="m823 968h-646v-30h52c-14-76-42-354 266-452 300-96 257-367 244-425h-479c-6 33-23 137 19 236l-28 12c-43-103-30-206-22-248h-52v-30h646v30h-54c14 75 45 355-265 454-297 94-257 363-244 423h479c12-57 50-305-206-409l12-28c264 108 238 364 225 437h53v30z" horiz-adv-x="1000" />
|
||||||
<glyph glyph-name="clock" unicode="" d="m501 484h-307v31h291v161h32v-180l-6-12-10 0z m483 16c0 267-217 484-484 484-39 0-78-4-116-14l8-30c35 9 71 13 108 13 250 0 453-203 453-453s-203-453-453-453-453 203-453 453c0 53 9 106 27 155l-29 11c-20-53-29-109-29-166 0-267 217-484 484-484 267 0 484 217 484 484z m-53 401c-2 21-12 40-28 54-17 14-37 21-58 19-21-1-40-11-54-27l24-20c8 10 19 15 32 16 13 1 25-3 36-12 10-8 16-20 17-33 1-12-2-24-10-34l23-20c14 16 20 36 18 57z m-415 31h-31v-61h31v61z m0-806h-31v-61h31v61z m418 388h-61v-31h61v31z m-806 0h-61v-31h61v31z" horiz-adv-x="1000" />
|
<glyph glyph-name="clock" unicode="" d="m501 484h-307v31h291v161h32v-180l-6-12-10 0z m483 16c0 267-217 484-484 484-39 0-78-4-116-14l8-30c35 9 71 13 108 13 250 0 453-203 453-453s-203-453-453-453-453 203-453 453c0 53 9 106 27 155l-29 11c-20-53-29-109-29-166 0-267 217-484 484-484 267 0 484 217 484 484z m-53 401c-2 21-12 40-28 54-17 14-37 21-58 19-21-1-40-11-54-27l24-20c8 10 19 15 32 16 13 1 25-3 36-12 10-8 16-20 17-33 1-12-2-24-10-34l23-20c14 16 20 36 18 57z m-415 31h-31v-61h31v61z m0-806h-31v-61h31v61z m418 388h-61v-31h61v31z m-806 0h-61v-31h61v31z" horiz-adv-x="1000" />
|
||||||
<glyph glyph-name="group" unicode="" d="m500 429c-58 0-105 48-105 106 0 59 47 107 105 107 58 0 106-48 106-107 0-58-48-106-106-106z m0 181c-40 0-74-33-74-75s34-75 74-75c41 0 74 34 74 75s-33 75-74 75z m243-356h-31c0 63-97 115-211 115-115 0-212-52-212-115h-31c0 82 107 147 243 147 136 0 242-65 242-147z m-544 327c-50 0-91 41-91 90 0 50 41 91 91 91 50 0 91-41 91-91 0-49-41-90-91-90z m0 149c-33 0-60-26-60-59 0-32 27-59 60-59 33 0 60 27 60 59 0 33-27 59-60 59z m181-309h-32c0 57-63 99-150 99-88 0-151-42-151-99h-31c0 75 76 130 182 130 105 0 182-55 182-130z m422 158c-50 0-90 41-90 91 0 50 40 91 90 91s91-41 91-91c0-50-41-91-91-91z m0 151c-32 0-59-27-59-60 0-33 27-59 59-59s60 26 60 59c0 33-27 60-60 60z m182-309h-31c0 58-63 100-150 100-88 0-151-42-151-100h-31c0 76 76 131 182 131 105 0 181-55 181-131z" horiz-adv-x="1000" />
|
<glyph glyph-name="group" unicode="" d="m500 429c-58 0-105 48-105 106 0 59 47 107 105 107 58 0 106-48 106-107 0-58-48-106-106-106z m0 181c-40 0-74-33-74-75s34-75 74-75c41 0 74 34 74 75s-33 75-74 75z m243-356h-31c0 63-97 115-211 115-115 0-212-52-212-115h-31c0 82 107 147 243 147 136 0 242-65 242-147z m-544 327c-50 0-91 41-91 90 0 50 41 91 91 91 50 0 91-41 91-91 0-49-41-90-91-90z m0 149c-33 0-60-26-60-59 0-32 27-59 60-59 33 0 60 27 60 59 0 33-27 59-60 59z m181-309h-32c0 57-63 99-150 99-88 0-151-42-151-99h-31c0 75 76 130 182 130 105 0 182-55 182-130z m422 158c-50 0-90 41-90 91 0 50 40 91 90 91s91-41 91-91c0-50-41-91-91-91z m0 151c-32 0-59-27-59-60 0-33 27-59 59-59s60 26 60 59c0 33-27 60-60 60z m182-309h-31c0 58-63 100-150 100-88 0-151-42-151-100h-31c0 76 76 131 182 131 105 0 181-55 181-131z" horiz-adv-x="1000" />
|
||||||
|
<glyph glyph-name="gas" unicode="" d="m500 16c-267 0-484 217-484 484 0 103 32 202 93 285l25-19c-57-77-86-169-86-266 0-250 203-453 452-453 250 0 452 203 452 453 0 250-202 453-452 453-79 0-156-20-224-59l-15 27c72 41 155 63 239 63 267 0 484-217 484-484 0-267-217-484-484-484z m280 453l-13 28 66 28c-6 179-153 322-333 322-183 0-333-149-333-332h-31c0 201 163 364 364 364 201 0 364-163 364-364v-10l-84-36z m-280-270v31c25 0 45 20 45 44 0 44-24 259-45 309-21-50-45-265-45-309h-31c0 18 7 102 18 181 21 154 40 167 58 167 19 0 37-13 58-167 11-79 18-163 18-181 0-41-34-75-76-75z" horiz-adv-x="1000" />
|
||||||
|
<glyph glyph-name="difficulty" unicode="" d="m498 21c-9 0-17 3-23 9l-450 450c-12 13-12 33 0 45l140 140c-23 6-43 17-60 34-24 24-38 57-38 92s14 67 38 92c25 25 57 38 92 38s68-13 92-38c25-25 39-58 38-93l-31 0c0 27-10 52-29 71-19 19-43 29-70 29-26 0-51-11-70-29-18-19-29-44-29-70 0-26 11-51 29-70 19-19 45-30 71-29l39 0-190-189 450-451 452 450-140 141c-6-23-17-43-34-60-25-24-57-38-92-38s-67 14-92 38c-25 25-38 57-38 92 0 35 13 68 38 92 17 17 37 29 60 34l-153 152-30-29-22 22 29 29c13 13 33 13 46 0l201-201-38 0c-27 1-52-10-71-29-19-19-29-43-29-70s10-51 29-70c19-18 44-29 70-29s51 11 70 29c19 19 29 44 29 71l-1 39 190-190c6-6 9-14 9-22s-3-17-9-23l-450-450c-6-6-15-9-23-9z" horiz-adv-x="1000" />
|
||||||
</font>
|
</font>
|
||||||
</defs>
|
</defs>
|
||||||
</svg>
|
</svg>
|
Before Width: | Height: | Size: 10 KiB After Width: | Height: | Size: 12 KiB |
Binary file not shown.
Binary file not shown.
@ -11,7 +11,9 @@ function StatsCtrl($scope, $filter, socket, _, toastr) {
|
|||||||
$scope.nodesActive = 0;
|
$scope.nodesActive = 0;
|
||||||
$scope.bestBlock = 0;
|
$scope.bestBlock = 0;
|
||||||
$scope.lastBlock = 0;
|
$scope.lastBlock = 0;
|
||||||
|
$scope.lastDifficulty = 0;
|
||||||
$scope.upTimeTotal = 0;
|
$scope.upTimeTotal = 0;
|
||||||
|
$scope.avgBlockTime = 0;
|
||||||
|
|
||||||
$scope.nodes = [];
|
$scope.nodes = [];
|
||||||
$scope.map = [];
|
$scope.map = [];
|
||||||
@ -69,6 +71,11 @@ function StatsCtrl($scope, $filter, socket, _, toastr) {
|
|||||||
case "info":
|
case "info":
|
||||||
$scope.nodes[findIndex({id: data.id})].info = data.info;
|
$scope.nodes[findIndex({id: data.id})].info = data.info;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case "inactive":
|
||||||
|
$scope.nodes[findIndex({id: data.id})].stats = data.stats;
|
||||||
|
toastr['error']("Node went away!", "Node connection was lost!");
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
updateStats();
|
updateStats();
|
||||||
@ -112,6 +119,14 @@ function StatsCtrl($scope, $filter, socket, _, toastr) {
|
|||||||
return parseInt(node.stats.block.timestamp);
|
return parseInt(node.stats.block.timestamp);
|
||||||
}).stats.block.timestamp;
|
}).stats.block.timestamp;
|
||||||
|
|
||||||
|
$scope.lastDifficulty = _.max($scope.nodes, function(node) {
|
||||||
|
return parseInt(node.stats.block.timestamp);
|
||||||
|
}).stats.block.difficulty;
|
||||||
|
|
||||||
|
$scope.avgBlockTime = _.max($scope.nodes, function(node) {
|
||||||
|
return parseInt(node.stats.block.timestamp);
|
||||||
|
}).stats.blocktimeAvg;
|
||||||
|
|
||||||
$scope.upTimeTotal = _.reduce($scope.nodes, function(total, node) {
|
$scope.upTimeTotal = _.reduce($scope.nodes, function(total, node) {
|
||||||
return total + node.stats.uptime;
|
return total + node.stats.uptime;
|
||||||
}, 0) / $scope.nodes.length;
|
}, 0) / $scope.nodes.length;
|
||||||
|
@ -44,7 +44,9 @@ angular.module('netStatsApp.filters', [])
|
|||||||
version = version.replace('eth version ', 'v')
|
version = version.replace('eth version ', 'v')
|
||||||
.replace("\n" + 'Network protocol version: ', ' (')
|
.replace("\n" + 'Network protocol version: ', ' (')
|
||||||
.replace("\n" + 'Client database version: ', ',')
|
.replace("\n" + 'Client database version: ', ',')
|
||||||
.replace("\n" + 'Build: ', ')<br>');
|
.replace("\n" + 'Build: ', ') - ')
|
||||||
|
.replace('/Debug', '')
|
||||||
|
.replace('/.', '');
|
||||||
return $sce.trustAsHtml(version);
|
return $sce.trustAsHtml(version);
|
||||||
};
|
};
|
||||||
})
|
})
|
||||||
@ -63,6 +65,32 @@ angular.module('netStatsApp.filters', [])
|
|||||||
return timeClass(timestamp);
|
return timeClass(timestamp);
|
||||||
};
|
};
|
||||||
})
|
})
|
||||||
|
.filter('blockTimeFilter', function() {
|
||||||
|
return function(timestamp) {
|
||||||
|
if(timestamp === 0)
|
||||||
|
return '∞';
|
||||||
|
|
||||||
|
var time = Math.floor((new Date()).getTime() / 1000);
|
||||||
|
var diff = time - timestamp;
|
||||||
|
|
||||||
|
if(diff < 60)
|
||||||
|
return Math.round(diff) + ' s';
|
||||||
|
|
||||||
|
return moment.duration(Math.round(diff), 's').humanize() + ' ago';
|
||||||
|
};
|
||||||
|
}).filter('avgTimeFilter', function() {
|
||||||
|
return function(time) {
|
||||||
|
if(time < 60)
|
||||||
|
return Math.round(time) + ' s';
|
||||||
|
|
||||||
|
return moment.duration(Math.round(time), 's').humanize();
|
||||||
|
};
|
||||||
|
})
|
||||||
|
.filter('avgTimeClass', function() {
|
||||||
|
return function(time) {
|
||||||
|
return blockTimeClass(time);
|
||||||
|
}
|
||||||
|
})
|
||||||
.filter('upTimeFilter', function() {
|
.filter('upTimeFilter', function() {
|
||||||
return function(uptime) {
|
return function(uptime) {
|
||||||
return Math.round(uptime) + '%';
|
return Math.round(uptime) + '%';
|
||||||
@ -115,6 +143,11 @@ function timeClass(timestamp)
|
|||||||
var time = Math.floor((new Date()).getTime() / 1000);
|
var time = Math.floor((new Date()).getTime() / 1000);
|
||||||
var diff = time - timestamp;
|
var diff = time - timestamp;
|
||||||
|
|
||||||
|
return blockTimeClass(diff);
|
||||||
|
}
|
||||||
|
|
||||||
|
function blockTimeClass(diff)
|
||||||
|
{
|
||||||
if(diff <= 12)
|
if(diff <= 12)
|
||||||
return 'text-success';
|
return 'text-success';
|
||||||
|
|
||||||
@ -124,5 +157,5 @@ function timeClass(timestamp)
|
|||||||
if(diff <= 30)
|
if(diff <= 30)
|
||||||
return 'text-warning';
|
return 'text-warning';
|
||||||
|
|
||||||
return 'text-danger';
|
return 'text-danger'
|
||||||
}
|
}
|
@ -3,5 +3,11 @@
|
|||||||
$(this).tooltip('show');
|
$(this).tooltip('show');
|
||||||
}).on('mouseleave', '[data-toggle="tooltip"]', function( event ) {
|
}).on('mouseleave', '[data-toggle="tooltip"]', function( event ) {
|
||||||
$(this).tooltip('hide');
|
$(this).tooltip('hide');
|
||||||
})
|
});
|
||||||
|
|
||||||
|
moment.relativeTimeTreshold('s', 60);
|
||||||
|
moment.relativeTimeTreshold('m', 60);
|
||||||
|
moment.relativeTimeTreshold('h', 24);
|
||||||
|
moment.relativeTimeTreshold('d', 28);
|
||||||
|
moment.relativeTimeTreshold('M', 12);
|
||||||
})();
|
})();
|
@ -32,7 +32,7 @@ app.factory('toastr', function ($rootScope) {
|
|||||||
toastr.options = {
|
toastr.options = {
|
||||||
"closeButton": false,
|
"closeButton": false,
|
||||||
"debug": false,
|
"debug": false,
|
||||||
"progressBar": true,
|
"progressBar": false,
|
||||||
"newestOnTop": true,
|
"newestOnTop": true,
|
||||||
"positionClass": "toast-top-right",
|
"positionClass": "toast-top-right",
|
||||||
"preventDuplicates": false,
|
"preventDuplicates": false,
|
||||||
|
@ -3,14 +3,14 @@ extends layout
|
|||||||
block content
|
block content
|
||||||
div.container-fluid(ng-controller='StatsCtrl')
|
div.container-fluid(ng-controller='StatsCtrl')
|
||||||
div.row
|
div.row
|
||||||
div.col-lg-6(ng-cloak)
|
div.col-lg-7(ng-cloak)
|
||||||
div.col-sm-12
|
div.col-sm-12
|
||||||
h1= title
|
h1= title
|
||||||
p Welcome to #{title}
|
//- p Welcome to #{title}
|
||||||
|
|
||||||
div.clearfix
|
div.clearfix
|
||||||
|
|
||||||
div.col-xs-6.stat-holder
|
div.col-xs-4.stat-holder
|
||||||
div.row.big-info.nodesactive(class="{{ nodesActive | nodesActiveClass : nodesTotal }}")
|
div.row.big-info.nodesactive(class="{{ nodesActive | nodesActiveClass : nodesTotal }}")
|
||||||
div.pull-left.icon-full-width
|
div.pull-left.icon-full-width
|
||||||
i.icon-bulb
|
i.icon-bulb
|
||||||
@ -18,23 +18,15 @@ block content
|
|||||||
span.small-title active nodes
|
span.small-title active nodes
|
||||||
span.big-details {{nodesActive}}/{{nodesTotal}}
|
span.big-details {{nodesActive}}/{{nodesTotal}}
|
||||||
div.clearfix
|
div.clearfix
|
||||||
div.col-xs-6.stat-holder
|
div.col-xs-5.stat-holder
|
||||||
div.row.big-info.bestblock.text-info
|
div.row.big-info.difficulty.text-info
|
||||||
div.pull-left.icon-full-width
|
div.pull-left.icon-full-width
|
||||||
i.icon-block
|
i.icon-difficulty
|
||||||
div.pull-left
|
div.pull-left
|
||||||
span.small-title best block
|
span.small-title difficulty
|
||||||
span.big-details {{"#" + bestBlock}}
|
span.big-details {{ lastDifficulty }}
|
||||||
div.clearfix
|
div.clearfix
|
||||||
div.col-xs-6.stat-holder
|
div.col-xs-3.stat-holder
|
||||||
div.row.big-info.blocktime(class="{{ lastBlock | timeClass }}")
|
|
||||||
div.pull-left.icon-full-width
|
|
||||||
i.icon-time
|
|
||||||
div.pull-left
|
|
||||||
span.small-title last block
|
|
||||||
span.big-details(am-time-ago="lastBlock", am-preprocess="unix") ∞
|
|
||||||
div.clearfix
|
|
||||||
div.col-xs-6.stat-holder
|
|
||||||
div.row.big-info.uptime(class="{{ upTimeTotal | upTimeClass }}")
|
div.row.big-info.uptime(class="{{ upTimeTotal | upTimeClass }}")
|
||||||
div.pull-left.icon-full-width
|
div.pull-left.icon-full-width
|
||||||
i.icon-clock
|
i.icon-clock
|
||||||
@ -42,10 +34,34 @@ block content
|
|||||||
span.small-title up-time
|
span.small-title up-time
|
||||||
span.big-details {{ upTimeTotal | upTimeFilter }}
|
span.big-details {{ upTimeTotal | upTimeFilter }}
|
||||||
div.clearfix
|
div.clearfix
|
||||||
|
div.col-xs-4.stat-holder
|
||||||
|
div.row.big-info.bestblock.text-info
|
||||||
|
div.pull-left.icon-full-width
|
||||||
|
i.icon-block
|
||||||
|
div.pull-left
|
||||||
|
span.small-title best block
|
||||||
|
span.big-details {{"#" + bestBlock}}
|
||||||
|
div.clearfix
|
||||||
|
div.col-xs-5.stat-holder
|
||||||
|
div.row.big-info.blocktime(class="{{ lastBlock | timeClass }}")
|
||||||
|
div.pull-left.icon-full-width
|
||||||
|
i.icon-time
|
||||||
|
div.pull-left
|
||||||
|
span.small-title last block
|
||||||
|
span.big-details {{ lastBlock | blockTimeFilter }}
|
||||||
|
div.clearfix
|
||||||
|
div.col-xs-3.stat-holder
|
||||||
|
div.row.big-info.avgblocktime(class="{{ avgBlockTime | timeClass }}")
|
||||||
|
div.pull-left.icon-full-width
|
||||||
|
i.icon-gas
|
||||||
|
div.pull-left
|
||||||
|
span.small-title avg block time
|
||||||
|
span.big-details {{ avgBlockTime | avgTimeFilter }}
|
||||||
|
div.clearfix
|
||||||
|
|
||||||
div.clearfix
|
div.clearfix
|
||||||
|
|
||||||
div.col-lg-6
|
div.col-lg-5
|
||||||
div.col-xs-12
|
div.col-xs-12
|
||||||
nodemap#mapHolder(data="map")
|
nodemap#mapHolder(data="map")
|
||||||
|
|
||||||
@ -61,13 +77,17 @@ block content
|
|||||||
i.icon-node(data-toggle="tooltip", data-placement="top", title="Node")
|
i.icon-node(data-toggle="tooltip", data-placement="top", title="Node")
|
||||||
th
|
th
|
||||||
i.icon-laptop(data-toggle="tooltip", data-placement="top", title="Node type")
|
i.icon-laptop(data-toggle="tooltip", data-placement="top", title="Node type")
|
||||||
|
th
|
||||||
|
i.icon-mining(data-toggle="tooltip", data-placement="top", title="Is mining")
|
||||||
th
|
th
|
||||||
i.icon-group(data-toggle="tooltip", data-placement="top", title="Peers")
|
i.icon-group(data-toggle="tooltip", data-placement="top", title="Peers")
|
||||||
th
|
th
|
||||||
i.icon-mining(data-toggle="tooltip", data-placement="top", title="Is mining")
|
i.icon-network(data-toggle="tooltip", data-placement="top", title="Pending transactions")
|
||||||
th
|
th
|
||||||
i.icon-block(data-toggle="tooltip", data-placement="top", title="Last node block")
|
i.icon-block(data-toggle="tooltip", data-placement="top", title="Last node block")
|
||||||
th.hidden-sm.hidden-xs
|
th.hidden-sm.hidden-xs
|
||||||
|
th
|
||||||
|
i.icon-check-o(data-toggle="tooltip", data-placement="top", title="Block transactions")
|
||||||
th
|
th
|
||||||
i.icon-time(data-toggle="tooltip", data-placement="top", title="Last node time")
|
i.icon-time(data-toggle="tooltip", data-placement="top", title="Last node time")
|
||||||
th
|
th
|
||||||
@ -76,16 +96,18 @@ block content
|
|||||||
tr(ng-repeat='node in nodes', class="{{ node.stats | mainClass : bestBlock }}")
|
tr(ng-repeat='node in nodes', class="{{ node.stats | mainClass : bestBlock }}")
|
||||||
td(rel="{{node.id}}")
|
td(rel="{{node.id}}")
|
||||||
span(data-toggle="tooltip", data-placement="top", data-original-title="{{node.geo | geoTooltip}}") {{node.info.name}}
|
span(data-toggle="tooltip", data-placement="top", data-original-title="{{node.geo | geoTooltip}}") {{node.info.name}}
|
||||||
div.small {{node.info.ip}}
|
span.small  ({{node.info.ip}})
|
||||||
td.small
|
td
|
||||||
div.small(ng-bind-html="node.info.node | nodeVersion")
|
div.small(ng-bind-html="node.info.node | nodeVersion")
|
||||||
div.small {{node.info.os}}, {{node.info.os_v}}
|
//- div.small {{node.info.os}}, {{node.info.os_v}}
|
||||||
td(class="{{ node.stats.peers | peerClass }}") {{node.stats.peers}}
|
|
||||||
td(class="{{ node.stats.mining | miningClass }}")
|
td(class="{{ node.stats.mining | miningClass }}")
|
||||||
i(class="{{ node.stats.mining | miningIconClass }}")
|
i(class="{{ node.stats.mining | miningIconClass }}")
|
||||||
|
td(class="{{ node.stats.peers | peerClass }}", style="padding-left: 18px;") {{node.stats.peers}}
|
||||||
|
td(style="padding-left: 18px;") {{node.stats.pending}}
|
||||||
td(class="{{ node.stats.block.number | blockClass : bestBlock }}") {{'#' + node.stats.block.number}}
|
td(class="{{ node.stats.block.number | blockClass : bestBlock }}") {{'#' + node.stats.block.number}}
|
||||||
td(class="{{ node.stats.block.number | blockClass : bestBlock }}").hidden-sm.hidden-xs
|
td(class="{{ node.stats.block.number | blockClass : bestBlock }}").hidden-sm.hidden-xs
|
||||||
span.small {{node.stats.block.hash}}
|
span.small {{node.stats.block.hash}}
|
||||||
div.small Difficulty: {{node.stats.block.difficulty | gasFilter}} | Gas used: {{node.stats.block.gasUsed | gasFilter}} | Min gas price: {{node.stats.block.minGasPrice | gasFilter}} | Gas limit: {{node.stats.block.gasLimit | gasFilter}}
|
//- div.small Difficulty: {{node.stats.block.difficulty | gasFilter}} | Gas used: {{node.stats.block.gasUsed | gasFilter}} | Min gas price: {{node.stats.block.minGasPrice | gasFilter}} | Gas limit: {{node.stats.block.gasLimit | gasFilter}}
|
||||||
td(am-time-ago="node.stats.block.timestamp", am-preprocess="unix", class="{{ node.stats.block.timestamp | timeClass }}") ∞
|
td(style="padding-left: 18px;") {{node.stats.block.txCount}}
|
||||||
|
td(class="{{ node.stats.block.timestamp | timeClass }}") {{node.stats.block.timestamp | blockTimeFilter }}
|
||||||
td(class="{{ node.stats.uptime | upTimeClass }}") {{ node.stats.uptime | upTimeFilter }}
|
td(class="{{ node.stats.uptime | upTimeClass }}") {{ node.stats.uptime | upTimeFilter }}
|
||||||
|
Loading…
Reference in New Issue
Block a user