From 49714a59ea1a8dd1589fbcf4935d418bfb6d392a Mon Sep 17 00:00:00 2001 From: BoulderBadgeDad Date: Sun, 21 Jun 2026 08:47:59 -0700 Subject: [PATCH] Video watchlist: sort alphabetically by name by default MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The default sort put manual follows first (newest date_added), then airing shows A–Z — so recently-followed shows like 'Welcome to Widows Bay' and 'From' jumped to the top. A manual follow is no more special than an auto-added airing show; default now sorts everything by name A–Z. 'added' (newest first) stays as an opt-in sort. --- database/video_database.py | 8 ++++---- tests/test_video_database.py | 13 +++++++++++++ 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/database/video_database.py b/database/video_database.py index 3cbca89e..d8224198 100644 --- a/database/video_database.py +++ b/database/video_database.py @@ -2041,11 +2041,11 @@ class VideoDatabase: s = (search or "").strip().lower() if s: items = [it for it in items if s in (it.get("title") or "").lower()] - if sort == "title": - items.sort(key=lambda it: (it.get("title") or "").lower()) - elif sort == "added": # explicit follows (have a date) newest-first; airing defaults last + if sort == "added": # opt-in: explicit follows (have a date) newest-first items.sort(key=lambda it: (it.get("date_added") or ""), reverse=True) - # "default": keep the natural effective order (follows first, then airing A–Z) + else: # "default" / "title": alphabetical by name — a manual follow is no more + # special than an auto-added airing show, so they sort together A–Z + items.sort(key=lambda it: (it.get("sort_title") or it.get("title") or "").lower()) total = len(items) total_pages = max(1, (total + limit - 1) // limit) page = min(page, total_pages) diff --git a/tests/test_video_database.py b/tests/test_video_database.py index 9478682e..eb34007c 100644 --- a/tests/test_video_database.py +++ b/tests/test_video_database.py @@ -845,6 +845,19 @@ def test_query_watchlist_paginates_and_searches(db): assert db.query_watchlist("person", page=99, limit=3)["pagination"]["page"] == 3 +def test_query_watchlist_default_sort_is_alphabetical(db): + # added out of alphabetical order — a manual follow must NOT float to the top; + # everything sorts by name A–Z by default. + db.add_to_watchlist("show", 1, "Welcome to Widows Bay") + db.add_to_watchlist("show", 2, "From") + db.add_to_watchlist("show", 3, "Andor") + titles = [it["title"] for it in db.query_watchlist("show")["items"]] + assert titles == ["Andor", "From", "Welcome to Widows Bay"] + # 'added' is still available opt-in (newest first) + added = [it["title"] for it in db.query_watchlist("show", sort="added")["items"]] + assert added[0] == "Andor" # most recently added + + # ── wishlist (movies + episodes; show/season are bulk ops over episodes) ────── def test_wishlist_movie_add_is_idempotent(db):