fix: split layout, top-to-bottom queue processing, persist queue on close

- Queue table limited to 50% height with scrollbar, links panel below
- Upload processes files sequentially (file1 all hosters, then file2, etc.)
- Queue state persists immediately after adding files (not debounced)
- Add beforeunload handler to flush pending queue state

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Administrator 2026-03-11 01:48:39 +01:00
parent 6fbfa4b61e
commit f7e8f9a56c
4 changed files with 41 additions and 10 deletions

View File

@ -67,9 +67,24 @@ class UploadManager extends EventEmitter {
// Start global stats emitter
this._startStatsTimer();
// Create job promises — semaphore controls concurrency per hoster
const promises = tasks.map((task) => this._runJob(task, results, signal));
// Group tasks by file to process files top-to-bottom
// Within each file, all hosters run in parallel
const fileOrder = [];
const tasksByFile = new Map();
for (const task of tasks) {
if (!tasksByFile.has(task.file)) {
tasksByFile.set(task.file, []);
fileOrder.push(task.file);
}
tasksByFile.get(task.file).push(task);
}
for (const file of fileOrder) {
if (signal.aborted) break;
const fileTasks = tasksByFile.get(file);
const promises = fileTasks.map((task) => this._runJob(task, results, signal));
await Promise.allSettled(promises);
}
this._stopStatsTimer();
this.running = false;

View File

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

View File

@ -200,7 +200,7 @@ function applyHosterSelection() {
}
renderHosterSummary();
updateUploadView();
persistQueueStateSoon();
persistQueueStateSoon(true); // immediate persist after adding files
document.getElementById('hosterModal').style.display = 'none';
}
@ -297,8 +297,12 @@ async function persistQueueStateNow() {
await window.api.saveGlobalSettings(globalSettings);
}
function persistQueueStateSoon() {
function persistQueueStateSoon(immediate) {
clearTimeout(queuePersistTimer);
if (immediate) {
persistQueueStateNow().catch(() => {});
return;
}
// Use longer debounce during uploads to reduce disk I/O
const delay = uploading ? 3000 : 500;
queuePersistTimer = setTimeout(() => {
@ -1515,6 +1519,16 @@ function sortHistoryRows(rows) {
});
}
// Flush pending queue state on window close
window.addEventListener('beforeunload', () => {
if (queuePersistTimer) {
clearTimeout(queuePersistTimer);
queuePersistTimer = null;
// Synchronous-ish: fire and forget since window is closing
persistQueueStateNow().catch(() => {});
}
});
// --- Setup Listeners ---
function setupListeners() {
document.getElementById('addFilesBtn').addEventListener('click', pickFiles);

View File

@ -175,8 +175,9 @@ body {
flex-direction: column;
}
.queue-container {
flex: 1;
min-height: 220px;
flex: 1 1 50%;
min-height: 150px;
max-height: 50%;
overflow: auto;
padding: 0;
background: rgba(255, 255, 255, 0.02);
@ -290,12 +291,13 @@ body {
}
.recent-files-panel {
min-height: 220px;
max-height: 280px;
flex: 1 1 auto;
min-height: 150px;
display: flex;
flex-direction: column;
border-top: 1px solid var(--border);
background: linear-gradient(180deg, rgba(255,255,255,0.015), rgba(0,0,0,0.12));
overflow: auto;
}
.recent-files-header {
display: flex;