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
@@ -3,7 +3,10 @@ import type {
|
||||
ExternalPlayerSession,
|
||||
PlayerContentInfo,
|
||||
} from '@iptvnator/shared/interfaces';
|
||||
import { createExternalPlaybackButtonState } from './external-playback-button-state';
|
||||
import {
|
||||
createExternalPlaybackButtonState,
|
||||
isLiveExternalPlayerSession,
|
||||
} from './external-playback-button-state';
|
||||
|
||||
function session(
|
||||
overrides: Partial<ExternalPlayerSession> = {}
|
||||
@@ -105,6 +108,21 @@ describe('createExternalPlaybackButtonState', () => {
|
||||
}
|
||||
);
|
||||
|
||||
it('offers Stop for an errored session whose process may still be alive', () => {
|
||||
const { api } = setup(
|
||||
session({
|
||||
status: 'error',
|
||||
error: 'Process exit was not confirmed',
|
||||
canClose: true,
|
||||
})
|
||||
);
|
||||
|
||||
expect(api.matchedSession()).not.toBeNull();
|
||||
expect(api.buttonState()).toBe('stop');
|
||||
expect(api.primaryLabel()).toBe('Stop MPV');
|
||||
expect(api.isStopAction()).toBe(true);
|
||||
});
|
||||
|
||||
it('reports a launching session', () => {
|
||||
const { api } = setup(session({ status: 'launching' }));
|
||||
|
||||
@@ -208,3 +226,30 @@ describe('createExternalPlaybackButtonState', () => {
|
||||
expect(api.matchedSession()).toBeNull();
|
||||
});
|
||||
});
|
||||
|
||||
describe('isLiveExternalPlayerSession', () => {
|
||||
it('keeps ownership while a teardown error can still be stopped', () => {
|
||||
expect(
|
||||
isLiveExternalPlayerSession(
|
||||
session({
|
||||
status: 'error',
|
||||
error: 'Process exit was not confirmed',
|
||||
canClose: true,
|
||||
})
|
||||
)
|
||||
).toBe(true);
|
||||
});
|
||||
|
||||
it('treats an unclosable error and a confirmed close as terminal', () => {
|
||||
expect(
|
||||
isLiveExternalPlayerSession(
|
||||
session({ status: 'error', canClose: false })
|
||||
)
|
||||
).toBe(false);
|
||||
expect(
|
||||
isLiveExternalPlayerSession(
|
||||
session({ status: 'closed', canClose: false })
|
||||
)
|
||||
).toBe(false);
|
||||
});
|
||||
});
|
||||
@@ -48,6 +48,21 @@ export interface ExternalPlaybackButtonStateApi {
|
||||
buttonState: Signal<ExternalPlaybackButtonState>;
|
||||
}
|
||||
|
||||
/**
|
||||
* An error can still own a real process when bounded teardown could not
|
||||
* confirm its exit. Keep that session live until Stop succeeds; only a
|
||||
* confirmed close or an unclosable failure is terminal.
|
||||
*/
|
||||
export function isLiveExternalPlayerSession(
|
||||
session: ExternalPlayerSession | null | undefined
|
||||
): session is ExternalPlayerSession {
|
||||
return (
|
||||
!!session &&
|
||||
session.status !== 'closed' &&
|
||||
(session.status !== 'error' || session.canClose)
|
||||
);
|
||||
}
|
||||
|
||||
export function createExternalPlaybackButtonState(
|
||||
config: ExternalPlaybackButtonStateConfig
|
||||
): ExternalPlaybackButtonStateApi {
|
||||
@@ -56,11 +71,7 @@ export function createExternalPlaybackButtonState(
|
||||
const matchedSession = computed(() => {
|
||||
const session = config.session();
|
||||
// A closed or errored session says nothing about what is playing now.
|
||||
if (
|
||||
!session?.contentInfo ||
|
||||
session.status === 'closed' ||
|
||||
session.status === 'error'
|
||||
) {
|
||||
if (!session?.contentInfo || !isLiveExternalPlayerSession(session)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -92,6 +103,7 @@ export function createExternalPlaybackButtonState(
|
||||
return `Opening in ${player}...`;
|
||||
case 'opened':
|
||||
case 'playing':
|
||||
case 'error':
|
||||
return `Stop ${player}`;
|
||||
default:
|
||||
return null;
|
||||
@@ -104,6 +116,7 @@ export function createExternalPlaybackButtonState(
|
||||
return 'hourglass_top';
|
||||
case 'opened':
|
||||
case 'playing':
|
||||
case 'error':
|
||||
return 'stop_circle';
|
||||
default:
|
||||
return 'play_arrow';
|
||||
@@ -116,7 +129,9 @@ export function createExternalPlaybackButtonState(
|
||||
|
||||
const isStopAction = computed(() => {
|
||||
const status = matchedSession()?.status;
|
||||
return status === 'opened' || status === 'playing';
|
||||
return (
|
||||
status === 'opened' || status === 'playing' || status === 'error'
|
||||
);
|
||||
});
|
||||
|
||||
const buttonState = computed<ExternalPlaybackButtonState>(() => {
|
||||
|
||||
Reference in new issue
Block a user