fix: keep large queue cancellation responsive
This commit is contained in:
@@ -8,7 +8,7 @@ Multi-Hoster-Upload is a Windows desktop application for sending file batches to
|
||||
|
||||
Download the current Setup or Portable build from the [latest GitHub release](https://github.com/Sucukdeluxe/Multi-Hoster-Upload/releases/latest).
|
||||
|
||||
The latest public release is version 2.1.12. Use the release page for the executables and the full English changelog.
|
||||
The latest public release is version 2.1.15. Use the release page for the executables and the full English changelog.
|
||||
|
||||
## Features
|
||||
|
||||
|
||||
@@ -471,6 +471,7 @@ class UploadManager extends EventEmitter {
|
||||
};
|
||||
|
||||
const emitFinalStatus = (status, payload = {}) => {
|
||||
if (status === 'aborted' && this.abortController.signal.aborted) return;
|
||||
this._emitProgress(uploadId, fileName, task.hoster, { accountId: task.accountId,
|
||||
jobId,
|
||||
status,
|
||||
|
||||
Generated
+2
-2
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "multi-hoster-uploader",
|
||||
"version": "2.1.14",
|
||||
"version": "2.1.15",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "multi-hoster-uploader",
|
||||
"version": "2.1.14",
|
||||
"version": "2.1.15",
|
||||
"dependencies": {
|
||||
"chokidar": "^3.6.0",
|
||||
"undici": "^7.29.0",
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "multi-hoster-uploader",
|
||||
"version": "2.1.14",
|
||||
"version": "2.1.15",
|
||||
"description": "Upload files to doodstream, voe, vidmoly, byse simultaneously",
|
||||
"main": "main.js",
|
||||
"scripts": {
|
||||
|
||||
@@ -2305,6 +2305,8 @@ function showRecentContextMenu(row, x, y) {
|
||||
applyRecentSelectionClasses();
|
||||
}
|
||||
const menu = document.getElementById('recentContextMenu');
|
||||
const copyItem = menu.querySelector('[data-action="recent-copy-links"]');
|
||||
if (copyItem) copyItem.textContent = selectedRecentIds.size > 1 ? `Links kopieren (${selectedRecentIds.size})` : 'Link kopieren';
|
||||
menu.style.display = 'block';
|
||||
menu.style.left = Math.min(x, window.innerWidth - menu.offsetWidth - 5) + 'px';
|
||||
menu.style.top = Math.min(y, window.innerHeight - menu.offsetHeight - 5) + 'px';
|
||||
|
||||
@@ -1486,6 +1486,9 @@ setTimeout(async () => {
|
||||
const historyWorkspaceLayout = await wc.executeJavaScript('(() => { const view = document.getElementById("history-view"); const sidebar = view?.querySelector(":scope > .view-sidebar"); const main = view?.querySelector(":scope > .view-main"); if (!sidebar || !main) return false; const sidebarRect = sidebar.getBoundingClientRect(); const mainRect = main.getBoundingClientRect(); return sidebarRect.width > 0 && mainRect.width > 0 && sidebarRect.right <= mainRect.left; })()');
|
||||
check('History view separates sidebar and main workspace', historyWorkspaceLayout === true);
|
||||
|
||||
const singleRecentLinkContextLabel = await wc.executeJavaScript('(() => { selectedRecentIds.clear(); const row = document.createElement("tr"); row.dataset.order = "1001"; showRecentContextMenu(row, 8, 8); const label = document.querySelector("#recentContextMenu [data-action=recent-copy-links]")?.textContent?.trim(); hideContextMenu(); return label; })()');
|
||||
check('Recent upload context menu uses singular copy text for one link', singleRecentLinkContextLabel === 'Link kopieren');
|
||||
|
||||
const historySidebarInformation = await wc.executeJavaScript('(() => { const sidebar = document.querySelector("#history-view > .view-sidebar")?.getBoundingClientRect(); const section = document.querySelector("#history-view .view-sidebar-section")?.getBoundingClientRect(); const retention = document.getElementById("historySidebarRetention")?.textContent?.trim(); return Boolean(sidebar && section && section.top >= sidebar.top + sidebar.height * 0.55 && retention === "Alles behalten"); })()');
|
||||
check('History sidebar shows the active retention in its lower area', historySidebarInformation === true);
|
||||
|
||||
|
||||
@@ -225,6 +225,39 @@ describe('UploadManager', () => {
|
||||
assert.ok(batchDone, 'batch-done should be emitted even after cancel');
|
||||
});
|
||||
|
||||
it('does not emit one aborted progress event per job when cancelling a whole batch', async () => {
|
||||
mockUploadFile.mock.mockImplementation(async (hoster, filePath, apiKey, onProgress, signal) => {
|
||||
await new Promise((resolve, reject) => {
|
||||
const timer = setTimeout(resolve, 10000);
|
||||
signal.addEventListener('abort', () => {
|
||||
clearTimeout(timer);
|
||||
reject(new Error('Aborted'));
|
||||
}, { once: true });
|
||||
});
|
||||
return { download_url: `https://${hoster}/d/ok123`, embed_url: null, file_code: 'ok123' };
|
||||
});
|
||||
|
||||
const mgr = new UploadManager({
|
||||
'doodstream.com': { retries: 0, parallelCount: 1, maxSpeedKbs: 0, restartBelowKbs: 0, timeIntervalSec: 0, maxSizeMb: 0 }
|
||||
});
|
||||
const statuses = [];
|
||||
mgr.on('progress', (data) => statuses.push(data.status));
|
||||
|
||||
const tasks = Array.from({ length: 60 }, (_, index) => ({
|
||||
jobId: `cancel-${index}`,
|
||||
file: `/test/cancel-${index}.mp4`,
|
||||
hoster: 'doodstream.com',
|
||||
apiKey: 'key1'
|
||||
}));
|
||||
const batchPromise = mgr.startBatch(tasks);
|
||||
|
||||
await new Promise((resolve) => setTimeout(resolve, 50));
|
||||
mgr.cancel();
|
||||
await batchPromise;
|
||||
|
||||
assert.equal(statuses.filter((status) => status === 'aborted').length, 0);
|
||||
});
|
||||
|
||||
it('maxSizeMb filter skips oversized files', async () => {
|
||||
fakeFileSize = 5 * 1024 * 1024; // 5 MB
|
||||
|
||||
|
||||
Reference in New Issue
Block a user