release 0.2.5
This commit is contained in:
parent
35135c9a5b
commit
5e6361c31b
82
CHANGELOG.md
82
CHANGELOG.md
@ -1,5 +1,87 @@
|
||||
# Changelog
|
||||
|
||||
## 0.2.5
|
||||
|
||||
Full UI overhaul (icon buttons, compact top bar, responsive video controls), popout resize-pivot anchor, layout flip, and the main_window.py controller decomposition.
|
||||
|
||||
## Changes since 0.2.4
|
||||
|
||||
### Refactor: main_window.py controller decomposition
|
||||
|
||||
`main_window.py` went from a 3,318-line god-class to a 1,164-line coordinator plus 7 controller modules. Every other subsystem in the codebase had already been decomposed (popout state machine, library save, category fetcher) — BooruApp was the last monolith. 11 commits, pure refactor, no behavior change. Design doc at `docs/MAIN_WINDOW_REFACTOR.md`.
|
||||
|
||||
- New `gui/window_state.py` (293 lines) — geometry persistence, Hyprland IPC, splitter savers.
|
||||
- New `gui/privacy.py` (66 lines) — privacy overlay toggle + popout coordination.
|
||||
- New `gui/search_controller.py` (572 lines) — search orchestration, infinite scroll, backfill, blacklist filtering, tag building, autocomplete, thumbnail fetching.
|
||||
- New `gui/media_controller.py` (273 lines) — image/video loading, prefetch, download progress, video streaming fast-path, cache eviction.
|
||||
- New `gui/popout_controller.py` (204 lines) — popout lifecycle (open/close), state sync, geometry persistence, navigation delegation.
|
||||
- New `gui/post_actions.py` (561 lines) — bookmarks, save/library, batch download, unsave, bulk ops, blacklist actions from popout.
|
||||
- New `gui/context_menus.py` (246 lines) — single-post and multi-select context menu building + dispatch.
|
||||
- Controller-pattern: each takes `app: BooruApp` via constructor, accesses app internals as trusted collaborator via `self._app`. No mixins, no ABC, no dependency injection — just plain classes with one reference each. `TYPE_CHECKING` import for `BooruApp` avoids circular imports at runtime.
|
||||
- Cleaned up 14 dead imports from `main_window.py`.
|
||||
- The `_fullscreen_window` reference (52 sites across the codebase) was fully consolidated into `PopoutController.window`. No file outside `popout_controller.py` touches `_fullscreen_window` directly anymore.
|
||||
|
||||
### New: Phase 2 test suite (64 tests for extracted pure functions)
|
||||
|
||||
Each controller extraction also pulled decision-making code out into standalone module-level functions that take plain data in and return plain data out. Controllers call those functions; tests import them directly. Same structural forcing function as the popout state machine tests — the test files fail to collect if anyone adds a Qt import to a tested module.
|
||||
|
||||
- `tests/gui/test_search_controller.py` (24 tests): `build_search_tags` rating/score/media filter mapping per API type, `filter_posts` blacklist/dedup/seen-ids interaction, `should_backfill` termination conditions.
|
||||
- `tests/gui/test_window_state.py` (16 tests): `parse_geometry` / `format_geometry` round-trip, `parse_splitter_sizes` validation edge cases, `build_hyprctl_restore_cmds` for every floating/tiled permutation including the no_anim priming path.
|
||||
- `tests/gui/test_media_controller.py` (9 tests): `compute_prefetch_order` for Nearby (cardinals) and Aggressive (ring expansion) modes, including bounds, cap, and dedup invariants.
|
||||
- `tests/gui/test_post_actions.py` (10 tests): `is_batch_message` progress-pattern detection, `is_in_library` path-containment check.
|
||||
- `tests/gui/test_popout_controller.py` (3 tests): `build_video_sync_dict` shape.
|
||||
- Total suite: **186 tests** (57 core + 65 popout state machine + 64 new controller pure functions), ~0.3s runtime, all import-pure.
|
||||
- PySide6 imports in controller modules were made lazy (inside method bodies) so the Phase 2 tests can collect on CI, which only installs `httpx`, `Pillow`, and `pytest`.
|
||||
|
||||
### UI overhaul: icon buttons and responsive layout
|
||||
|
||||
Toolbar and video controls moved from fixed-width text buttons to 24x24 icon buttons. Preview toolbar uses Unicode symbols (☆/★ bookmark, ↓/✕ save, ⊘ blacklist tag, ⊗ blacklist post, ⧉ popout) — both the embedded preview and the popout toolbar share the same object names (`#_tb_bookmark`, `#_tb_save`, `#_tb_bl_tag`, `#_tb_bl_post`, `#_tb_popout`) so one QSS rule styles both. Video controls (play/pause, mute, loop, autoplay) render via QPainter using the palette's `buttonText` color so they match any theme automatically, with `1×` as bold text for the Once loop state.
|
||||
|
||||
- Responsive video controls bar: hides volume slider below 320px, duration label below 240px, current time label below 200px. Play/pause/seek/mute/loop always visible.
|
||||
- Compact top bar: combos use `AdjustToContents`, 3px spacing, top/nav bars wrapped in `#_top_bar` / `#_nav_bar` named containers for theme targeting.
|
||||
- Main window minimum size dropped from 900x600 to 740x400 — the hard floor was blocking Hyprland's keyboard resize mode on narrow floating windows.
|
||||
- Preview pane minimum width dropped from 380 to 200.
|
||||
- Info panel title + details use `QSizePolicy.Ignored` horizontally so long source URLs wrap within the splitter instead of pushing it wider.
|
||||
|
||||
### New: popout anchor setting (resize pivot)
|
||||
|
||||
Combo in Settings > General. Controls which point of the popout window stays fixed across navigations as the aspect ratio changes: `Center` (default, pins window center), or one of the four corners (pins that corner, window grows/shrinks from the opposite corner). The user can still drag the window anywhere — the anchor only controls the resize direction, not the screen position. Works on all platforms; on Hyprland the hyprctl dispatch path is used, elsewhere Qt's `setGeometry` fallback handles the same math.
|
||||
|
||||
- `Viewport.center_x`/`center_y` repurposed as anchor point coordinates — in center mode it's the window center, in corner modes it's the pinned corner. New `anchor_point()` helper in `viewport.py` extracts the right point from a window rect based on mode.
|
||||
- `_compute_window_rect` branches on anchor: center mode keeps the existing symmetric math, corner modes derive position from the anchor point + the new size.
|
||||
- Hyprland monitor reserved-area handling: reads `reserved` from `hyprctl monitors -j` so window positioning respects Waybar's exclusive zone (Qt's `screen.availableGeometry()` doesn't see layer-shell reservations on Wayland).
|
||||
|
||||
### New: layout flip setting
|
||||
|
||||
Checkbox in Settings > General (restart required). Swaps the main splitter — preview+info panel on the left, grid on the right. Useful for left-handed workflows or multi-monitor setups where you want the preview closer to your other reference windows.
|
||||
|
||||
### New: thumbnail fade-in animation
|
||||
|
||||
Thumbnails animate from 0 to 1 opacity over 200ms (OutCubic easing) as they load. Uses a `QPropertyAnimation` on a `thumbOpacity` Qt Property applied in `paintEvent`. The animation is stored on the widget instance to prevent Python garbage collection before the Qt event loop runs it.
|
||||
|
||||
### New: B / F / S keyboard shortcuts
|
||||
|
||||
- `B` or `F` — toggle bookmark on the selected post (works in main grid and popout).
|
||||
- `S` — toggle save to library (Unfiled). If already saved, unsaves. Works in main grid and popout.
|
||||
- The popout gained a new `toggle_save_requested` signal that routes to a shared `PostActionsController.toggle_save_from_preview` so both paths use the same toggle logic.
|
||||
|
||||
### UX: grid click behavior
|
||||
|
||||
- Clicking empty grid space (blue area around thumbnails, cell padding outside the pixmap, or the 2px gaps between cells) deselects everything. Cell padding clicks work via a direct parent-walk from `ThumbnailWidget.mousePressEvent` to the grid — Qt event propagation through `QScrollArea` swallows events too aggressively to rely on.
|
||||
- Rubber band drag selection now works from any empty space — not just the 2px gaps. 30px manhattan threshold gates activation so single clicks on padding just deselect without flashing a zero-size rubber band.
|
||||
- Hover highlight only appears when the cursor is actually over the pixmap, not the cell padding. Uses the same `_hit_pixmap` hit-test as clicks. Cursor swaps between pointing-hand (over pixmap) and arrow (over padding) via `mouseMoveEvent` tracking.
|
||||
- Clicking an already-showing post no longer restarts the video (fixes the click-to-drag case where the drag-start click was restarting mpv).
|
||||
- Escape clears the grid selection.
|
||||
- Stuck forbidden cursor after cancelled drag-and-drop is reset on mouse release. Stuck hover states on Wayland fast-exits are force-cleared in `ThumbnailGrid.leaveEvent`.
|
||||
|
||||
### Themes
|
||||
|
||||
All 12 bundled QSS themes were trimmed and regenerated:
|
||||
|
||||
- Removed 12 dead selector groups that the app never instantiates: `QRadioButton`, `QToolButton`, `QToolBar`, `QDockWidget`, `QTreeView`/`QTreeWidget`, `QTableView`/`QTableWidget`, `QHeaderView`, `QDoubleSpinBox`, `QPlainTextEdit`, `QFrame`.
|
||||
- Popout overlay buttons now use `font-size: 15px; font-weight: bold` so the icon symbols read well against the translucent-black overlay.
|
||||
- `themes/README.md` documents the new `#_tb_*` toolbar button object names and the popout overlay styling. Removed the old Nerd Font remapping note — QSS can't change button text, so that claim was incorrect.
|
||||
|
||||
## 0.2.4 (pre-release)
|
||||
|
||||
Library filename templates, tag category fetching for all backends, and a popout video streaming overhaul. 50+ commits since v0.2.3.
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
|
||||
[Setup]
|
||||
AppName=booru-viewer
|
||||
AppVersion=pre-release 0.2.4
|
||||
AppVersion=0.2.5
|
||||
AppPublisher=pax
|
||||
AppPublisherURL=https://git.pax.moe/pax/booru-viewer
|
||||
DefaultDirName={localappdata}\booru-viewer
|
||||
|
||||
@ -4,7 +4,7 @@ build-backend = "hatchling.build"
|
||||
|
||||
[project]
|
||||
name = "booru-viewer"
|
||||
version = "pre-release 0.2.4"
|
||||
version = "0.2.5"
|
||||
description = "Local booru image browser with Qt6 GUI"
|
||||
requires-python = ">=3.11"
|
||||
dependencies = [
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user