feat: per-photo permanent delete + discarded thumbnail treatment

Discarded photos now look discarded in the grid (50% opacity + grayscale)
with a red trash badge in the corner instead of a bare icon. The discard
action bar gains a "Delete N" button that permanently deletes only the
current selection, complementing the existing "Empty discard pile".

Backend: new DELETE /discard endpoint accepting {photo_ids: [...]} that
permanently removes only listed photos. Skips ids that aren't in the
discard pile so it can never bypass the soft-delete safety net.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-04-08 13:12:11 +02:00
parent 3a03a56db2
commit b870084be0
4 changed files with 108 additions and 12 deletions

View File

@@ -140,7 +140,10 @@ export function PhotoThumbnail({
alt={photo.filename}
className={clsx(
'h-full w-full object-cover transition-opacity duration-200',
imageLoaded ? 'opacity-100' : 'opacity-0'
imageLoaded ? 'opacity-100' : 'opacity-0',
// Discarded photos fade out + desaturate so the trash section
// reads as a trash section, not just another grid view.
photo.is_discarded && 'opacity-50 grayscale'
)}
onLoad={handleImageLoad}
onError={handleImageError}
@@ -216,7 +219,12 @@ export function PhotoThumbnail({
</div>
)}
{photo.is_discarded && (
<Trash2 className="h-4 w-4 text-reject" />
<div
className="flex h-5 w-5 items-center justify-center rounded-full bg-reject text-white shadow-md"
title="Discarded"
>
<Trash2 className="h-3 w-3" />
</div>
)}
</div>