fix: sync completed state after playback
This commit is contained in:
@@ -4,6 +4,7 @@ import (
|
||||
"context"
|
||||
"database/sql"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"io"
|
||||
"log"
|
||||
"net/http"
|
||||
@@ -100,6 +101,10 @@ func (h *Handler) HandleWatchPage(w http.ResponseWriter, r *http.Request) {
|
||||
pageData := templates.WatchPageData{
|
||||
MalID: data.MalID,
|
||||
Title: data.Title,
|
||||
TitleEnglish: anime.TitleEnglish,
|
||||
TitleJapanese: anime.TitleJapanese,
|
||||
ImageURL: anime.ImageURL(),
|
||||
Airing: anime.Airing,
|
||||
CurrentEpisode: data.CurrentEpisode,
|
||||
TotalEpisodes: anime.Episodes,
|
||||
StartTimeSeconds: data.StartTimeSeconds,
|
||||
@@ -279,6 +284,21 @@ func (h *Handler) HandleSaveProgress(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
}
|
||||
|
||||
watchListEntry, watchListErr := h.svc.db.GetWatchListEntry(r.Context(), database.GetWatchListEntryParams{
|
||||
UserID: user.ID,
|
||||
AnimeID: animeID,
|
||||
})
|
||||
if watchListErr == nil && watchListEntry.Status == "completed" {
|
||||
if err := h.svc.db.DeleteContinueWatchingEntry(r.Context(), database.DeleteContinueWatchingEntryParams{
|
||||
UserID: user.ID,
|
||||
AnimeID: animeID,
|
||||
}); err != nil {
|
||||
log.Printf("save progress failed to clear continue entry user_id=%s mal_id=%d err=%v", user.ID, payload.MalID, err)
|
||||
}
|
||||
w.WriteHeader(http.StatusNoContent)
|
||||
return
|
||||
}
|
||||
|
||||
if err := h.svc.db.SaveWatchProgress(r.Context(), database.SaveWatchProgressParams{
|
||||
CurrentEpisode: sql.NullInt64{Int64: int64(payload.Episode), Valid: true},
|
||||
CurrentTimeSeconds: timeSeconds,
|
||||
@@ -379,6 +399,30 @@ func (h *Handler) HandleCompleteAnime(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
if _, err := h.svc.db.GetContinueWatchingEntry(r.Context(), database.GetContinueWatchingEntryParams{
|
||||
UserID: user.ID,
|
||||
AnimeID: animeID,
|
||||
}); err == nil {
|
||||
log.Printf("complete anime failed to clear continue entry user_id=%s mal_id=%d", user.ID, payload.MalID)
|
||||
http.Error(w, "failed to mark anime completed", http.StatusInternalServerError)
|
||||
return
|
||||
} else if !errors.Is(err, sql.ErrNoRows) {
|
||||
log.Printf("complete anime failed to verify continue clear user_id=%s mal_id=%d err=%v", user.ID, payload.MalID, err)
|
||||
http.Error(w, "failed to mark anime completed", http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
if err := h.svc.db.SaveWatchProgress(r.Context(), database.SaveWatchProgressParams{
|
||||
CurrentEpisode: sql.NullInt64{Int64: int64(payload.Episode), Valid: true},
|
||||
CurrentTimeSeconds: 0,
|
||||
UserID: user.ID,
|
||||
AnimeID: animeID,
|
||||
}); err != nil {
|
||||
if err.Error() != "sql: no rows in result set" {
|
||||
log.Printf("complete anime failed to reset watchlist progress user_id=%s mal_id=%d err=%v", user.ID, payload.MalID, err)
|
||||
}
|
||||
}
|
||||
|
||||
w.WriteHeader(http.StatusNoContent)
|
||||
}
|
||||
|
||||
|
||||
@@ -13,6 +13,10 @@ import (
|
||||
type WatchPageData struct {
|
||||
MalID int
|
||||
Title string
|
||||
TitleEnglish string
|
||||
TitleJapanese string
|
||||
ImageURL string
|
||||
Airing bool
|
||||
CurrentEpisode string
|
||||
TotalEpisodes int
|
||||
StartTimeSeconds float64
|
||||
@@ -88,7 +92,9 @@ templ WatchPage(anime jikan.Anime, data WatchPageData) {
|
||||
} else {
|
||||
<span class="inline-flex h-8 items-center bg-(--panel-soft) px-2 text-xs text-(--text-faint) opacity-50">Next ▶</span>
|
||||
}
|
||||
@WatchlistDropdown(anime.MalID, anime.Title, anime.TitleEnglish, anime.TitleJapanese, anime.ImageURL(), data.CurrentStatus, anime.Airing)
|
||||
<span id="watch-status-dropdown">
|
||||
@WatchlistDropdown(anime.MalID, anime.Title, anime.TitleEnglish, anime.TitleJapanese, anime.ImageURL(), data.CurrentStatus, anime.Airing)
|
||||
</span>
|
||||
</div>
|
||||
<section>
|
||||
<h3 class="mb-3 text-lg font-semibold tracking-wide text-(--text)">Watch more seasons of this anime</h3>
|
||||
@@ -201,6 +207,11 @@ templ VideoPlayer(data WatchPageData) {
|
||||
data-video-player
|
||||
data-stream-url="/watch/proxy/stream"
|
||||
data-current-episode={ data.CurrentEpisode }
|
||||
data-anime-title={ data.Title }
|
||||
data-anime-title-english={ data.TitleEnglish }
|
||||
data-anime-title-japanese={ data.TitleJapanese }
|
||||
data-anime-image={ data.ImageURL }
|
||||
data-anime-airing={ fmt.Sprintf("%v", data.Airing) }
|
||||
data-start-time-seconds={ fmt.Sprintf("%.3f", data.StartTimeSeconds) }
|
||||
data-initial-mode={ data.InitialMode }
|
||||
data-available-modes={ toJSON(data.AvailableModes) }
|
||||
|
||||
@@ -107,7 +107,7 @@ templ Watchlist(entries []database.GetUserWatchListRow, layout string, currentSt
|
||||
}
|
||||
|
||||
templ ifHasProgress(entry database.GetUserWatchListRow) {
|
||||
if entry.CurrentEpisode.Valid && entry.CurrentEpisode.Int64 > 0 {
|
||||
if entry.CurrentEpisode.Valid && entry.CurrentEpisode.Int64 > 0 && entry.Status != "completed" {
|
||||
<p class="m-0 mt-1 text-xs text-(--text-faint)">
|
||||
Continue ep { fmt.Sprintf("%d", entry.CurrentEpisode.Int64) }
|
||||
if entry.CurrentTimeSeconds > 0 {
|
||||
|
||||
Reference in New Issue
Block a user