feat: editable taken_at + folder-based date repair and filter
Lets operators fix corrupted capture dates at scale. Adds an editable Date Taken field with a folder/filename-derived suggestion hint, a bulk Date Taken section in the multi-select sidebar that either applies one date to the whole selection or infers a per-photo date from each path, a warning badge on thumbnails whose stored date disagrees with the path, and a "Date issues" filter pill so suspicious photos can be surfaced and fixed as a group. Edits are written back to EXIF on disk so rescans don't clobber the fix. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1,5 +1,13 @@
|
||||
import { useState, useEffect, useCallback, useRef } from 'react'
|
||||
import { Star, ShoppingBasket, Trash2, RefreshCw, Check, Copy } from 'lucide-react'
|
||||
import {
|
||||
Star,
|
||||
ShoppingBasket,
|
||||
Trash2,
|
||||
RefreshCw,
|
||||
Check,
|
||||
Copy,
|
||||
AlertTriangle,
|
||||
} from 'lucide-react'
|
||||
import clsx from 'clsx'
|
||||
import { photos as photosApi } from '../../services/api'
|
||||
import type { Photo } from '../../types/photo'
|
||||
@@ -92,6 +100,13 @@ export function PhotoThumbnail({
|
||||
const baseUrl = photosApi.getThumbnailUrl(photo.id, 'medium')
|
||||
const thumbnailUrl = retryCount > 0 ? `${baseUrl}?retry=${retryCount}` : baseUrl
|
||||
|
||||
// "Capture date probably wrong" — read straight from the stored
|
||||
// `has_date_warning` flag rather than recomputing the heuristic
|
||||
// client-side. The backend sets this column at scan time and
|
||||
// refreshes it on any taken_at edit, so the UI, the filter, and the
|
||||
// thumbnail badge all read from one source of truth.
|
||||
const dateWarning = photo.has_date_warning === true
|
||||
|
||||
// Square cells (Lightroom-style grid). Variable-aspect cells previously
|
||||
// overflowed their row because TanStack Virtual estimates row height as a
|
||||
// single fixed value — portraits in a landscape row would overlap the row
|
||||
@@ -323,6 +338,21 @@ export function PhotoThumbnail({
|
||||
<Trash2 className={THUMB_BADGE_ICON} strokeWidth={2.5} />
|
||||
</div>
|
||||
)}
|
||||
{dateWarning && (
|
||||
<div
|
||||
className={clsx(
|
||||
THUMB_BADGE_BASE,
|
||||
THUMB_BADGE_SQUARE,
|
||||
// Amber fill with the same chiseled frame as other affirmative
|
||||
// badges so it reads as a first-class warning rather than a
|
||||
// neutral info chip.
|
||||
'bg-amber-500 shadow-[0_0_0_1px_rgba(0,0,0,0.55),inset_0_1px_0_rgba(255,255,255,0.28),0_1px_2px_rgba(0,0,0,0.5)]'
|
||||
)}
|
||||
title="Capture date may be wrong — folder/filename suggests a different date"
|
||||
>
|
||||
<AlertTriangle className={THUMB_BADGE_ICON} strokeWidth={2.5} />
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
{/* TR — file-type metadata (RAW / VIDEO) */}
|
||||
|
||||
Reference in New Issue
Block a user