mirror of
https://github.com/4gray/iptvnator.git
synced 2026-10-08 17:06:15 -08:00
refactor(external-playback): improve session handling and remove dismiss functionality
This commit is contained in:
1 parent
ec84eea924
commit
c42e35b48d
8 files changed
+77
-27
No files matched your search
@@ -94,22 +94,57 @@ describe('ExternalPlaybackService', () => {
|
||||
contentType: 'vod',
|
||||
})
|
||||
).toBeNull();
|
||||
expect(service.visibleSession()).toBeNull();
|
||||
});
|
||||
|
||||
it('delegates close requests for closable sessions', async () => {
|
||||
const session = createSession({ status: 'opened' });
|
||||
listener?.(session);
|
||||
|
||||
closeExternalPlayerSession.mockResolvedValue(
|
||||
createSession({
|
||||
...session,
|
||||
status: 'closed',
|
||||
canClose: false,
|
||||
updatedAt: '2026-03-07T10:00:10.000Z',
|
||||
})
|
||||
);
|
||||
|
||||
await service.closeActiveSession();
|
||||
|
||||
expect(closeExternalPlayerSession).toHaveBeenCalledWith(session.id);
|
||||
expect(service.visibleSession()).toBeNull();
|
||||
});
|
||||
|
||||
it('can close a specific session directly', async () => {
|
||||
const session = createSession({ id: 'session-2', status: 'playing' });
|
||||
|
||||
closeExternalPlayerSession.mockResolvedValue(
|
||||
createSession({
|
||||
...session,
|
||||
status: 'closed',
|
||||
canClose: false,
|
||||
updatedAt: '2026-03-07T10:00:12.000Z',
|
||||
})
|
||||
);
|
||||
|
||||
await service.closeSession(session);
|
||||
|
||||
expect(closeExternalPlayerSession).toHaveBeenCalledWith('session-2');
|
||||
});
|
||||
|
||||
it('hides terminal sessions from the dock', () => {
|
||||
listener?.(createSession({ status: 'closed', canClose: false }));
|
||||
expect(service.visibleSession()).toBeNull();
|
||||
|
||||
listener?.(
|
||||
createSession({
|
||||
id: 'session-3',
|
||||
status: 'error',
|
||||
error: 'Launch failed',
|
||||
canClose: false,
|
||||
})
|
||||
);
|
||||
expect(service.visibleSession()).toBeNull();
|
||||
});
|
||||
});
|
||||
@@ -10,7 +10,11 @@ export class ExternalPlaybackService {
|
||||
|
||||
readonly visibleSession = computed(() => {
|
||||
const session = this.activeSession();
|
||||
if (!session || session.status === 'closed') {
|
||||
if (
|
||||
!session ||
|
||||
session.status === 'closed' ||
|
||||
session.status === 'error'
|
||||
) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -43,11 +47,43 @@ export class ExternalPlaybackService {
|
||||
async closeSession(
|
||||
session: ExternalPlayerSession | null | undefined
|
||||
): Promise<void> {
|
||||
if (!session?.canClose || !window.electron?.closeExternalPlayerSession) {
|
||||
if (!session) {
|
||||
return;
|
||||
}
|
||||
|
||||
await window.electron.closeExternalPlayerSession(session.id);
|
||||
if (!session.canClose || !window.electron?.closeExternalPlayerSession) {
|
||||
this.dismissedSessionId.set(session.id);
|
||||
return;
|
||||
}
|
||||
|
||||
const previousDismissedSessionId = this.dismissedSessionId();
|
||||
this.dismissedSessionId.set(session.id);
|
||||
|
||||
try {
|
||||
const updatedSession = await window.electron.closeExternalPlayerSession(
|
||||
session.id
|
||||
);
|
||||
if (updatedSession) {
|
||||
this.handleSessionUpdate(updatedSession);
|
||||
return;
|
||||
}
|
||||
|
||||
this.activeSession.update((current) =>
|
||||
current?.id === session.id
|
||||
? {
|
||||
...current,
|
||||
status: 'closed',
|
||||
canClose: false,
|
||||
updatedAt: new Date().toISOString(),
|
||||
}
|
||||
: current
|
||||
);
|
||||
} catch (error) {
|
||||
if (this.dismissedSessionId() === session.id) {
|
||||
this.dismissedSessionId.set(previousDismissedSessionId);
|
||||
}
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
findMatchingSession(
|
||||
|
||||
-9
@@ -53,14 +53,5 @@
|
||||
}
|
||||
</button>
|
||||
}
|
||||
<button
|
||||
type="button"
|
||||
mat-icon-button
|
||||
class="external-playback-dock__dismiss"
|
||||
(click)="dismissClicked.emit()"
|
||||
aria-label="Dismiss now playing panel"
|
||||
>
|
||||
<mat-icon>close</mat-icon>
|
||||
</button>
|
||||
</div>
|
||||
</section>
|
||||
+1
-4
@@ -150,10 +150,7 @@
|
||||
|
||||
.external-playback-dock__button {
|
||||
border-radius: 999px;
|
||||
}
|
||||
|
||||
.external-playback-dock__dismiss {
|
||||
color: var(--mat-sys-on-surface-variant);
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
@media (max-width: 720px) {
|
||||
|
||||
+2
-5
@@ -36,17 +36,14 @@ describe('ExternalPlaybackDockComponent', () => {
|
||||
expect(text).toContain('Close player');
|
||||
});
|
||||
|
||||
it('emits close and dismiss actions', () => {
|
||||
it('emits a single close action', () => {
|
||||
const closeSpy = jest.fn();
|
||||
const dismissSpy = jest.fn();
|
||||
component.closeClicked.subscribe(closeSpy);
|
||||
component.dismissClicked.subscribe(dismissSpy);
|
||||
|
||||
const buttons = fixture.debugElement.queryAll(By.css('button'));
|
||||
buttons[0].nativeElement.click();
|
||||
buttons[1].nativeElement.click();
|
||||
|
||||
expect(closeSpy).toHaveBeenCalled();
|
||||
expect(dismissSpy).toHaveBeenCalled();
|
||||
expect(buttons).toHaveLength(1);
|
||||
});
|
||||
});
|
||||
@@ -22,7 +22,6 @@ export class ExternalPlaybackDockComponent {
|
||||
readonly compact = input(false);
|
||||
|
||||
readonly closeClicked = output<void>();
|
||||
readonly dismissClicked = output<void>();
|
||||
|
||||
readonly playerLabel = computed(() => this.session().player.toUpperCase());
|
||||
readonly statusLabel = computed(() => {
|
||||
|
||||
@@ -261,7 +261,6 @@
|
||||
<app-external-playback-dock
|
||||
[session]="session"
|
||||
(closeClicked)="closeActiveExternalSession()"
|
||||
(dismissClicked)="dismissActiveExternalSession()"
|
||||
/>
|
||||
</footer>
|
||||
}
|
||||
|
||||
@@ -312,10 +312,6 @@ export class WorkspaceShellComponent {
|
||||
this.externalPlayback.activeSession()
|
||||
);
|
||||
}
|
||||
|
||||
dismissActiveExternalSession(): void {
|
||||
this.externalPlayback.dismissActiveSession();
|
||||
}
|
||||
readonly searchPlaceholder = computed(() => {
|
||||
this.languageTick();
|
||||
|
||||
|
||||
Reference in new issue
Block a user