Full document, spreadsheet, slideshow, and diagram tooling
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

at main 99 lines 3.5 kB view raw
1/** 2 * Delegated trash-list click handler (restore, permanent delete, 3 * empty all) and the trash-section toggle listener. 4 * 5 * Phase 1: All operations are local (IndexedDB via local-store). 6 */ 7 8import type { EventDeps } from './landing-events.js'; 9import { showToast } from './landing-toast.js'; 10import { modalConfirm } from './lib/modal-dialog.js'; 11import { 12 restoreDocument, 13 deleteDocument, 14} from './lib/local-store.js'; 15 16// ── Delegated trash-list listener ──────────────────────────── 17 18export function attachTrashListListener(deps: EventDeps): void { 19 deps.trashListEl.addEventListener('click', async (e) => { 20 const target = e.target as HTMLElement; 21 22 // Restore 23 const restoreBtn = target.closest('.trash-restore') as HTMLElement | null; 24 if (restoreBtn) { 25 const id = restoreBtn.dataset.id!; 26 await restoreDocument(id); 27 const doc = deps.getTrashedDocs().find(d => d.id === id); 28 if (doc) { 29 doc.deleted_at = null; 30 deps.setTrashedDocs(deps.getTrashedDocs().filter(d => d.id !== id)); 31 deps.setAllDocs([...deps.getAllDocs(), doc]); 32 } 33 deps.renderDocuments(); 34 return; 35 } 36 37 // Permanent delete 38 const permBtn = target.closest('.trash-permanent') as HTMLElement | null; 39 if (permBtn) { 40 const doc = deps.getTrashedDocs().find(d => d.id === permBtn.dataset.id); 41 const name = doc?.name || 'this document'; 42 const ok = await modalConfirm({ 43 title: 'Permanently delete?', 44 message: `Permanently delete "${name}"? This cannot be undone.`, 45 okLabel: 'Delete', 46 destructive: true, 47 }); 48 if (!ok) return; 49 const id = permBtn.dataset.id!; 50 await deleteDocument(id); 51 deps.setTrashedDocs(deps.getTrashedDocs().filter(d => d.id !== id)); 52 53 const k = JSON.parse(localStorage.getItem('atmos-keys') || '{}'); 54 delete k[id]; 55 localStorage.setItem('atmos-keys', JSON.stringify(k)); 56 57 deps.renderDocuments(); 58 showToast('Permanently deleted.'); 59 return; 60 } 61 62 // Empty all trash 63 const emptyBtn = target.closest('.trash-empty-all') as HTMLElement | null; 64 if (emptyBtn) { 65 const docs = deps.getTrashedDocs(); 66 const ok = await modalConfirm({ 67 title: 'Empty trash?', 68 message: `Permanently delete all ${docs.length} trashed documents? This cannot be undone.`, 69 okLabel: 'Delete all', 70 destructive: true, 71 }); 72 if (!ok) return; 73 const keys = JSON.parse(localStorage.getItem('atmos-keys') || '{}'); 74 for (const doc of docs) { 75 try { 76 await deleteDocument(doc.id); 77 delete keys[doc.id]; 78 } catch { 79 showToast('Failed to delete a document', 4000, true); 80 } 81 } 82 localStorage.setItem('atmos-keys', JSON.stringify(keys)); 83 deps.setTrashedDocs([]); 84 deps.renderDocuments(); 85 showToast(`Permanently deleted ${docs.length} document(s).`); 86 } 87 }); 88} 89 90// ── Trash toggle one-off listener ──────────────────────────── 91 92export function attachTrashToggleListener(deps: EventDeps): void { 93 deps.trashToggle.addEventListener('click', () => { 94 deps.setTrashExpanded(!deps.getTrashExpanded()); 95 const icon = deps.trashToggle.querySelector('.trash-toggle-icon'); 96 if (icon) icon.textContent = deps.getTrashExpanded() ? '\u25BC' : '\u25B6'; 97 deps.renderDocuments(); 98 }); 99}