diff --git a/renderer/app.js b/renderer/app.js index 2232c20..a78028c 100644 --- a/renderer/app.js +++ b/renderer/app.js @@ -28,7 +28,8 @@ let historySortState = { key: 'date', direction: 'desc' }; // Session-specific files for the "Files" panel (resets each session) let sessionFilesData = []; -let recentSortState = { key: 'date', direction: 'desc' }; // null key = default (date desc) +let recentSortState = { key: 'date', direction: 'desc' }; +let selectedRecentIds = new Set(); // --- Init --- async function init() { @@ -780,6 +781,22 @@ function showContextMenu(x, y) { function hideContextMenu() { document.getElementById('contextMenu').style.display = 'none'; + document.getElementById('recentContextMenu').style.display = 'none'; +} + +function deleteSelectedRecentFiles() { + if (selectedRecentIds.size === 0) return; + sessionFilesData = sessionFilesData.filter(r => !selectedRecentIds.has(r.order)); + selectedRecentIds.clear(); + renderRecentUploadsPanel(); +} + +function copySelectedRecentLinks() { + const links = sessionFilesData + .filter(r => selectedRecentIds.has(r.order) && !r.isError) + .map(r => r.link) + .filter(Boolean); + if (links.length) { window.api.copyToClipboard(links.join('\n')); showCopyToast(`${links.length} Links kopiert`); } } document.addEventListener('click', (e) => { @@ -790,30 +807,40 @@ document.addEventListener('keydown', (e) => { hideContextMenu(); cancelHosterModal(); } - // Ctrl+A — select all queue jobs (only when not in an input/textarea) - if ((e.ctrlKey || e.metaKey) && e.key === 'a' && !e.target.closest('input, textarea, select')) { - const activeView = document.querySelector('.view.active'); - if (activeView && activeView.id === 'upload-view' && queueJobs.length > 0) { + if (e.target.closest('input, textarea, select')) return; + const activeView = document.querySelector('.view.active'); + // Ctrl+A + if ((e.ctrlKey || e.metaKey) && e.key === 'a') { + if (activeView && activeView.id === 'upload-view') { e.preventDefault(); - queueJobs.forEach(j => selectedJobIds.add(j.id)); - renderQueueTable(); + // If recent files panel is focused / has selection, select all recent files + if (selectedRecentIds.size > 0 || document.activeElement?.closest('.recent-files-panel')) { + sessionFilesData.forEach(r => selectedRecentIds.add(r.order)); + renderRecentUploadsPanel(); + } else if (queueJobs.length > 0) { + queueJobs.forEach(j => selectedJobIds.add(j.id)); + renderQueueTable(); + } } } - // Delete — remove selected queue jobs - if (e.key === 'Delete' && !e.target.closest('input, textarea, select')) { - const activeView = document.querySelector('.view.active'); - if (activeView && activeView.id === 'upload-view' && selectedJobIds.size > 0 && !uploading) { + // Delete + if (e.key === 'Delete') { + if (activeView && activeView.id === 'upload-view') { e.preventDefault(); - queueJobs = queueJobs.filter(j => { - if (selectedJobIds.has(j.id)) { removeJobFromIndex(j); return false; } - return true; - }); - selectedJobIds.clear(); - syncSelectedFilesFromQueue(); - renderQueueTable(); - if (queueJobs.length === 0) { selectedFiles = []; updateUploadView(); } - updateStatusBar(); - persistQueueStateSoon(); + if (selectedRecentIds.size > 0) { + deleteSelectedRecentFiles(); + } else if (selectedJobIds.size > 0 && !uploading) { + queueJobs = queueJobs.filter(j => { + if (selectedJobIds.has(j.id)) { removeJobFromIndex(j); return false; } + return true; + }); + selectedJobIds.clear(); + syncSelectedFilesFromQueue(); + renderQueueTable(); + if (queueJobs.length === 0) { selectedFiles = []; updateUploadView(); } + updateStatusBar(); + persistQueueStateSoon(); + } } } }); @@ -1976,7 +2003,7 @@ function renderRecentUploadsPanel() { const rows = sortRecentFiles(sessionFilesData); tbody.innerHTML = rows.map(row => ` -