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:
parent
6fbfa4b61e
commit
f7e8f9a56c
@ -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));
|
||||
await Promise.allSettled(promises);
|
||||
// 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;
|
||||
|
||||
@ -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": {
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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;
|
||||
|
||||
Loading…
Reference in New Issue
Block a user