package templates import ( "encoding/json" "fmt" "mal/internal/jikan" "net/url" ) // WatchPageData holds the data needed for the watch page type WatchPageData struct { MalID int Title string CurrentEpisode string InitialMode string AvailableModes []string ModeSources map[string]ModeSource Segments []SkipSegment } // ModeSource represents a stream source for a specific mode (dub/sub) type ModeSource struct { URL string `json:"url"` Referer string `json:"referer"` Subtitles []SubtitleItem `json:"subtitles"` } // SubtitleItem represents a subtitle track type SubtitleItem struct { Lang string `json:"lang"` URL string `json:"url"` Referer string `json:"referer"` } // SkipSegment represents a skippable segment (intro/outro) type SkipSegment struct { Type string `json:"type"` Start float64 `json:"start"` End float64 `json:"end"` } templ WatchPage(anime jikan.Anime, data WatchPageData) { @Layout(fmt.Sprintf("%s - episode %s", anime.DisplayTitle(), data.CurrentEpisode), true) {
@VideoPlayer(data)

{ anime.DisplayTitle() }

Episode { data.CurrentEpisode } if anime.Episodes > 0 { / { fmt.Sprintf("%d", anime.Episodes) } }

} } templ LoadingIndicatorSmall() {
} templ EpisodeList(episodes []jikan.Episode, currentEpisode string, animeID int) { if len(episodes) == 0 {

No episodes available

} else {
for _, ep := range episodes { @EpisodeItem(ep, currentEpisode, animeID) }
} } templ EpisodeItem(episode jikan.Episode, currentEpisode string, animeID int) { {{ isCurrent := fmt.Sprintf("%d", episode.MalID) == currentEpisode }} { fmt.Sprintf("%d", episode.MalID) } if episode.Title != "" { { episode.Title } } else { Episode { fmt.Sprintf("%d", episode.MalID) } } if episode.Filler { Filler } if episode.Recap { Recap } } templ VideoPlayer(data WatchPageData) { {{ streamURL := buildStreamURL(data.InitialMode, data.ModeSources) }}
00:00 / 00:00
} func buildStreamURL(mode string, modeSources map[string]ModeSource) string { stateJSON, _ := json.Marshal(modeSources) return fmt.Sprintf("/watch/proxy/stream?mode=%s&state=%s", url.QueryEscape(mode), url.QueryEscape(string(stateJSON))) } func toJSON(v interface{}) string { b, _ := json.Marshal(v) return string(b) }