fix(ui): keep Bandcamp link across history refreshes
This commit is contained in:
1 parent
3ae4dc3dab
commit
d2b4f1bf64
2 files changed
+76
-1
No files matched your search
+19
-1
@@ -139,6 +139,7 @@ class SomaFMApp(App[None]):
|
||||
self.artwork_bytes: bytes | None = None
|
||||
self._art_track_key = ""
|
||||
self._bandcamp_key = ""
|
||||
self._bandcamp_urls: dict[str, str] = {}
|
||||
self._http: httpx.AsyncClient | None = None
|
||||
self._closed = False
|
||||
self._tick_timer = None
|
||||
@@ -376,6 +377,10 @@ class SomaFMApp(App[None]):
|
||||
previous = station.now_playing
|
||||
station.history = songs
|
||||
station.now_playing = songs[0]
|
||||
if previous is not None and previous.key() == songs[0].key():
|
||||
# History refreshes replace the Song object even when the track has
|
||||
# not changed. Keep the asynchronously discovered Bandcamp link.
|
||||
songs[0].bandcamp_url = previous.bandcamp_url
|
||||
changed = previous is None or previous.key() != songs[0].key()
|
||||
if self.current is not None and self.current.id == station_id:
|
||||
if changed:
|
||||
@@ -432,13 +437,24 @@ class SomaFMApp(App[None]):
|
||||
def _update_bandcamp(self) -> None:
|
||||
"""Find a Bandcamp track link once per now-playing track."""
|
||||
station = self.current
|
||||
if station is None or self.offline or self._http is None:
|
||||
if station is None:
|
||||
return
|
||||
song = station.now_playing
|
||||
if song is None or not (song.artist.strip() or song.title.strip()):
|
||||
return
|
||||
|
||||
track_key = f"{station.id}|{song.key()}"
|
||||
cached_url = self._bandcamp_urls.get(track_key)
|
||||
if cached_url:
|
||||
self._bandcamp_key = track_key
|
||||
if song.bandcamp_url != cached_url:
|
||||
song.bandcamp_url = cached_url
|
||||
with contextlib.suppress(NoMatches):
|
||||
self.query_one(StagePanel).refresh_stage()
|
||||
return
|
||||
|
||||
if self.offline or self._http is None:
|
||||
return
|
||||
if track_key == self._bandcamp_key:
|
||||
return
|
||||
self._bandcamp_key = track_key
|
||||
@@ -461,6 +477,7 @@ class SomaFMApp(App[None]):
|
||||
if not url:
|
||||
return
|
||||
|
||||
self._bandcamp_urls[f"{station_id}|{song_key}"] = url
|
||||
station = next((s for s in self.stations if s.id == station_id), None)
|
||||
if station is None or self.current is None or self.current.id != station_id:
|
||||
return
|
||||
@@ -822,6 +839,7 @@ class SomaFMApp(App[None]):
|
||||
def action_refresh(self) -> None:
|
||||
self._last_history_fetch = 0.0
|
||||
self._bandcamp_key = ""
|
||||
self._bandcamp_urls.clear()
|
||||
self._set_notice("refreshing…", 2)
|
||||
if self.offline:
|
||||
self._set_notice("offline mode — nothing to refresh", 3)
|
||||
|
||||
@@ -159,6 +159,63 @@ async def test_stage_shows_bandcamp_link_only_when_present() -> None:
|
||||
assert "Bandcamp" not in rendered_text(app)
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_bandcamp_link_survives_history_refresh(monkeypatch) -> None:
|
||||
app = SomaFMApp(autoplay=False, offline=True, audio=False)
|
||||
async with app.run_test(size=(110, 40)) as pilot:
|
||||
await pilot.pause()
|
||||
station = app.current
|
||||
assert station is not None
|
||||
url = "https://jensbuchert.bandcamp.com/track/rauschebart"
|
||||
old_song = Song(
|
||||
title="Rauschebart",
|
||||
artist="Jens Buchert",
|
||||
album="Gravity",
|
||||
bandcamp_url=url,
|
||||
)
|
||||
station.now_playing = old_song
|
||||
station.history = [old_song]
|
||||
|
||||
async def fake_fetch_history(client, station_id):
|
||||
assert station_id == station.id
|
||||
return [
|
||||
Song(
|
||||
title="Rauschebart",
|
||||
artist="Jens Buchert",
|
||||
album="Gravity",
|
||||
)
|
||||
]
|
||||
|
||||
monkeypatch.setattr("somafm_tui.app.api.fetch_history", fake_fetch_history)
|
||||
worker = app._fetch_history(station.id)
|
||||
await worker.wait()
|
||||
await pilot.pause()
|
||||
|
||||
assert station.now_playing is not None
|
||||
assert station.now_playing is not old_song
|
||||
assert station.now_playing.bandcamp_url == url
|
||||
assert "Bandcamp" in rendered_text(app)
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_cached_bandcamp_link_is_reapplied_to_new_song() -> None:
|
||||
app = SomaFMApp(autoplay=False, offline=True, audio=False)
|
||||
async with app.run_test(size=(110, 40)) as pilot:
|
||||
await pilot.pause()
|
||||
station = app.current
|
||||
assert station is not None
|
||||
url = "https://jensbuchert.bandcamp.com/track/rauschebart"
|
||||
song = Song(title="Rauschebart", artist="Jens Buchert", album="Gravity")
|
||||
app._bandcamp_urls[f"{station.id}|{song.key()}"] = url
|
||||
station.now_playing = song
|
||||
|
||||
app._update_bandcamp()
|
||||
await pilot.pause()
|
||||
|
||||
assert song.bandcamp_url == url
|
||||
assert "Bandcamp" in rendered_text(app)
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_media_session_commands_drive_the_app() -> None:
|
||||
app = SomaFMApp(autoplay=False, offline=True, audio=False)
|
||||
|
||||
Reference in new issue
Block a user