mirror of
https://github.com/4gray/iptvnator.git
synced 2026-10-11 10:56:43 -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
@@ -2,9 +2,7 @@ import { ExternalPlayerSession } from '@iptvnator/shared/interfaces';
|
||||
import { ExternalPlaybackService } from './external-playback.service';
|
||||
|
||||
describe('ExternalPlaybackService', () => {
|
||||
let listener:
|
||||
| ((session: ExternalPlayerSession) => void)
|
||||
| undefined;
|
||||
let listener: ((session: ExternalPlayerSession) => void) | undefined;
|
||||
let closeExternalPlayerSession: jest.Mock;
|
||||
let service: ExternalPlaybackService;
|
||||
|
||||
@@ -94,7 +92,9 @@ describe('ExternalPlaybackService', () => {
|
||||
contentType: 'vod',
|
||||
})
|
||||
).toBeNull();
|
||||
expect(service.visibleSession()).toBeNull();
|
||||
expect(service.visibleSession()).toEqual(
|
||||
expect.objectContaining({ status: 'error' })
|
||||
);
|
||||
});
|
||||
|
||||
it('delegates close requests for closable sessions', async () => {
|
||||
@@ -133,18 +133,48 @@ describe('ExternalPlaybackService', () => {
|
||||
expect(closeExternalPlayerSession).toHaveBeenCalledWith('session-2');
|
||||
});
|
||||
|
||||
it('hides terminal sessions from the dock', () => {
|
||||
it('hides closed sessions but keeps errors visible until dismissed', () => {
|
||||
listener?.(createSession({ status: 'closed', canClose: false }));
|
||||
expect(service.visibleSession()).toBeNull();
|
||||
|
||||
listener?.(
|
||||
createSession({
|
||||
id: 'session-3',
|
||||
status: 'error',
|
||||
error: 'Launch failed',
|
||||
canClose: false,
|
||||
})
|
||||
);
|
||||
const failed = createSession({
|
||||
id: 'session-3',
|
||||
status: 'error',
|
||||
error: 'Launch failed',
|
||||
canClose: false,
|
||||
});
|
||||
listener?.(createSession({ id: failed.id }));
|
||||
listener?.(failed);
|
||||
|
||||
expect(service.visibleSession()).toEqual(failed);
|
||||
|
||||
service.dismissActiveSession();
|
||||
expect(service.visibleSession()).toBeNull();
|
||||
});
|
||||
|
||||
it('adopts an exactly correlated restored session after replacement teardown fails', () => {
|
||||
const previous = createSession({
|
||||
id: 'session-previous',
|
||||
status: 'opened',
|
||||
title: 'Previous stream',
|
||||
});
|
||||
const replacement = createSession({
|
||||
id: 'session-replacement',
|
||||
title: 'Replacement stream',
|
||||
});
|
||||
listener?.(previous);
|
||||
listener?.(replacement);
|
||||
|
||||
listener?.({
|
||||
...previous,
|
||||
restoredFromSessionId: replacement.id,
|
||||
updatedAt: '2026-03-07T10:00:20.000Z',
|
||||
});
|
||||
|
||||
expect(service.activeSession()).toMatchObject({
|
||||
id: previous.id,
|
||||
status: 'opened',
|
||||
});
|
||||
expect(service.visibleSession()?.id).toBe(previous.id);
|
||||
});
|
||||
});
|
||||
@@ -1,5 +1,8 @@
|
||||
import { computed, Injectable, signal } from '@angular/core';
|
||||
import { ExternalPlayerSession, PlayerContentInfo } from '@iptvnator/shared/interfaces';
|
||||
import {
|
||||
ExternalPlayerSession,
|
||||
PlayerContentInfo,
|
||||
} from '@iptvnator/shared/interfaces';
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root',
|
||||
@@ -10,11 +13,7 @@ export class ExternalPlaybackService {
|
||||
|
||||
readonly visibleSession = computed(() => {
|
||||
const session = this.activeSession();
|
||||
if (
|
||||
!session ||
|
||||
session.status === 'closed' ||
|
||||
session.status === 'error'
|
||||
) {
|
||||
if (!session || session.status === 'closed') {
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -60,9 +59,8 @@ export class ExternalPlaybackService {
|
||||
this.dismissedSessionId.set(session.id);
|
||||
|
||||
try {
|
||||
const updatedSession = await window.electron.closeExternalPlayerSession(
|
||||
session.id
|
||||
);
|
||||
const updatedSession =
|
||||
await window.electron.closeExternalPlayerSession(session.id);
|
||||
if (updatedSession) {
|
||||
this.handleSessionUpdate(updatedSession);
|
||||
return;
|
||||
@@ -105,12 +103,19 @@ export class ExternalPlaybackService {
|
||||
|
||||
private handleSessionUpdate(session: ExternalPlayerSession): void {
|
||||
const current = this.activeSession();
|
||||
const restoresCurrentReplacement =
|
||||
current?.id === session.restoredFromSessionId;
|
||||
|
||||
if (!current || current.id === session.id || session.status === 'launching') {
|
||||
if (
|
||||
!current ||
|
||||
current.id === session.id ||
|
||||
session.status === 'launching' ||
|
||||
restoresCurrentReplacement
|
||||
) {
|
||||
this.activeSession.set(session);
|
||||
}
|
||||
|
||||
if (session.status === 'launching') {
|
||||
if (session.status === 'launching' || restoresCurrentReplacement) {
|
||||
this.dismissedSessionId.set(null);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user