Adds .coderabbit.yaml so CodeRabbit no longer reviews or comments on PRs opened by dependabot[bot].
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Corrections from my review of #1198: Exposure is Esposizione (not Tempo di esposizione, the shutter time), Sharpening is Nitidezza (not Contrasto), Preset stays Preset in every preset label, and blurry photos are sfocate, not mosse.
Adds the 339 interface messages Italian lacked (print, slideshow, mask effects, faces, HDR, external editors, keywords, focus points and their dialogs) and translates the 60 format strings still in English in it-formats.json. Only the What's New lines stay in English, as before: 2,628 of 3,278 messages.
On a profiled display the Grey and Sharpening-mask views rendered in the display's primaries, so
their histogram counted display-primary pixels, not the photo's sRGB ones. They now render in sRGB
like the clipping views (`Overlay::renders_in_srgb`) and are converted for the display after; they
show no photo colour, so nothing is lost.
The GPU equivalence test now covers Grey (mean/max LSB limits) and the shadow/highlight clipping
views (share of differing pixels, as for Visualize Spots: both renderers draw them with the same
`visualize::apply`, and a 1-LSB difference at 0/255 flips a pixel).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Only a drag timed at full size (median of its full-size drafts, after the
first, at most 20 ms) forgets a slow-drag verdict; a drag that drafts small
from its start, or times fewer than two full-size drafts, leaves it unchanged,
as `DragScale::finish` does.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The folder's mtime may not move from the save's listing to the list that follows (same clock tick on a fast machine), so the stale cache hid the bad files and problems came back empty - deterministic on a warm build. The test drops the cache as its own wild.json case already did (and as templates_changed documents).
The folder tree writes FolderNode.path with forward slashes on every platform, but tests_folder_drop built its widget ids from to_string_lossy, which gives backslashes on Windows: the 8 tests never found their rows there. row_path() normalizes the way tests_sync already does. Same class of fix in tests_export (path comparison) and an unused-import guard in catalog's staging tests (the module's only test is unix-only).
The test checked that Restore All was listed but clicked it only when the
machine already had a hidden location, so CI never exercised that path.
It now hides two places and restores them with Restore All, then hides
one and checks the row restores it directly, without a list.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AbegtYaPuwqZ81pGfELsFK
The menu bar turned a command's error into a toast only for exports, so
File ▸ Back Up Library… did nothing visible when the host refused (changes
still unsaved, or nothing stored in this browser); the refusal reached only
the control channel (found in a real-browser check of PR #1987). Backup and
restore refusals are toasted too. Menu items are registered for automation
as `menuitem:<command id>`, and a headless test clicks File ▸ Back Up
Library… against a refusing host and reads the toast.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AbegtYaPuwqZ81pGfELsFK
"Show N hidden locations" put every location removed from Local back at
once. With several hidden, the row now lists them (name, path on hover):
each comes back on its own, or all with Restore All. With one hidden, the
row restores it directly, as before. The command side already had
local.restoreHidden {path}; only the panel called it without a path.
The headless test hides a second place, opens the list from the row,
restores one, checks the other stays hidden, then restores the rest.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AbegtYaPuwqZ81pGfELsFK
`face_download::Downloads::drop` gave a running download a second to stop,
with `Instant::now()` and `thread::sleep`, which panic on wasm32 ("time not
implemented on this platform"). The web host replaces its Session when the
library can't be opened, so with this branch an unreadable `catalog.log`
killed the page with the generic panic screen instead of showing the
library-problem window (found in a real-browser check of PR #1988). The wait
is skipped on wasm32, where there are no download threads; the cancel flags
are still set. Native test: an idle Downloads drops at once.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AbegtYaPuwqZ81pGfELsFK
A bad `orientation` was refused only on the refit path: "current" and an
unlocked "toggle" returned before the check, so {"aspect": "current",
"orientation": "bogus"} succeeded silently, and a value that isn't a string
fell back to the default. It is parsed first now, so every path refuses a
wrong word, a number, a boolean or null, and nothing changes (CodeRabbit on
PR #2280).
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AbegtYaPuwqZ81pGfELsFK
Found while testing crates/meta/src/exif.rs:455 (write_exif)
Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
A click on a grid stack badge expands or collapses the stack. A double-click,
as in Lightroom, toggled it twice: the second click undid the first and the
stack stayed as it was. The badge now ignores the second click of a
double-click.
set_aspect always turned the ratio to the image's orientation, so a Custom
ratio taller than wide came out landscape on a landscape photo, and a
ratio picked after X (crop.rotateAspect) turned the crop back. A named
ratio now takes the crop's present orientation (landscape, or portrait
after X; a square crop follows the image), a custom [w, h] is used as
given, and crop.aspect takes orientation: "crop" | "given" to choose.
The window reapplies the remembered ratio to an untouched photo with
orientation "crop", as before.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AbegtYaPuwqZ81pGfELsFK
GeoNames cities15000 holds towns of 15 000 people or more, so a photo in a
smaller town got the nearest larger one in City (Portofino → Rapallo,
5.3 km), another municipality. metadata.reverseGeocode takes maxDistance
(metres): past it, City and Sublocation stay empty, State and Country
still fill, and the reply names the town as nearestCity. Hostile values
are refused. The command help, the Fill Location tooltip and the parity
row say what the list holds. Default unchanged.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AbegtYaPuwqZ81pGfELsFK
Preset commands change the preset list outside pending_log, and a failed
presets.json write was only logged: unsaved() stayed None, so nothing
warned and the web backup (#1987) would zip a stale presets.json; on
desktop a full disk lost the preset silently. The failure is now kept
(presets_error), counted by unsaved() (plus one change), retried by
persist_if_dirty with the same back-off as failed appends, and cleared
once the write succeeds.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AbegtYaPuwqZ81pGfELsFK
CodeRabbit's docstring check counted the touched functions without doc
comments (read_with_progress, apply_prepared, inspect_report, result_dialog
and a test helper). Comments only.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RhZLBHaSnSko1eMByPibfh