feat(web): filter tabs and recent strip by status bucket

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
2026-07-27 12:56:12 +07:00
parent f783b72a81
commit 5aae678668
2 changed files with 115 additions and 16 deletions
+29 -16
View File
@@ -145,38 +145,51 @@ func (h *webHandler) index(w http.ResponseWriter, r *http.Request) {
h.render(w, http.StatusOK, "app", view)
}
// filterBookmarks returns the subset keep reports true for, preserving order.
// It always returns a non-nil slice so an empty tab renders its empty state.
func filterBookmarks(all []Bookmark, keep func(Bookmark) bool) []Bookmark {
out := []Bookmark{}
for _, b := range all {
if keep(b) {
out = append(out, b)
}
}
return out
}
// buildListView loads the list once and derives both the tab-filtered items and
// the recent strip from it. The strip always reflects overall recency, not the
// active tab, so it is built before filtering.
// the recent strip from it.
//
// Archived and finished series appear in their own tab and nowhere else — not
// in All, not in Updated, not in Favourites, and not in the recent strip. An
// archived favourite therefore shows only under Archived: Favourites means
// "favourites I am currently reading".
func (h *webHandler) buildListView(tab string) (listView, error) {
all, err := h.store.List() // already ordered updated_at DESC
if err != nil {
return listView{}, err
}
reading := filterBookmarks(all, func(b Bookmark) bool { return b.Status == statusReading })
recent := all
// The strip reflects overall reading recency, not the active tab.
recent := reading
if len(recent) > recentCount {
recent = recent[:recentCount]
}
items := all
var items []Bookmark
switch tab {
case "fav":
items = []Bookmark{}
for _, b := range all {
if b.Favorite {
items = append(items, b)
}
}
items = filterBookmarks(reading, func(b Bookmark) bool { return b.Favorite })
case "new":
items = []Bookmark{}
for _, b := range all {
if b.HasNewChapter() {
items = append(items, b)
}
}
items = filterBookmarks(reading, func(b Bookmark) bool { return b.HasNewChapter() })
case "archived":
items = filterBookmarks(all, func(b Bookmark) bool { return b.Status == statusArchived })
case "finished":
items = filterBookmarks(all, func(b Bookmark) bool { return b.Status == statusFinished })
default:
tab = "all"
items = reading
}
return listView{Tab: tab, Recent: recent, Items: items}, nil
}