fix(xtream): never report another panel's status for the selected playlist

Review follow-up (Greptile): callers gate content initialization on the
value `checkPortalStatus()` returns for whatever is selected NOW. When the
answer no longer describes the selected playlist (source switch or in-place
edit during the request), the store's own verdict about the current
selection is returned instead of the old panel's status — on success and on
failure alike.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
4grayandClaude Fable 5.1 committed 2026-09-06 23:54:52 +02:00
1 parent e634cdea6e
commit 5953e60d9a
2 files changed
+18 -8

No files matched your search

@@ -242,7 +242,9 @@ describe('withPortal', () => {
server_info: { timezone: 'Europe/London' },
});
await expect(pending).resolves.toBe('active');
// The answer describes A; callers gating content init on the
// result get the store's verdict about B instead.
await expect(pending).resolves.toBe('unavailable');
expect(store.currentPlaylist()).toEqual(other);
expect(store.portalStatus()).toBe('unavailable');
expect(transformPlaylistMeta).toHaveBeenCalledWith(
@@ -277,7 +279,7 @@ describe('withPortal', () => {
server_info: { timezone: 'Europe/London' },
});
await expect(pending).resolves.toBe('active');
await expect(pending).resolves.toBe('unavailable');
expect(store.currentPlaylist()).toEqual(moved);
expect(store.portalStatus()).toBe('unavailable');
expect(storedPlaylist.serverTimezone).toBeUndefined();
@@ -326,7 +328,8 @@ describe('withPortal', () => {
fail(new Error('panel down'));
await expect(pending).resolves.toBe('unavailable');
// A's failure says nothing about B, so the caller gets B's verdict.
await expect(pending).resolves.toBe('active');
expect(store.portalStatus()).toBe('active');
});
@@ -199,10 +199,10 @@ export function withPortal() {
// request may hand the old panel's status or clock
// to the new one.
const current = store.currentPlaylist();
if (
const describesCurrent =
current?.id === playlist.id &&
answersFor(current, credentials)
) {
answersFor(current, credentials);
if (describesCurrent) {
patchState(store, {
portalStatus,
currentPlaylist: {
@@ -226,7 +226,12 @@ export function withPortal() {
serverTimezone
);
}
return portalStatus;
// Callers gate content initialization on this value
// for whatever is selected NOW; an answer about
// another panel must not unblock it.
return describesCurrent
? portalStatus
: store.portalStatus();
} catch (error) {
logger.error('Error checking portal status', error);
const current = store.currentPlaylist();
@@ -236,7 +241,9 @@ export function withPortal() {
) {
patchState(store, { portalStatus: 'unavailable' });
}
return 'unavailable';
// The old panel's failure says nothing about a
// playlist selected or edited meanwhile.
return store.portalStatus();
}
},