✨ feat(queue): add "Hoster entfernen" submenu to context menu
Right-click on queue now shows a "Hoster entfernen ▸" submenu listing all hosters with job count (e.g. "Vidmoly (3)"). Clicking removes all jobs for that hoster, cancels active uploads, and saves immediately. Also fixes submenu viewport flip measurement (was reading offsetWidth on display:none elements). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
ccfb7c18ba
commit
a64ebd1587
@ -1019,6 +1019,25 @@ function showContextMenu(x, y) {
|
|||||||
cancelSep.style.display = 'none';
|
cancelSep.style.display = 'none';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Dynamic "delete by hoster" submenu
|
||||||
|
const deleteHosterSubmenu = menu.querySelector('.ctx-hoster-delete-submenu');
|
||||||
|
const deleteHosterContainer = menu.querySelector('.ctx-hoster-delete-items');
|
||||||
|
const hosterCounts = new Map();
|
||||||
|
queueJobs.forEach(j => hosterCounts.set(j.hoster, (hosterCounts.get(j.hoster) || 0) + 1));
|
||||||
|
deleteHosterContainer.innerHTML = '';
|
||||||
|
if (hosterCounts.size > 0) {
|
||||||
|
deleteHosterSubmenu.style.display = '';
|
||||||
|
hosterCounts.forEach((count, hoster) => {
|
||||||
|
const item = document.createElement('div');
|
||||||
|
item.className = 'ctx-item ctx-item-danger';
|
||||||
|
item.dataset.action = `delete-hoster:${hoster}`;
|
||||||
|
item.textContent = `${getHosterLabel(hoster)} (${count})`;
|
||||||
|
deleteHosterContainer.appendChild(item);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
deleteHosterSubmenu.style.display = 'none';
|
||||||
|
}
|
||||||
|
|
||||||
menu.style.display = 'block';
|
menu.style.display = 'block';
|
||||||
const menuX = Math.min(x, window.innerWidth - menu.offsetWidth - 5);
|
const menuX = Math.min(x, window.innerWidth - menu.offsetWidth - 5);
|
||||||
menu.style.left = menuX + 'px';
|
menu.style.left = menuX + 'px';
|
||||||
@ -1026,7 +1045,12 @@ function showContextMenu(x, y) {
|
|||||||
|
|
||||||
// Flip submenus if they would overflow the viewport right edge
|
// Flip submenus if they would overflow the viewport right edge
|
||||||
menu.querySelectorAll('.ctx-submenu-items').forEach(sub => {
|
menu.querySelectorAll('.ctx-submenu-items').forEach(sub => {
|
||||||
|
// Temporarily show to measure actual width (display:none → offsetWidth=0)
|
||||||
|
sub.style.visibility = 'hidden';
|
||||||
|
sub.style.display = 'block';
|
||||||
sub.classList.toggle('flip-left', menuX + menu.offsetWidth + sub.offsetWidth > window.innerWidth);
|
sub.classList.toggle('flip-left', menuX + menu.offsetWidth + sub.offsetWidth > window.innerWidth);
|
||||||
|
sub.style.display = '';
|
||||||
|
sub.style.visibility = '';
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1252,6 +1276,25 @@ async function handleContextAction(action) {
|
|||||||
renderQueueTable();
|
renderQueueTable();
|
||||||
updateStatusBar();
|
updateStatusBar();
|
||||||
updateQueueActionButtons();
|
updateQueueActionButtons();
|
||||||
|
} else if (action.startsWith('delete-hoster:')) {
|
||||||
|
const hoster = action.replace('delete-hoster:', '');
|
||||||
|
// Cancel active uploads for this hoster
|
||||||
|
const activeIds = queueJobs
|
||||||
|
.filter(j => j.hoster === hoster && (j.status === 'uploading' || j.status === 'queued' || j.status === 'retrying' || j.status === 'getting-server' || j.status === 'preview'))
|
||||||
|
.map(j => j.id);
|
||||||
|
if (activeIds.length > 0) await window.api.cancelSelectedJobs(activeIds);
|
||||||
|
// Remove ALL jobs for this hoster
|
||||||
|
queueJobs = queueJobs.filter(j => {
|
||||||
|
if (j.hoster === hoster) { removeJobFromIndex(j); return false; }
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
selectedJobIds.clear();
|
||||||
|
syncSelectedFilesFromQueue();
|
||||||
|
renderQueueTable();
|
||||||
|
if (queueJobs.length === 0) { selectedFiles = []; updateUploadView(); }
|
||||||
|
updateStatusBar();
|
||||||
|
updateQueueActionButtons();
|
||||||
|
persistQueueStateSoon(true);
|
||||||
} else if (action.startsWith('shutdown-')) {
|
} else if (action.startsWith('shutdown-')) {
|
||||||
const mode = action.replace('shutdown-', '');
|
const mode = action.replace('shutdown-', '');
|
||||||
await window.api.setShutdownAfterFinish(mode);
|
await window.api.setShutdownAfterFinish(mode);
|
||||||
|
|||||||
@ -265,6 +265,10 @@
|
|||||||
<div class="ctx-separator"></div>
|
<div class="ctx-separator"></div>
|
||||||
<div class="ctx-item" data-action="delete-selected">Entfernen</div>
|
<div class="ctx-item" data-action="delete-selected">Entfernen</div>
|
||||||
<div class="ctx-item" data-action="delete-all">Alle entfernen</div>
|
<div class="ctx-item" data-action="delete-all">Alle entfernen</div>
|
||||||
|
<div class="ctx-submenu ctx-hoster-delete-submenu" style="display:none">
|
||||||
|
<div class="ctx-item ctx-item-danger">Hoster entfernen ▸</div>
|
||||||
|
<div class="ctx-submenu-items ctx-hoster-delete-items"></div>
|
||||||
|
</div>
|
||||||
<div class="ctx-separator ctx-hoster-cancel-sep" style="display:none"></div>
|
<div class="ctx-separator ctx-hoster-cancel-sep" style="display:none"></div>
|
||||||
<div class="ctx-hoster-cancel-items"></div>
|
<div class="ctx-hoster-cancel-items"></div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user