mirror of
https://github.com/4gray/iptvnator.git
synced 2026-10-10 10:06:15 -08:00
fix(portals): the Stalker launch guard is per movie
A launch still resolving for the movie the user left no longer blocks the explicit launch of the movie now on screen; only a repeat for the same movie is ignored. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
1 parent
b47aeda543
commit
95a3130883
2 files changed
+38
-6
No files matched your search
@@ -131,6 +131,31 @@ describe('createStalkerVodDetailActions openExternal', () => {
|
||||
expect(t.openExternalPlayback).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
it('still launches another movie while the first link resolves', async () => {
|
||||
let selected = 42;
|
||||
const t = setup(() => selected);
|
||||
void t.actions.openExternal({
|
||||
item: MOVIE,
|
||||
player: 'mpv',
|
||||
positionSeconds: null,
|
||||
});
|
||||
selected = 7;
|
||||
const other = {
|
||||
...MOVIE,
|
||||
data: { id: '7' },
|
||||
} as unknown as VodDetailsItem;
|
||||
const second = t.actions.openExternal({
|
||||
item: other,
|
||||
player: 'mpv',
|
||||
positionSeconds: null,
|
||||
});
|
||||
t.resolveLink();
|
||||
await second;
|
||||
|
||||
expect(t.beginPendingStart).toHaveBeenCalledTimes(2);
|
||||
expect(t.openExternalPlayback).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
it('drops the stream once another movie was selected meanwhile', async () => {
|
||||
let selected = 42;
|
||||
const t = setup(() => selected);
|
||||
|
||||
@@ -71,9 +71,10 @@ export function createStalkerVodDetailActions(
|
||||
deps.snackBar.open(deps.translate.instant(key), undefined, {
|
||||
duration: 3000,
|
||||
});
|
||||
// A second "Open in external player" during a slow `create_link` would
|
||||
// resolve beside the first and start a second player.
|
||||
let externalLaunchInFlight = false;
|
||||
// A second "Open in external player" for the SAME movie during a slow
|
||||
// `create_link` would resolve beside the first and start a second
|
||||
// player; another movie's launch is not held back by it.
|
||||
let externalLaunchInFlight: string | null = null;
|
||||
|
||||
return {
|
||||
/** The inline player copied the stream URL. */
|
||||
@@ -96,15 +97,19 @@ export function createStalkerVodDetailActions(
|
||||
},
|
||||
|
||||
async openExternal(event: StalkerVodExternalPlayEvent): Promise<void> {
|
||||
if (event.item.type !== 'stalker' || externalLaunchInFlight) {
|
||||
if (event.item.type !== 'stalker') {
|
||||
return;
|
||||
}
|
||||
externalLaunchInFlight = true;
|
||||
// The `create_link` round trip may outlive the selection: a
|
||||
// stream resolved for a movie the user left is dropped, and its
|
||||
// failure is not reported over the new one.
|
||||
const playlistId = deps.playlistId();
|
||||
const vodId = Number(event.item.data.id);
|
||||
const launchKey = `${playlistId}:${vodId}`;
|
||||
if (externalLaunchInFlight === launchKey) {
|
||||
return;
|
||||
}
|
||||
externalLaunchInFlight = launchKey;
|
||||
const stillSelected = () =>
|
||||
deps.selectedVodId() === vodId &&
|
||||
deps.playlistId() === playlistId;
|
||||
@@ -141,7 +146,9 @@ export function createStalkerVodDetailActions(
|
||||
notify('PORTALS.PLAYBACK_ERROR');
|
||||
}
|
||||
} finally {
|
||||
externalLaunchInFlight = false;
|
||||
if (externalLaunchInFlight === launchKey) {
|
||||
externalLaunchInFlight = null;
|
||||
}
|
||||
settlePendingStart?.();
|
||||
}
|
||||
},
|
||||
|
||||
Reference in new issue
Block a user