Files
mal/web/templates/watch.templ

144 lines
4.9 KiB
Plaintext

package templates
import (
"fmt"
"mal/integrations/jikan"
components "mal/web/components"
"mal/web/components/ui"
"mal/web/components/watch"
"mal/web/components/watchlist"
"mal/web/shared"
"mal/web/shared/layout"
)
templ WatchPage(anime jikan.Anime, data shared.WatchPageData) {
@layout.Layout(fmt.Sprintf("%s - episode %s", anime.DisplayTitle(), data.CurrentEpisode), true) {
<div class="w-full overflow-x-clip">
<div class="mx-auto grid w-full gap-4 lg:gap-5 lg:grid-cols-[220px_minmax(0,1fr)_250px] xl:grid-cols-[240px_minmax(0,1fr)_280px]">
<!-- Left sidebar: Episodes -->
<aside class="order-2 w-full min-w-0 lg:order-1">
<div class="flex h-full max-h-[320px] flex-col sm:max-h-[420px] lg:max-h-[800px]">
<div class="p-3 flex items-center justify-between">
<h3 class="text-sm font-semibold tracking-wide text-(--text)">Episodes</h3>
</div>
<div
id="episodes-list"
hx-get={ string(templ.URL(fmt.Sprintf("/api/anime/%d/episodes?current=%s", anime.MalID, data.CurrentEpisode))) }
hx-trigger="load"
class="overflow-y-auto flex-1 [&::-webkit-scrollbar]:hidden"
>
@ui.LoadingIndicatorSmall()
</div>
</div>
</aside>
<!-- Main content: Video and Controls -->
<div
class="order-1 flex min-w-0 flex-1 flex-col gap-4 sm:gap-5 lg:order-2"
hx-boost="true"
>
@watch.VideoPlayer(data, anime.DisplayTitle())
<div class="flex flex-wrap items-center gap-2">
<button
data-autoplay
class="inline-flex h-8 items-center gap-1.5 bg-(--panel-soft) px-2 text-xs text-(--text) hover:bg-(--panel)"
title="Autoplay: On"
>
<svg class="h-4 w-4 shrink-0" viewBox="0 0 24 24" aria-hidden="true">
<polygon points="5 6 16 12 5 18" fill="currentColor" stroke="none"></polygon>
<line x1="19" y1="6" x2="19" y2="18" stroke="currentColor" stroke-width="2" stroke-linecap="round"></line>
</svg>
Autoplay: On
</button>
<div class="ml-auto flex flex-wrap items-center gap-2">
if shared.CanGoPrevEpisode(data.CurrentEpisode) {
<a
href={ templ.URL(shared.EpisodeWithOffsetURL(anime.MalID, data.CurrentEpisode, -1)) }
class="inline-flex h-8 items-center bg-(--panel-soft) px-2 text-xs text-(--text) no-underline hover:bg-(--panel) hover:text-(--text) hover:no-underline"
>
◀ Prev
</a>
} else {
<span class="inline-flex h-8 items-center bg-(--panel-soft) px-2 text-xs text-(--text-faint) opacity-50">
◀ Prev
</span>
}
if shared.CanGoNextEpisode(data.CurrentEpisode, anime.Episodes) {
<a
href={ templ.URL(shared.EpisodeWithOffsetURL(anime.MalID, data.CurrentEpisode, 1)) }
class="inline-flex h-8 items-center bg-(--panel-soft) px-2 text-xs text-(--text) no-underline hover:bg-(--panel) hover:text-(--text) hover:no-underline"
>
Next ▶
</a>
} else {
<span class="inline-flex h-8 items-center bg-(--panel-soft) px-2 text-xs text-(--text-faint) opacity-50">
Next ▶
</span>
}
<span id="watch-status-dropdown">
@watchlist.WatchlistDropdown(
anime.MalID,
anime.Title,
anime.TitleEnglish,
anime.TitleJapanese,
anime.ImageURL(),
data.CurrentStatus,
anime.Airing,
)
</span>
</div>
</div>
<section>
<h3 class="mb-3 text-lg font-semibold tracking-wide text-(--text)">
Watch more seasons of this anime
</h3>
<div
hx-get={ string(templ.URL(fmt.Sprintf("/api/anime/%d/relations", anime.MalID))) }
hx-trigger="load"
>
@components.LoadingIndicator("Loading relations")
</div>
</section>
</div>
<!-- Right sidebar: Anime Info -->
<aside class="order-3 w-full min-w-0 flex flex-col gap-4 lg:order-3">
<img
src={ anime.Images.Webp.LargeImageURL }
alt={ anime.Title }
class="mx-auto w-full max-w-sm object-cover shadow-lg lg:max-w-none"
/>
<div>
<h2 class="text-xl font-bold text-(--text)">{ anime.DisplayTitle() }</h2>
<div class="mt-2 flex flex-wrap items-center gap-2 text-xs text-(--text-muted)">
if anime.ShortRating() != "" {
<span>{ anime.ShortRating() }</span>
<span>•</span>
}
<span>HD</span>
<span>•</span>
<span>{ anime.Type }</span>
<span>•</span>
if anime.ShortDuration() != "" {
<span>{ anime.ShortDuration() }</span>
} else {
<span>{ anime.Duration }</span>
}
</div>
<p class="text-sm text-(--text-muted) mt-4 line-clamp-6">
{ anime.Synopsis }
</p>
</div>
<a
href={ templ.URL(fmt.Sprintf("/anime/%d", anime.MalID)) }
class="inline-flex h-9 items-center justify-center bg-(--panel-soft) px-4 text-sm font-semibold text-(--text) no-underline hover:bg-(--panel) hover:text-(--text) transition-colors"
>
View detail
</a>
</aside>
</div>
</div>
}
}