Wire up the SSE push channel in both frontend dashboards
app/static/index.html: opens an EventSource against /rounds/stream (no auth needed, see the previous commit) alongside the existing polling loops. On an "update" notification, immediately re-runs the same refreshes polling would eventually do (refreshRound/refreshMe/checkLastRoundResult when logged in, refreshChainStatusOnly when logged out). Also reacts to the browser's "open" event, which fires on the initial connection and on every automatic reconnect — this re-syncs right away instead of leaving the page on stale state until the next event or poll tick, which matters most right after a dropped connection comes back. app/static/admin.html: same channel, refreshing the chain-status bar and whichever admin section is currently open (Utenti/Round/Transazioni pendenti/Audit log) instead of requiring a manual tab switch to see new data. Polling intervals are untouched in both pages — this is purely additive, so a blocked/dropped SSE connection just degrades to the pre-existing behavior. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
+29
-2
@@ -241,14 +241,16 @@ function stopChainStatusPolling() {
|
||||
}
|
||||
|
||||
const VIEWS = ['parametri', 'utenti', 'round', 'pending', 'audit'];
|
||||
const VIEW_LOADERS = { utenti: loadUsers, round: loadRounds, pending: loadPending, audit: loadAuditLog };
|
||||
let currentAdminView = 'parametri';
|
||||
|
||||
function switchView(name) {
|
||||
currentAdminView = name;
|
||||
for (const key of VIEWS) {
|
||||
document.getElementById('nav-' + key).classList.toggle('active', key === name);
|
||||
document.getElementById('view-' + key).classList.toggle('active', key === name);
|
||||
}
|
||||
const loaders = { utenti: loadUsers, round: loadRounds, pending: loadPending, audit: loadAuditLog };
|
||||
if (loaders[name]) loaders[name]();
|
||||
if (VIEW_LOADERS[name]) VIEW_LOADERS[name]();
|
||||
}
|
||||
|
||||
function showDashboard() {
|
||||
@@ -521,6 +523,31 @@ window.addEventListener('pageshow', (event) => {
|
||||
if (event.persisted) initAuthState();
|
||||
});
|
||||
|
||||
// Same server-push channel as app/static/index.html (see app/rounds/events.py):
|
||||
// a content-free "something changed" ping. Here it refreshes the chain-status
|
||||
// bar immediately, and reloads whichever admin section is currently open
|
||||
// (Utenti/Round/Transazioni pendenti/Audit log) so it doesn't need a manual
|
||||
// switch-away-and-back to pick up a new row. Polling stays in place as a
|
||||
// fallback if this connection is ever blocked or drops.
|
||||
let adminEventSource = null;
|
||||
|
||||
function onAdminServerEvent() {
|
||||
if (!adminToken) return;
|
||||
refreshChainStatus();
|
||||
if (VIEW_LOADERS[currentAdminView]) VIEW_LOADERS[currentAdminView]();
|
||||
}
|
||||
|
||||
function connectAdminEvents() {
|
||||
if (adminEventSource) return;
|
||||
adminEventSource = new EventSource('/rounds/stream');
|
||||
adminEventSource.addEventListener('update', onAdminServerEvent);
|
||||
// Fires on the initial connection AND every successful auto-reconnect —
|
||||
// re-syncs immediately instead of waiting for the next event or poll tick
|
||||
// to notice whatever changed while this connection was down.
|
||||
adminEventSource.addEventListener('open', onAdminServerEvent);
|
||||
}
|
||||
|
||||
connectAdminEvents();
|
||||
initAuthState();
|
||||
</script>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user