web(review): scope date suggestion to EXIF Stripped tab + 'a' shortcut

- Gate the sidebar's "Suggested from path" row on /review?tab=stripped_exif
  instead of a per-photo TakenSrc heuristic — PhotoPrism stores a guessed
  TakenAt for stripped-EXIF photos too, so the heuristic was hiding the
  row even when a path-derived date was available.
- Same gate on the BulkActionBar's "Accept date & Keep" button.
- Extract acceptDateAndKeep() + cachedPhoto() into photoActions so the
  bar button and a new bare-'a' shortcut in gridKeyNav share one path.
- Show an 'A' kbd hint on the bar button.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-05-20 11:31:04 +02:00
parent d1ddc48f81
commit 97f51a05c4
4 changed files with 123 additions and 78 deletions

View File

@@ -6,6 +6,7 @@
PUT (Details fields need the full body).
-->
<script lang="ts">
import { page } from '$app/state';
import { createMutation, createQuery, useQueryClient } from '@tanstack/svelte-query';
import { toast } from 'svelte-sonner';
import {
@@ -128,19 +129,21 @@
commit({ Caption: caption, CaptionSrc: 'manual' });
}
const takenAtValid = $derived(takenAt === '' || isValidISODate(takenAt));
// Path-based date guess. Surfaced only when the photo's stored date is
// missing or untrusted — same heuristic the review adapter uses to
// bucket photos into `stripped_exif`. Tying it to the heuristic rather
// than a specific tab means the suggestion shows up wherever the user
// lands on a date-less photo (timeline drill-in, archive, etc.).
const needsDate = $derived(
!photo.TakenSrc || photo.TakenSrc === 'name' || !photo.TakenAt
// Path-based date guess. Scoped to the EXIF Stripped review tab: those
// are the photos with definitionally-untrusted dates, and showing the
// row anywhere else would compete with the existing TakenAt.
// PhotoPrism stores a TakenAt for stripped-EXIF photos too (filename
// guess or file mtime), so a per-photo "needs date" heuristic would
// silently hide the suggestion — the tab is the more reliable signal.
const onExifStrippedTab = $derived(
page.url.pathname === '/review' &&
page.url.searchParams.get('tab') === 'stripped_exif'
);
const dateSuggestion = $derived(
suggestDateFromPath({ fileName: photo.FileName, path: photo.Path })
);
const showDateSuggestion = $derived(
needsDate && !!dateSuggestion && dateSuggestion !== takenAt
onExifStrippedTab && !!dateSuggestion && dateSuggestion !== takenAt
);
function applyDateSuggestion() {
if (!dateSuggestion) return;