refactor: extract watchlist map to service, optimize command palette queries
This commit is contained in:
@@ -26,6 +26,28 @@ func NewAnimeHandler(svc domain.AnimeService, watchlistSvc domain.WatchlistServi
|
||||
}
|
||||
}
|
||||
|
||||
func (h *AnimeHandler) watchlistMapForAnimes(ctx context.Context, userID string, animes []domain.Anime) map[int]bool {
|
||||
animeIDs := make([]int64, 0, len(animes))
|
||||
for _, anime := range animes {
|
||||
if anime.MalID > 0 {
|
||||
animeIDs = append(animeIDs, int64(anime.MalID))
|
||||
}
|
||||
}
|
||||
return h.watchlistMapForIDs(ctx, userID, animeIDs)
|
||||
}
|
||||
|
||||
func (h *AnimeHandler) watchlistMapForIDs(ctx context.Context, userID string, animeIDs []int64) map[int]bool {
|
||||
if userID == "" || len(animeIDs) == 0 {
|
||||
return map[int]bool{}
|
||||
}
|
||||
|
||||
watchlistMap, err := h.watchlistSvc.GetWatchlistMap(ctx, userID, animeIDs)
|
||||
if err != nil {
|
||||
return map[int]bool{}
|
||||
}
|
||||
return watchlistMap
|
||||
}
|
||||
|
||||
func (h *AnimeHandler) Register(r *gin.Engine) {
|
||||
|
||||
r.GET("/", h.HandleCatalog)
|
||||
@@ -47,18 +69,11 @@ func (h *AnimeHandler) Register(r *gin.Engine) {
|
||||
|
||||
func (h *AnimeHandler) HandleCatalog(c *gin.Context) {
|
||||
user, _ := c.Get("User")
|
||||
watchlistMap := make(map[int]bool)
|
||||
if u, ok := user.(*domain.User); ok {
|
||||
entries, _ := h.watchlistSvc.GetWatchlist(c.Request.Context(), u.ID)
|
||||
for _, e := range entries {
|
||||
watchlistMap[int(e.AnimeID)] = true
|
||||
}
|
||||
}
|
||||
|
||||
c.HTML(http.StatusOK, "index.gohtml", gin.H{
|
||||
"CurrentPath": "/",
|
||||
"User": user,
|
||||
"WatchlistMap": watchlistMap,
|
||||
"WatchlistMap": map[int]bool{},
|
||||
})
|
||||
}
|
||||
|
||||
@@ -85,12 +100,9 @@ func (h *AnimeHandler) renderCatalogSection(c *gin.Context, section string) {
|
||||
return
|
||||
}
|
||||
|
||||
watchlistMap := make(map[int]bool)
|
||||
if userID != "" {
|
||||
entries, _ := h.watchlistSvc.GetWatchlist(c.Request.Context(), userID)
|
||||
for _, e := range entries {
|
||||
watchlistMap[int(e.AnimeID)] = true
|
||||
}
|
||||
watchlistMap := map[int]bool{}
|
||||
if animes, ok := data["Animes"].([]domain.Anime); ok {
|
||||
watchlistMap = h.watchlistMapForAnimes(c.Request.Context(), userID, animes)
|
||||
}
|
||||
|
||||
data["Section"] = section
|
||||
@@ -130,12 +142,9 @@ func (h *AnimeHandler) renderDiscoverSection(c *gin.Context, section string) {
|
||||
return
|
||||
}
|
||||
|
||||
watchlistMap := make(map[int]bool)
|
||||
if userID != "" {
|
||||
entries, _ := h.watchlistSvc.GetWatchlist(c.Request.Context(), userID)
|
||||
for _, e := range entries {
|
||||
watchlistMap[int(e.AnimeID)] = true
|
||||
}
|
||||
watchlistMap := map[int]bool{}
|
||||
if animes, ok := data["Animes"].([]domain.Anime); ok {
|
||||
watchlistMap = h.watchlistMapForAnimes(c.Request.Context(), userID, animes)
|
||||
}
|
||||
|
||||
data["Section"] = section
|
||||
@@ -170,13 +179,11 @@ func (h *AnimeHandler) HandleBrowse(c *gin.Context) {
|
||||
}
|
||||
|
||||
user, _ := c.Get("User")
|
||||
watchlistMap := make(map[int]bool)
|
||||
userID := ""
|
||||
if u, ok := user.(*domain.User); ok {
|
||||
entries, _ := h.watchlistSvc.GetWatchlist(c.Request.Context(), u.ID)
|
||||
for _, e := range entries {
|
||||
watchlistMap[int(e.AnimeID)] = true
|
||||
}
|
||||
userID = u.ID
|
||||
}
|
||||
watchlistMap := h.watchlistMapForAnimes(c.Request.Context(), userID, res.Animes)
|
||||
|
||||
if c.GetHeader("HX-Request") == "true" && page > 1 {
|
||||
c.HTML(http.StatusOK, "browse.gohtml", gin.H{
|
||||
@@ -246,27 +253,30 @@ func (h *AnimeHandler) HandleAnimeDetails(c *gin.Context) {
|
||||
|
||||
section := c.Query("section")
|
||||
if section != "" && c.GetHeader("HX-Request") == "true" {
|
||||
sectionCtx, cancel := context.WithTimeout(c.Request.Context(), 4*time.Second)
|
||||
defer cancel()
|
||||
|
||||
var data any
|
||||
var tplName string
|
||||
var err error
|
||||
switch section {
|
||||
case "characters":
|
||||
data, err = h.svc.GetCharacters(c.Request.Context(), id)
|
||||
data, err = h.svc.GetCharacters(sectionCtx, id)
|
||||
tplName = "anime_characters"
|
||||
case "recommendations":
|
||||
data, err = h.svc.GetRecommendations(c.Request.Context(), id)
|
||||
data, err = h.svc.GetRecommendations(sectionCtx, id)
|
||||
tplName = "anime_recommendations"
|
||||
|
||||
case "statistics":
|
||||
data, err = h.svc.GetStatistics(c.Request.Context(), id)
|
||||
data, err = h.svc.GetStatistics(sectionCtx, id)
|
||||
tplName = "anime_statistics"
|
||||
case "themes":
|
||||
data, err = h.svc.GetThemes(c.Request.Context(), id)
|
||||
data, err = h.svc.GetThemes(sectionCtx, id)
|
||||
tplName = "anime_themes"
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
c.Status(http.StatusInternalServerError)
|
||||
c.String(http.StatusOK, "")
|
||||
return
|
||||
}
|
||||
|
||||
@@ -326,19 +336,22 @@ func (h *AnimeHandler) HandleHTMLWatchOrder(c *gin.Context) {
|
||||
userID = u.ID
|
||||
}
|
||||
|
||||
relations, err := h.svc.GetRelations(c.Request.Context(), id)
|
||||
relationsCtx, cancel := context.WithTimeout(c.Request.Context(), 5*time.Second)
|
||||
defer cancel()
|
||||
|
||||
relations, err := h.svc.GetRelations(relationsCtx, id)
|
||||
if err != nil {
|
||||
c.Status(http.StatusInternalServerError)
|
||||
c.String(http.StatusOK, "")
|
||||
return
|
||||
}
|
||||
|
||||
watchlistMap := make(map[int]bool)
|
||||
if userID != "" {
|
||||
entries, _ := h.watchlistSvc.GetWatchlist(c.Request.Context(), userID)
|
||||
for _, e := range entries {
|
||||
watchlistMap[int(e.AnimeID)] = true
|
||||
relationAnimeIDs := make([]int64, 0, len(relations))
|
||||
for _, relation := range relations {
|
||||
if relation.Anime.MalID > 0 {
|
||||
relationAnimeIDs = append(relationAnimeIDs, int64(relation.Anime.MalID))
|
||||
}
|
||||
}
|
||||
watchlistMap := h.watchlistMapForIDs(c.Request.Context(), userID, relationAnimeIDs)
|
||||
|
||||
c.HTML(http.StatusOK, "anime.gohtml", gin.H{
|
||||
"_fragment": "watch_order",
|
||||
@@ -362,13 +375,11 @@ func (h *AnimeHandler) HandleQuickSearch(c *gin.Context) {
|
||||
}
|
||||
|
||||
user, _ := c.Get("User")
|
||||
watchlistMap := make(map[int]bool)
|
||||
userID := ""
|
||||
if u, ok := user.(*domain.User); ok {
|
||||
entries, _ := h.watchlistSvc.GetWatchlist(c.Request.Context(), u.ID)
|
||||
for _, e := range entries {
|
||||
watchlistMap[int(e.AnimeID)] = true
|
||||
}
|
||||
userID = u.ID
|
||||
}
|
||||
watchlistMap := h.watchlistMapForAnimes(c.Request.Context(), userID, res.Animes)
|
||||
|
||||
type quickSearchResult struct {
|
||||
ID int `json:"id"`
|
||||
@@ -462,7 +473,7 @@ func (h *AnimeHandler) commandPaletteNavigationItems(query string) []commandPale
|
||||
}
|
||||
|
||||
func (h *AnimeHandler) commandPaletteAnimeResults(c *gin.Context, query string) []commandPaletteItem {
|
||||
searchCtx, cancel := context.WithTimeout(c.Request.Context(), 1500*time.Millisecond)
|
||||
searchCtx, cancel := context.WithTimeout(c.Request.Context(), 800*time.Millisecond)
|
||||
defer cancel()
|
||||
|
||||
res, err := h.svc.SearchAdvanced(searchCtx, query, "", "", "", "", nil, true, 1, 5)
|
||||
@@ -487,35 +498,23 @@ func (h *AnimeHandler) commandPaletteAnimeResults(c *gin.Context, query string)
|
||||
func (h *AnimeHandler) commandPalettePersonalItems(c *gin.Context, userID string, query string) []commandPaletteItem {
|
||||
items := make([]commandPaletteItem, 0, 5)
|
||||
|
||||
watchlist, err := h.watchlistSvc.GetWatchlist(c.Request.Context(), userID)
|
||||
watchlist, err := h.watchlistSvc.GetCommandPaletteWatchlist(c.Request.Context(), userID, query, 5)
|
||||
if err != nil {
|
||||
return items
|
||||
}
|
||||
|
||||
watchlistCount := 0
|
||||
for _, status := range []string{"watching", "plan_to_watch"} {
|
||||
for _, entry := range watchlist {
|
||||
if watchlistCount >= 5 {
|
||||
return items
|
||||
}
|
||||
if entry.Status != status {
|
||||
continue
|
||||
}
|
||||
|
||||
title := watchlistTitle(entry)
|
||||
if query != "" && !commandPaletteMatches(query, title, entry.Status) {
|
||||
continue
|
||||
}
|
||||
|
||||
items = append(items, commandPaletteItem{
|
||||
ID: fmt.Sprintf("watchlist:%d", entry.AnimeID),
|
||||
Type: "watchlist",
|
||||
Label: title,
|
||||
Subtitle: watchlistStatusLabel(entry.Status),
|
||||
Href: fmt.Sprintf("/anime/%d", entry.AnimeID),
|
||||
Image: entry.ImageUrl,
|
||||
})
|
||||
watchlistCount++
|
||||
for _, entry := range watchlist {
|
||||
title := watchlistTitle(entry)
|
||||
items = append(items, commandPaletteItem{
|
||||
ID: fmt.Sprintf("watchlist:%d", entry.AnimeID),
|
||||
Type: "watchlist",
|
||||
Label: title,
|
||||
Subtitle: watchlistStatusLabel(entry.Status),
|
||||
Href: fmt.Sprintf("/anime/%d", entry.AnimeID),
|
||||
Image: entry.ImageUrl,
|
||||
})
|
||||
if len(items) >= 5 {
|
||||
return items
|
||||
}
|
||||
}
|
||||
|
||||
@@ -525,33 +524,29 @@ func (h *AnimeHandler) commandPalettePersonalItems(c *gin.Context, userID string
|
||||
func (h *AnimeHandler) commandPaletteContinueItems(c *gin.Context, userID string, query string) []commandPaletteItem {
|
||||
items := make([]commandPaletteItem, 0, 5)
|
||||
|
||||
data, err := h.svc.GetCatalogSection(c.Request.Context(), userID, "Continue")
|
||||
if err == nil {
|
||||
if rows, ok := data["ContinueWatching"].([]db.GetContinueWatchingEntriesRow); ok {
|
||||
for _, row := range rows {
|
||||
if len(items) >= 5 {
|
||||
break
|
||||
}
|
||||
rows, err := h.watchlistSvc.GetCommandPaletteContinueWatching(c.Request.Context(), userID, query, 5)
|
||||
if err != nil {
|
||||
return items
|
||||
}
|
||||
|
||||
title := continueWatchingTitle(row)
|
||||
if query != "" && !commandPaletteMatches(query, title, "Continue watching") {
|
||||
continue
|
||||
}
|
||||
episode := ""
|
||||
href := fmt.Sprintf("/anime/%d/watch", row.AnimeID)
|
||||
if row.CurrentEpisode.Valid {
|
||||
episode = fmt.Sprintf(" episode %d", row.CurrentEpisode.Int64)
|
||||
href = fmt.Sprintf("%s?ep=%d", href, row.CurrentEpisode.Int64)
|
||||
}
|
||||
items = append(items, commandPaletteItem{
|
||||
ID: fmt.Sprintf("continue:%d", row.AnimeID),
|
||||
Type: "continue",
|
||||
Label: "Continue watching " + title,
|
||||
Subtitle: "Resume" + episode,
|
||||
Href: href,
|
||||
Image: row.ImageUrl,
|
||||
})
|
||||
}
|
||||
for _, row := range rows {
|
||||
title := continueWatchingTitle(row)
|
||||
episode := ""
|
||||
href := fmt.Sprintf("/anime/%d/watch", row.AnimeID)
|
||||
if row.CurrentEpisode.Valid {
|
||||
episode = fmt.Sprintf(" episode %d", row.CurrentEpisode.Int64)
|
||||
href = fmt.Sprintf("%s?ep=%d", href, row.CurrentEpisode.Int64)
|
||||
}
|
||||
items = append(items, commandPaletteItem{
|
||||
ID: fmt.Sprintf("continue:%d", row.AnimeID),
|
||||
Type: "continue",
|
||||
Label: "Continue watching " + title,
|
||||
Subtitle: "Resume" + episode,
|
||||
Href: href,
|
||||
Image: row.ImageUrl,
|
||||
})
|
||||
if len(items) >= 5 {
|
||||
return items
|
||||
}
|
||||
}
|
||||
|
||||
@@ -594,7 +589,10 @@ func watchlistStatusLabel(status string) string {
|
||||
}
|
||||
|
||||
func (h *AnimeHandler) HandleRandomAnime(c *gin.Context) {
|
||||
anime, err := h.svc.GetRandomAnime(c.Request.Context())
|
||||
ctx, cancel := context.WithTimeout(c.Request.Context(), 5*time.Second)
|
||||
defer cancel()
|
||||
|
||||
anime, err := h.svc.GetRandomAnime(ctx)
|
||||
if err != nil {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to fetch random anime"})
|
||||
return
|
||||
@@ -607,13 +605,8 @@ func (h *AnimeHandler) HandleRandomAnime(c *gin.Context) {
|
||||
user, _ := c.Get("User")
|
||||
inWatchlist := false
|
||||
if u, ok := user.(*domain.User); ok {
|
||||
entries, _ := h.watchlistSvc.GetWatchlist(c.Request.Context(), u.ID)
|
||||
for _, e := range entries {
|
||||
if int(e.AnimeID) == anime.MalID {
|
||||
inWatchlist = true
|
||||
break
|
||||
}
|
||||
}
|
||||
watchlistMap := h.watchlistMapForIDs(c.Request.Context(), u.ID, []int64{int64(anime.MalID)})
|
||||
inWatchlist = watchlistMap[anime.MalID]
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
|
||||
@@ -5,6 +5,8 @@ import (
|
||||
"mal/integrations/jikan"
|
||||
"mal/internal/db"
|
||||
"mal/internal/domain"
|
||||
"math/rand"
|
||||
"time"
|
||||
|
||||
"golang.org/x/sync/errgroup"
|
||||
)
|
||||
@@ -20,9 +22,8 @@ func NewAnimeService(jikan *jikan.Client, repo domain.AnimeRepository) domain.An
|
||||
|
||||
func (s *animeService) GetCatalogSection(ctx context.Context, userID string, section string) (map[string]any, error) {
|
||||
var (
|
||||
res jikan.TopAnimeResult
|
||||
cw []db.GetContinueWatchingEntriesRow
|
||||
watchlist []db.GetUserWatchListRow
|
||||
res jikan.TopAnimeResult
|
||||
cw []db.GetContinueWatchingEntriesRow
|
||||
)
|
||||
|
||||
g, gCtx := errgroup.WithContext(ctx)
|
||||
@@ -38,18 +39,10 @@ func (s *animeService) GetCatalogSection(ctx context.Context, userID string, sec
|
||||
return err
|
||||
})
|
||||
|
||||
if userID != "" {
|
||||
g.Go(func() error {
|
||||
if section == "Continue" {
|
||||
var err error
|
||||
cw, err = s.repo.GetContinueWatchingEntries(gCtx, userID)
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
})
|
||||
if userID != "" && section == "Continue" {
|
||||
g.Go(func() error {
|
||||
var err error
|
||||
watchlist, err = s.repo.GetUserWatchList(gCtx, userID)
|
||||
cw, err = s.repo.GetContinueWatchingEntries(gCtx, userID)
|
||||
return err
|
||||
})
|
||||
}
|
||||
@@ -63,23 +56,14 @@ func (s *animeService) GetCatalogSection(ctx context.Context, userID string, sec
|
||||
animes = animes[:6]
|
||||
}
|
||||
|
||||
watchlistMap := make(map[int64]bool)
|
||||
for _, entry := range watchlist {
|
||||
watchlistMap[entry.AnimeID] = true
|
||||
}
|
||||
|
||||
return map[string]any{
|
||||
"Animes": animes,
|
||||
"ContinueWatching": cw,
|
||||
"WatchlistMap": watchlistMap,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (s *animeService) GetDiscoverSection(ctx context.Context, userID string, section string) (map[string]any, error) {
|
||||
var (
|
||||
res jikan.TopAnimeResult
|
||||
watchlist []db.GetUserWatchListRow
|
||||
)
|
||||
var res jikan.TopAnimeResult
|
||||
|
||||
g, gCtx := errgroup.WithContext(ctx)
|
||||
|
||||
@@ -96,14 +80,6 @@ func (s *animeService) GetDiscoverSection(ctx context.Context, userID string, se
|
||||
return err
|
||||
})
|
||||
|
||||
if userID != "" {
|
||||
g.Go(func() error {
|
||||
var err error
|
||||
watchlist, err = s.repo.GetUserWatchList(gCtx, userID)
|
||||
return err
|
||||
})
|
||||
}
|
||||
|
||||
if err := g.Wait(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -113,14 +89,8 @@ func (s *animeService) GetDiscoverSection(ctx context.Context, userID string, se
|
||||
animes = animes[:8]
|
||||
}
|
||||
|
||||
watchlistMap := make(map[int64]bool)
|
||||
for _, entry := range watchlist {
|
||||
watchlistMap[entry.AnimeID] = true
|
||||
}
|
||||
|
||||
return map[string]any{
|
||||
"Animes": animes,
|
||||
"WatchlistMap": watchlistMap,
|
||||
"Animes": animes,
|
||||
}, nil
|
||||
}
|
||||
|
||||
@@ -173,7 +143,27 @@ func (s *animeService) GetReviews(ctx context.Context, id int, page int) ([]doma
|
||||
}
|
||||
|
||||
func (s *animeService) GetRandomAnime(ctx context.Context) (domain.Anime, error) {
|
||||
return s.jikan.GetRandomAnime(ctx)
|
||||
randomCtx, cancel := context.WithTimeout(ctx, 2*time.Second)
|
||||
defer cancel()
|
||||
|
||||
anime, err := s.jikan.GetRandomAnime(randomCtx)
|
||||
if err == nil {
|
||||
return anime, nil
|
||||
}
|
||||
|
||||
for _, fallback := range []func(context.Context, int) (jikan.TopAnimeResult, error){
|
||||
s.jikan.GetSeasonsNow,
|
||||
s.jikan.GetTopAnime,
|
||||
s.jikan.GetSeasonsUpcoming,
|
||||
} {
|
||||
res, fallbackErr := fallback(ctx, 1)
|
||||
if fallbackErr != nil || len(res.Animes) == 0 {
|
||||
continue
|
||||
}
|
||||
return res.Animes[rand.Intn(len(res.Animes))], nil
|
||||
}
|
||||
|
||||
return domain.Anime{}, err
|
||||
}
|
||||
|
||||
func (s *animeService) GetAllEpisodes(ctx context.Context, id int) ([]domain.EpisodeData, error) {
|
||||
|
||||
@@ -12,6 +12,9 @@ type WatchlistService interface {
|
||||
UpdateEntry(ctx context.Context, userID string, animeID int64, status string) error
|
||||
RemoveEntry(ctx context.Context, userID string, animeID int64) error
|
||||
GetWatchlist(ctx context.Context, userID string) ([]UserWatchListRow, error)
|
||||
GetWatchlistMap(ctx context.Context, userID string, animeIDs []int64) (map[int]bool, error)
|
||||
GetCommandPaletteWatchlist(ctx context.Context, userID string, query string, limit int64) ([]UserWatchListRow, error)
|
||||
GetCommandPaletteContinueWatching(ctx context.Context, userID string, query string, limit int64) ([]db.GetContinueWatchingEntriesRow, error)
|
||||
GetWatchListEntry(ctx context.Context, userID string, animeID int64) (WatchlistEntry, error)
|
||||
GetContinueWatchingEntry(ctx context.Context, userID string, animeID int64) (db.ContinueWatchingEntry, error)
|
||||
DeleteContinueWatching(ctx context.Context, userID string, animeID int64) error
|
||||
@@ -23,6 +26,9 @@ type WatchlistRepository interface {
|
||||
UpsertWatchListEntry(ctx context.Context, arg db.UpsertWatchListEntryParams) (db.WatchListEntry, error)
|
||||
DeleteWatchListEntry(ctx context.Context, arg db.DeleteWatchListEntryParams) error
|
||||
GetUserWatchList(ctx context.Context, userID string) ([]db.GetUserWatchListRow, error)
|
||||
GetUserWatchlistAnimeIDs(ctx context.Context, userID string, animeIDs []int64) ([]int64, error)
|
||||
GetCommandPaletteWatchlist(ctx context.Context, userID string, query string, limit int64) ([]db.GetUserWatchListRow, error)
|
||||
GetCommandPaletteContinueWatching(ctx context.Context, userID string, query string, limit int64) ([]db.GetContinueWatchingEntriesRow, error)
|
||||
GetWatchListEntry(ctx context.Context, arg db.GetWatchListEntryParams) (db.WatchListEntry, error)
|
||||
GetContinueWatchingEntry(ctx context.Context, arg db.GetContinueWatchingEntryParams) (db.ContinueWatchingEntry, error)
|
||||
DeleteContinueWatchingEntry(ctx context.Context, arg db.DeleteContinueWatchingEntryParams) error
|
||||
|
||||
@@ -34,6 +34,18 @@ func (r *watchlistRepository) GetUserWatchList(ctx context.Context, userID strin
|
||||
return r.queries.GetUserWatchList(ctx, userID)
|
||||
}
|
||||
|
||||
func (r *watchlistRepository) GetUserWatchlistAnimeIDs(ctx context.Context, userID string, animeIDs []int64) ([]int64, error) {
|
||||
return r.queries.GetUserWatchlistAnimeIDs(ctx, userID, animeIDs)
|
||||
}
|
||||
|
||||
func (r *watchlistRepository) GetCommandPaletteWatchlist(ctx context.Context, userID string, query string, limit int64) ([]db.GetUserWatchListRow, error) {
|
||||
return r.queries.GetCommandPaletteWatchlist(ctx, userID, query, limit)
|
||||
}
|
||||
|
||||
func (r *watchlistRepository) GetCommandPaletteContinueWatching(ctx context.Context, userID string, query string, limit int64) ([]db.GetContinueWatchingEntriesRow, error) {
|
||||
return r.queries.GetCommandPaletteContinueWatching(ctx, userID, query, limit)
|
||||
}
|
||||
|
||||
func (r *watchlistRepository) GetWatchListEntry(ctx context.Context, arg db.GetWatchListEntryParams) (db.WatchListEntry, error) {
|
||||
return r.queries.GetWatchListEntry(ctx, arg)
|
||||
}
|
||||
|
||||
@@ -55,6 +55,32 @@ func (s *watchlistService) GetWatchlist(ctx context.Context, userID string) ([]d
|
||||
return s.repo.GetUserWatchList(ctx, userID)
|
||||
}
|
||||
|
||||
func (s *watchlistService) GetWatchlistMap(ctx context.Context, userID string, animeIDs []int64) (map[int]bool, error) {
|
||||
watchlistMap := make(map[int]bool)
|
||||
if userID == "" || len(animeIDs) == 0 {
|
||||
return watchlistMap, nil
|
||||
}
|
||||
|
||||
matches, err := s.repo.GetUserWatchlistAnimeIDs(ctx, userID, animeIDs)
|
||||
if err != nil {
|
||||
return watchlistMap, err
|
||||
}
|
||||
|
||||
for _, animeID := range matches {
|
||||
watchlistMap[int(animeID)] = true
|
||||
}
|
||||
|
||||
return watchlistMap, nil
|
||||
}
|
||||
|
||||
func (s *watchlistService) GetCommandPaletteWatchlist(ctx context.Context, userID string, query string, limit int64) ([]domain.UserWatchListRow, error) {
|
||||
return s.repo.GetCommandPaletteWatchlist(ctx, userID, query, limit)
|
||||
}
|
||||
|
||||
func (s *watchlistService) GetCommandPaletteContinueWatching(ctx context.Context, userID string, query string, limit int64) ([]db.GetContinueWatchingEntriesRow, error) {
|
||||
return s.repo.GetCommandPaletteContinueWatching(ctx, userID, query, limit)
|
||||
}
|
||||
|
||||
func (s *watchlistService) GetWatchListEntry(ctx context.Context, userID string, animeID int64) (db.WatchListEntry, error) {
|
||||
return s.repo.GetWatchListEntry(ctx, db.GetWatchListEntryParams{
|
||||
UserID: userID,
|
||||
|
||||
Reference in New Issue
Block a user