Tweak design, numerous fixes

This commit is contained in:
Cryptkeeper 2015-11-09 01:03:03 -06:00
parent e310891e8d
commit 56233745e0
7 changed files with 114 additions and 19 deletions

3
TODO

@ -1,6 +1,5 @@
Fix icons not updating when a network that was offline comes online. Fix icons not updating when a network that was offline comes online.
Show offline server messages on frontend.
Add auto-reconnect to frontend. Add auto-reconnect to frontend.
Add sorting.
Finish design. Finish design.
Deploy to actual website. Deploy to actual website.
Add new API.

@ -34,6 +34,19 @@ body {
border-bottom: 1px dashed transparent; border-bottom: 1px dashed transparent;
} }
#header > .slogan {
letter-spacing: 2px;
font-size: 20px;
}
#header > .info {
font-size: 17px;
}
#header > h1 {
font-size: 42px;
}
/* Tagline */ /* Tagline */
#tagline { #tagline {
padding: 10px 0; padding: 10px 0;
@ -66,7 +79,7 @@ body {
/* Server listing */ /* Server listing */
#server-container { #server-container {
width: 800px; width: 800px;
margin: 10px auto; margin: 10px auto 20px auto;
} }
#server-container .server:nth-child(2n) { #server-container .server:nth-child(2n) {
@ -77,6 +90,7 @@ body {
.server { .server {
overflow: auto; overflow: auto;
padding: 10px; padding: 10px;
margin: 5px;
} }
.server > .column > img { .server > .column > img {
@ -116,7 +130,7 @@ h3 {
} }
.color-red { .color-red {
color: #c0392b; color: #e74c3c;
} }
.text-uppercase { .text-uppercase {

@ -17,9 +17,8 @@
<div id="header"> <div id="header">
<h1 class="text-uppercase">Minetrack</h1> <h1 class="text-uppercase">Minetrack</h1>
<p class="slogan text-uppercase">All your favorite Minecraft servers, right now.</p>
<p class="text-uppercase">All your favorite Minecraft servers, right now.</p> <p class="info text-uppercase">Made with <span style="color: #e74c3c;">&#9829;</span> by <a href="http://cryptkpr.me">Cryptkeeper</a> &middot; Open source'd on <a href="https://github.com/Cryptkeeper/Minetrack">Github</a></p>
<p class="text-uppercase">Made by <a href="http://cryptkpr.me">Cryptkeeper</a> | Source code on <a href="https://github.com/Cryptkeeper/Minetrack">Github</a></p>
</div> </div>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 6.7 KiB

@ -11,7 +11,7 @@ var smallChartOptions = {
show: false show: false
}, },
yaxis: { yaxis: {
minTickSize: 100, minTickSize: 75,
tickDecimals: 0, tickDecimals: 0,
show: true, show: true,
tickLength: 10, tickLength: 10,
@ -25,7 +25,7 @@ var smallChartOptions = {
}, },
grid: { grid: {
hoverable: true, hoverable: true,
color: "#C4C4C4" color: "#696969"
}, },
colors: [ colors: [
"#E9E581" "#E9E581"
@ -38,6 +38,10 @@ var lastPlayerEntries = {};
// Generate (and set) the HTML that displays Mojang status. // Generate (and set) the HTML that displays Mojang status.
function updateMojangServices() { function updateMojangServices() {
if (!lastMojangServiceUpdate) {
return;
}
var keys = Object.keys(lastMojangServiceUpdate); var keys = Object.keys(lastMojangServiceUpdate);
var newStatus = 'Mojang Services: '; var newStatus = 'Mojang Services: ';
var serviceCountByType = { var serviceCountByType = {
@ -75,18 +79,28 @@ function updateMojangServices() {
$('#tagline-text').text(newStatus); $('#tagline-text').text(newStatus);
} }
function findErrorMessage(error) {
if (error.description) {
return error.description;
} else if (error.errno) {
return error.errno;
}
}
function updateServerStatus(lastEntry) { function updateServerStatus(lastEntry) {
var info = lastEntry.info; var info = lastEntry.info;
var div = $('#status_' + safeName(info.name)); var div = $('#status_' + safeName(info.name));
if (lastEntry.result) { if (lastEntry.result) {
var result = lastEntry.result; var result = lastEntry.result;
var newStatus = formatNumber(result.players.online) + '/' + formatNumber(result.players.max); var newStatus = 'Players: ' + formatNumber(result.players.online);
if (lastPlayerEntries[info.name]) { var listing = graphs[lastEntry.info.name].listing;
if (listing.length > 0) {
newStatus += '<span class="color-gray"> ('; newStatus += '<span class="color-gray"> (';
var playerDifference = lastPlayerEntries[info.name] - result.players.online; var playerDifference = listing[listing.length - 1][1] - listing[0][1];
if (playerDifference >= 0) { if (playerDifference >= 0) {
newStatus += '+'; newStatus += '+';
@ -111,6 +125,31 @@ function updateServerStatus(lastEntry) {
lastLatencyEntries[info.name] = result.latency; lastLatencyEntries[info.name] = result.latency;
div.html(newStatus); div.html(newStatus);
} else {
var newStatus = '<span class="color-red">Failed to ping!';
if (findErrorMessage(lastEntry.error)) {
newStatus += '<br />' + findErrorMessage(lastEntry.error);
}
div.html(newStatus + '</span>');
}
}
function sortServers() {
var keys = Object.keys(lastPlayerEntries);
var nameList = [];
keys.sort(function(a, b) {
return lastPlayerEntries[b] - lastPlayerEntries[a];
});
keys.reverse();
for (var i = 0; i < keys.length; i++) {
$('#' + safeName(keys[i])).prependTo('#server-container');
$('#ranking_' + safeName(keys[i])).text('#' + (keys.length - i));
} }
} }
@ -131,8 +170,8 @@ $(document).ready(function() {
clearInterval(mojangServicesUpdater); clearInterval(mojangServicesUpdater);
} }
$('#tagline').attr('class', 'status-connecting'); $('#tagline').attr('class', 'status-offline');
$('#tagline-text').text('Attempting reconnnect...'); $('#tagline-text').text('Disconnected! Refresh?');
lastPlayerEntries = {}; lastPlayerEntries = {};
lastLatencyEntries = {}; lastLatencyEntries = {};
@ -159,11 +198,21 @@ $(document).ready(function() {
var lastEntry = history[history.length - 1]; var lastEntry = history[history.length - 1];
var info = lastEntry.info; var info = lastEntry.info;
if (lastEntry.error) {
lastPlayerEntries[info.name] = 0;
lastLatencyEntries[info.name] = 0;
} else if (lastEntry.result) {
lastPlayerEntries[info.name] = lastEntry.result.players.online;
lastLatencyEntries[info.name] = lastEntry.result.latency;
}
$('<div/>', { $('<div/>', {
id: safeName(info.name), id: safeName(info.name),
class: 'server', class: 'server',
html: '<div class="column" style="width: 80px;">\ html: '<div class="column" style="width: 80px;">\
<img style="padding-top: 5px;" id="favicon_' + safeName(info.name) + '">\ <img style="padding-top: 5px;" id="favicon_' + safeName(info.name) + '">\
<br />\
<span id="ranking_' + safeName(info.name) + '"></span>\
</div>\ </div>\
<div class="column" style="width: 280px;"><h3>' + info.name + '</h3>\ <div class="column" style="width: 280px;"><h3>' + info.name + '</h3>\
<span class="color-gray">' + info.ip + '</span>\ <span class="color-gray">' + info.ip + '</span>\
@ -183,13 +232,13 @@ $(document).ready(function() {
$('#favicon_' + safeName(info.name)).attr('src', favicon); $('#favicon_' + safeName(info.name)).attr('src', favicon);
updateServerStatus(lastEntry);
graphs[lastEntry.info.name] = { graphs[lastEntry.info.name] = {
listing: listing, listing: listing,
plot: $.plot('#chart_' + safeName(info.name), [listing], smallChartOptions) plot: $.plot('#chart_' + safeName(info.name), [listing], smallChartOptions)
}; };
updateServerStatus(lastEntry);
$('#chart_' + safeName(info.name)).bind('plothover', function(event, pos, item) { $('#chart_' + safeName(info.name)).bind('plothover', function(event, pos, item) {
if (item) { if (item) {
renderTooltip(item.pageX + 5, item.pageY + 5, getTimestamp(item.datapoint[0] / 1000) + '\ renderTooltip(item.pageX + 5, item.pageY + 5, getTimestamp(item.datapoint[0] / 1000) + '\
@ -200,9 +249,21 @@ $(document).ready(function() {
} }
}); });
} }
sortServers();
}); });
socket.on('update', function(update) { socket.on('update', function(update) {
// Prevent weird race conditions.
if (!graphs[update.info.name]) {
return;
}
// We have a new favicon, update the old one.
if (update.result && update.result.favicon) {
$('#favicon_' + safeName(update.info.name)).attr('src', update.result.favicon);
}
var graph = graphs[update.info.name]; var graph = graphs[update.info.name];
updateServerStatus(update); updateServerStatus(update);
@ -230,4 +291,8 @@ $(document).ready(function() {
mojangServicesUpdater = setInterval(function() { mojangServicesUpdater = setInterval(function() {
updateMojangServices(); updateMojangServices();
}, 1000); }, 1000);
setInterval(function() {
sortServers();
}, 30 * 1000);
}); });

@ -86,9 +86,19 @@
"type": "PC" "type": "PC"
}, },
{ {
"name": "Shock", "name": "Shock Network",
"ip": "play.snw.io", "ip": "play.snw.io",
"type": "PC" "type": "PC"
},
{
"name": "MCBrawl",
"ip": "mcbrawl.com",
"type": "PC"
},
{
"name": "SaicoPvP",
"ip": "saicopvp.com",
"type": "PC"
} }
], ],
"routes": { "routes": {

@ -25,7 +25,15 @@ exports.start = function(callback) {
logger.log('info', '%s requested: %s', req.connection.remoteAddress, requestUrl); logger.log('info', '%s requested: %s', req.connection.remoteAddress, requestUrl);
if (requestUrl in urlMapping) { if (requestUrl === '/status.json') {
res.setHeader('Content-Type', 'text/plain');
res.write(JSON.stringify({
error: true,
message: 'API deprecated.'
}));
res.end();
} else if (requestUrl in urlMapping) {
var file = urlMapping[requestUrl]; var file = urlMapping[requestUrl];
res.setHeader('Content-Type', mime.lookup(file)); res.setHeader('Content-Type', mime.lookup(file));