fix(dashboard): refresh corrected guides and pause expiry timers while hidden

Review follow-ups:

- A programme still on air was not asked for again until it ended, so a
  guide import that corrected it could leave the dashboard wrong for
  hours. Re-ask at once on EpgService.epgAvailable$ (guide import or
  source change), and at least every five minutes
  (LIVE_EPG_MAX_ANSWER_AGE_MS) for changes that arrive by other paths.
- The source-expiry clock scheduled from its last tick, so facts that
  arrived long after it could be scheduled up to an hour late. Schedule
  from Date.now().
- The expiry timer stayed armed while the page was hidden. Arm none until
  the page is visible again; becoming visible moves the clock at once.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
4grayandClaude Opus 5.5 committed 2026-09-29 20:48:56 +02:00
1 parent 81f78dea8c
commit bfb89b0910
6 files changed
+169 -33

No files matched your search

+9 -4
View File
@@ -207,9 +207,12 @@ hooks: `dashboard-hero`, `dashboard-hero-slide` (`data-hero-kind`),
the XMLTV lookup has cards or the portal presenter wants one, and
only while the document is visible; it reads the clock at once when
it starts again. A tick re-reads progress for every live card. It
re-asks an XMLTV scope only after one of its programmes has ended or
while a key has no programme, and an unchanged answer is not
re-emitted.
re-asks an XMLTV scope only after one of its programmes has ended,
while a key has no programme, or once the answer is five minutes old
(`LIVE_EPG_MAX_ANSWER_AGE_MS`), because a guide refreshed elsewhere
can correct a programme still on air. A guide import or source change
(`EpgService.epgAvailable$`) re-asks at once. An unchanged answer is
not re-emitted.
Xtream and Stalker cards have no XMLTV key of their own; their "now on
air" line comes from the portal, **lazily and per card**:
- `buildDashboardPortalLiveEpgEntry` (dashboard data-access) turns a
@@ -404,5 +407,7 @@ full-playlist read. The chip is not a separate account-refresh request.
The badge only changes at day boundaries, so the rails do not poll the clock:
`createSourceExpiryClock` arms one timer for the earliest boundary among the
known facts (`nextSourceExpiryChangeMs`), capped at an hour because timers do
not follow system sleep, and re-reads the clock when the page becomes visible.
not follow system sleep. It arms no timer while the page is hidden and
re-reads the clock when the page becomes visible. It schedules from the real
time, so facts that arrive long after the last tick are not scheduled late.
Facts whose badge can no longer change arm no timer.