diff --git a/CHANGELOG.md b/CHANGELOG.md index 4ebcbd4..7fbef99 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Changelog +## 0.52.15 - 2026-08-18 + +- Replaced duplicated Watchlist refresh-all progress text with a single progress bar and current-anime label. + ## 0.52.14 - 2026-08-18 - Moved each completed episode from staging into the configured downloads library as soon as the downloader reports that episode finished. diff --git a/README.md b/README.md index bcb94ef..ae69f6e 100644 --- a/README.md +++ b/README.md @@ -15,7 +15,7 @@ Kaizoku is a local web app for searching, tracking, and downloading anime from A - Save files with Jellyfin-friendly layout: `TV/Series Name/Season 01/Series Name - S01E01.mp4`. - Save English external subtitles when the provider exposes usable subtitle tracks. - Manage focused watchlists for `Watching`, `Planned`, `Finished`, and `Dropped`, with provider source tags and title links back to the original provider page. -- Periodically refresh selected watchlists and auto-download newly available episodes. +- Periodically refresh selected watchlists with a single progress bar and auto-download newly available episodes. - Sync watchlist download flags from the filesystem. - Hand completed libraries to Jellyfin TV or movie folders. - Export/import watchlist backups. diff --git a/VERSION b/VERSION index 07bd608..cac7789 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.52.14 +0.52.15 diff --git a/test_app.py b/test_app.py index 6911b7f..ff830b1 100644 --- a/test_app.py +++ b/test_app.py @@ -4301,6 +4301,15 @@ class TemplateHelperTests(unittest.TestCase): self.assertIn("else if (state.queuedCount > 0)", APP.WATCHLIST_HTML) self.assertIn("fetchWatchlist(state.watchlistPage, { silent: true })", APP.WATCHLIST_HTML) + def test_watchlist_page_renders_single_refresh_progress_bar(self): + self.assertIn('class="refresh-progress" id="refreshJobStatus"', APP.WATCHLIST_HTML) + self.assertIn('class="refresh-progress-fill" id="refreshJobFill"', APP.WATCHLIST_HTML) + self.assertIn("function refreshJobPercent(job)", APP.WATCHLIST_HTML) + self.assertIn('$("refreshJobFill").style.width = `${percent}%`;', APP.WATCHLIST_HTML) + self.assertIn('`Refreshing ${job.current_title}`', APP.WATCHLIST_HTML) + self.assertEqual(APP.WATCHLIST_HTML.count('id="refreshJobStatus"'), 1) + self.assertNotIn("refreshed${job.current_title", APP.WATCHLIST_HTML) + def test_watchlist_page_highlights_fully_ready_cards(self): self.assertIn(".anime-card.fully-ready", APP.WATCHLIST_HTML) self.assertIn("const isFullyReady = item.sub_complete && item.dub_complete;", APP.WATCHLIST_HTML) diff --git a/watchlist_page.py b/watchlist_page.py index 641d33f..415bbbe 100644 --- a/watchlist_page.py +++ b/watchlist_page.py @@ -254,6 +254,44 @@ WATCHLIST_HTML = r""" color: #ddd0ff; font-size: 13px; } + .refresh-progress { + display: none; + gap: 7px; + min-width: 0; + } + .refresh-progress.visible { + display: grid; + } + .refresh-progress-header { + align-items: center; + color: var(--muted); + display: flex; + font-size: 12px; + font-weight: 700; + justify-content: space-between; + gap: 10px; + text-transform: uppercase; + } + .refresh-progress-track { + background: rgba(255, 255, 255, 0.08); + border: 1px solid var(--line); + border-radius: 999px; + height: 11px; + overflow: hidden; + } + .refresh-progress-fill { + background: linear-gradient(90deg, var(--accent), var(--accent-2)); + border-radius: inherit; + height: 100%; + transition: width 0.2s ease; + width: 0%; + } + .refresh-progress-current { + color: #ddd0ff; + font-size: 13px; + min-height: 20px; + overflow-wrap: anywhere; + } .field-hint { color: var(--muted); font-size: 12px; @@ -716,6 +754,16 @@ WATCHLIST_HTML = r"""
+Compact poster grid for faster scanning.
-