Compare commits

..

No commits in common. "7a025be6457b1ad6aeb94422642f0e1fb427c15c" and "1b0be5f81735b1d40164c908bad24c0cee91ae9f" have entirely different histories.

2 changed files with 9 additions and 52 deletions

View File

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

View File

@ -71,7 +71,6 @@ let _sessionUploadedBytes = 0; // Bytes fully uploaded this session (done jobs)
const _sessionTrackedJobs = new Set(); // Job IDs already counted for totalBytes
const _sessionDoneJobs = new Set(); // Job IDs already counted for uploadedBytes
const _completedUploadKeys = new Set(); // 'filepath|hoster' keys for done uploads (survives removeFromQueueOnDone)
const _suppressedPreviewKeys = new Set();
const _deletedJobIds = new Set(); // IDs of jobs explicitly deleted by user (prevents re-creation from stale progress callbacks)
// Coalesce removeFromQueueOnDone removals into one filter pass per microtask
// to avoid O(N²) behaviour when a burst of jobs finish at once. Logic now
@ -216,7 +215,6 @@ async function init() {
}
if (newFiles.length > 0) {
const newPaths = new Set(newFiles.map(f => f.path));
clearDedupKeysForPaths(newPaths);
selectedFiles.push(...newFiles);
buildQueuePreview();
updateUploadView();
@ -673,7 +671,12 @@ function applyHosterSelection() {
selectedFiles.push(..._pendingFiles);
_pendingFiles = [];
}
clearDedupKeysForPaths(pendingPaths);
if (pendingPaths.size > 0) {
for (const key of [..._completedUploadKeys]) {
const sep = key.lastIndexOf('|');
if (sep > 0 && pendingPaths.has(key.slice(0, sep))) _completedUploadKeys.delete(key);
}
}
renderHosterSummary();
// During an active upload, build preview jobs for the new files and inject
@ -722,12 +725,6 @@ function restoreQueueStateFromConfig() {
}
}
if (Array.isArray(pending.suppressedKeys)) {
for (const k of pending.suppressedKeys) {
if (typeof k === 'string' && k) _suppressedPreviewKeys.add(k);
}
}
selectedUploadHosters = Array.isArray(pending.selectedUploadHosters)
? pending.selectedUploadHosters.filter(Boolean)
: selectedUploadHosters;
@ -805,17 +802,11 @@ function buildPersistedQueueState() {
const sep = k.lastIndexOf('|');
if (sep > 0 && selectedFileMap.has(k.slice(0, sep))) completedKeys.push(k);
}
const suppressedKeys = [];
for (const k of _suppressedPreviewKeys) {
const sep = k.lastIndexOf('|');
if (sep > 0 && selectedFileMap.has(k.slice(0, sep))) suppressedKeys.push(k);
}
return {
savedAt: Date.now(),
selectedUploadHosters: getSelectedHosters(),
selectedFiles: Array.from(selectedFileMap.values()),
completedKeys,
suppressedKeys,
queueJobs: queueJobs.map(job => {
const isTerminal = TERMINAL.has(job.status);
return {
@ -1071,25 +1062,6 @@ function updateQueueActionButtons() {
if (moveBottomBtn) moveBottomBtn.disabled = !hasMovableSelection;
}
function clearDedupKeysForPaths(pathSet) {
if (!pathSet || pathSet.size === 0) return;
for (const set of [_completedUploadKeys, _suppressedPreviewKeys]) {
for (const key of [...set]) {
const sep = key.lastIndexOf('|');
if (sep > 0 && pathSet.has(key.slice(0, sep))) set.delete(key);
}
}
}
function suppressPreviewKeysStillSelected(keys) {
if (!keys || keys.length === 0) return;
const stillSelected = new Set(selectedFiles.map(f => f.path));
for (const key of keys) {
const sep = key.lastIndexOf('|');
if (sep > 0 && stillSelected.has(key.slice(0, sep))) _suppressedPreviewKeys.add(key);
}
}
// Build preview jobs from selected files x selected hosters (before upload starts)
function buildQueuePreview() {
const hosters = getSelectedHosters();
@ -1112,7 +1084,7 @@ function buildQueuePreview() {
for (const file of selectedFiles) {
for (const hoster of hosters) {
const key = `${file.path}|${hoster}`;
if (!existingKeys.has(key) && !_completedUploadKeys.has(key) && !_suppressedPreviewKeys.has(key)) {
if (!existingKeys.has(key) && !_completedUploadKeys.has(key)) {
const job = {
id: `preview-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`,
file: file.path, fileName: file.name, hoster,
@ -1898,18 +1870,12 @@ document.addEventListener('keydown', (e) => {
return j && (j.status === 'uploading' || j.status === 'queued' || j.status === 'retrying' || j.status === 'getting-server');
});
if (activeIds.length > 0) window.api.cancelSelectedJobs(activeIds);
const _deletedKeys = [];
queueJobs = queueJobs.filter(j => {
if (selectedJobIds.has(j.id)) {
if (j.file && j.hoster && j.status !== 'done') _deletedKeys.push(`${j.file}|${j.hoster}`);
removeJobFromIndex(j);
return false;
}
if (selectedJobIds.has(j.id)) { removeJobFromIndex(j); return false; }
return true;
});
selectedJobIds.clear();
syncSelectedFilesFromQueue();
suppressPreviewKeysStillSelected(_deletedKeys);
renderQueueTable();
if (queueJobs.length === 0) { selectedFiles = []; updateUploadView(); }
updateStatusBar();
@ -1945,10 +1911,8 @@ async function handleContextAction(action) {
return j && (j.status === 'uploading' || j.status === 'queued' || j.status === 'retrying' || j.status === 'getting-server');
});
if (activeIds.length > 0) window.api.cancelSelectedJobs(activeIds);
const _deletedKeys = [];
queueJobs = queueJobs.filter(j => {
if (selectedJobIds.has(j.id)) {
if (j.file && j.hoster && j.status !== 'done') _deletedKeys.push(`${j.file}|${j.hoster}`);
removeJobFromIndex(j);
return false;
}
@ -1956,7 +1920,6 @@ async function handleContextAction(action) {
});
selectedJobIds.clear();
syncSelectedFilesFromQueue();
suppressPreviewKeysStillSelected(_deletedKeys);
renderQueueTable();
if (queueJobs.length === 0) { selectedFiles = []; updateUploadView(); }
updateStatusBar();
@ -2641,12 +2604,6 @@ async function retrySelectedJobs() {
}
});
if (retryJobs.length === 0) return;
for (const j of retryJobs) {
if (j.file && j.hoster) {
_completedUploadKeys.delete(`${j.file}|${j.hoster}`);
_suppressedPreviewKeys.delete(`${j.file}|${j.hoster}`);
}
}
// Select the retry jobs and start them immediately.
// No renderQueueTable / updateQueueActionButtons / updateStatusBar here: