Commit Graph

7 Commits

Author SHA1 Message Date
LyAhn a34d38d9d3 feat: notification batching, per-folder mute, and global pause
Debounce embedding/tagging completion notifications per folder (6s window)
so rapid file additions from downloaders fire one notification instead of
one per file. Add per-folder mute via the sidebar context menu and a global
pause toggle in Settings > General, both persisted across restarts.
2026-06-11 06:28:16 +01:00
LyAhn b89e7406e9 fix(settings): improve thumbnail cleanup UX with live state and time warning
Clear stale stats during cleanup, show zero when done, and warn when the
file count is large enough to take a few minutes.
2026-06-09 06:45:24 +01:00
LyAhn 3707a35cc4 feat(settings): add orphaned thumbnail cleanup to General section
Scans the thumbnails directory and cross-references against thumbnail_path
values in the images table, deleting any files not linked to an indexed image.
Surfaces count and reclaimable MB in the General section alongside the
existing Compact database card.
2026-06-09 01:09:29 +01:00
LyAhn d1eb75a4f5 feat(settings): add compact database card to General section
Adds get_database_info and vacuum_database Tauri commands. The General
section now shows current DB size and reclaimable space on load, with a
Compact now button that runs PRAGMA wal_checkpoint(FULL) + VACUUM and
reports how many MB were freed. Button disables automatically when the
database is already compact (< 0.5 MB reclaimable).
2026-06-09 00:40:05 +01:00
LyAhn fbdd43d9d9 fix(settings): correct invoke payload keys and error handler routing
- folder_ids: use snake_case in both set_tagging_queue_folder_ids invoke
  calls (toggleTaggingQueueFolder and setTaggingQueueFolderIds) to match
  the Rust SetTaggingQueueFolderIdsParams serde field name
- threshold save error: route setTaggerThreshold() catch to
  setTaggerThresholdError instead of setTaggerQueueStatus so the error
  surfaces next to the threshold input, not the queue targets card
2026-06-09 00:22:30 +01:00
LyAhn 33fb3c6c77 feat(settings): overhaul Settings modal with improvements and General section
- Remove Workers section (read-only status, belongs in background tasks panel)
- Remove Captioning coming-soon placeholder
- Add General section with Open data folder button (tauri-plugin-opener)
- Persist queue scope and folder selection across sessions via settings files
- Show inline validation errors on threshold/batch size inputs instead of silent revert
- Fix acceleration save errors appearing in wrong card
- Disable folder selection controls when target scope is All media
2026-06-09 00:14:49 +01:00
LyAhn 0ca4d142d8 feat(discovery): AI tagging, semantic search, similarity, duplicate finder, folder management
Adds a full discovery and organisation layer to the gallery.

## AI Tagger
- WD tagger (ONNX via ort) with DirectML/CPU acceleration
- Per-image and per-folder tag queuing; configurable batch size and
  confidence threshold; model downloaded on first use via ureq/zip
- Tags stored with source ('ai' | 'user'); user tags are never
  overwritten by AI; AI tags protected from accidental promotion
- Tagger pause/resume per folder; in-flight batches discarded cleanly
  on pause or cancellation without leaving jobs stuck in processing

## Semantic & Tag Search
- CLIP text-query embedding via candle (HuggingFace hub model)
- Progressive candidate doubling with filter post-processing so
  folder/rating/media-kind filters do not silently under-return results
- Tag search with DB-backed pagination (offset + COUNT total)
- Filename search unchanged; prefix syntax: s:, t:, f: in search bar

## Similarity Search
- HNSW in-memory index (hnsw_rs) with monotonic embedding_revision
  counter for cache invalidation; build_index retries if a concurrent
  write advances the revision during construction
- Folder-scoped similar search uses brute-force cosine scan (no k limit)
- Region-based similarity: crop an arbitrary rectangle in the lightbox,
  embed it with CLIP, find the nearest images globally or within folder
- Pagination for both similar and region results; scope toggle
  (all media / current folder) re-runs the query without reopening image

## Duplicate Finder
- Three-phase detection: stat (size) → sample hash (4×16 KB windows)
  → full-file hash (xxh3, large files only) to eliminate false positives
- Filesystem-first deletion: only removes DB rows for files successfully
  deleted from disk; failed files remain visible for retry
- Persisted scan cache (SQLite) with invalidation on reindex and deletion;
  both global and per-folder scopes invalidated after any deletion

## Tag Cloud & Explore
- Visual cluster explore: k-means over CLIP embeddings, configurable k,
  representative thumbnail per cluster; cache keyed on xxh3 of embedding set
- Tag explore: ranked tag list with image counts and representative
  thumbnail per tag; invalidated when AI tagging completes or folder removed
- Tag autocomplete for search bar

## Folder Management
- Inline rename (display name only, not OS rename)
- Relocate: file-picker to update folder path; all image paths rewritten
  using SUBSTR prefix replacement to avoid corrupting paths that contain
  the folder name as a substring
- Missing-folder recovery banner: Locate or Remove, never silent deletion
- Right-click context menu on sidebar items: Reindex, Rename, Locate,
  Remove; hover buttons preserved alongside context menu

## Background Tasks
- Per-folder progress panel with embedding, tagging, caption, and
  thumbnail stage breakdown
- Retry button per task for failed embeddings and tagging jobs
- Completed-task notifications (system tray via tauri-plugin-notification)
- Scan errors shown inline; WalkDir permission errors protect existing
  records from deletion rather than cascading data loss

## Backend correctness
- sqlite-vec DML performed outside transactions throughout (virtual-table
  limitation); embedding revision incremented on delete as well as insert
- Tagging job discard checks status = 'processing' so paused jobs reset
  to 'pending' are also skipped, not just cancelled ones
- Stale async responses in Lightbox guarded with cancellation flags and
  currentImageIdRef for both tag-load and tag-add callbacks
- Duplicate cache cleared on reindex; folder-removal clears vector rows
  outside transaction before deleting the folder row
2026-06-07 22:43:16 +00:00