Skip to content

feat: add tag filter for assets - #52

Merged
Majorfi merged 2 commits into
mainfrom
feat/tag-filter
Jun 26, 2026
Merged

feat: add tag filter for assets#52
Majorfi merged 2 commits into
mainfrom
feat/tag-filter

Conversation

@Majorfi

@Majorfi Majorfi commented Jun 26, 2026

Copy link
Copy Markdown
Owner

Closes #51 — lets you filter photos by an Immich tag across the grid and map, so already-tagged images can be found and mass-geolocated.

Backend

  • New tags / assetTags tables (migration 016), synced from Immich via getTags + getTagAssetIDs with a syncTags routine mirroring syncAlbums.
  • tagID threaded through asset, map-marker, day-count and page-info queries; new GET /tags endpoint for the dropdown.
  • Map-marker queries now also honor startDate/endDate.
  • getTags count joins through to real assets, excluding orphaned rows and stack-secondary / hidden-library assets, so the badge matches the filtered list.
  • Tag and album sync now advance updatedAt only after assets are replaced — a transient fetch failure is retried next sync instead of leaving membership stale; per-item failures are isolated.
  • deleteUserSyncData clears tags/assetTags on API-key change.

Frontend

  • TagFilterGroup searchable dropdown, disabled on the album list and cleared when leaving an album.
  • tagID persisted in the URL and threaded through view/catalog/map state.
  • Map viewport re-fits when the tag or date filter changes the marker set.
  • URL sync reads a live ref so chained filter changes no longer clobber one another.

Tests

  • New backend regression tests for the tag-count fix, deferred-updatedAt sync (tag and album), and the failed-fetch-recovers behavior.
  • Full backend suite + go vet pass; frontend tsc + eslint clean.
  • Tag/date map re-fit verified manually in the running app.

