'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'}.
);
}