mirror of
https://github.com/4gray/iptvnator.git
synced 2026-10-16 06:06:18 -08:00
fix(playback): clarify external player launch feedback (#1388)
This commit is contained in:
1 parent
8442747c37
commit
d73acd6bfc
101 files changed
+8819
-850
No files matched your search
+41
-1
@@ -41,6 +41,7 @@ import {
|
||||
import {
|
||||
Channel,
|
||||
EpgProgram,
|
||||
ExternalPlayerSession,
|
||||
ResolvedPortalPlayback,
|
||||
Settings,
|
||||
VideoPlayer,
|
||||
@@ -197,6 +198,7 @@ describe('VideoPlayerComponent', () => {
|
||||
const stripCountryPrefix = signal(false);
|
||||
const epgViewMode = signal<'timeline' | 'list'>('timeline');
|
||||
const epgUrlSetting = signal<string[]>([]);
|
||||
const externalSession = signal<ExternalPlayerSession | null>(null);
|
||||
const originalElectron = window.electron;
|
||||
|
||||
const overlayRef = {
|
||||
@@ -325,6 +327,7 @@ describe('VideoPlayerComponent', () => {
|
||||
channelsLoading.set(false);
|
||||
currentEpgProgram.set(null);
|
||||
activeEpgProgram.set(null);
|
||||
externalSession.set(null);
|
||||
currentEpgProgram$.next(null);
|
||||
epgPrograms$.next([]);
|
||||
overlayMock.create.mockClear();
|
||||
@@ -415,7 +418,7 @@ describe('VideoPlayerComponent', () => {
|
||||
{
|
||||
provide: PORTAL_EXTERNAL_PLAYBACK,
|
||||
useValue: {
|
||||
activeSession: signal(null),
|
||||
activeSession: externalSession,
|
||||
},
|
||||
},
|
||||
],
|
||||
@@ -582,9 +585,13 @@ describe('VideoPlayerComponent', () => {
|
||||
Origin: 'https://origin.example.com',
|
||||
},
|
||||
};
|
||||
const launch = Promise.resolve();
|
||||
const trackLaunch = jest.fn();
|
||||
dataServiceMock.sendIpcEvent.mockReturnValueOnce(launch);
|
||||
component.handleExternalFallbackRequest({
|
||||
player: 'mpv',
|
||||
playback,
|
||||
trackLaunch,
|
||||
diagnostic: {
|
||||
code: 'unsupported-codec',
|
||||
source: 'hls',
|
||||
@@ -605,6 +612,7 @@ describe('VideoPlayerComponent', () => {
|
||||
origin: 'https://origin.example.com',
|
||||
}
|
||||
);
|
||||
expect(trackLaunch).toHaveBeenCalledWith(launch);
|
||||
});
|
||||
|
||||
it('renders the embedded mpv inline player with the EPG panel', () => {
|
||||
@@ -641,6 +649,38 @@ describe('VideoPlayerComponent', () => {
|
||||
).toBe(false);
|
||||
});
|
||||
|
||||
it('clears the channel when a closable error becomes terminal', () => {
|
||||
syncStoreState(sampleChannel);
|
||||
player.set(VideoPlayer.MPV);
|
||||
const closableError: ExternalPlayerSession = {
|
||||
id: 'external-1',
|
||||
player: 'mpv',
|
||||
status: 'error',
|
||||
title: sampleChannel.name,
|
||||
streamUrl: sampleChannel.url,
|
||||
startedAt: '2026-08-08T00:00:00.000Z',
|
||||
updatedAt: '2026-08-08T00:00:00.000Z',
|
||||
error: 'Process exit was not confirmed',
|
||||
canClose: true,
|
||||
};
|
||||
externalSession.set(closableError);
|
||||
fixture.detectChanges();
|
||||
expect(storeMock.dispatch).not.toHaveBeenCalledWith(
|
||||
ChannelActions.resetActiveChannel()
|
||||
);
|
||||
|
||||
externalSession.set({
|
||||
...closableError,
|
||||
canClose: false,
|
||||
updatedAt: '2026-08-08T00:00:01.000Z',
|
||||
});
|
||||
fixture.detectChanges();
|
||||
|
||||
expect(storeMock.dispatch).toHaveBeenCalledWith(
|
||||
ChannelActions.resetActiveChannel()
|
||||
);
|
||||
});
|
||||
|
||||
it('keeps DASH channels inline on the HTML5 player even when MPV is configured', () => {
|
||||
syncStoreState({
|
||||
...sampleChannel,
|
||||
|
||||
@@ -80,6 +80,7 @@ import {
|
||||
persistLiveEpgPanelState,
|
||||
persistLiveSidebarState,
|
||||
PORTAL_EXTERNAL_PLAYBACK,
|
||||
isLiveExternalPlayerSession,
|
||||
restoreLiveEpgPanelState,
|
||||
restoreLiveSidebarState,
|
||||
WorkspaceHeaderContextService,
|
||||
@@ -1083,10 +1084,14 @@ export class VideoPlayerComponent implements OnInit, OnDestroy {
|
||||
return;
|
||||
}
|
||||
|
||||
this.dataService.sendIpcEvent(
|
||||
request.player === 'mpv' ? OPEN_MPV_PLAYER : OPEN_VLC_PLAYER,
|
||||
payload
|
||||
const launch = Promise.resolve(
|
||||
this.dataService.sendIpcEvent<ExternalPlayerSession>(
|
||||
request.player === 'mpv' ? OPEN_MPV_PLAYER : OPEN_VLC_PLAYER,
|
||||
payload
|
||||
)
|
||||
);
|
||||
request.trackLaunch(launch);
|
||||
void launch;
|
||||
}
|
||||
|
||||
private toLiveEpgPanelSummary(
|
||||
@@ -1110,7 +1115,10 @@ export class VideoPlayerComponent implements OnInit, OnDestroy {
|
||||
return null;
|
||||
}
|
||||
|
||||
return `${session.id}:${session.status}`;
|
||||
const lifecycle = isLiveExternalPlayerSession(session)
|
||||
? 'live'
|
||||
: 'terminal';
|
||||
return `${session.id}:${session.status}:${lifecycle}`;
|
||||
}
|
||||
|
||||
private isExternalPlayer(
|
||||
@@ -1122,7 +1130,7 @@ export class VideoPlayerComponent implements OnInit, OnDestroy {
|
||||
private isTerminalExternalSession(
|
||||
session: ExternalPlayerSession | null | undefined
|
||||
): boolean {
|
||||
return session?.status === 'closed' || session?.status === 'error';
|
||||
return !!session && !isLiveExternalPlayerSession(session);
|
||||
}
|
||||
|
||||
private registerHeaderShortcut(): void {
|
||||
|
||||
Reference in new issue
Block a user