TUI: 60s sports-only live poll while a game is in progress
27f29920d734d374d60affc5208b835973b4b6f1
humdrum <me@humdrum.me> · 2026-07-08 16:20
parent a108f506
TUI: 60s sports-only live poll while a game is in progress Adds poll_sports_live worker that force-refreshes only the sports source every 60s while a game is live, re-rendering just the Scores panel instead of re-fetching every source. Dormant when nothing is live. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
1 files changed
tui/dashboard.py +23 −0
@@ -1078,6 +1078,7 @@ table.cursor_type = "none"
self.refresh_data()
self.set_interval(REFRESH_SECS, self.refresh_data)
+ self.set_interval(60, self.poll_sports_live)
def _q(self, selector: str, expect_type):
"""query_one against the main screen — app.query_one resolves against
@@ -1194,6 +1195,28 @@ self._sports_id = None
self._sports_live = False
self._connected = connected
self._update_subtitle()
+
+ @work(exclusive=True, group="sports")
+ async def poll_sports_live(self) -> None:
+ # While any game is in progress, force-refresh ONLY the sports source so
+ # live scores tick without re-fetching every other source. Dormant when
+ # nothing is live.
+ if not (self._sports_live and self._sports_id):
+ return
+ try:
+ async with httpx.AsyncClient(timeout=15) as c:
+ r = await c.post(f"{BASE_URL}/api/sources/{self._sports_id}/refresh")
+ r.raise_for_status()
+ state = r.json().get("source") or {}
+ except Exception:
+ return
+ snap = state.get("snapshot") or {}
+ p = snap.get("payload") if snap.get("ok") else None
+ self._q("#sports", DashPanel).set_content(
+ render_sports(p) if p else Text("No games.", style="dim italic")
+ )
+ games = (p or {}).get("games", [])
+ self._sports_live = any(g.get("state") == "in" for g in games)
@work(exclusive=True, thread=True, group="sys")
def refresh_system(self) -> None: