fix(viewer): hold filter refresh when tagging the active image out of view #110

Merged
ValleyGeek merged 3 commits from 0.1.36/issue-38-viewer-tag-skip into main 2026-06-20 06:06:30 +00:00
Member

Summary

  • Tagging the viewer's active image while a tag filter (e.g. "Untagged Only") is active used to silently auto-advance the viewer to the next surviving image the instant the tag was applied, before the user pressed any navigation key — a subsequent d/a press then skipped one further image.
  • Added ImageFilterProxy.set_pinned_relative_path to force-include one row regardless of filter criteria. While the viewer shows the just-tagged active image, main_window.py pins it so the display/filmstrip/carousel stay untouched, and stages a deferred resync (ImageViewer.defer_resync) that only fires on the user's next intentional navigation — landing exactly on the image immediately following/preceding the tagged one.
  • The grid view behind the viewer still updates its own filter immediately, unaffected.

Fixes #38.

Test plan

  • ruff check . && ruff format --check .
  • pytest — 367 passed, 1 skipped
  • Added regression tests in tests/test_pr8_viewer.py covering next/prev navigation after tagging the active image out of an "Untagged Only" filter
  • ./scripts/smoke-ui-exit.sh — clean Qt teardown
  • pip install -e . + scripts/get-version.py --canonical resolves dev/release version correctly
  • ./scripts/check-version-bump.sh — VERSION bumped 0.1.36 → 0.1.37
## Summary - Tagging the viewer's active image while a tag filter (e.g. "Untagged Only") is active used to silently auto-advance the viewer to the next surviving image the instant the tag was applied, before the user pressed any navigation key — a subsequent `d`/`a` press then skipped one further image. - Added `ImageFilterProxy.set_pinned_relative_path` to force-include one row regardless of filter criteria. While the viewer shows the just-tagged active image, `main_window.py` pins it so the display/filmstrip/carousel stay untouched, and stages a deferred resync (`ImageViewer.defer_resync`) that only fires on the user's next intentional navigation — landing exactly on the image immediately following/preceding the tagged one. - The grid view behind the viewer still updates its own filter immediately, unaffected. Fixes #38. ## Test plan - [x] `ruff check . && ruff format --check .` - [x] `pytest` — 367 passed, 1 skipped - [x] Added regression tests in `tests/test_pr8_viewer.py` covering next/prev navigation after tagging the active image out of an "Untagged Only" filter - [x] `./scripts/smoke-ui-exit.sh` — clean Qt teardown - [x] `pip install -e .` + `scripts/get-version.py --canonical` resolves dev/release version correctly - [x] `./scripts/check-version-bump.sh` — VERSION bumped 0.1.36 → 0.1.37
fix(viewer): hold filter refresh when tagging the active image out of view
Some checks failed
CI / lint (push) Successful in 14s
CI / test (push) Failing after 2m35s
CI / appimage (push) Has been skipped
CI / windows-exe (push) Has been skipped
CI / build-appimage (push) Failing after 0s
CI / build-windows-exe (push) Failing after 0s
6d3c4615e0
Tagging the viewer's active image while a tag filter (e.g. "Untagged
Only") is active used to silently auto-advance the viewer to the next
surviving image the instant the tag was applied, before the user ever
pressed a navigation key. A subsequent 'd'/'a' press then skipped one
further image, since the active position had already moved.

Pin the active image into the live filter proxy while the viewer is
showing it, so the filmstrip/carousel/display stay untouched. The pin
releases on the next intentional navigation (or on leaving the
viewer), at which point the proxy re-filters and navigation lands on
the image immediately following/preceding the tagged one.

Threading notes: no worker changes; all touched code (image_filter_proxy,
image_viewer, main_window) runs on the main thread only.

Fixes #38.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
CHANGELOG entries for compiled-input changes belong in the dedicated
PR-prep commit, not earlier feature commits (AGENTS.md). The premature
[Unreleased] entry also broke test_build_release_notes.py, which
asserts [Unreleased] stays empty between releases.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
docs: PR-prep for issue 38 - bump to 0.1.37
All checks were successful
CI / lint (push) Successful in 7s
CI / test (push) Successful in 1m43s
CI / appimage (push) Successful in 8m13s
CI / build-appimage (push) Successful in 0s
CI / windows-exe (push) Successful in 11m17s
CI / build-windows-exe (push) Successful in 0s
bfb7a1528b
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
ValleyGeek deleted branch 0.1.36/issue-38-viewer-tag-skip 2026-06-20 06:06:30 +00:00
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
ai-collab/bulk-image-organizer!110
No description provided.