Compare commits

..

No commits in common. "e6bad780ee1e0c8713bf35cc0e9f0decfb806543" and "14490d947a1183b176e2fa1abd297daed62b68ce" have entirely different histories.

4 changed files with 30 additions and 107 deletions

View File

@ -1,6 +1,6 @@
{ {
"name": "multi-hoster-uploader", "name": "multi-hoster-uploader",
"version": "1.6.5", "version": "1.6.4",
"description": "Upload files to doodstream, voe, vidmoly, byse simultaneously", "description": "Upload files to doodstream, voe, vidmoly, byse simultaneously",
"main": "main.js", "main": "main.js",
"scripts": { "scripts": {

View File

@ -28,8 +28,7 @@ let historySortState = { key: 'date', direction: 'desc' };
// Session-specific files for the "Files" panel (resets each session) // Session-specific files for the "Files" panel (resets each session)
let sessionFilesData = []; let sessionFilesData = [];
let recentSortState = { key: 'date', direction: 'desc' }; let recentSortState = { key: 'date', direction: 'desc' }; // null key = default (date desc)
let selectedRecentIds = new Set();
// --- Init --- // --- Init ---
async function init() { async function init() {
@ -781,22 +780,6 @@ function showContextMenu(x, y) {
function hideContextMenu() { function hideContextMenu() {
document.getElementById('contextMenu').style.display = 'none'; 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) => { document.addEventListener('click', (e) => {
@ -807,40 +790,30 @@ document.addEventListener('keydown', (e) => {
hideContextMenu(); hideContextMenu();
cancelHosterModal(); cancelHosterModal();
} }
if (e.target.closest('input, textarea, select')) return; // Ctrl+A — select all queue jobs (only when not in an input/textarea)
const activeView = document.querySelector('.view.active'); if ((e.ctrlKey || e.metaKey) && e.key === 'a' && !e.target.closest('input, textarea, select')) {
// Ctrl+A const activeView = document.querySelector('.view.active');
if ((e.ctrlKey || e.metaKey) && e.key === 'a') { if (activeView && activeView.id === 'upload-view' && queueJobs.length > 0) {
if (activeView && activeView.id === 'upload-view') {
e.preventDefault(); e.preventDefault();
// If recent files panel is focused / has selection, select all recent files queueJobs.forEach(j => selectedJobIds.add(j.id));
if (selectedRecentIds.size > 0 || document.activeElement?.closest('.recent-files-panel')) { renderQueueTable();
sessionFilesData.forEach(r => selectedRecentIds.add(r.order));
renderRecentUploadsPanel();
} else if (queueJobs.length > 0) {
queueJobs.forEach(j => selectedJobIds.add(j.id));
renderQueueTable();
}
} }
} }
// Delete // Delete — remove selected queue jobs
if (e.key === 'Delete') { if (e.key === 'Delete' && !e.target.closest('input, textarea, select')) {
if (activeView && activeView.id === 'upload-view') { const activeView = document.querySelector('.view.active');
if (activeView && activeView.id === 'upload-view' && selectedJobIds.size > 0 && !uploading) {
e.preventDefault(); e.preventDefault();
if (selectedRecentIds.size > 0) { queueJobs = queueJobs.filter(j => {
deleteSelectedRecentFiles(); if (selectedJobIds.has(j.id)) { removeJobFromIndex(j); return false; }
} else if (selectedJobIds.size > 0 && !uploading) { return true;
queueJobs = queueJobs.filter(j => { });
if (selectedJobIds.has(j.id)) { removeJobFromIndex(j); return false; } selectedJobIds.clear();
return true; syncSelectedFilesFromQueue();
}); renderQueueTable();
selectedJobIds.clear(); if (queueJobs.length === 0) { selectedFiles = []; updateUploadView(); }
syncSelectedFilesFromQueue(); updateStatusBar();
renderQueueTable(); persistQueueStateSoon();
if (queueJobs.length === 0) { selectedFiles = []; updateUploadView(); }
updateStatusBar();
persistQueueStateSoon();
}
} }
} }
}); });
@ -2003,7 +1976,7 @@ function renderRecentUploadsPanel() {
const rows = sortRecentFiles(sessionFilesData); const rows = sortRecentFiles(sessionFilesData);
tbody.innerHTML = rows.map(row => ` tbody.innerHTML = rows.map(row => `
<tr class="recent-file-row${row.isError ? ' error' : ''}${selectedRecentIds.has(row.order) ? ' selected' : ''}" data-order="${row.order}" data-link="${escapeAttr(row.link)}"> <tr class="recent-file-row${row.isError ? ' error' : ''}" data-link="${escapeAttr(row.link)}">
<td>${escapeHtml(row.date)}</td> <td>${escapeHtml(row.date)}</td>
<td title="${escapeAttr(row.filename)}">${escapeHtml(row.filename)}</td> <td title="${escapeAttr(row.filename)}">${escapeHtml(row.filename)}</td>
<td>${escapeHtml(row.host)}</td> <td>${escapeHtml(row.host)}</td>
@ -2011,32 +1984,14 @@ function renderRecentUploadsPanel() {
</tr> </tr>
`).join(''); `).join('');
tbody.querySelectorAll('.recent-file-row').forEach(tr => { tbody.querySelectorAll('.recent-file-row').forEach(row => {
tr.addEventListener('click', (e) => { row.addEventListener('click', () => {
const id = parseInt(tr.dataset.order, 10); if (row.classList.contains('error')) return;
if (e.ctrlKey || e.metaKey) { const link = row.dataset.link;
if (selectedRecentIds.has(id)) selectedRecentIds.delete(id); if (link) {
else selectedRecentIds.add(id); window.api.copyToClipboard(link);
} else if (e.shiftKey && selectedRecentIds.size > 0) { showCopyToast('Link kopiert');
const sortedOrders = rows.map(r => r.order);
const lastIdx = sortedOrders.findIndex(o => selectedRecentIds.has(o));
const curIdx = sortedOrders.indexOf(id);
if (lastIdx >= 0 && curIdx >= 0) {
const from = Math.min(lastIdx, curIdx);
const to = Math.max(lastIdx, curIdx);
for (let i = from; i <= to; i++) selectedRecentIds.add(sortedOrders[i]);
}
} else {
selectedRecentIds.clear();
selectedRecentIds.add(id);
} }
renderRecentUploadsPanel();
});
tr.addEventListener('dblclick', () => {
if (tr.classList.contains('error')) return;
const link = tr.dataset.link;
if (link) { window.api.copyToClipboard(link); showCopyToast('Link kopiert'); }
}); });
}); });
@ -2129,32 +2084,6 @@ function setupListeners() {
} }
renderRecentUploadsPanel(); renderRecentUploadsPanel();
}); });
// Recent files context menu
document.getElementById('recentFilesBody').addEventListener('contextmenu', (e) => {
const tr = e.target.closest('.recent-file-row');
if (!tr) return;
e.preventDefault();
const id = parseInt(tr.dataset.order, 10);
if (!selectedRecentIds.has(id)) {
selectedRecentIds.clear();
selectedRecentIds.add(id);
renderRecentUploadsPanel();
}
const menu = document.getElementById('recentContextMenu');
menu.style.display = 'block';
menu.style.left = Math.min(e.clientX, window.innerWidth - 180) + 'px';
menu.style.top = Math.min(e.clientY, window.innerHeight - 80) + 'px';
});
document.getElementById('recentContextMenu').addEventListener('click', (e) => {
const item = e.target.closest('.ctx-item');
if (!item) return;
hideContextMenu();
const action = item.dataset.action;
if (action === 'recent-copy-links') copySelectedRecentLinks();
else if (action === 'recent-delete') deleteSelectedRecentFiles();
});
document.getElementById('reuploadSelectedBtn').addEventListener('click', retrySelectedJobs); document.getElementById('reuploadSelectedBtn').addEventListener('click', retrySelectedJobs);
document.getElementById('abortSelectedBtn').addEventListener('click', abortSelectedJobs); document.getElementById('abortSelectedBtn').addEventListener('click', abortSelectedJobs);
document.getElementById('finishStopBtn').addEventListener('click', finishUploadsInProgress); document.getElementById('finishStopBtn').addEventListener('click', finishUploadsInProgress);

View File

@ -241,11 +241,6 @@
<div class="ctx-item" data-action="copy-all-links">Alle Links kopieren</div> <div class="ctx-item" data-action="copy-all-links">Alle Links kopieren</div>
</div> </div>
<div class="context-menu" id="recentContextMenu" style="display:none">
<div class="ctx-item" data-action="recent-copy-links">Links kopieren</div>
<div class="ctx-item" data-action="recent-delete">Entfernen</div>
</div>
<div class="statusbar" id="statusbar"> <div class="statusbar" id="statusbar">
<span class="sb-state" id="sbState">Bereit</span> <span class="sb-state" id="sbState">Bereit</span>
<span class="sb-separator">|</span> <span class="sb-separator">|</span>

View File

@ -473,7 +473,6 @@ body {
.recent-file-row:hover { .recent-file-row:hover {
background: rgba(255, 255, 255, 0.03); background: rgba(255, 255, 255, 0.03);
} }
.recent-file-row.selected { background: rgba(102, 126, 234, 0.12) !important; }
.recent-file-row.error { .recent-file-row.error {
color: var(--danger); color: var(--danger);
opacity: 0.75; opacity: 0.75;