An item can carry several credits blocks with mid- and post-credit scenes between them, and Plex flags the one that really ends it. The player left at the first block. Now the Plex-final block moves on (by the auto-skip or the Skip button), an earlier block is only skipped to its end by the button, and with no final flag the last block ends the item by the button alone.
34 lines
1.5 KiB
TypeScript
34 lines
1.5 KiB
TypeScript
// What skipping an intro/credits marker does. An item can carry several credits blocks — mid- and
|
|
// post-credit scenes play between them — so only the block that ends the item moves on to the next
|
|
// one: the block Plex flags `final`, else the last one. Every other credits block is skipped like an
|
|
// intro, to its own end. And only an end Plex itself vouches for is left on its own (the credits
|
|
// auto-skip); an end inferred from the list waits for the viewer's Skip — the stretch after it may
|
|
// still be the show.
|
|
import type { PlexMarker } from "./api";
|
|
|
|
/** `leaves`: skipping it moves on to the next item (else: jumps to its end). `auto`: the auto-skip
|
|
* setting may act on it without the viewer. */
|
|
export interface MarkerSkip {
|
|
leaves: boolean;
|
|
auto: boolean;
|
|
}
|
|
|
|
function endCredits(markers: readonly PlexMarker[]): PlexMarker | undefined {
|
|
const credits = markers.filter((m) => m.type === "credits");
|
|
return (
|
|
credits.find((m) => m.final) ??
|
|
credits.reduce<PlexMarker | undefined>(
|
|
(last, m) => (last && last.start_s > m.start_s ? last : m),
|
|
undefined,
|
|
)
|
|
);
|
|
}
|
|
|
|
export function markerSkip(marker: PlexMarker, markers: readonly PlexMarker[]): MarkerSkip {
|
|
if (marker.type === "intro") return { leaves: false, auto: true };
|
|
// By offset, not identity: a refetched list hands back equal-but-new objects.
|
|
const end = endCredits(markers);
|
|
const leaves = end != null && end.start_s === marker.start_s && end.end_s === marker.end_s;
|
|
return { leaves, auto: leaves && marker.final };
|
|
}
|