feat: update video overlay on episode transition

This commit is contained in:
2026-04-26 23:32:00 +02:00
parent 19481caeec
commit 2325ff4561
3 changed files with 27 additions and 0 deletions

View File

@@ -392,6 +392,15 @@ func (h *Handler) HandleEpisodeData(w http.ResponseWriter, r *http.Request) {
return
}
episodeTitle := ""
epNum, epErr := strconv.Atoi(episode)
if epErr == nil && epNum > 0 {
episodeData, epErr := h.jikanClient.GetEpisode(ctx, malID, epNum)
if epErr == nil && episodeData.Data.Title != "" {
episodeTitle = episodeData.Data.Title
}
}
clientModeSources := convertModeSources(data.ModeSources)
initialMode := data.InitialMode
token := ""
@@ -409,6 +418,7 @@ func (h *Handler) HandleEpisodeData(w http.ResponseWriter, r *http.Request) {
AvailableModes []string `json:"available_modes"`
ModeSources map[string]shared.ModeSource `json:"mode_sources"`
Segments []shared.SkipSegment `json:"segments"`
EpisodeTitle string `json:"episode_title"`
}{
MalID: malID,
Title: data.Title,
@@ -419,6 +429,7 @@ func (h *Handler) HandleEpisodeData(w http.ResponseWriter, r *http.Request) {
AvailableModes: data.AvailableModes,
ModeSources: clientModeSources,
Segments: convertToSharedSegments(data.Segments),
EpisodeTitle: episodeTitle,
}
w.Header().Set("Content-Type", "application/json")

View File

@@ -30,6 +30,7 @@ interface EpisodeData {
available_modes: string[]
mode_sources: Record<string, ModeSource>
segments: SkipSegment[]
episode_title: string
}
interface EpisodeData {
@@ -42,6 +43,7 @@ interface EpisodeData {
available_modes: string[]
mode_sources: Record<string, ModeSource>
segments: SkipSegment[]
episode_title: string
}
let playerInitialized = false
@@ -144,6 +146,7 @@ const initPlayer = (): void => {
const previewPopover = container.querySelector('[data-preview-popover]') as HTMLElement
const previewTime = container.querySelector('[data-preview-time]') as HTMLElement
const videoOverlay = container.querySelector('[data-video-overlay]') as HTMLElement
const streamUrlForMode = (mode: string): string => {
const modeParam = encodeURIComponent(mode)
const modeSource = modeSources[mode]
@@ -310,6 +313,17 @@ const initPlayer = (): void => {
})
}
const updateVideoOverlay = (episode: string, episodeTitle: string): void => {
if (!videoOverlay) return
const episodeText = episodeTitle
? `Episode ${episode}, ${episodeTitle}`
: `Episode ${episode}`
const secondLine = videoOverlay.querySelector('p')
if (secondLine) {
secondLine.textContent = episodeText
}
}
const formatTime = (seconds: number): string => {
if (!Number.isFinite(seconds) || seconds < 0) return '00:00'
const mins = Math.floor(seconds / 60)
@@ -867,6 +881,7 @@ const loadNextEpisodeInPlace = async (animeID: number, nextEpisode: number): Pro
renderSegments()
updateSubtitleOptions()
updateModeButtons(data.initial_mode)
updateVideoOverlay(String(nextEpisode), data.episode_title)
const nextUrl = `/watch/${animeID}/${nextEpisode}`
window.history.replaceState(null, '', nextUrl)

View File

@@ -38,6 +38,7 @@ templ VideoPlayer(data shared.WatchPageData, displayTitle string) {
src={ shared.BuildStreamURL(data.InitialMode, streamToken) }
></video>
<div
data-video-overlay
class="pointer-events-none absolute inset-x-0 top-0 z-30 flex flex-col items-start bg-linear-to-b from-black/80 via-black/40 to-transparent p-4 opacity-100 transition-opacity duration-300 sm:p-6 sm:opacity-0 group-[.show-controls]/player:opacity-100 sm:group-[.show-controls]/player:opacity-100"
>
<h2 class="text-lg font-bold text-white drop-shadow-md sm:text-xl md:text-2xl">{ displayTitle }</h2>