Show SABnzbd's queue in the header on every page
All checks were successful
Deploy / deploy (push) Successful in 21s
All checks were successful
Deploy / deploy (push) Successful in 21s
Adds a live download figure next to the header clock, present on every page (not just Activity/System). It's populated by the same /api/sabnzbd poll those pages already use, extended to run unconditionally and to fill in a new #head-dl span — never a server-rendered fetch, so an unreachable SABnzbd can't add latency to pages that don't otherwise touch it. Quiet ink at "0 IN QUEUE" when idle, live cyan with a speed reading once something's moving.
This commit is contained in:
parent
cef66e7361
commit
d672c3f02d
3 changed files with 29 additions and 7 deletions
|
|
@ -33,7 +33,6 @@
|
||||||
text-transform: uppercase;
|
text-transform: uppercase;
|
||||||
}
|
}
|
||||||
.tt-head-clock {
|
.tt-head-clock {
|
||||||
margin-left: auto;
|
|
||||||
color: var(--live);
|
color: var(--live);
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
min-width: 0;
|
min-width: 0;
|
||||||
|
|
@ -45,6 +44,16 @@
|
||||||
letter-spacing: 0.3em;
|
letter-spacing: 0.3em;
|
||||||
}
|
}
|
||||||
.tt-entry[hidden] { display: none; }
|
.tt-entry[hidden] { display: none; }
|
||||||
|
/* SABnzbd's queue, live on every page — filled in by service.js, empty
|
||||||
|
(and so invisible) until its first poll returns. Quiet ink when
|
||||||
|
idle; the live colour only while something is actually moving. */
|
||||||
|
.tt-head-dl {
|
||||||
|
margin-left: auto;
|
||||||
|
color: var(--ink-dim);
|
||||||
|
white-space: nowrap;
|
||||||
|
min-width: 0;
|
||||||
|
}
|
||||||
|
.tt-head-dl.live { color: var(--live); }
|
||||||
|
|
||||||
/* ── Page ───────────────────────────────────────────────
|
/* ── Page ───────────────────────────────────────────────
|
||||||
One measure for every page in the service. Nothing is ever
|
One measure for every page in the service. Nothing is ever
|
||||||
|
|
@ -602,6 +611,7 @@ a.tt-row:focus-visible .tt-row-sub { color: var(--tt-black); }
|
||||||
.tt-row-title { white-space: normal; }
|
.tt-row-title { white-space: normal; }
|
||||||
.tt-row-val { margin-left: auto; white-space: normal; }
|
.tt-row-val { margin-left: auto; white-space: normal; }
|
||||||
.tt-head-name { letter-spacing: 0.12em; }
|
.tt-head-name { letter-spacing: 0.12em; }
|
||||||
|
.tt-head-dl { margin-left: 0; flex-basis: 100%; }
|
||||||
.tt-head-clock { margin-left: 0; flex-basis: 100%; }
|
.tt-head-clock { margin-left: 0; flex-basis: 100%; }
|
||||||
|
|
||||||
/* The System disk table swaps for its row reflow here — see the
|
/* The System disk table swaps for its row reflow here — see the
|
||||||
|
|
|
||||||
|
|
@ -160,14 +160,15 @@
|
||||||
The queue and the active streams are the only two numbers
|
The queue and the active streams are the only two numbers
|
||||||
that must be accurate to the second, so they are the only
|
that must be accurate to the second, so they are the only
|
||||||
two that poll. Everything else is cached server-side and
|
two that poll. Everything else is cached server-side and
|
||||||
arrives with the page. */
|
arrives with the page. The queue also drives the header's
|
||||||
|
download row, present on every page, so it polls
|
||||||
|
unconditionally rather than only where #sab-queue exists. */
|
||||||
function setText(id, value) {
|
function setText(id, value) {
|
||||||
var el = document.getElementById(id);
|
var el = document.getElementById(id);
|
||||||
if (el) el.textContent = value;
|
if (el) el.textContent = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
function pollSab() {
|
function pollSab() {
|
||||||
if (!document.getElementById('sab-queue')) return;
|
|
||||||
fetch(BASE + '/api/sabnzbd')
|
fetch(BASE + '/api/sabnzbd')
|
||||||
.then(function (r) { return r.json(); })
|
.then(function (r) { return r.json(); })
|
||||||
.then(function (d) {
|
.then(function (d) {
|
||||||
|
|
@ -175,6 +176,14 @@
|
||||||
setText('sab-queue', d.queue_count);
|
setText('sab-queue', d.queue_count);
|
||||||
setText('sab-speed', d.speed || '0');
|
setText('sab-speed', d.speed || '0');
|
||||||
setText('sab-remaining', d.sizeleft || '—');
|
setText('sab-remaining', d.sizeleft || '—');
|
||||||
|
var dl = document.getElementById('head-dl');
|
||||||
|
if (dl) {
|
||||||
|
var active = d.queue_count > 0;
|
||||||
|
dl.textContent = active
|
||||||
|
? d.queue_count + ' IN QUEUE · ' + (d.speed || '0')
|
||||||
|
: '0 IN QUEUE';
|
||||||
|
dl.classList.toggle('live', active);
|
||||||
|
}
|
||||||
})
|
})
|
||||||
.catch(function () { /* offline is the dev baseline, not an error */ });
|
.catch(function () { /* offline is the dev baseline, not an error */ });
|
||||||
}
|
}
|
||||||
|
|
@ -190,10 +199,8 @@
|
||||||
.catch(function () { /* as above */ });
|
.catch(function () { /* as above */ });
|
||||||
}
|
}
|
||||||
|
|
||||||
if (document.getElementById('sab-queue')) {
|
pollSab();
|
||||||
pollSab();
|
setInterval(pollSab, 5000);
|
||||||
setInterval(pollSab, 5000);
|
|
||||||
}
|
|
||||||
if (document.getElementById('tt-streams')) {
|
if (document.getElementById('tt-streams')) {
|
||||||
pollTautulli();
|
pollTautulli();
|
||||||
setInterval(pollTautulli, 15000);
|
setInterval(pollTautulli, 15000);
|
||||||
|
|
|
||||||
|
|
@ -42,6 +42,11 @@ provenance.
|
||||||
<span class="tt-head-num">P{{ here[1] }}</span>
|
<span class="tt-head-num">P{{ here[1] }}</span>
|
||||||
<span class="tt-head-name">{{ here[2] }}</span>
|
<span class="tt-head-name">{{ here[2] }}</span>
|
||||||
<span class="tt-entry" id="page-entry" hidden aria-live="polite"></span>
|
<span class="tt-entry" id="page-entry" hidden aria-live="polite"></span>
|
||||||
|
{#- SABnzbd's queue, on every page — the same live /api/sabnzbd poll
|
||||||
|
Activity and System already use, not a server-rendered fetch, so
|
||||||
|
an unreachable SABnzbd never adds latency to a page that doesn't
|
||||||
|
otherwise need it. Starts blank and fills in within a second. -#}
|
||||||
|
<span class="tt-head-dl" id="head-dl" aria-live="polite"></span>
|
||||||
<span class="tt-head-clock" id="head-clock"></span>
|
<span class="tt-head-clock" id="head-clock"></span>
|
||||||
</header>
|
</header>
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue