Skip to content

Persist gallery filter/sort state across navigation#81

Merged
travisdock merged 16 commits intomainfrom
copilot/add-saved-filter-sort-state
Mar 18, 2026
Merged

Persist gallery filter/sort state across navigation#81
travisdock merged 16 commits intomainfrom
copilot/add-saved-filter-sort-state

Conversation

Copy link
Contributor

Copilot AI commented Mar 17, 2026

Gallery filter, sort, search, and view mode state resets whenever the user navigates away (e.g., clicks an image). State should survive round-trips to ImageView and next/prev navigation should respect the active filter.

Changes

ImageGallery.js

  • Added optional galleryKey prop (falls back to projectId) for scoped state storage
  • All five control states (viewMode, sortBy, searchField, searchValue, reviewFilter) initialized from and persisted to localStorage under key gallery_state_${galleryKey}

GroupGalleryView.js

  • Passes a group-scoped galleryKey to ImageGallery so each group gallery maintains independent state:
    galleryKey={isUngrouped ? `${projectId}_ungrouped` : `${projectId}_group_${groupId}`}
    

ImageView.js

  • loadProjectImages() now reads the saved gallery state and applies:
    • Search filter — same client-side logic as ImageGallery (filename, metadata, content type, etc.)
    • Review filter — fetches /api/projects/{id}/image-review-statuses if a non-all filter is saved; silently skips on failure
    • Sort order — date / name / size, matching gallery sort

This ensures the prev/next buttons navigate through the same ordered, filtered image set the user last configured.

Original prompt

This section details on the original issue you should resolve

<issue_title>Saved Filter/Sort State</issue_title>
<issue_description>Currently if you filter or sort images in the image gallery, it resets as soon as you click an image.

It should save the state of the filter for that user, on that page. So if a user clicks away from that image gallery, say by clicking an image or visiting another page, and then return to that same image gallery, their filter and sort should be what it was when they left.

It should respect the sort and filter state when navigating images via the next/previous buttons as well.</issue_description>

Comments on the Issue (you are @copilot in this section)


💬 Send tasks to Copilot coding agent from Slack and Teams to turn conversations into code. Copilot posts an update in your thread when it's finished.

…tion

Co-authored-by: travisdock <36681963+travisdock@users.noreply.github.com>
Copilot AI changed the title [WIP] Add saved filter and sort state for image gallery Persist gallery filter/sort state across navigation Mar 17, 2026
Copilot AI requested a review from travisdock March 17, 2026 16:40
  ImageGallery and ImageView duplicated the same search filtering, review
  status filtering, and sort logic. Extract these into a shared utility
  to keep them in sync and reduce line counts. Add unit tests for state
  persistence (ImageGallery) and navigation filtering (ImageView).
  - Extract duplicated filter/sort/search logic from ImageGallery and
    ImageView into shared utils/galleryState.js
  - Fix stale state when ImageGallery is reused with a different
    galleryKey by detecting key changes and reloading from localStorage
  - Fix fragile ungrouped gallery key detection in ImageView by passing
    galleryKey explicitly as a URL search param instead of sniffing
    localStorage; prev/next navigation preserves the param
  - Add unit tests for the shared utility (23 tests), ImageGallery state
    persistence and key-change behavior (7 tests), and ImageView
    galleryKey URL handling (3 tests)
@travisdock travisdock marked this pull request as ready for review March 17, 2026 18:07
Copilot AI review requested due to automatic review settings March 17, 2026 18:07
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds persistent, scoped gallery UI state (filter/sort/search/view mode) so it survives navigation away from the gallery and ensures ImageView prev/next navigation respects the same active filters and ordering.

Changes:

  • Introduces shared galleryState utilities for localStorage persistence plus filter/sort application, with unit tests.
  • Persists/restores ImageGallery control state via a new optional galleryKey (project- or group-scoped), and includes galleryKey in navigation URLs.
  • Updates ImageView to apply saved gallery filters/sorts when building the navigation image list, with additional tests.

Reviewed changes

Copilot reviewed 7 out of 7 changed files in this pull request and generated 6 comments.

Show a summary per file
File Description
frontend/src/utils/galleryState.js New shared persistence + filter/sort utilities used by both gallery and ImageView navigation.
frontend/src/utils/tests/galleryState.test.js Unit tests for persistence and filter/sort helpers.
frontend/src/components/ImageGallery.js Loads/saves gallery control state to localStorage and appends galleryKey to ImageView navigation URLs.
frontend/src/components/GroupGalleryView.js Provides a group-scoped galleryKey so each group’s gallery state is independent.
frontend/src/components/tests/ImageGallery.test.js Extends component tests to validate localStorage persistence/restore and galleryKey URL behavior.
frontend/src/ImageView.js Applies saved gallery filter/sort (and optional review status filtering) to prev/next navigation list and preserves galleryKey in navigation.
frontend/src/tests/ImageView.test.js Adds tests around reading saved gallery state for navigation behavior.

travisdock and others added 8 commits March 17, 2026 14:05
  loadGalleryState was called separately for each useState initializer,
  parsing the same JSON five times on mount. Add GALLERY_STATE_DEFAULTS
  and loadGalleryStateWithDefaults to galleryState.js so defaults live in
  one place. ImageGallery now loads state once and initializes all controls
  from that object. The key-change reset effect uses the same helper.
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds shared, persisted gallery filter/sort state so users keep their gallery configuration across navigation and ImageView prev/next respects the same filtered + ordered image set (project and group scoped).

Changes:

  • Introduces frontend/src/utils/galleryState.js to centralize localStorage persistence, filtering, and sorting logic used by both ImageGallery and ImageView.
  • Updates ImageGallery to persist/restore controls via galleryKey-scoped localStorage and to propagate galleryKey through the ImageView URL.
  • Updates ImageView navigation list building to apply the saved gallery search/review/sort state, with added frontend test coverage.

Reviewed changes

Copilot reviewed 8 out of 8 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
test/backend_tests.sh Adds fallback UV_CACHE_DIR when default location isn’t writable.
frontend/src/utils/galleryState.js New shared persistence + filter/sort utilities with TTL/cap cleanup.
frontend/src/utils/tests/galleryState.test.js Unit tests for persistence, cleanup, filtering, and sorting helpers.
frontend/src/components/ImageGallery.js Loads/saves gallery state from localStorage; adds galleryKey prop; appends galleryKey to ImageView links.
frontend/src/components/GroupGalleryView.js Passes group-/ungrouped-scoped galleryKey to ImageGallery.
frontend/src/components/tests/ImageGallery.test.js Adds tests covering persisted state behavior and galleryKey URL propagation.
frontend/src/ImageView.js Applies saved gallery filters/sort to prev/next navigation list; preserves galleryKey across navigation.
frontend/src/tests/ImageView.test.js Adds navigation tests validating sort/filter behavior and galleryKey preservation.

  When navigating prev/next from the ungrouped gallery, loadProjectImages
  was not passing ungrouped=true to the API, causing navigation to include
  grouped images. Detect the ungrouped gallery key from the URL and scope
  the fetch accordingly.
@travisdock travisdock merged commit c2f6696 into main Mar 18, 2026
9 checks passed
@travisdock travisdock deleted the copilot/add-saved-filter-sort-state branch March 18, 2026 14:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Saved Filter/Sort State

3 participants