From 95b54d05f40aa42e2c36e34572fd4b170ec3a8d1 Mon Sep 17 00:00:00 2001 From: Anthony Ettinger Date: Wed, 11 Nov 2026 08:19:20 +0000 Subject: [PATCH] fix(guide): a room is on the air until its show ends, not only when its source is a live feed (0.80.3) A podcast mp3 carried as a link channel lists live:false (its SOURCE is not a live feed) the whole time it plays, so its live.streaming room read as offline. The probe now asks whether the channel has ended. Co-Authored-By: Claude Opus 5.5 --- package.json | 2 +- src/guide-rooms.ts | 7 ++++++- test/guide-rooms.test.ts | 4 ++++ 3 files changed, 11 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 71f4714..b927590 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "nixamp", - "version": "0.80.2", + "version": "0.80.3", "description": "It really whips the terminal's ass. A Winamp-shaped audio player for your terminal.", "license": "MIT", "type": "module", diff --git a/src/guide-rooms.ts b/src/guide-rooms.ts index bc0e809..0ff7b44 100644 --- a/src/guide-rooms.ts +++ b/src/guide-rooms.ts @@ -174,6 +174,8 @@ interface ChannelRow { name?: string; kind?: string; live?: boolean; + /** Wall clock when its show ended (the outro is playing). */ + ended?: number; playlist?: unknown[]; codecs?: { tags?: { title?: string; artist?: string; album?: string } }; } @@ -211,7 +213,10 @@ export class RoomProbe { if (!row) return null; const tags = row.codecs?.tags; return { - live: row.live !== false, + // On the air until its show has ended. The row's own `live` says whether + // the SOURCE is a live feed: a podcast mp3 carried as a channel is + // live:false the whole time it plays, and its room read as offline. + live: !row.ended, name: String(row.name ?? address.channel).replace(/\/+$/, "").slice(0, 120), kind: row.kind === "video" ? "video" : "audio", nowPlaying: tags && (tags.title || tags.artist) ? { title: String(tags.title ?? ""), artist: String(tags.artist ?? "") } : null, diff --git a/test/guide-rooms.test.ts b/test/guide-rooms.test.ts index b05da72..8479c8e 100644 --- a/test/guide-rooms.test.ts +++ b/test/guide-rooms.test.ts @@ -61,6 +61,10 @@ test("the probe reads a room's name, kind and what is on from its own server, an const probe = new RoomProbe(fakeServer([CHANNEL])); assert.deepEqual(await probe.state(PLAY), { live: true, name: "Dropkick Murphys - Studio Discography", kind: "audio", nowPlaying: { title: "John Law", artist: "Dropkick Murphys" }, folder: true, album: "" }); assert.equal(await new RoomProbe(fakeServer([])).state(PLAY), null); + // A podcast mp3 carried as a channel is not a live SOURCE but is on the air until it ends. + const episode = { id: "folder-b19b85542264", name: "Episode 1", kind: "audio", live: false }; + assert.equal((await new RoomProbe(fakeServer([episode])).state(PLAY))?.live, true); + assert.equal((await new RoomProbe(fakeServer([{ ...episode, ended: Date.now() }])).state(PLAY))?.live, false); assert.equal(await new RoomProbe(fakeServer([CHANNEL]), async () => "a private address").state(PLAY), null); });