dashboard fix/online off , and warehouse
This commit is contained in:
@@ -27,15 +27,20 @@
|
||||
color: #c8a44a;
|
||||
letter-spacing: 1px;
|
||||
}
|
||||
#connection-status {
|
||||
.status-indicator {
|
||||
margin-left: auto;
|
||||
display: flex;
|
||||
gap: 10px;
|
||||
align-items: center;
|
||||
}
|
||||
.conn-badge {
|
||||
font-size: 0.8rem;
|
||||
padding: 4px 10px;
|
||||
border-radius: 12px;
|
||||
background: #333;
|
||||
}
|
||||
#connection-status.online { background: #1a4a1a; color: #6fcf6f; }
|
||||
#connection-status.offline { background: #4a1a1a; color: #cf6f6f; }
|
||||
.conn-badge.online { background: #1a4a1a; color: #6fcf6f; }
|
||||
.conn-badge.offline { background: #4a1a1a; color: #cf6f6f; }
|
||||
|
||||
.layout {
|
||||
display: grid;
|
||||
@@ -210,7 +215,10 @@
|
||||
|
||||
<header>
|
||||
<h1>⚔️ Grepolis Remote</h1>
|
||||
<div id="connection-status">Connecting…</div>
|
||||
<div class="status-indicator">
|
||||
<div id="server-status" class="conn-badge">Server…</div>
|
||||
<div id="client-status" class="conn-badge">Client…</div>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<div class="layout">
|
||||
@@ -330,6 +338,8 @@
|
||||
// ================================================================
|
||||
let towns = [];
|
||||
let selectedTownId = null;
|
||||
let clientOnline = false; // tracks Tampermonkey script heartbeat
|
||||
let wasClientOnline = null; // previous known state (null = unknown)
|
||||
const POLL_INTERVAL = 4000;
|
||||
|
||||
const BUILDING_NAMES_GR = {
|
||||
@@ -373,15 +383,36 @@ async function fetchTowns() {
|
||||
const res = await fetch('/dashboard/towns');
|
||||
towns = await res.json();
|
||||
renderTowns();
|
||||
updateConnectionStatus(true);
|
||||
|
||||
updateServerStatus(true);
|
||||
|
||||
if (selectedTownId) {
|
||||
renderBuildQueuePreview();
|
||||
renderBuildingDropdown();
|
||||
renderTownDetails();
|
||||
}
|
||||
} catch (e) {
|
||||
updateConnectionStatus(false);
|
||||
updateServerStatus(false);
|
||||
}
|
||||
}
|
||||
|
||||
async function fetchClientStatus() {
|
||||
try {
|
||||
const res = await fetch('/dashboard/client-status');
|
||||
const data = await res.json();
|
||||
const isOnline = data.online === true;
|
||||
|
||||
// Detect transition: online → offline
|
||||
if (wasClientOnline === true && !isOnline) {
|
||||
// Fail all queued commands immediately
|
||||
await fetch('/dashboard/commands/fail-stale', { method: 'POST' });
|
||||
fetchLog();
|
||||
}
|
||||
|
||||
clientOnline = isOnline;
|
||||
wasClientOnline = isOnline;
|
||||
updateClientStatus(isOnline);
|
||||
} catch (e) {
|
||||
updateClientStatus(false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -393,14 +424,33 @@ async function fetchLog() {
|
||||
} catch (e) {}
|
||||
}
|
||||
|
||||
function updateConnectionStatus(online) {
|
||||
const el = document.getElementById('connection-status');
|
||||
function updateServerStatus(online) {
|
||||
const el = document.getElementById('server-status');
|
||||
if (online) {
|
||||
el.textContent = '● Online';
|
||||
el.className = 'online';
|
||||
el.textContent = '● Server';
|
||||
el.className = 'conn-badge online';
|
||||
} else {
|
||||
el.textContent = '● Offline';
|
||||
el.className = 'offline';
|
||||
el.textContent = '● Server offline';
|
||||
el.className = 'conn-badge offline';
|
||||
}
|
||||
}
|
||||
|
||||
function updateClientStatus(online) {
|
||||
const el = document.getElementById('client-status');
|
||||
if (online) {
|
||||
el.textContent = '● Script';
|
||||
el.className = 'conn-badge online';
|
||||
} else {
|
||||
el.textContent = '● Script offline';
|
||||
el.className = 'conn-badge offline';
|
||||
}
|
||||
// Enable/disable the Send button
|
||||
const btn = document.querySelector('#command-form-wrap .btn-gold');
|
||||
if (btn) {
|
||||
btn.disabled = !online;
|
||||
btn.title = online ? '' : 'Script is offline — cannot send commands';
|
||||
btn.style.opacity = online ? '' : '0.4';
|
||||
btn.style.cursor = online ? '' : 'not-allowed';
|
||||
}
|
||||
}
|
||||
|
||||
@@ -471,7 +521,7 @@ function renderTownDetails() {
|
||||
return 'color: #fff;';
|
||||
};
|
||||
|
||||
const capFmt = t.resources.storage ? fmt(t.resources.storage) : '?';
|
||||
const capFmt = (t.resources.storage != null && t.resources.storage !== '') ? fmt(t.resources.storage) : '?';
|
||||
|
||||
document.getElementById('td-resources').innerHTML = `
|
||||
<div style="font-size:0.75rem; color:#aaa; margin-bottom: 4px;">Χωρητικότητα: <strong style="color:#eee">${capFmt}</strong></div>
|
||||
@@ -554,6 +604,7 @@ function onCmdTypeChange() {
|
||||
// Send command
|
||||
// ================================================================
|
||||
async function sendCommand() {
|
||||
if (!clientOnline) return alert('Το script είναι offline — δεν μπορείτε να στείλετε εντολές.');
|
||||
const town = getSelectedTown();
|
||||
if (!town) return alert('Select a town first.');
|
||||
|
||||
@@ -583,6 +634,8 @@ async function sendCommand() {
|
||||
const data = await res.json();
|
||||
if (data.ok) {
|
||||
fetchLog();
|
||||
} else if (data.error === 'client_offline') {
|
||||
alert(data.message || 'Το script είναι offline.');
|
||||
} else {
|
||||
alert('Error: ' + JSON.stringify(data));
|
||||
}
|
||||
@@ -637,8 +690,10 @@ async function cancelCommand(id) {
|
||||
// ================================================================
|
||||
fetchTowns();
|
||||
fetchLog();
|
||||
setInterval(fetchTowns, POLL_INTERVAL);
|
||||
setInterval(fetchLog, POLL_INTERVAL);
|
||||
fetchClientStatus();
|
||||
setInterval(fetchTowns, POLL_INTERVAL);
|
||||
setInterval(fetchLog, POLL_INTERVAL);
|
||||
setInterval(fetchClientStatus, POLL_INTERVAL);
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
Reference in New Issue
Block a user