feat: persist watchlist status on anime cards with white bookmark and outline play button

This commit is contained in:
2026-04-21 00:41:23 +02:00
parent a5f2628d1e
commit cd8df7d2bf
10 changed files with 89 additions and 63 deletions

View File

@@ -5,18 +5,19 @@ import (
ui "mal/web/components"
)
templ Recommendations(recs []jikan.Anime) {
templ Recommendations(recs []jikan.Anime, watchlistStatuses map[int]string) {
if len(recs) > 0 {
<div class="grid grid-cols-2 gap-3 sm:grid-cols-3 md:gap-4 lg:grid-cols-4 xl:grid-cols-6">
for _, anime := range recs {
@ui.AnimeCard(ui.AnimeCardProps{
ID: anime.MalID,
Title: anime.DisplayTitle(),
ImageURL: anime.ImageURL(),
TitleEnglish: anime.TitleEnglish,
TitleJapanese: anime.TitleJapanese,
Airing: anime.Airing,
Synopsis: anime.Synopsis,
ID: anime.MalID,
Title: anime.DisplayTitle(),
ImageURL: anime.ImageURL(),
TitleEnglish: anime.TitleEnglish,
TitleJapanese: anime.TitleJapanese,
Airing: anime.Airing,
Synopsis: anime.Synopsis,
WatchlistStatus: watchlistStatuses[anime.MalID],
})
}
</div>

View File

@@ -5,18 +5,19 @@ import (
ui "mal/web/components"
)
templ RelationsList(relations []jikan.RelationEntry) {
templ RelationsList(relations []jikan.RelationEntry, watchlistStatuses map[int]string) {
if len(relations) > 1 {
<div class="grid grid-cols-2 gap-3 sm:grid-cols-3 md:gap-4 lg:grid-cols-4 xl:grid-cols-6" id="relations-grid">
for _, rel := range relations {
@ui.AnimeCard(ui.AnimeCardProps{
ID: rel.Anime.MalID,
Title: rel.Anime.DisplayTitle(),
ImageURL: rel.Anime.ImageURL(),
TitleEnglish: rel.Anime.TitleEnglish,
TitleJapanese: rel.Anime.TitleJapanese,
Airing: rel.Anime.Airing,
CurrentNode: rel.IsCurrent,
ID: rel.Anime.MalID,
Title: rel.Anime.DisplayTitle(),
ImageURL: rel.Anime.ImageURL(),
TitleEnglish: rel.Anime.TitleEnglish,
TitleJapanese: rel.Anime.TitleJapanese,
Airing: rel.Anime.Airing,
CurrentNode: rel.IsCurrent,
WatchlistStatus: watchlistStatuses[rel.Anime.MalID],
}) {
if rel.IsCurrent {
<div class="mt-2 h-0.5 w-10 bg-white"></div>
@@ -31,5 +32,3 @@ templ RelationsList(relations []jikan.RelationEntry) {
<p class="text-sm text-(--text-muted)">No related anime found.</p>
}
}

View File

@@ -87,7 +87,7 @@ templ animeCardPoster(props AnimeCardProps) {
>
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<title>Play</title>
<path d="M8 5V19L19 12L8 5Z" fill="currentColor" stroke="currentColor" stroke-width="1.5" stroke-linejoin="round"/>
<path d="M8 5V19L19 12L8 5Z" stroke="currentColor" stroke-width="1.5" stroke-linejoin="round"/>
</svg>
</a>
}

View File

@@ -5,10 +5,10 @@ import (
"mal/integrations/jikan"
)
templ InfiniteAnimeList(animes []jikan.Anime, hasNext bool, nextURL string, containerID string) {
templ InfiniteAnimeList(animes []jikan.Anime, watchlistStatuses map[int]string, hasNext bool, nextURL string, containerID string) {
for _, anime := range animes {
<div class="min-w-0" data-id={ fmt.Sprintf("%d", anime.MalID) }>
@CatalogItem(anime)
@CatalogItem(anime, watchlistStatuses[anime.MalID])
</div>
}
if hasNext {
@@ -29,15 +29,16 @@ templ InfiniteAnimeList(animes []jikan.Anime, hasNext bool, nextURL string, cont
</script>
}
templ CatalogItem(anime jikan.Anime) {
templ CatalogItem(anime jikan.Anime, watchlistStatus string) {
@AnimeCard(AnimeCardProps{
ID: anime.MalID,
Title: anime.DisplayTitle(),
ImageURL: anime.ImageURL(),
TitleEnglish: anime.TitleEnglish,
TitleJapanese: anime.TitleJapanese,
Airing: anime.Airing,
Synopsis: anime.Synopsis,
PlayHref: fmt.Sprintf("/watch/%d/1", anime.MalID),
ID: anime.MalID,
Title: anime.DisplayTitle(),
ImageURL: anime.ImageURL(),
TitleEnglish: anime.TitleEnglish,
TitleJapanese: anime.TitleJapanese,
Airing: anime.Airing,
Synopsis: anime.Synopsis,
PlayHref: fmt.Sprintf("/watch/%d/1", anime.MalID),
WatchlistStatus: watchlistStatus,
})
}

View File

@@ -12,7 +12,7 @@ templ CardButton(
inWatchlist bool,
) {
<button
class={ "cursor-pointer border-0 bg-transparent p-0", templ.KV("text-blue-500", inWatchlist), templ.KV("text-white hover:text-blue-400", !inWatchlist) }
class={ "cursor-pointer border-0 bg-transparent p-0", templ.KV("text-white", inWatchlist), templ.KV("text-white hover:text-white/70", !inWatchlist) }
if !inWatchlist {
hx-post="/api/watchlist/card"
hx-vals={ fmt.Sprintf(`{"anime_id": "%d", "anime_title": "%s", "anime_title_english": "%s", "anime_title_japanese": "%s", "anime_image": "%s", "airing": "%v"}`, animeID, title, titleEnglish, titleJapanese, imageURL, airing) }