mirror of
https://github.com/4gray/iptvnator.git
synced 2026-10-09 01:16:15 -08:00
fix(portals): twelfth review round on the cinematic details
- The Stalker explicit-launch guard tracks every in-flight movie, so a repeat of a pending launch is rejected even after another movie's launch was started in between. - The Xtream movie reset only touches the route's state while it still shows the movie the reset started on. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
1 parent
95a3130883
commit
b3c422c9b5
3 files changed
+40
-9
No files matched your search
@@ -156,6 +156,30 @@ describe('createStalkerVodDetailActions openExternal', () => {
|
||||
expect(t.openExternalPlayback).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
it('still rejects a repeat of the first movie after another one was started', async () => {
|
||||
let selected = 42;
|
||||
const t = setup(() => selected);
|
||||
const other = {
|
||||
...MOVIE,
|
||||
data: { id: '7' },
|
||||
} as unknown as VodDetailsItem;
|
||||
const launch = (item: VodDetailsItem) =>
|
||||
t.actions.openExternal({
|
||||
item,
|
||||
player: 'mpv',
|
||||
positionSeconds: null,
|
||||
});
|
||||
void launch(MOVIE);
|
||||
selected = 7;
|
||||
void launch(other);
|
||||
selected = 42;
|
||||
await launch(MOVIE);
|
||||
|
||||
// A, B, A again: the second A is a repeat of a pending launch.
|
||||
expect(t.beginPendingStart).toHaveBeenCalledTimes(2);
|
||||
expect(t.openExternalPlayback).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('drops the stream once another movie was selected meanwhile', async () => {
|
||||
let selected = 42;
|
||||
const t = setup(() => selected);
|
||||
|
||||
@@ -71,10 +71,10 @@ export function createStalkerVodDetailActions(
|
||||
deps.snackBar.open(deps.translate.instant(key), undefined, {
|
||||
duration: 3000,
|
||||
});
|
||||
// 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;
|
||||
// A second "Open in external player" for a movie whose `create_link` is
|
||||
// still resolving would resolve beside the first and start a second
|
||||
// player; other movies' launches are not held back by it.
|
||||
const externalLaunchesInFlight = new Set<string>();
|
||||
|
||||
return {
|
||||
/** The inline player copied the stream URL. */
|
||||
@@ -106,10 +106,10 @@ export function createStalkerVodDetailActions(
|
||||
const playlistId = deps.playlistId();
|
||||
const vodId = Number(event.item.data.id);
|
||||
const launchKey = `${playlistId}:${vodId}`;
|
||||
if (externalLaunchInFlight === launchKey) {
|
||||
if (externalLaunchesInFlight.has(launchKey)) {
|
||||
return;
|
||||
}
|
||||
externalLaunchInFlight = launchKey;
|
||||
externalLaunchesInFlight.add(launchKey);
|
||||
const stillSelected = () =>
|
||||
deps.selectedVodId() === vodId &&
|
||||
deps.playlistId() === playlistId;
|
||||
@@ -146,9 +146,7 @@ export function createStalkerVodDetailActions(
|
||||
notify('PORTALS.PLAYBACK_ERROR');
|
||||
}
|
||||
} finally {
|
||||
if (externalLaunchInFlight === launchKey) {
|
||||
externalLaunchInFlight = null;
|
||||
}
|
||||
externalLaunchesInFlight.delete(launchKey);
|
||||
settlePendingStart?.();
|
||||
}
|
||||
},
|
||||
|
||||
@@ -192,6 +192,15 @@ export class VodDetailsMenuService {
|
||||
this.logger.error('Resetting the playback position failed', error);
|
||||
return;
|
||||
}
|
||||
// The clear was async: the route may show another movie by now
|
||||
// (the Similar rail reuses it), whose own state must stay.
|
||||
if (
|
||||
this.bindings()?.vodId() !== vodId ||
|
||||
this.xtreamStore.currentPlaylist()?.id !== playlistId
|
||||
) {
|
||||
void this.xtreamStore.loadAllPositions(playlistId);
|
||||
return;
|
||||
}
|
||||
// A read still in flight started from the pre-write row; letting it
|
||||
// land would bring the position back.
|
||||
this.playback.discardPendingPositionLoads();
|
||||
|
||||
Reference in new issue
Block a user