finished_at lands on series (0016 seeds it from the pre-flip finished bookmarks, then flips those bookmarks to archived), the poll gate and eligible count read the flag instead of a per-Reader vote, PUT rejects the finished status like any unknown value, and the web UI drops the Finished tab, badge and finish button. Novel merge rank is archived > reading. Per-Reader disagreement (one Reader keeps a finished Series in reading forever) is what the flag repairs; the cutover keeps polling state unchanged for every Series.
This commit is contained in:
+10
-11
@@ -293,10 +293,11 @@ func libOf(q string) string {
|
||||
// buildListView loads one reader's list once and derives both the tab-filtered
|
||||
// items and 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".
|
||||
// Archived 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". There is no Finished tab: finished is a fact about
|
||||
// the Series, not a bookmark bucket (issue #157).
|
||||
func (h *Handler) buildListView(readerID int64, lib, tab string) (listView, error) {
|
||||
all, err := h.store.List(readerID) // already ordered updated_at DESC
|
||||
if err != nil {
|
||||
@@ -327,8 +328,6 @@ func (h *Handler) buildListView(readerID int64, lib, tab string) (listView, erro
|
||||
items = withNew
|
||||
case "archived":
|
||||
items = filterBookmarks(all, func(b store.Bookmark) bool { return b.Status == store.StatusArchived })
|
||||
case "finished":
|
||||
items = filterBookmarks(all, func(b store.Bookmark) bool { return b.Status == store.StatusFinished })
|
||||
default:
|
||||
tab = "all"
|
||||
items = reading
|
||||
@@ -392,7 +391,7 @@ func currentLib(r *http.Request) string {
|
||||
// writeChromeOOB appends the regions that live outside #list — the recent
|
||||
// strip, the Updated badge and the action key — as out-of-band swaps, so a
|
||||
// mutation cannot leave them describing the library as it was before the tap.
|
||||
// The key is in here because it is tab-shaped too: archived and finished swap
|
||||
// The key is in here because it is tab-shaped too: the archived bucket swaps
|
||||
// Archive for Restore.
|
||||
func (h *Handler) writeChromeOOB(w http.ResponseWriter, view listView) {
|
||||
view.OOB = true
|
||||
@@ -492,9 +491,9 @@ func (h *Handler) uiFavorite(w http.ResponseWriter, r *http.Request) {
|
||||
h.saveAndRenderCard(w, r, b)
|
||||
}
|
||||
|
||||
// uiStatus moves a bookmark between lifecycle buckets. This is the only place
|
||||
// a series can be marked finished — the JSON API refuses that value, so the
|
||||
// userscript cannot set it even by accident.
|
||||
// uiStatus moves a bookmark between the two lifecycle buckets. Finished is not
|
||||
// one of them: it is a fact about the Series, decided from the admin surface,
|
||||
// so the web UI's per-bookmark control cannot set it (issue #157).
|
||||
//
|
||||
// last_chapter_num is untouched, so Upsert keeps the stored updated_at and the
|
||||
// list does not reorder.
|
||||
@@ -508,7 +507,7 @@ func (h *Handler) uiStatus(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
switch s := r.PostFormValue("status"); s {
|
||||
case store.StatusReading, store.StatusArchived, store.StatusFinished:
|
||||
case store.StatusReading, store.StatusArchived:
|
||||
b.Status = s
|
||||
default:
|
||||
http.Error(w, "invalid status", http.StatusBadRequest)
|
||||
|
||||
Reference in New Issue
Block a user