Files
mal/web/shared/watch.go

124 lines
2.6 KiB
Go

package shared
import (
"encoding/json"
"fmt"
"log"
"strconv"
)
// WatchPageData holds the data needed for the watch page
type WatchPageData struct {
MalID int
Title string
TitleEnglish string
TitleJapanese string
ImageURL string
Airing bool
CurrentEpisode string
TotalEpisodes int
StartTimeSeconds float64
CurrentStatus 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 {
Token string `json:"token"`
Subtitles []SubtitleItem `json:"subtitles"`
}
// SubtitleItem represents a subtitle track
type SubtitleItem struct {
Lang string `json:"lang"`
Token string `json:"token"`
}
// SkipSegment represents a skippable segment (intro/outro)
type SkipSegment struct {
Type string `json:"type"`
Start float64 `json:"start"`
End float64 `json:"end"`
}
func ModeToken(mode string, modeSources map[string]ModeSource) string {
normalizedMode := mode
if _, ok := modeSources[normalizedMode]; !ok {
if _, ok := modeSources["dub"]; ok {
normalizedMode = "dub"
} else if _, ok := modeSources["sub"]; ok {
normalizedMode = "sub"
} else {
for key := range modeSources {
normalizedMode = key
break
}
}
}
source, ok := modeSources[normalizedMode]
if !ok {
return ""
}
return source.Token
}
func ToJSON(v interface{}) string {
b, err := json.Marshal(v)
if err != nil {
log.Printf("ToJSON error: %v", err)
return "{}"
}
return string(b)
}
func EpisodeWithOffsetURL(animeID int, currentEpisode string, offset int) string {
episodeID, err := strconv.Atoi(currentEpisode)
if err != nil {
episodeID = 1
}
nextEpisode := episodeID + offset
if nextEpisode < 1 {
nextEpisode = 1
}
return fmt.Sprintf("/watch/%d/%d", animeID, nextEpisode)
}
func CanGoPrevEpisode(currentEpisode string) bool {
episodeID, err := strconv.Atoi(currentEpisode)
if err != nil {
return false
}
return episodeID > 1
}
func CanGoNextEpisode(currentEpisode string, totalEpisodes int) bool {
if totalEpisodes <= 0 {
return true
}
episodeID, err := strconv.Atoi(currentEpisode)
if err != nil {
return false
}
return episodeID < totalEpisodes
}
func ModeAvailable(modes []string, mode string) bool {
for _, value := range modes {
if value == mode {
return true
}
}
return false
}
func ModeButtonTitle(label string, enabled bool) string {
if enabled {
return label
}
return label + " unavailable for this episode"
}