Two related fixes for the File → Batch Download Page (Ctrl+D) flow.
1. Saved-dot refresh
Pre-fix: when the user picked a destination inside the library, the
batch wrote files to disk but the browse grid's saved-dots stayed dark
until the next refresh. The grid was lying about local state.
Fix: stash the chosen destination as self._batch_dest at the dispatch
site, then in _on_batch_progress (which already fires per-file via
the existing batch_progress signal) check whether dest is inside
saved_dir(); if so, find the just-finished post in self._posts by id
and light its grid thumb's saved-locally dot. Dots appear incrementally
as each file lands, not all at once at the end.
The batch_progress signal grew a third int param (post_id of the
just-finished item). It's a single-consumer signal — only
_on_batch_progress connects to it — so the shape change is local.
Both batch download paths (the file menu's _batch_download and the
multi-select menu's _batch_download_posts) pass post.id through.
When the destination is OUTSIDE the library, dots stay dark — the
saved-dot means "in library", not "downloaded somewhere". The check
uses Path.is_relative_to (Python 3.11+).
self._batch_dest is cleared in _on_batch_done after the batch finishes
so a subsequent non-batch save doesn't accidentally see a stale dest.
2. Tab gating
Pre-fix: File → Batch Download Page... was enabled on Bookmarks and
Library tabs, where it makes no sense (those tabs already show local
files). Ctrl+D fired regardless of active tab.
Fix: store the QAction as self._batch_action instead of a local var
in _setup_menu, then toggle setEnabled(index == 0) from _switch_view.
Disabling the QAction also disables its keyboard shortcut, so Ctrl+D
becomes a no-op on non-browse tabs without a separate guard.
Verified manually:
- Browse tab → menu enabled, Ctrl+D works
- Bookmarks/Library tabs → menu grayed out, Ctrl+D no-op
- Batch dl into ~/.local/share/booru-viewer/saved → dots light up
one-by-one as files land
- Batch dl into /tmp → files written, dots stay dark
30 lines
1.2 KiB
Python
30 lines
1.2 KiB
Python
"""Qt signal hub for async worker results."""
|
|
|
|
from __future__ import annotations
|
|
|
|
from PySide6.QtCore import QObject, Signal
|
|
|
|
|
|
class AsyncSignals(QObject):
|
|
"""Signals for async worker results."""
|
|
search_done = Signal(list)
|
|
search_append = Signal(list)
|
|
search_error = Signal(str)
|
|
thumb_done = Signal(int, str)
|
|
image_done = Signal(str, str)
|
|
image_error = Signal(str)
|
|
# Fast-path for uncached video posts: emit the remote URL directly
|
|
# so mpv can start streaming + decoding immediately instead of
|
|
# waiting for download_image to write the whole file to disk first.
|
|
# download_image still runs in parallel to populate the cache for
|
|
# next time. Args: (url, info, width, height) — width/height come
|
|
# from post.width/post.height for the popout pre-fit optimization.
|
|
video_stream = Signal(str, str, int, int)
|
|
bookmark_done = Signal(int, str)
|
|
bookmark_error = Signal(str)
|
|
autocomplete_done = Signal(list)
|
|
batch_progress = Signal(int, int, int) # current, total, post_id (of the just-finished item)
|
|
batch_done = Signal(str)
|
|
download_progress = Signal(int, int) # bytes_downloaded, total_bytes
|
|
prefetch_progress = Signal(int, float) # index, progress (0-1 or -1 to hide)
|