feat: add prettier and eslint with pre-commit hook

This commit is contained in:
2026-05-10 19:23:53 +02:00
parent be9fbe0f64
commit 3703bbfcfe
33 changed files with 1643 additions and 1245 deletions

View File

@@ -1,43 +1,43 @@
import { ModeSource, SkipSegment, SubtitleCue, SubtitleTrack, ActiveSegment } from './types'
import { q, qs, dataset } from '../q'
import { ModeSource, SkipSegment, SubtitleCue, SubtitleTrack, ActiveSegment } from './types';
import { q, qs, dataset } from '../q';
export interface PlayerState {
container: HTMLElement
video: HTMLVideoElement
progress: HTMLElement
scrubber: HTMLElement
buffered: HTMLElement
timeDisplay: HTMLElement
durationDisplay: HTMLElement
modeSources: Record<string, ModeSource>
availableModes: string[]
currentMode: string
currentEpisode: string
totalEpisodes: number
malID: number
streamURL: string
initialStreamToken: string
shouldAutoPlay: boolean
parsedSegments: SkipSegment[]
activeSegments: ActiveSegment[]
activeSkipSegment: ActiveSegment | null
activeSubtitles: SubtitleCue[]
currentSubtitleTracks: SubtitleTrack[]
lastKnownVolume: number
pendingSeekTime: number | null
isScrubbing: boolean
isFullscreen: boolean
playerControlsTimeout: number | undefined
progressSaveTimer: number | undefined
transitionEpisode: number | null
completionSent: boolean
completionAttempts: number
lastSavedProgress: { episode: string; seconds: number }
episodeGrid: HTMLElement | null
episodeList: HTMLElement | null
previewPopover: HTMLElement | null
previewTime: HTMLElement | null
videoOverlay: HTMLElement | null
container: HTMLElement;
video: HTMLVideoElement;
progress: HTMLElement;
scrubber: HTMLElement;
buffered: HTMLElement;
timeDisplay: HTMLElement;
durationDisplay: HTMLElement;
modeSources: Record<string, ModeSource>;
availableModes: string[];
currentMode: string;
currentEpisode: string;
totalEpisodes: number;
malID: number;
streamURL: string;
initialStreamToken: string;
shouldAutoPlay: boolean;
parsedSegments: SkipSegment[];
activeSegments: ActiveSegment[];
activeSkipSegment: ActiveSegment | null;
activeSubtitles: SubtitleCue[];
currentSubtitleTracks: SubtitleTrack[];
lastKnownVolume: number;
pendingSeekTime: number | null;
isScrubbing: boolean;
isFullscreen: boolean;
playerControlsTimeout: number | undefined;
progressSaveTimer: number | undefined;
transitionEpisode: number | null;
completionSent: boolean;
completionAttempts: number;
lastSavedProgress: { episode: string; seconds: number };
episodeGrid: HTMLElement | null;
episodeList: HTMLElement | null;
previewPopover: HTMLElement | null;
previewTime: HTMLElement | null;
videoOverlay: HTMLElement | null;
}
export const state: PlayerState = {
@@ -77,50 +77,53 @@ export const state: PlayerState = {
previewPopover: null,
previewTime: null,
videoOverlay: null,
}
};
export const initState = (c: HTMLElement): void => {
state.container = c
state.video = q<HTMLVideoElement>(c, 'video')!
state.progress = q<HTMLElement>(c, '[data-progress]')
state.scrubber = q<HTMLElement>(c, '[data-scrubber]')
state.buffered = q<HTMLElement>(c, '[data-buffered]')
state.timeDisplay = q<HTMLElement>(c, '[data-time]')
state.durationDisplay = q<HTMLElement>(c, '[data-duration]')
state.previewPopover = q<HTMLElement>(c, '[data-preview-popover]')
state.previewTime = q<HTMLElement>(c, '[data-preview-time]')
state.videoOverlay = q<HTMLElement>(c, '[data-video-overlay]')
state.container = c;
state.video = q<HTMLVideoElement>(c, 'video')!;
state.progress = q<HTMLElement>(c, '[data-progress]');
state.scrubber = q<HTMLElement>(c, '[data-scrubber]');
state.buffered = q<HTMLElement>(c, '[data-buffered]');
state.timeDisplay = q<HTMLElement>(c, '[data-time]');
state.durationDisplay = q<HTMLElement>(c, '[data-duration]');
state.previewPopover = q<HTMLElement>(c, '[data-preview-popover]');
state.previewTime = q<HTMLElement>(c, '[data-preview-time]');
state.videoOverlay = q<HTMLElement>(c, '[data-video-overlay]');
state.malID = Number.parseInt(dataset(c, 'malId'), 10)
state.currentEpisode = dataset(c, 'currentEpisode') || '1'
state.totalEpisodes = Number.parseInt(dataset(c, 'totalEpisodes'), 10)
state.streamURL = dataset(c, 'streamUrl') || '/watch/proxy/stream'
state.initialStreamToken = dataset(c, 'streamToken') || ''
state.shouldAutoPlay = sessionStorage.getItem('mal:autoplay-next') === 'true'
sessionStorage.removeItem('mal:autoplay-next')
state.malID = Number.parseInt(dataset(c, 'malId'), 10);
state.currentEpisode = dataset(c, 'currentEpisode') || '1';
state.totalEpisodes = Number.parseInt(dataset(c, 'totalEpisodes'), 10);
state.streamURL = dataset(c, 'streamUrl') || '/watch/proxy/stream';
state.initialStreamToken = dataset(c, 'streamToken') || '';
state.shouldAutoPlay = sessionStorage.getItem('mal:autoplay-next') === 'true';
sessionStorage.removeItem('mal:autoplay-next');
state.episodeGrid = qs<HTMLElement>('[data-episode-grid]')
state.episodeList = qs<HTMLElement>('[data-episode-list]')
state.episodeGrid = qs<HTMLElement>('[data-episode-grid]');
state.episodeList = qs<HTMLElement>('[data-episode-list]');
const safeJson = <T>(raw: string | undefined, fallback: T): T => {
try { return JSON.parse(raw ?? '') as T } catch { return fallback }
}
try {
return JSON.parse(raw ?? '') as T;
} catch {
return fallback;
}
};
state.modeSources = safeJson(dataset(c, 'modeSources'), {} as Record<string, ModeSource>)
state.availableModes = safeJson(dataset(c, 'availableModes'), [] as string[])
state.modeSources = safeJson(dataset(c, 'modeSources'), {} as Record<string, ModeSource>);
state.availableModes = safeJson(dataset(c, 'availableModes'), [] as string[]);
const backendInitialMode = dataset(c, 'initialMode') || 'dub'
const storedMode = localStorage.getItem('player-audio-mode')
const initialMode = (storedMode && state.availableModes.includes(storedMode)) ? storedMode : backendInitialMode
const fallbackMode = Object.keys(state.modeSources).find(
m => state.modeSources[m]?.token
)
state.currentMode =
(state.modeSources[initialMode]?.token) ? initialMode :
(fallbackMode ?? state.availableModes[0] ?? 'dub')
const backendInitialMode = dataset(c, 'initialMode') || 'dub';
const storedMode = localStorage.getItem('player-audio-mode');
const initialMode =
storedMode && state.availableModes.includes(storedMode) ? storedMode : backendInitialMode;
const fallbackMode = Object.keys(state.modeSources).find(m => state.modeSources[m]?.token);
state.currentMode = state.modeSources[initialMode]?.token
? initialMode
: (fallbackMode ?? state.availableModes[0] ?? 'dub');
const segments = safeJson(dataset(c, 'segments'), [] as SkipSegment[])
const segments = safeJson(dataset(c, 'segments'), [] as SkipSegment[]);
state.parsedSegments = segments
.map(s => ({ ...s, start: Number(s.start) || 0, end: Number(s.end) || 0 }))
.filter(s => s.end > s.start)
}
.filter(s => s.end > s.start);
};