feat(ui): add catalogue picker, schedule pane and per-provider hero

This commit is contained in:
beefcarver committed 2026-11-03 17:51:27 -05:00
1 parent 058d336a2c
commit b31ad3f6fb
16 files changed
+1211 -65

No files matched your search

+33 -1
View File
@@ -24,7 +24,7 @@ from urllib.parse import quote
import httpx
from .. import config
from ..models import Song, Station
from ..models import Broadcast, Song, Station
__all__ = [
"PLAYLIST_TTL",
@@ -92,6 +92,28 @@ class RadioProvider(ABC):
#: ``User-Agent`` for this catalogue's requests (SomaFM likes to know).
user_agent: str = ""
# -- header hero ----------------------------------------------------- #
#: Rows of header art drawn at the top left (rich markup is allowed).
hero: tuple[str, ...] = ()
#: Paint :attr:`hero` with the app's spectrum gradient (a wordmark) instead
#: of the colours the art carries itself (a picture).
hero_gradient: bool = False
#: Short lines printed beside the hero, top to bottom.
hero_lines: tuple[str, ...] = ()
# -- left pane ------------------------------------------------------- #
#: Show a broadcast schedule in the left pane instead of a station list.
#: Set by single-stream catalogues, where a list of one station is a waste
#: of the pane and "what is on, what is next" is the useful view.
has_schedule: bool = False
#: Look the current track up on Bandcamp and offer a link when it is found.
#: Off for catalogues whose rotation is unlikely to be there (and for
#: stations that would rather not be scraped).
bandcamp: bool = True
# -- catalogue ------------------------------------------------------- #
@abstractmethod
@@ -118,6 +140,16 @@ class RadioProvider(ABC):
def load_cached_history(self, station_id: str) -> list[Song]:
"""The last good song history from disk, or ``[]``."""
# -- schedule -------------------------------------------------------- #
async def fetch_schedule(self, client: httpx.AsyncClient) -> list[Broadcast]:
"""Upcoming broadcasts, soonest first (the live one, if any, first)."""
return []
def load_cached_schedule(self) -> list[Broadcast]:
"""The last good schedule from disk, or ``[]``."""
return []
# -- streams --------------------------------------------------------- #
def fallback_urls(self, station: Station) -> list[str]: