162 lines
4.0 KiB
JavaScript
162 lines
4.0 KiB
JavaScript
(function () {
|
|
var LIVE_IMAGE = "live/live.png";
|
|
var LIVE_DATA = "live/live.json";
|
|
var REFRESH_MS = 60 * 1000;
|
|
var TICK_MS = 1000;
|
|
|
|
var img = document.getElementById("live-feed");
|
|
var timestampEl = document.getElementById("live-timestamp");
|
|
var statUptime = document.getElementById("stat-uptime");
|
|
var statListeners = document.getElementById("stat-listeners");
|
|
var statStatus = document.getElementById("stat-status");
|
|
var lastCapturedAt = null;
|
|
|
|
if (!img) {
|
|
return;
|
|
}
|
|
|
|
function formatTimeAgo(unixSeconds) {
|
|
var diff = Math.floor(Date.now() / 1000) - unixSeconds;
|
|
if (diff < 0) {
|
|
diff = 0;
|
|
}
|
|
|
|
if (diff < 60) {
|
|
return diff === 1 ? "1 second ago" : diff + " seconds ago";
|
|
}
|
|
|
|
var minutes = Math.floor(diff / 60);
|
|
if (minutes < 60) {
|
|
return minutes === 1 ? "1 minute ago" : minutes + " minutes ago";
|
|
}
|
|
|
|
var hours = Math.floor(diff / 3600);
|
|
if (hours < 24) {
|
|
return hours === 1 ? "1 hour ago" : hours + " hours ago";
|
|
}
|
|
|
|
var days = Math.floor(diff / 86400);
|
|
return days === 1 ? "1 day ago" : days + " days ago";
|
|
}
|
|
|
|
function formatDuration(seconds) {
|
|
var diff = Math.max(0, Math.floor(seconds));
|
|
var days = Math.floor(diff / 86400);
|
|
var hours = Math.floor((diff % 86400) / 3600);
|
|
var minutes = Math.floor((diff % 3600) / 60);
|
|
|
|
if (days > 0) {
|
|
return days + "d " + hours + "h";
|
|
}
|
|
if (hours > 0) {
|
|
return hours + "h " + minutes + "m";
|
|
}
|
|
if (minutes > 0) {
|
|
return minutes + "m";
|
|
}
|
|
return diff + "s";
|
|
}
|
|
|
|
function formatUptime(value) {
|
|
if (value === null || value === undefined || value === "") {
|
|
return "---";
|
|
}
|
|
if (typeof value === "number") {
|
|
return formatDuration(value);
|
|
}
|
|
return String(value);
|
|
}
|
|
|
|
function formatListeners(value) {
|
|
if (value === null || value === undefined || value === "") {
|
|
return "---";
|
|
}
|
|
return String(value);
|
|
}
|
|
|
|
function formatStatus(value) {
|
|
if (value === null || value === undefined || value === "") {
|
|
return "---";
|
|
}
|
|
return String(value);
|
|
}
|
|
|
|
function updateTimeAgo() {
|
|
if (!timestampEl) {
|
|
return;
|
|
}
|
|
|
|
if (!lastCapturedAt) {
|
|
timestampEl.textContent = "";
|
|
return;
|
|
}
|
|
|
|
timestampEl.textContent = "Captured " + formatTimeAgo(lastCapturedAt);
|
|
}
|
|
|
|
function updateStats(data) {
|
|
if (statUptime) {
|
|
statUptime.textContent = formatUptime(data.uptime);
|
|
}
|
|
if (statListeners) {
|
|
var listeners = data.listeners;
|
|
if (listeners === undefined) {
|
|
listeners = data.live_listeners;
|
|
}
|
|
statListeners.textContent = formatListeners(listeners);
|
|
}
|
|
if (statStatus) {
|
|
var statusText = formatStatus(data.status);
|
|
statStatus.textContent = statusText;
|
|
statStatus.classList.remove("stat-value--ok", "stat-value--bad");
|
|
if (statusText !== "---" && String(data.status).toLowerCase() !== "online") {
|
|
statStatus.classList.add("stat-value--bad");
|
|
} else if (statusText !== "---") {
|
|
statStatus.classList.add("stat-value--ok");
|
|
}
|
|
}
|
|
}
|
|
|
|
function clearStats() {
|
|
updateStats({});
|
|
}
|
|
|
|
function fetchLiveData() {
|
|
fetch(LIVE_DATA + "?t=" + Date.now())
|
|
.then(function (response) {
|
|
if (!response.ok) {
|
|
throw new Error("live data unavailable");
|
|
}
|
|
return response.json();
|
|
})
|
|
.then(function (data) {
|
|
if (data && data.timestamp) {
|
|
lastCapturedAt = data.timestamp;
|
|
updateTimeAgo();
|
|
} else {
|
|
lastCapturedAt = null;
|
|
updateTimeAgo();
|
|
}
|
|
updateStats(data || {});
|
|
})
|
|
.catch(function () {
|
|
lastCapturedAt = null;
|
|
updateTimeAgo();
|
|
clearStats();
|
|
});
|
|
}
|
|
|
|
function refreshLiveImage() {
|
|
img.src = LIVE_IMAGE + "?t=" + Date.now();
|
|
fetchLiveData();
|
|
}
|
|
|
|
img.addEventListener("error", function () {
|
|
img.alt = "Live feed unavailable";
|
|
});
|
|
|
|
refreshLiveImage();
|
|
setInterval(refreshLiveImage, REFRESH_MS);
|
|
setInterval(updateTimeAgo, TICK_MS);
|
|
})();
|