web(review): YYYY/MM path fallback + suggestion row below date + tighten 'a' gate
- suggestDateFromPath: when only year+month appear in the path (e.g. 2024/01/), synthesize day=01 so date-only foldering yields a usable suggestion instead of null. - RightSidebar: move the suggestion row below the Taken-at input. - BulkActionBar + gridKeyNav: show the "Accept date & Keep" button and fire the bare 'a' shortcut only when EVERY targeted photo has a path-derivable date — no more silent approve-without-fix for mixed selections. - gridKeyNav: drop local cachedPhoto duplicate, use the shared one. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1,8 +1,12 @@
|
||||
/**
|
||||
* Best-effort calendar date guessed from a photo's filename / parent
|
||||
* folders. Returns `YYYY-MM-DD` only when year + month + day are all
|
||||
* present and form a real date; returns `null` for year-only or
|
||||
* unparseable inputs.
|
||||
* folders. Returns `YYYY-MM-DD`:
|
||||
* - high-confidence when year + month + day are all parseable
|
||||
* (basename or path)
|
||||
* - month-anchored when only year + month appear in the path (day
|
||||
* synthesised to `01` so the value drops cleanly into a date
|
||||
* input; the user reviews + adjusts before committing)
|
||||
* Returns `null` for year-only or unparseable inputs.
|
||||
*
|
||||
* Used by the EXIF Stripped review tab to pre-fill the metadata
|
||||
* sidebar's date suggestion row.
|
||||
@@ -32,8 +36,12 @@ function tryDate(y: number, m: number, d: number): string | null {
|
||||
// `20070612` cleanly without bleeding into the trailing timestamp.
|
||||
const BASENAME_YMD = /(?<!\d)(\d{4})[-_]?(\d{2})[-_]?(\d{2})(?!\d)/;
|
||||
|
||||
// Path variant accepts `/` as a separator too — `2007/06/12`, `2007-06-12/`.
|
||||
// Path Y-M-D first (e.g. `2007/06/12`, `2007-06-12/`). Y-M fallback
|
||||
// (`2024/01/`, `Photos/2024-01/inner`) trips when the user only foldered
|
||||
// by month — the day defaults to `01` so the field has a sensible
|
||||
// pre-filled value rather than nothing.
|
||||
const PATH_YMD = /(?<!\d)(\d{4})[-_/](\d{2})[-_/](\d{2})(?!\d)/;
|
||||
const PATH_YM = /(?<!\d)(\d{4})[-_/](\d{2})(?!\d)/;
|
||||
|
||||
export function suggestDateFromPath(input: Input): string | null {
|
||||
const fileName = (input.fileName ?? '').trim();
|
||||
@@ -46,9 +54,14 @@ export function suggestDateFromPath(input: Input): string | null {
|
||||
}
|
||||
|
||||
if (path) {
|
||||
const pMatch = path.match(PATH_YMD);
|
||||
if (pMatch) {
|
||||
const iso = tryDate(Number(pMatch[1]), Number(pMatch[2]), Number(pMatch[3]));
|
||||
const ymd = path.match(PATH_YMD);
|
||||
if (ymd) {
|
||||
const iso = tryDate(Number(ymd[1]), Number(ymd[2]), Number(ymd[3]));
|
||||
if (iso) return iso;
|
||||
}
|
||||
const ym = path.match(PATH_YM);
|
||||
if (ym) {
|
||||
const iso = tryDate(Number(ym[1]), Number(ym[2]), 1);
|
||||
if (iso) return iso;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user