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).
|
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
|
## Features
|
||||||
|
|
||||||
|
|||||||
@@ -471,6 +471,7 @@ class UploadManager extends EventEmitter {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const emitFinalStatus = (status, payload = {}) => {
|
const emitFinalStatus = (status, payload = {}) => {
|
||||||
|
if (status === 'aborted' && this.abortController.signal.aborted) return;
|
||||||
this._emitProgress(uploadId, fileName, task.hoster, { accountId: task.accountId,
|
this._emitProgress(uploadId, fileName, task.hoster, { accountId: task.accountId,
|
||||||
jobId,
|
jobId,
|
||||||
status,
|
status,
|
||||||
|
|||||||
Generated
+2
-2
@@ -1,12 +1,12 @@
|
|||||||
{
|
{
|
||||||
"name": "multi-hoster-uploader",
|
"name": "multi-hoster-uploader",
|
||||||
"version": "2.1.14",
|
"version": "2.1.15",
|
||||||
"lockfileVersion": 3,
|
"lockfileVersion": 3,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "multi-hoster-uploader",
|
"name": "multi-hoster-uploader",
|
||||||
"version": "2.1.14",
|
"version": "2.1.15",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"chokidar": "^3.6.0",
|
"chokidar": "^3.6.0",
|
||||||
"undici": "^7.29.0",
|
"undici": "^7.29.0",
|
||||||
|
|||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "multi-hoster-uploader",
|
"name": "multi-hoster-uploader",
|
||||||
"version": "2.1.14",
|
"version": "2.1.15",
|
||||||
"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": {
|
||||||
|
|||||||
@@ -2305,6 +2305,8 @@ function showRecentContextMenu(row, x, y) {
|
|||||||
applyRecentSelectionClasses();
|
applyRecentSelectionClasses();
|
||||||
}
|
}
|
||||||
const menu = document.getElementById('recentContextMenu');
|
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.display = 'block';
|
||||||
menu.style.left = Math.min(x, window.innerWidth - menu.offsetWidth - 5) + 'px';
|
menu.style.left = Math.min(x, window.innerWidth - menu.offsetWidth - 5) + 'px';
|
||||||
menu.style.top = Math.min(y, window.innerHeight - menu.offsetHeight - 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; })()');
|
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);
|
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"); })()');
|
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);
|
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');
|
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 () => {
|
it('maxSizeMb filter skips oversized files', async () => {
|
||||||
fakeFileSize = 5 * 1024 * 1024; // 5 MB
|
fakeFileSize = 5 * 1024 * 1024; // 5 MB
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user