Commit Graph

160 Commits

Author SHA1 Message Date
LyAhn d619b01f2e refactor(ui): replace native app tooltips
github/actions/ci GitHub Actions CI finished: success
Wrap app controls with the shared Tooltip component and use cursor-positioned tooltip placement for icon buttons, chips, path labels, and media controls.

Leave native title attributes on the window chrome buttons so Minimize, Maximize, and Close keep platform-style behavior.
2026-06-30 23:25:43 +01:00
LyAhn 1a971899d1 feat(search): filter tag results by colour
Pass the active colour filter through tag searches and apply the existing palette match inside the tag query and count paths.

Update the UI Lab mock backend so colour filtering behaves the same way when testing tag search results.
2026-06-30 23:24:25 +01:00
LyAhn 8fe5daf25d Dev/codex cloud setup (#9)
## Summary
- Adds `scripts/codex-cloud-setup.sh` for Codex Cloud environment setup
- Installs Linux/Tauri native dependencies, Node/pnpm, Rust tooling, JS dependencies, and Rust crates
- Uses CPU-safe Rust checks with `--no-default-features` because Phokus enables CUDA by default
- Adds UI Lab/browser guidance for `pnpm dev:ui` on port `1422`

## Notes
- The script is intended to be pasted into the Codex Cloud setup field or run from the repo root.
- It avoids full release builds during setup to keep Codex cache warm without making environment creation too heavy.

Reviewed-on: #9
2026-06-30 14:35:20 +00:00
LyAhn 619bd0c9d2 Merge: rename 'tag cloud' to 'visual clusters' across the stack
github/actions/ci GitHub Actions CI finished: success
Disambiguate the Explore feature naming: the visual k-means cluster view was
named tag_cloud/tagCloud/TagCloud everywhere while the actual tag list is
explore_tags, which was easy to confuse. The cluster side is now
visual_cluster/visualCluster/VisualCluster (command, types, store, DB cache
table, and the ExploreView component); the tags side and the user-facing
"Tag Cloud" label are unchanged. Includes a mock-fixture fix so the dev
"huge" scenario surfaces a realistic field of clusters.
2026-06-30 10:01:25 +01:00
LyAhn 996bb71375 fix(mock): scale visual-cluster fixtures to the scenario
The mock Explore clusters were a fixed 10 regardless of scenario, so the "huge"
dev scenario looked sparse next to its large tag vocabulary. Mirror the backend's
k = (n / 20).clamp(5, 30): the huge scenario now surfaces ~30 clusters with a
long-tailed, big-library-sized count distribution, so Explore looks realistic.
2026-06-30 09:59:50 +01:00
LyAhn 0d9229635b refactor(explore): rename misnamed "tag cloud" to "visual clusters"
The visual k-means cluster feature was confusingly named tag_cloud / tagCloud /
TagCloud across the whole stack, while the actual tag list is explore_tags — the
two were trivially easy to mix up (and did cause confusion). Rename the cluster
side to visual_cluster / visualCluster / VisualCluster everywhere: command
get_tag_cloud -> get_visual_clusters (+ lib.rs registration and the invoke
string), VisualClusterEntry, the store fields/actions/tokens, and the mock
backend. Old names are retired rather than reused, so any missed reference fails
loudly instead of silently resolving to the wrong concept.

The tags side keeps its accurate explore_tags naming, and the user-facing
"Tag Cloud" UI label is unchanged.

Also rename the SQLite tag_cloud_cache table -> visual_cluster_cache (the old
table is dropped during schema setup — it is a disposable cache already
invalidated by the clustering version bump) and the TagCloud.tsx component file
-> ExploreView.tsx, since it is the Explore container hosting both the cluster
and tag views.
2026-06-30 09:48:38 +01:00
LyAhn cdb8aa20b9 Merge: faster Explore visual clustering on large libraries
Sampled, parallel k-means with density-aware k-means++ seeding makes first-time
visual clustering on large libraries fast, without a single cluster swallowing
tens of thousands of generic images. Together with the earlier cache-hit
optimization, the Explore tab no longer stalls for several seconds on 80k+
libraries.
2026-06-30 09:10:15 +01:00
LyAhn d2af84d9e8 perf(explore): sampled, parallel visual clustering for large libraries
Computing visual clusters was O(n·k·dim) per Lloyd iteration over the whole
library, single-threaded — several seconds on an 80k-image library on first
view. Find centroids on a deterministic, evenly-strided sample (<=3000
embeddings) and then assign every image to its nearest centroid in one parallel
rayon pass. Libraries at or below the sample cap are unchanged.

Replace the greedy farthest-point seeding (which seeds outliers, leaving the
dense core under-represented on a sample so one centroid absorbed tens of
thousands of generic images) with proper density-aware k-means++ D² seeding,
made deterministic via a small fixed-seed SplitMix64 PRNG. This keeps clusters
balanced on large libraries.

A CLUSTER_CACHE_VERSION is folded into the tag-cloud cache key so existing
caches computed by the old algorithm are invalidated and recomputed. The
clustering timing line and the cache-write failure now go through the `log`
facade (debug/warn) instead of eprintln.
2026-06-30 09:08:48 +01:00
LyAhn 68a9df5ab3 feat(lightbox): two-column metadata layout
github/actions/ci GitHub Actions CI finished: failure
Lay the lightbox info-panel metadata out in a two-column grid: paired fields
(Dimensions/Duration, Video codec/Audio codec, Type/File size) sit side by side
while Rating, Modified, and Embedding span the full width. More compact panel
with less scrolling. Tags and EXIF sections are unchanged.
2026-06-29 20:35:13 +01:00
LyAhn 79ce458fd5 feat(tags): open the tag manager from Settings
Add an "Open tag manager" button under a new Tag library group in Settings →
AI Workspace. It closes Settings and jumps to Explore's tag Manage mode.

To make manage mode reachable from outside the Explore view, lift its flag out
of TagCloud's local state into the store (tagManagerOpen / setTagManagerOpen)
behind an openTagManager() action. Manage mode is reset whenever Explore is
entered normally or the visual-cluster view is selected, so openTagManager()
stays the only path that opens it programmatically.
2026-06-29 20:26:49 +01:00
LyAhn a9a8f8422e feat(ui): quick theme switch from the settings cog
Right-clicking the settings cog in the title bar opens a small theme menu
(Phokus / Subtle Light / Conventional Dark) with the active theme checked,
anchored under the cog and dismissed on outside-click or Escape. Left-click
still opens Settings. Keeps theme switching one gesture away without cluttering
the title bar with another icon.
2026-06-29 20:26:08 +01:00
LyAhn ab7022e118 perf(explore): instant tag-cloud cache hits + fix stale-on-switch loading
The get_tag_cloud cache key was built by loading and hashing every embedding
blob for the scope *before* checking the cache, so even a cache hit re-read
hundreds of MB on large libraries and stalled Explore for several seconds.
Validate the cache from a lightweight image-ID-set signature plus the embedding
revision instead, so a hit never loads embeddings. The ID-set hash keeps the key
membership-sensitive (add/remove/move between folders) and the revision covers
an image being re-embedded in place. Cache write failures are now logged rather
than silently ignored.

On the frontend, switching folders (or re-entering Explore) no longer leaves the
previous folder's clusters/tags on screen with no loading indicator:
loadTagCloud/loadExploreTags clear stale entries on a real folder switch. The
displayed folder is tracked separately (exploreTagsShownFolderId) from the
cache-dirty marker so a same-folder invalidation (tag edits, new AI tags) does
not masquerade as a switch and wipe the visible list mid-refresh.
2026-06-29 20:25:38 +01:00
LyAhn 23e9850c7a Merge feat/tagging-ux: tagging model choice, related tags, tag manager, and UX polish
github/actions/ci GitHub Actions CI finished: failure
- JoyTag added as a second selectable tagger alongside WD; model switches on demand, tags attributed per-model

- Related tags atlas in Explore: clicking a tag shows co-occurring tags with animated connection lines and image counts

- Persist worker pauses across restarts via a Settings toggle

- Tag manager gains live filter, sort (most-used / least-used / A–Z / Z–A), and virtualisation for large libraries

- Tooltip portal with anchorToCursor mode for precise hover positioning

- Noisy AI tags (e.g. generic background descriptors) filtered at store time; existing tags cleaned on migration

- Fix: tag cloud hover glow and atlas gradient now adapt to Subtle Light theme

- Fix: AI Workspace 'Selected Folders' scope no longer pre-selects the first folder

- Fix: changelog version lookup strips build suffixes so What's New works in UI Lab
2026-06-29 18:36:01 +01:00
LyAhn c111032d99 fix(changelog): strip build suffixes before version lookup
UI-lab builds append a suffix to the version string (e.g.
"0.1.1-ui") which caused getChangelogForVersion to find no match and
fall back to the "not available in-app" message. A regex now strips any
hyphen-and-letter suffix before the lookup so the What's New modal
renders correctly in all build modes.
2026-06-29 18:06:45 +01:00
LyAhn c13f78c68b docs(changelog): add unreleased entries for feat/tagging-ux
Adds the user-facing changes introduced on this branch that were missing
from the [Unreleased] section:

Added:
- Related tags in Explore (tag atlas connection lines + co-occurrence counts)
- Persist worker pauses across restarts (Settings toggle)

Changed:
- Tag manager search/sort/virtualisation

Fixed:
- Noisy AI tags filtered automatically (removal list applied at store time)
- Explore Tag Cloud hover glow and atlas gradient in Subtle Light theme
- AI Workspace "Selected Folders" scope no longer pre-selects a folder
2026-06-29 17:23:20 +01:00
LyAhn f2939d70ab fix: atlas glow and AI Workspace scope pre-selection in light theme
Two targeted fixes:

- Tag Cloud atlas SVG radial gradient now switches its inner stop from white
  to a warm dark tone (rgba 60 50 30) when the Subtle Light theme is active,
  matching the explore-tag hover glow style used elsewhere in light mode.
- Switching the AI Workspace tagging queue scope to "Selected Folders" no
  longer auto-selects the first folder in the list; the selection now starts
  empty so the user can choose exactly which folders to target.
2026-06-29 17:23:03 +01:00
LyAhn 8dbabc2d9e fix: match tag cloud hover glow to dark mode in light theme
Replace the flat background hover override with a dark warm radial
gradient on the ::before pseudo-element, mirroring the same elliptical
glow effect used in dark mode.
2026-06-29 17:06:50 +01:00
LyAhn 5bc397af01 chore: add Playwright test scaffolding
Adds @playwright/test and @types/node as dev dependencies, playwright.config.ts
with a localhost:1420 base URL targeting the Vite dev server, an example
spec, and the standard Playwright output directories to .gitignore.
2026-06-29 16:30:05 +01:00
LyAhn af3c8418ee feat: virtualized tag manager with filter, sort, and light-theme support
Replaces the flat TagManageRow list with a virtualized grid of
TagManageTile cards using @tanstack/react-virtual and dynamic measured
heights (46px idle, 82px when editing/confirming). Adds a filter input
and a sort dropdown (most-used / least-used / A-Z / Z-A). renameTag and
deleteTag no longer clear exploreTagEntries on invalidation so the
manager keeps its filter/sort state during the background refresh.
Light-theme overrides cover all new tag-manager class names.
2026-06-29 16:29:12 +01:00
LyAhn 9144be2518 feat: Tooltip portal with anchorToCursor mode
Tooltip now portals cursor-anchored variants into document.body via a
`mounted` guard, preventing transformed parents and scroll-container
overflow from distorting coordinates. New `anchorToCursor` prop locks
position at hover entry without tracking; `followCursor` retains the
spring-animated tracking behaviour. Color swatches (ColorFilter),
timeline scrubber dots/labels (Timeline), and toolbar dropdowns (Toolbar)
are updated to use the appropriate cursor mode. Toolbar z-index bumped
z-20→z-40 (dropdowns z-30→z-50) to layer above portaled content; tag
autocomplete result guard added (Array.isArray).
2026-06-29 16:28:35 +01:00
LyAhn d81624573d feat: persist worker-pause state across restarts
Worker pause states can optionally survive app restarts. A new toggle in
Settings saves the current pause map to settings/worker_pauses.json; on
startup lib.rs restores it before workers are spawned. Backend: new
snapshot/replace helpers in indexer.rs, persist functions in commands.rs
(get/set_worker_pauses_persist). Frontend: workerPausesPersist store
field, load/setWorkerPausesPersist actions, toggle in SettingsModal.
2026-06-29 13:21:53 +01:00
LyAhn 949382f28c feat: related-tags atlas in Explore view
Hovering a tag in Explore now loads and displays co-occurring tags as a
weighted cloud. New `get_related_tags` SQL self-join (db.rs/commands.rs),
`loadRelatedTags` store action with per-folder keyed cache, and TagCloud
atlas UI with ResizeObserver-driven layout and RAF animation. Explore tag
limit raised to 180; tag cloud auto-refreshes 700ms after new AI tagging
completes.
2026-06-29 13:21:43 +01:00
LyAhn e4a63c8bb0 fix: filter noisy AI tags
Add an editable AI tag removal list and apply it to WD/JoyTag output before tags are stored. Clean existing generated AI tags during database migration while leaving manual user tags untouched.
2026-06-29 11:24:21 +01:00
LyAhn 1685134116 fix(tagger): model-neutral session log; changelog for JoyTag
create_tagger_session is shared by both models but logged "WD tagger: using
CPU execution provider" even when loading JoyTag. Make the CPU/DirectML
session logs model-neutral. Add the JoyTag tagging-model picker to the
changelog now that it's runtime-verified.
2026-06-29 10:26:51 +01:00
LyAhn 705f8c2e56 feat(tagger): Settings picker to switch tagging model (WD / JoyTag)
Adds a "Tagging model" control to Settings → AI Workspace that calls
get/set_tagger_model, alongside the existing acceleration/threshold/batch
controls. Switching refreshes the model status so the download/ready row and
the model name/description reflect the selected model, and the threshold hint
shows the model-appropriate default (0.4 for JoyTag, 0.35 for WD).

Frontend only; mirrors the existing acceleration toggle pattern. End-to-end
JoyTag tagging still needs the model files on disk to verify.
2026-06-29 09:51:30 +01:00
LyAhn 52d54d2404 feat(tagger): add JoyTag provider behind a tagger-model abstraction
Introduces a selectable tagging model so Phokus isn't locked to the
anime-leaning WD tagger. JoyTag uses the Danbooru schema but generalizes to
photographic content and is strong on NSFW concepts — a better fit for a photo
manager while keeping the explicitness range.

- `TaggerModel` enum (wd | joytag) persisted as a `tagger_model` setting;
  `model_dir`, status, and download now follow the active model (per-model
  repo/dir/file list). WD stays the default.
- `Tagger` trait implemented by `WdTagger` and the new `JoyTagger`;
  `create_active_tagger` builds the selected one. The worker holds
  `Box<dyn Tagger>` and rebuilds on model change (TAGGER_SESSION_DIRTY).
- Shared `assemble_batch` skeleton (pack -> one forward pass -> per-image
  fallback, results in input order); both providers and the shared
  decode/pad/resize are de-duped onto common helpers.
- JoyTag specifics: NCHW + RGB + CLIP-normalized input (vs WD's NHWC/BGR/raw),
  flat top_tags.txt labels, logits -> sigmoid -> threshold (default 0.4). It has
  no native rating, so the explicitness rating is derived from its NSFW tags.
- Tags are attributed to the model that produced them (ai_tagger_model),
  via Tagger::model_name, instead of a hardcoded WD constant.
- New get/set_tagger_model commands.

Backend only; the Settings model picker and end-to-end testing against the
JoyTag model files come next.
2026-06-29 09:40:12 +01:00
LyAhn 3a2b134103 Merge perf/tagging: faster, non-freezing AI tagging
github/actions/ci GitHub Actions CI finished: success
Tagging inference no longer monopolises the GPU. It now runs in small
chunked forward passes with a brief yield between them, so a tagging run
keeps the UI responsive instead of freezing the whole app for seconds at a
time — worst on first launch with a cold batch. Throughput is also steadier
(the old wide batches caused periodic slowdowns).

CPU-provider tagging is multi-threaded instead of pinned to a single core
(~2.7x faster on a representative machine), leaving headroom so the rest of
the app stays responsive. DirectML/GPU tagging behaviour is unchanged.
2026-06-29 09:19:40 +01:00
LyAhn 71ad7bf762 perf(tagger): multi-thread CPU inference instead of pinning to one core
The ONNX session was built with intra_threads(1) unconditionally. That's
correct for DirectML (compute is on the GPU), but on the CPU execution
provider it pinned all matmul/conv work to a single core — ~1.78s/image,
~14s for an 8-image batch.

Derive the intra-op thread count from available_parallelism() for the CPU EP
(leaving 2 logical cores free for the UI and a possible concurrent scan;
tagging is the lowest-priority worker, so heavier workers are idle when it
runs). DirectML/Auto keep a single thread. Measured ~2.7x on a representative
machine (14s -> 5.3s per 8-image batch); sublinear because swinv2 inference is
memory-bandwidth-bound. The selected thread count is logged at load.
2026-06-29 09:09:29 +01:00
LyAhn 992417710f perf(tagger): chunked, yielding inference so tagging stops freezing the UI
The tagging worker claimed a batch from the DB but ran the model one image
at a time, so `tagger_batch_size` had no effect on inference. Batching the
whole claim into a single DirectML forward pass fixed that but introduced a
worse problem: on a shared GPU each wide dispatch locks the device (and the
WebView2 compositor with it) for 1-3.7s, freezing the entire app while
tagging runs — worst of all on first launch with a cold graph compile.

The WD model is compute-bound here (~50-230ms/image of actual GPU work), so
a wide batch buys almost no throughput; it only lengthens each uninterruptible
GPU lock. So decouple DB claim size from GPU granularity: claim
`tagger_batch_size` for DB efficiency, but feed the GPU in TAGGER_INFER_CHUNK
(4) images per forward pass with a brief yield between chunks. Each dispatch
now lasts ~200-900ms, the UI gets windows to paint, peak decode memory is
bounded, and the cold compile is for a smaller shape. As a bonus the wide-batch
throughput spikes disappear — steady ~1.6-1.8s/16 vs the old 0.8-3.7s swings.

- run_batch: parallel (rayon) decode + single forward pass per chunk, with
  per-image fallback and decode failures kept attached to their input slot.
- Worker iterates source_paths.chunks(TAGGER_INFER_CHUNK), yielding 40ms
  between chunks; outputs zip back to jobs 1:1, write tx unchanged.
- Remove now-dead WdTagger::run() (fallback uses infer_one directly).
2026-06-29 01:09:47 +01:00
LyAhn 4c6da99507 Merge feat/ui-lab: Add browser-only UI Lab
github/actions/ci GitHub Actions CI finished: success
- Adds a Vite UI Lab mode that boots the real Phokus frontend with mocked
  Tauri APIs.
- Introduces deterministic mock backend scenarios for rich, empty, busy,
  duplicate, album, error, and large-library states.
- Adds fixture media plus a mediaSrc helper so browser previews and Tauri file
  URLs share one rendering path.
- Documents the UI Lab workflow and exposes it through pnpm dev:ui.
2026-06-29 00:12:51 +01:00
LyAhn 24d4e82950 feat: expand UI Lab media fixtures
Add a derived dev-media fixture pack and wire UI Lab scenarios to use the broader image set for more useful browser screenshots.
2026-06-29 00:06:58 +01:00
LyAhn 7a18011b0f feat: add Phokus UI Lab
Add a dev-only Vite UI mode with Tauri API mocks, in-memory fixture scenarios, reusable media source handling, and documentation for browser-based visual testing.
2026-06-29 00:04:48 +01:00
LyAhn cebd709391 fix: anchor cluster Open pill to corner so it stays on small cards
github/actions/ci GitHub Actions CI finished: success
2026-06-28 21:19:32 +01:00
LyAhn d55e4c7502 docs: changelog for unreleased fixes
github/actions/ci GitHub Actions CI finished: success
2026-06-28 21:13:12 +01:00
LyAhn a40a2e8d12 chore: split production build into CPU and CUDA scripts 2026-06-28 21:13:12 +01:00
LyAhn 2ce1547844 fix: improve Explore cluster layout and light-theme readability 2026-06-28 21:12:26 +01:00
LyAhn 623aabbb51 fix: surface actively-processing folder over paused one in background tasks bar 2026-06-28 21:12:24 +01:00
LyAhn f65fd350cc fix: make toolbar, sidebar, and lightbox responsive on small screens 2026-06-28 21:12:22 +01:00
LyAhn 86a1a53289 fix: clamp window to monitor work area so it fits small screens on first launch 2026-06-28 21:12:21 +01:00
LyAhn ebf16e8cb9 fix: skip Phokus's own app-data dir when indexing to break self-indexing loop 2026-06-28 21:12:21 +01:00
LyAhn e7d9c39fd1 docs: regroup unreleased changelog Added entries
github/actions/ci GitHub Actions CI finished: success
2026-06-28 14:56:00 +01:00
LyAhn 136d74a81b Merge feat/smart-albums-multiselect: albums, multi-select, EXIF, tag management, color search
- Manual albums (create/rename/delete/reorder; multi-select bulk add/remove) in a distinct sidebar section
- Gallery multi-select + bulk actions (tag, rate, favorite, add-to-album, delete with disk-delete confirmation)
- Lightbox EXIF/camera panel (on-demand) with a GPS map link
- Tag management in Explore (rename/merge/delete, library-wide)
- Album-scoped similar-image search
- Color search — filter the gallery by dominant color (swatches + custom picker), with background backfill
- Reusable tooltip component, duplicate-finder delete confirmation, CPU/CUDA build badge
- Post-review security/accessibility hardening (validated URL-open commands, etc.)
2026-06-28 14:45:31 +01:00
LyAhn bb0038e0a1 chore: post-review hardening + changelog link tooltip
Security / robustness / a11y polish on top of the color-search + tooltips work:

- URL opening: route through validated backend commands (open_map_location
  with lat/lon bounds-checking, open_changelog_url with a fixed URL) instead
  of the frontend opener:allow-open-url capability, which is now removed.
- EXIF GPS parsing: validate coordinate ranges and require the correct
  N/S/E/W hemisphere ref byte, then clamp.
- Guard double-submit on album create / add-to-album (Lightbox, BulkActionBar,
  Sidebar) and discard stale autocomplete responses in the bulk tag editor.
- Gallery tile: stop nesting <button>s — non-interactive tile div with an
  overlay button for open/toggle; checkbox and Similar promoted with z-index
  + focus rings.
- Accessibility: keyboard handlers, focus-visible rings, and aria on album
  rows, tag-manage actions, and tile controls; Tooltip uses a block <div>
  wrapper in block mode and aria-hidden when hidden.
- Show the destination URL in a tooltip on the "Full changelog" link so the
  user can see where it goes before clicking.
- Toolbar "All" filter also clears the color filter; color-filtered views no
  longer get unfiltered newly-indexed images injected.
- Sidebar reorder: bail if the album set changed mid-drag.
- Tooling: add cargo fmt scripts; alphabetize package.json scripts.
2026-06-28 14:39:21 +01:00
LyAhn 90dec3b212 feat: add color search and reusable tooltips
Add dominant-color palette extraction, storage, filtering, and startup backfill so the gallery and Timeline can be filtered from the toolbar color picker.

Introduce a reusable tooltip component and migrate the color filter, update indicator, and gallery filename hover affordances to it.
2026-06-28 11:04:33 +01:00
LyAhn e3fde46e91 feat: add album scope for similar image search
Similar search scoping:
- Add current_album as a similar-scope option and remember the source album when similar or region searches are launched from an album.
- Route gallery and lightbox similar actions through scope-aware store helpers so Album/Folder/All choices are applied consistently.
- Keep pagination and scope toggles working for both whole-image and region-search result sets.

Backend filtering:
- Extend find_similar_images and find_similar_by_region params with album_id, giving album scope precedence over folder scope.
- Add album_membership filtering for HNSW whole-image search and brute-force crop embedding search.
2026-06-28 01:21:31 +01:00
LyAhn a12e81d8bd feat: lightbox EXIF panel, tag management, reorderable albums
EXIF info panel:
- New on-demand get_image_exif command (kamadak-exif) returning camera/lens/
  aperture/shutter/ISO/focal-length and decimal GPS; read from the file when the
  lightbox opens (no DB schema change, works on already-indexed images).
- Lightbox shows a Camera panel; GPS opens the location in the browser via
  OpenStreetMap (adds opener:allow-open-url capability).

Tag management:
- Backend rename_tag (rename, or merge when the target exists) and delete_tag
  (library-wide), both clearing the tag-cloud cache; store actions invalidate
  tag caches, refresh Explore, and re-point/refresh an active tag-search.
- Explore -> Tag Cloud gains a Manage mode: a flat list with per-tag rename/
  merge/delete.

Albums:
- Drag-to-reorder in the sidebar via framer-motion Reorder with a hover handle;
  order persists through the existing reorder_albums command.

Reads live store order on drag end and robustly derives GPS hemisphere from raw
EXIF ref bytes (review follow-ups). CHANGELOG updated.
2026-06-27 23:50:44 +01:00
LyAhn 6bef90b7fb feat: manual albums + gallery multi-select with bulk actions
Albums (manual collections):
- New albums/album_images tables with FK cascades; DB functions and Tauri
  commands for create/rename/delete/delete-many/reorder/list, add/remove
  images, and paginated get_album_images.
- Distinct sidebar "ALBUMS" section with cover thumbnails, create/rename/
  delete, and a Manage multi-select mode for bulk album deletion.
- Album view reuses the gallery grid (activeView "album" + selectedAlbumId);
  spans folders; add from the bulk bar or the lightbox, remove from within.

Gallery multi-select + bulk actions:
- gallerySelectedIds selection model with a top-left corner checkbox that
  reveals on corner hover; click-to-toggle in selection mode, double-click
  to open.
- Floating BulkActionBar: tag (inline autocomplete popover), rating,
  favorite, add-to-album, and a delete with an explicit "from disk"
  confirmation. Batch commands bulk_update_details/bulk_add_tags/
  bulk_remove_tag.

Also:
- Duplicate Finder delete now requires confirmation with clear "from disk"
  wording (was single-click fire-and-forget).
- CPU/CUDA build-variant badge in Settings (get_build_variant).
- Rating/favorite no longer re-sorts derived collections (similar/region/
  semantic/tag/album results); single and bulk paths replace in place there.
- Album-aware indexed-images/media-updated handlers so thumbnails paint and
  newly-indexed files don't leak into an album view.
- CHANGELOG updated.
2026-06-27 15:23:54 +01:00
LyAhn 55cd3b5aa7 Merge feat/whats-new-updater-ux: What's New screen + updater UX + light-theme fixes
github/actions/ci GitHub Actions CI finished: success
Post-0.1.1 polish queued for the next release (0.1.2):

- What's New: post-update toast that opens an in-app, offline release-notes
  screen (collapsible Added/Changed/Fixed sections) sourced from the bundled
  CHANGELOG.md, reopenable from Settings -> Updates. Backed by a
  last_seen_version settings file that tells upgrades from fresh installs.
- Updater: the progress toast reappears when an update is started from the
  title-bar indicator or Settings after the prompt was dismissed; Settings
  gains a real download progress bar with a percentage.
- Light theme: fix the recurring subtle-light breakage — neutral surfaces rely
  on the CSS-variable remap instead of light-theme:bg-white, and the green
  action buttons drop the broken light-theme:hover:bg-emerald-200 for an
  override-free emerald tint that auto-themes (updater, What's New, onboarding).
- Debug panel: What's New triggers.
2026-06-23 21:36:35 +01:00
LyAhn c878970180 feat: What's New screen + updater progress, plus light-theme fixes
Post-update UX for the next release (0.1.2):

- What's New: after a version change, greet the user with a toast that opens
  an in-app release-notes screen (collapsible Added/Changed/Fixed sections)
  sourced from the bundled CHANGELOG.md, reopenable from Settings -> Updates.
  Backed by a last_seen_version settings file (get/set_last_seen_version
  commands) that distinguishes upgrades from fresh installs.
- Updater: the download/install progress toast now reappears when an update is
  started from the title-bar indicator or Settings after the prompt was
  dismissed; Settings -> Updates gains a real progress bar with a percentage.
- Light theme: fix the recurring subtle-light breakage. Neutral surfaces now
  rely on the CSS-variable remap instead of light-theme:bg-white (which forced
  surfaces dark because --color-white is remapped dark); the green action
  buttons drop the broken light-theme:hover:bg-emerald-200 (remapped dark,
  unreadable on hover) for an override-free emerald-500 tint that auto-themes,
  across the updater, What's New, and onboarding.
- Debug panel: add What's New triggers (toast / modal / reset).
2026-06-23 21:33:08 +01:00
LyAhn 1a95e31f78 docs: fill in 0.1.1 release checksums
Add the SHA-256s for the published CPU and CUDA installers to the
0.1.1 release-notes draft.
2026-06-23 20:26:25 +01:00