Compare commits

..

No commits in common. "a75aa857125e6ee5a1b01ce6ed60b02cacde3383" and "ead6f971158aec247763543aa47c71f0b7b4a32c" have entirely different histories.

4 changed files with 20 additions and 25 deletions

View File

@ -698,23 +698,21 @@ class UploadManager extends EventEmitter {
} }
addJobs(tasks) { addJobs(tasks) {
if (!this.running || !tasks || tasks.length === 0) return 0; if (!this.running || !tasks || tasks.length === 0) return;
const { signal } = this.abortController; const { signal } = this.abortController;
const results = this._batchResults || new Map(); const results = this._batchResults || new Map();
let added = 0;
for (const task of tasks) { for (const task of tasks) {
// Skip if this job is already being processed (prevent duplicates)
if (task.jobId && this.jobAbortControllers.has(task.jobId)) continue;
const fileName = path.basename(task.file); const fileName = path.basename(task.file);
if (!results.has(task.file)) { if (!results.has(task.file)) {
let size = 0; let size = 0;
try { size = fs.statSync(task.file).size; } catch {} try { size = fs.statSync(task.file).size; } catch {}
results.set(task.file, { name: fileName, size, results: [] }); results.set(task.file, { name: fileName, size, results: [] });
} }
this._additionalPromises.push(this._runJob(task, results, signal));
added++;
} }
return added; // Start each new job and track promises so batch-done waits for them
for (const task of tasks) {
this._additionalPromises.push(this._runJob(task, results, signal));
}
} }
cancelJobs(jobIds) { cancelJobs(jobIds) {

View File

@ -786,9 +786,9 @@ ipcMain.handle('add-jobs-to-batch', (_event, payload) => {
const jobs = payload && Array.isArray(payload.jobs) ? payload.jobs : []; const jobs = payload && Array.isArray(payload.jobs) ? payload.jobs : [];
const tasks = buildUploadTasksFromJobs(config, jobs); const tasks = buildUploadTasksFromJobs(config, jobs);
if (tasks.length === 0) return { added: 0 }; if (tasks.length === 0) return { added: 0 };
const added = uploadManager.addJobs(tasks); uploadManager.addJobs(tasks);
debugLog(`add-jobs-to-batch: ${added} of ${tasks.length} tasks added (${tasks.length - added} already in batch)`); debugLog(`add-jobs-to-batch: added ${tasks.length} tasks to running batch`);
return { added }; return { added: tasks.length };
}); });
ipcMain.handle('finish-after-active', () => { ipcMain.handle('finish-after-active', () => {

View File

@ -1,6 +1,6 @@
{ {
"name": "multi-hoster-uploader", "name": "multi-hoster-uploader",
"version": "2.6.2", "version": "2.6.1",
"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

@ -1354,28 +1354,25 @@ function _markSkippedJobs(result) {
async function startSelectedUpload() { async function startSelectedUpload() {
if (uploading) { if (uploading) {
// Batch already running — add selected jobs (queued/error/aborted/skipped) to running batch // Batch already running — only add error/aborted/skipped jobs (not already-queued ones)
// Upload-manager has duplicate protection (skips jobs already tracked) const retryable = queueJobs.filter(j => selectedJobIds.has(j.id) && ['error', 'aborted', 'skipped'].includes(j.status));
const addable = queueJobs.filter(j => selectedJobIds.has(j.id) && ['queued', 'error', 'aborted', 'skipped'].includes(j.status)); if (retryable.length > 0) {
if (addable.length > 0) { retryable.forEach(j => {
addable.forEach(j => {
j.status = 'queued'; j.error = null; j.result = null; j.status = 'queued'; j.error = null; j.result = null;
j.bytesUploaded = 0; j.speedKbs = 0; j.progress = 0; j.uploadId = null; j.bytesUploaded = 0; j.speedKbs = 0; j.progress = 0; j.uploadId = null;
}); });
renderQueueTable(); renderQueueTable();
const result = await window.api.addJobsToBatch({ const result = await window.api.addJobsToBatch({
jobs: addable.map(j => ({ id: j.id, file: j.file, fileName: j.fileName, hoster: j.hoster })) jobs: retryable.map(j => ({ id: j.id, file: j.file, fileName: j.fileName, hoster: j.hoster }))
}); });
_markSkippedJobs(result); _markSkippedJobs(result);
persistQueueStateSoon(); persistQueueStateSoon();
const added = result && result.added || 0; showCopyToast(`${retryable.length} Jobs zum laufenden Upload hinzugefügt`);
const alreadyInBatch = addable.length - added; } else {
if (added > 0 && alreadyInBatch > 0) { // All selected jobs are already queued/uploading — just inform user
showCopyToast(`${added} Jobs hinzugefügt, ${alreadyInBatch} waren schon im Batch`); const waiting = queueJobs.filter(j => selectedJobIds.has(j.id) && j.status === 'queued');
} else if (added > 0) { if (waiting.length > 0) {
showCopyToast(`${added} Jobs zum laufenden Upload hinzugefügt`); showCopyToast(`${waiting.length} Jobs warten bereits auf ihren Upload-Slot`);
} else {
showCopyToast(`${addable.length} Jobs sind bereits im laufenden Batch`);
} }
} }
return; return;