formatters, device profile, media matching, subtitle utils, syncplay, trakt
This commit is contained in:
@@ -0,0 +1,70 @@
|
||||
import { createContext, useContext, type ReactNode } from 'react'
|
||||
import type { CinemetaEpisode } from '../api/cinemeta'
|
||||
import type { FillerFlag } from './anime-filler'
|
||||
|
||||
/**
|
||||
* Per-page-scoped enrichment for an episode list. DetailPage builds this
|
||||
* once for the current series and provides it; EpisodeRow + EpisodesPanel
|
||||
* read via the hooks so we don't have to drill three things through three
|
||||
* layers of components.
|
||||
*
|
||||
* Carries:
|
||||
* - `cinemetaMap`: Cinemeta video lookup keyed by `${season}:${episode}`
|
||||
* - `fillerOf`: pure function (season, episode) -> FillerFlag, computed
|
||||
* against the bundled anime-filler list using absolute episode number
|
||||
* derivation from the season-length map the provider builds.
|
||||
*/
|
||||
|
||||
type CinemetaMap = Map<string, CinemetaEpisode>
|
||||
type FillerOf = (season: number | null | undefined, episode: number | null | undefined) => FillerFlag
|
||||
|
||||
interface EpisodeMetaValue {
|
||||
cinemetaMap: CinemetaMap
|
||||
fillerOf: FillerOf
|
||||
}
|
||||
|
||||
const DEFAULT: EpisodeMetaValue = {
|
||||
cinemetaMap: new Map(),
|
||||
fillerOf: () => null,
|
||||
}
|
||||
|
||||
const EpisodeMetaContext = createContext<EpisodeMetaValue>(DEFAULT)
|
||||
|
||||
export function EpisodeMetaProvider({
|
||||
cinemetaMap,
|
||||
fillerOf,
|
||||
children,
|
||||
}: {
|
||||
cinemetaMap: CinemetaMap
|
||||
fillerOf: FillerOf
|
||||
children: ReactNode
|
||||
}) {
|
||||
return (
|
||||
<EpisodeMetaContext.Provider value={{ cinemetaMap, fillerOf }}>
|
||||
{children}
|
||||
</EpisodeMetaContext.Provider>
|
||||
)
|
||||
}
|
||||
|
||||
export function useEpisodeMeta(): EpisodeMetaValue {
|
||||
return useContext(EpisodeMetaContext)
|
||||
}
|
||||
|
||||
/** Convenience: pull a single episode's Cinemeta entry from context. */
|
||||
export function useCinemetaEpisode(
|
||||
season: number | null | undefined,
|
||||
episode: number | null | undefined,
|
||||
): CinemetaEpisode | null {
|
||||
const { cinemetaMap } = useEpisodeMeta()
|
||||
if (season == null || episode == null) return null
|
||||
return cinemetaMap.get(`${season}:${episode}`) || null
|
||||
}
|
||||
|
||||
/** Convenience: classify a single episode against the filler list. */
|
||||
export function useFillerFlag(
|
||||
season: number | null | undefined,
|
||||
episode: number | null | undefined,
|
||||
): FillerFlag {
|
||||
const { fillerOf } = useEpisodeMeta()
|
||||
return fillerOf(season, episode)
|
||||
}
|
||||
Reference in New Issue
Block a user