feat: add airing status and end-state helpers to player

This commit is contained in:
2026-05-29 00:04:05 +02:00
parent aebdd75942
commit 32586d6b08
3 changed files with 18 additions and 1 deletions

View File

@@ -38,6 +38,7 @@ type WatchData struct {
ModeSwitchedFrom string ModeSwitchedFrom string
AvailableModes []string AvailableModes []string
Segments []SkipSegment Segments []SkipSegment
Airing bool
} }
type SubtitleItem struct { type SubtitleItem struct {

View File

@@ -16,6 +16,7 @@ export interface PlayerState {
modeSwitchedFrom: string; modeSwitchedFrom: string;
currentEpisode: string; currentEpisode: string;
totalEpisodes: number; totalEpisodes: number;
isAiring: boolean;
malID: number; malID: number;
streamURL: string; streamURL: string;
initialStreamToken: string; initialStreamToken: string;
@@ -35,6 +36,7 @@ export interface PlayerState {
transitionEpisode: number | null; transitionEpisode: number | null;
completionSent: boolean; completionSent: boolean;
completionAttempts: number; completionAttempts: number;
endedProgressSaved: boolean;
lastSavedProgress: { episode: string; seconds: number }; lastSavedProgress: { episode: string; seconds: number };
episodeGrid: HTMLElement | null; episodeGrid: HTMLElement | null;
episodeList: HTMLElement | null; episodeList: HTMLElement | null;
@@ -57,6 +59,7 @@ const createInitialState = (): PlayerState => ({
modeSwitchedFrom: "", modeSwitchedFrom: "",
currentEpisode: "1", currentEpisode: "1",
totalEpisodes: 0, totalEpisodes: 0,
isAiring: false,
malID: 0, malID: 0,
streamURL: "/watch/proxy/stream", streamURL: "/watch/proxy/stream",
initialStreamToken: "", initialStreamToken: "",
@@ -76,6 +79,7 @@ const createInitialState = (): PlayerState => ({
transitionEpisode: null, transitionEpisode: null,
completionSent: false, completionSent: false,
completionAttempts: 0, completionAttempts: 0,
endedProgressSaved: false,
lastSavedProgress: { episode: "1", seconds: -1 }, lastSavedProgress: { episode: "1", seconds: -1 },
episodeGrid: null, episodeGrid: null,
episodeList: null, episodeList: null,
@@ -86,6 +90,15 @@ const createInitialState = (): PlayerState => ({
export const state: PlayerState = createInitialState(); export const state: PlayerState = createInitialState();
export const showEndState = (): void => {
state.container.classList.add("video-ended");
state.video.pause();
};
export const hideEndState = (): void => {
state.container.classList.remove("video-ended");
};
interface RequiredPlayerElements { interface RequiredPlayerElements {
video: HTMLVideoElement; video: HTMLVideoElement;
progress: HTMLElement; progress: HTMLElement;
@@ -143,7 +156,9 @@ export const initState = (c: HTMLElement): boolean => {
// data attributes from server // data attributes from server
state.malID = Number.parseInt(dataset(c, "malId"), 10); state.malID = Number.parseInt(dataset(c, "malId"), 10);
state.currentEpisode = dataset(c, "currentEpisode") || "1"; state.currentEpisode = dataset(c, "currentEpisode") || "1";
state.totalEpisodes = Number.parseInt(dataset(c, "totalEpisodes"), 10); state.totalEpisodes = Number.parseInt(dataset(c, "totalEpisodes"), 10);
state.isAiring = dataset(c, "isAiring") === "true";
state.streamURL = dataset(c, "streamUrl") || "/watch/proxy/stream"; state.streamURL = dataset(c, "streamUrl") || "/watch/proxy/stream";
state.initialStreamToken = dataset(c, "streamToken") || ""; state.initialStreamToken = dataset(c, "streamToken") || "";
state.startTimeSeconds = Number.parseFloat(dataset(c, "startTimeSeconds") || "0") || 0; state.startTimeSeconds = Number.parseFloat(dataset(c, "startTimeSeconds") || "0") || 0;

View File

@@ -10,9 +10,10 @@
data-mode-sources='{{json .WatchData.ModeSources}}' data-mode-sources='{{json .WatchData.ModeSources}}'
data-available-modes='{{json .WatchData.AvailableModes}}' data-available-modes='{{json .WatchData.AvailableModes}}'
data-segments='{{json .WatchData.Segments}}' data-segments='{{json .WatchData.Segments}}'
data-is-airing="{{.WatchData.Airing}}"
data-anime-title-english="{{.WatchData.Title}}" data-anime-title-english="{{.WatchData.Title}}"
data-anime-image="{{.WatchData.MalID}}" data-anime-image="{{.WatchData.MalID}}"
class="group relative aspect-video w-full overflow-hidden bg-black [&.show-controls_[data-video-overlay]]:opacity-100 [&.fullscreen:not(.show-controls)_[data-video-overlay]]:opacity-0 [&.fullscreen:not(.show-controls)_[data-video-overlay]]:pointer-events-none [&.fullscreen:not(.show-controls)]:cursor-none [&.fullscreen:not(.show-controls)_video]:cursor-none"> class="group relative aspect-video w-full overflow-hidden bg-black [&.show-controls_[data-video-overlay]]:opacity-100 [&.fullscreen:not(.show-controls)_[data-video-overlay]]:opacity-0 [&.fullscreen:not(.show-controls)_[data-video-overlay]]:pointer-events-none [&.fullscreen:not(.show-controls)]:cursor-none [&.fullscreen:not(.show-controls)_video]:cursor-none [&.video-ended_video]:opacity-0">
<video class="h-full w-full cursor-pointer" preload="metadata" playsinline></video> <video class="h-full w-full cursor-pointer" preload="metadata" playsinline></video>