'use client'; import { useState } from 'react'; import { TRASH_RETENTION_MS } from '../../constants'; import { daysUntilPermanentDelete } from '../../lib/format'; import { Icon } from '../../icons'; import { useViewMedia } from '../../hooks/useViewMedia'; import { useGallery, useGalleryStoreApi } from '../../store/context'; import { MediaGrid } from '../MediaGrid'; import { openSecuritySettings } from '../modals'; export function RecentlyDeletedView() { const api = useGalleryStoreApi(); const items = useViewMedia(); const lockConfigured = useGallery((s) => s.lockConfigured); const lockUnlocked = useGallery((s) => s.lockUnlocked); const lockError = useGallery((s) => s.lockError); const [pw, setPw] = useState(''); const [busy, setBusy] = useState(false); // Locked: a password is set and the user hasn't unlocked this session. if (lockConfigured && !lockUnlocked) { const submit = async () => { setBusy(true); await api.getState().unlockLock(pw); setBusy(false); setPw(''); }; return (
Enter Your Password to View Recently Deleted
{ setPw(e.target.value); api.getState().clearLockError(); }} onKeyDown={(e) => { if (e.key === 'Enter') void submit(); }} /> {lockError ? (
{lockError === 'wrong-password' ? 'Incorrect password.' : "Couldn't check the password. Please try again."}
) : null}
); } if (items.length === 0) { return (
No Recently Deleted Items
Deleted items are kept here for {Math.round(TRASH_RETENTION_MS / 86400000)} days.
); } // Soonest expiry = the smallest remaining days across all trashed items // (independent of display order, which is sorted by capture date). const nextExpiry = items.reduce((min, m) => { if (!m.deletedAt) return min; return Math.min(min, daysUntilPermanentDelete(m.deletedAt, TRASH_RETENTION_MS)); }, Infinity); const expiryDays = Number.isFinite(nextExpiry) ? nextExpiry : 0; return (
Items are deleted permanently after 30 days. Oldest expires in ~{expiryDays} day {expiryDays === 1 ? '' : 's'}.
); }