* feat: add ffmpeg for hls streaming * feat: torrent streaming with hls transcoding - add nyaa.si torrent search client - add streaming service using anacrolix/torrent - add hls transcoding via ffmpeg for browser playback - add watch page with episode selection - add socks5 proxy support via TORRENT_PROXY env - switch to modernc.org/sqlite (pure go, no cgo conflicts) - update dockerfile with ffmpeg
73 lines
1.9 KiB
Plaintext
73 lines
1.9 KiB
Plaintext
package templates
|
|
|
|
import "mal/internal/jikan"
|
|
import "fmt"
|
|
|
|
// EpisodesList renders a list of episodes for an anime
|
|
templ EpisodesList(animeID int, animeTitle string, episodes []jikan.Episode, totalEpisodes int) {
|
|
<section class="episodes-section">
|
|
<div class="episodes-header">
|
|
<h3>episodes</h3>
|
|
if totalEpisodes > 0 {
|
|
<span class="episode-count">{ fmt.Sprintf("%d episodes", totalEpisodes) }</span>
|
|
}
|
|
</div>
|
|
if len(episodes) == 0 {
|
|
<p class="no-episodes">no episode data available</p>
|
|
} else {
|
|
<div class="episodes-grid">
|
|
for _, ep := range episodes {
|
|
@EpisodeCard(animeID, animeTitle, ep)
|
|
}
|
|
</div>
|
|
}
|
|
</section>
|
|
}
|
|
|
|
// EpisodeCard renders a single episode card with play button
|
|
templ EpisodeCard(animeID int, animeTitle string, ep jikan.Episode) {
|
|
<div class="episode-card" data-episode={ fmt.Sprintf("%d", ep.MalID) }>
|
|
<div class="episode-number">{ fmt.Sprintf("%d", ep.MalID) }</div>
|
|
<div class="episode-info">
|
|
<div class="episode-title">
|
|
if ep.Title != "" {
|
|
{ ep.Title }
|
|
} else {
|
|
{ fmt.Sprintf("Episode %d", ep.MalID) }
|
|
}
|
|
</div>
|
|
if ep.Filler {
|
|
<span class="episode-tag filler">filler</span>
|
|
}
|
|
if ep.Recap {
|
|
<span class="episode-tag recap">recap</span>
|
|
}
|
|
</div>
|
|
<button
|
|
class="episode-play"
|
|
hx-get={ string(templ.URL(fmt.Sprintf("/watch/%d/%d", animeID, ep.MalID))) }
|
|
hx-target="body"
|
|
hx-push-url="true"
|
|
>
|
|
<svg viewBox="0 0 24 24" fill="currentColor" class="play-icon">
|
|
<path d="M8 5v14l11-7z"/>
|
|
</svg>
|
|
</button>
|
|
</div>
|
|
}
|
|
|
|
// EpisodesLoading renders a loading state for episodes
|
|
templ EpisodesLoading() {
|
|
<section class="episodes-section">
|
|
<div class="episodes-header">
|
|
<h3>episodes</h3>
|
|
</div>
|
|
<div class="loading-indicator">
|
|
<div class="loading-dot"></div>
|
|
<div class="loading-dot"></div>
|
|
<div class="loading-dot"></div>
|
|
<span>loading episodes</span>
|
|
</div>
|
|
</section>
|
|
}
|