Filter photos by Immich tag across the grid and map, mirroring the
existing album-filter pattern (closes #51).

Backend:
- New tags and assetTags tables (migration 016), synced from Immich via
  getTags + getTagAssetIDs and a syncTags routine mirroring syncAlbums
- Thread tagID through asset, map-marker, day-count and page-info queries;
  add GET /tags for the dropdown
- Honor startDate/endDate in map-marker queries
- getTags count joins through to real assets, excluding orphaned rows and
  stack-secondary / hidden-library assets
- Tag and album sync now advance updatedAt only after assets are replaced,
  so a transient fetch failure is retried instead of leaving membership
  stale; per-item failures are isolated
- deleteUserSyncData clears tags and assetTags on API-key change

Frontend:
- TagFilterGroup searchable dropdown, disabled on the album list
- Persist tagID in the URL and thread it through view/catalog/map state
- Re-fit the map viewport when the tag or date filter changes the markers
- URL sync reads a live ref so chained filter changes no longer clobber
  one another
@Majorfi
Majorfi requested a review from Copilot June 26, 2026 11:51
@Majorfi Majorfi self-assigned this Jun 26, 2026
@Majorfi Majorfi added the enhancement New feature or request label Jun 26, 2026

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

Adds an Immich tag-based filter that propagates end-to-end (URL/state → frontend grid/map → backend queries), enabling workflows like finding already-tagged photos and mass geolocating them.

Changes:

  • Introduces tag persistence and selection in frontend state/URL, plus a searchable TagFilterGroup UI control.
  • Adds backend tag storage + sync from Immich and exposes tags via a new GET /tags endpoint.
  • Threads tagID (and for map markers, date range) through asset, day-count, page-info, and map-marker queries.

Reviewed changes

Copilot reviewed 42 out of 42 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
src/utils/view.ts Adds URL param constant for tag selection.
src/shared/types/tag.ts Introduces shared tag row type for frontend consumption.
src/shared/types/context.ts Extends view/map context types to include tag selection and dates.
src/shared/services/backendApi.ts Threads tagID into asset/day-count/page-info/map-marker requests; adds fetchTags().
src/shared/services/backendApi.guards.ts Adds runtime guard for tag payloads.
src/shared/context/useViewDomain.ts Wires tag selection into view domain + URL sync; clears tag in album list mode.
src/shared/context/useUIMapController.ts Passes tag selection through map controller inputs.
src/shared/context/useProviderValues.ts Propagates tag selection + dates through provider memoization.
src/shared/context/useCatalogDomain.ts Threads tag selection into asset loading hook.
src/shared/context/useAppProviderState.ts Integrates tag state into app provider wiring.
src/shared/components/PhotoListContainer.tsx Clears tag when switching into album mode; passes tag props to filter bar.
src/shared/components/PhotoList.tsx Adds tag props to filter bar composition and disables tag filter on album list.
src/features/tags/useTags.ts New hook to fetch tags lazily (on-demand) with abort handling.
src/features/photoGrid/useAssets.ts Adds tag dependency to asset loading and refresh logic.
src/features/map/hooks/useMapViewModel.ts Threads tag/date into map marker loading and view model output.
src/features/map/hooks/useMapViewController.ts Includes tag/date in controller dependencies for fit/reload behavior.
src/features/map/hooks/useMapViewAutoFit.ts Resets auto-fit when tag/date filters change (defer fit until markers update).
src/features/map/hooks/useMapMarkers.ts Threads tag/date into map marker fetch and reload triggers.
src/features/map/hooks/useFocusMapAsset.ts Passes selected tag into focus resolution flow.
src/features/map/hooks/useFocusMapAsset.flow.ts Threads tag into page-info queries when resolving focus target.
src/features/filterBar/useURLState.ts Persists tag in URL state and switches URL sync to a live ref model.
src/features/filterBar/useDayCounts.ts Threads tag filter into day-count fetching.
src/features/filterBar/TagFilterGroup.tsx New searchable tag dropdown UI component.
src/features/filterBar/FilterBar.tsx Renders tag filter group and wires props.
src/features/albums/useAlbums.ts Adjusts album reload behavior when date/gps filters change.
backend/types.go Adds backend tag row + Immich tag response types.
backend/syncTags.go Implements tag metadata upsert + asset membership sync.
backend/syncService.go Integrates tag sync; changes album sync stamping behavior; adds tag fetch limit.
backend/syncService_test.go Adds regression tests for deferred updatedAt stamping and recovery behavior.
backend/migrations/016_add_tags.sql Adds tags and assetTags tables and index.
backend/migrations_test.go Updates expected migration version to 16.
backend/main.go Registers protected GET /tags route.
backend/interfaces.go Extends store interfaces to support tags and tag-aware queries.
backend/immichClient.go Adds Immich tag list + tag asset search calls.
backend/handlersAuth.go Updates map marker count calls for new signature.
backend/handlers.go Threads tag/date into handlers; adds handleGetTags; validates map marker date params.
backend/handlers_test.go Updates existing tests for new filtered-assets signature.
backend/databaseTags.go Adds tag persistence, tag membership replacement, and tag list query w/ counts.
backend/databaseLibraries_test.go Updates map marker/asset query calls for new signatures.
backend/databaseAlbums.go Adds setAlbumSynced() helper to stamp updatedAt post-success.
backend/database.go Adds tag-aware asset filters, tag/date-aware marker filters, and tag-aware page-info logic.
backend/database_test.go Updates tests and adds coverage for tag-filtered queries and tag counts.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/features/map/hooks/useMapMarkers.ts Outdated
Comment thread backend/syncService.go Outdated
Comment thread backend/syncService.go Outdated
Comment thread backend/handlers.go
…tags

- Record both album and tag failures via errors.Join instead of only the
  first (full + incremental sync)
- Clear map markers on date-range change too, matching album/tag, so stale
  out-of-range pins are not briefly shown or interactable
- Add handler test for GET /tags (authenticated success + unauthenticated)
@Majorfi
Majorfi merged commit 94f8d30 into main Jun 26, 2026
3 checks passed
@muxmix

muxmix commented Jun 27, 2026

Copy link
Copy Markdown

Thank you, very useful, I was able to geolocalize hundreds of images in a few minutes

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add a tag filter

3 participants