style: format static/player/state.ts
This commit is contained in:
@@ -1,9 +1,10 @@
|
|||||||
import type { ModeSource, SkipSegment, SubtitleCue, SubtitleTrack, ActiveSegment } from "./types";
|
import type { ModeSource, SkipSegment, SubtitleCue, SubtitleTrack, ActiveSegment } from "./types";
|
||||||
import { parseModeSources, parseSegments } from "./validate";
|
|
||||||
import { q, qs, dataset } from "../q";
|
import { q, qs, dataset } from "../q";
|
||||||
import { safeLocalStorage } from "./storage";
|
import { safeLocalStorage } from "./storage";
|
||||||
|
import { parseModeSources, parseSegments } from "./validate";
|
||||||
|
|
||||||
export interface PlayerState {
|
export type PlayerState = {
|
||||||
elements: {
|
elements: {
|
||||||
container: HTMLElement;
|
container: HTMLElement;
|
||||||
video: HTMLVideoElement;
|
video: HTMLVideoElement;
|
||||||
@@ -46,19 +47,10 @@ export interface PlayerState {
|
|||||||
activeSegments: ActiveSegment[];
|
activeSegments: ActiveSegment[];
|
||||||
activeSegment: ActiveSegment | null;
|
activeSegment: ActiveSegment | null;
|
||||||
};
|
};
|
||||||
subtitles: {
|
subtitles: { activeCues: SubtitleCue[]; tracks: SubtitleTrack[] };
|
||||||
activeCues: SubtitleCue[];
|
ui: { isScrubbing: boolean; isFullscreen: boolean };
|
||||||
tracks: SubtitleTrack[];
|
timers: { playerControlsTimeout: number | undefined; progressSaveTimer: number | undefined };
|
||||||
};
|
};
|
||||||
ui: {
|
|
||||||
isScrubbing: boolean;
|
|
||||||
isFullscreen: boolean;
|
|
||||||
};
|
|
||||||
timers: {
|
|
||||||
playerControlsTimeout: number | undefined;
|
|
||||||
progressSaveTimer: number | undefined;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
const createInitialState = (): PlayerState => ({
|
const createInitialState = (): PlayerState => ({
|
||||||
elements: {
|
elements: {
|
||||||
@@ -100,23 +92,10 @@ const createInitialState = (): PlayerState => ({
|
|||||||
endedProgressSaved: false,
|
endedProgressSaved: false,
|
||||||
lastSavedProgress: { episode: "1", seconds: -1 },
|
lastSavedProgress: { episode: "1", seconds: -1 },
|
||||||
},
|
},
|
||||||
skip: {
|
skip: { parsedSegments: [], activeSegments: [], activeSegment: null },
|
||||||
parsedSegments: [],
|
subtitles: { activeCues: [], tracks: [] },
|
||||||
activeSegments: [],
|
ui: { isScrubbing: false, isFullscreen: false },
|
||||||
activeSegment: null,
|
timers: { playerControlsTimeout: undefined, progressSaveTimer: undefined },
|
||||||
},
|
|
||||||
subtitles: {
|
|
||||||
activeCues: [],
|
|
||||||
tracks: [],
|
|
||||||
},
|
|
||||||
ui: {
|
|
||||||
isScrubbing: false,
|
|
||||||
isFullscreen: false,
|
|
||||||
},
|
|
||||||
timers: {
|
|
||||||
playerControlsTimeout: undefined,
|
|
||||||
progressSaveTimer: undefined,
|
|
||||||
},
|
|
||||||
});
|
});
|
||||||
|
|
||||||
export const state: PlayerState = createInitialState();
|
export const state: PlayerState = createInitialState();
|
||||||
@@ -130,14 +109,14 @@ export const hideEndState = (): void => {
|
|||||||
state.elements.container.classList.remove("video-ended");
|
state.elements.container.classList.remove("video-ended");
|
||||||
};
|
};
|
||||||
|
|
||||||
interface RequiredPlayerElements {
|
type RequiredPlayerElements = {
|
||||||
video: HTMLVideoElement;
|
video: HTMLVideoElement;
|
||||||
progress: HTMLElement;
|
progress: HTMLElement;
|
||||||
scrubber: HTMLElement;
|
scrubber: HTMLElement;
|
||||||
buffered: HTMLElement;
|
buffered: HTMLElement;
|
||||||
timeDisplay: HTMLElement;
|
timeDisplay: HTMLElement;
|
||||||
durationDisplay: HTMLElement;
|
durationDisplay: HTMLElement;
|
||||||
}
|
};
|
||||||
|
|
||||||
const findElement = <T extends Element>(
|
const findElement = <T extends Element>(
|
||||||
container: HTMLElement,
|
container: HTMLElement,
|
||||||
@@ -145,7 +124,9 @@ const findElement = <T extends Element>(
|
|||||||
elementType: new () => T,
|
elementType: new () => T,
|
||||||
): T | null => {
|
): T | null => {
|
||||||
const element = container.querySelector(selector);
|
const element = container.querySelector(selector);
|
||||||
if (element instanceof elementType) return element;
|
if (element instanceof elementType) {
|
||||||
|
return element;
|
||||||
|
}
|
||||||
return null;
|
return null;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -164,13 +145,12 @@ const requiredPlayerElements = (container: HTMLElement): RequiredPlayerElements
|
|||||||
return { video, progress, scrubber, buffered, timeDisplay, durationDisplay };
|
return { video, progress, scrubber, buffered, timeDisplay, durationDisplay };
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/** Initializes player state from DOM data attributes. Called once on page load or htmx swap. */
|
||||||
* Initializes player state from DOM data attributes.
|
|
||||||
* Called once on page load or htmx swap.
|
|
||||||
*/
|
|
||||||
export const initState = (c: HTMLElement): boolean => {
|
export const initState = (c: HTMLElement): boolean => {
|
||||||
const elements = requiredPlayerElements(c);
|
const elements = requiredPlayerElements(c);
|
||||||
if (!elements) return false;
|
if (!elements) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// core elements
|
// core elements
|
||||||
state.elements.container = c;
|
state.elements.container = c;
|
||||||
@@ -232,11 +212,15 @@ export const initState = (c: HTMLElement): boolean => {
|
|||||||
// This avoids mismatches where the UI highlights one mode but the video is actually playing the other.
|
// This avoids mismatches where the UI highlights one mode but the video is actually playing the other.
|
||||||
const deriveModeFromVideoSrc = (): string | null => {
|
const deriveModeFromVideoSrc = (): string | null => {
|
||||||
const raw = state.elements.video.currentSrc || state.elements.video.src;
|
const raw = state.elements.video.currentSrc || state.elements.video.src;
|
||||||
if (!raw) return null;
|
if (!raw) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
try {
|
try {
|
||||||
const u = new URL(raw, window.location.href);
|
const u = new URL(raw, window.location.href);
|
||||||
const modeParam = u.searchParams.get("mode");
|
const modeParam = u.searchParams.get("mode");
|
||||||
if (modeParam === "sub" || modeParam === "dub") return modeParam;
|
if (modeParam === "sub" || modeParam === "dub") {
|
||||||
|
return modeParam;
|
||||||
|
}
|
||||||
return null;
|
return null;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("failed to parse mode url:", error);
|
console.error("failed to parse mode url:", error);
|
||||||
|
|||||||
Reference in New Issue
Block a user