Compare commits
No commits in common. "ae46d90dc2fff1b1b931e30aef57c306bd7f86c7" and "571d507889d5f1c705053b9ab5e0eed3690387ad" have entirely different histories.
ae46d90dc2
...
571d507889
@ -32,7 +32,6 @@ export default [
|
|||||||
alert: 'readonly',
|
alert: 'readonly',
|
||||||
confirm: 'readonly',
|
confirm: 'readonly',
|
||||||
requestAnimationFrame: 'readonly',
|
requestAnimationFrame: 'readonly',
|
||||||
queueMicrotask: 'readonly',
|
|
||||||
Intl: 'readonly',
|
Intl: 'readonly',
|
||||||
crypto: 'readonly',
|
crypto: 'readonly',
|
||||||
URLSearchParams: 'readonly',
|
URLSearchParams: 'readonly',
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "multi-hoster-uploader",
|
"name": "multi-hoster-uploader",
|
||||||
"version": "2.8.5",
|
"version": "2.8.4",
|
||||||
"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": {
|
||||||
|
|||||||
@ -874,41 +874,25 @@ function _updateRowInPlace(tr, job) {
|
|||||||
const pct = Math.min(100, Math.round((job.progress || 0) * 100));
|
const pct = Math.min(100, Math.round((job.progress || 0) * 100));
|
||||||
const link = job.result ? (job.result.download_url || job.result.embed_url || '') : '';
|
const link = job.result ? (job.result.download_url || job.result.embed_url || '') : '';
|
||||||
|
|
||||||
// Write DOM only when the target value actually changes — a no-op progress
|
// Update row class
|
||||||
// tick (same pct, same speed) then performs zero DOM work. Massive saver
|
tr.className = `queue-row ${statusClass}${selectedJobIds.has(job.id) ? ' selected' : ''}`;
|
||||||
// when most of the visible jobs are idle/queued/done and only a few are
|
tr.dataset.link = link;
|
||||||
// actively uploading.
|
|
||||||
const newClass = `queue-row ${statusClass}${selectedJobIds.has(job.id) ? ' selected' : ''}`;
|
|
||||||
if (tr.className !== newClass) tr.className = newClass;
|
|
||||||
if (tr.dataset.link !== link) tr.dataset.link = link;
|
|
||||||
|
|
||||||
const cells = tr.children;
|
const cells = tr.children;
|
||||||
if (cells.length < 8) return false; // structure mismatch, needs full rebuild
|
if (cells.length < 8) return false; // structure mismatch, needs full rebuild
|
||||||
|
|
||||||
if (cells[1].textContent !== uploadedSize) cells[1].textContent = uploadedSize;
|
cells[1].textContent = uploadedSize;
|
||||||
// cells[0] (filename) and cells[2] (hoster) don't change during upload
|
// cells[0] (filename) and cells[2] (hoster) don't change during upload
|
||||||
const badge = cells[3].querySelector('.status-badge');
|
const badge = cells[3].querySelector('.status-badge');
|
||||||
if (badge) {
|
if (badge) { badge.className = `status-badge ${statusClass}`; badge.textContent = statusText; }
|
||||||
const badgeClass = `status-badge ${statusClass}`;
|
cells[4].textContent = elapsed;
|
||||||
if (badge.className !== badgeClass) badge.className = badgeClass;
|
cells[5].textContent = remaining;
|
||||||
if (badge.textContent !== statusText) badge.textContent = statusText;
|
cells[6].textContent = speed;
|
||||||
}
|
|
||||||
if (cells[4].textContent !== elapsed) cells[4].textContent = elapsed;
|
|
||||||
if (cells[5].textContent !== remaining) cells[5].textContent = remaining;
|
|
||||||
if (cells[6].textContent !== speed) cells[6].textContent = speed;
|
|
||||||
|
|
||||||
const fill = cells[7].querySelector('.progress-bar-fill');
|
const fill = cells[7].querySelector('.progress-bar-fill');
|
||||||
if (fill) {
|
if (fill) { fill.style.width = pct + '%'; fill.className = `progress-bar-fill ${statusClass}`; }
|
||||||
const pctStr = pct + '%';
|
|
||||||
if (fill.style.width !== pctStr) fill.style.width = pctStr;
|
|
||||||
const fillClass = `progress-bar-fill ${statusClass}`;
|
|
||||||
if (fill.className !== fillClass) fill.className = fillClass;
|
|
||||||
}
|
|
||||||
const pctSpan = cells[7].querySelector('.progress-pct');
|
const pctSpan = cells[7].querySelector('.progress-pct');
|
||||||
if (pctSpan) {
|
if (pctSpan) pctSpan.textContent = job.status === 'preview' ? '' : pct + '%';
|
||||||
const pctText = job.status === 'preview' ? '' : pct + '%';
|
|
||||||
if (pctSpan.textContent !== pctText) pctSpan.textContent = pctText;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -1015,22 +999,11 @@ function _onQueueScroll() {
|
|||||||
const _collatorDE = new Intl.Collator('de', { sensitivity: 'base', numeric: true });
|
const _collatorDE = new Intl.Collator('de', { sensitivity: 'base', numeric: true });
|
||||||
const _collatorSimple = new Intl.Collator('de');
|
const _collatorSimple = new Intl.Collator('de');
|
||||||
|
|
||||||
// Queue sort memoization. Keys that don't change during upload (filename, host,
|
|
||||||
// size) reuse the cached result across progress-driven re-renders. Dynamic keys
|
|
||||||
// (status/speed/progress) are recomputed each call since the sort order itself
|
|
||||||
// moves every tick. For a queue of 1000+ jobs sorted by filename, this skips
|
|
||||||
// the Collator-based O(n log n) sort on every 200ms progress render.
|
|
||||||
let _queueSortCache = { sig: '', result: [] };
|
|
||||||
const _STATIC_SORT_KEYS = new Set(['filename', 'host', 'size']);
|
|
||||||
|
|
||||||
function sortQueueJobs(jobs) {
|
function sortQueueJobs(jobs) {
|
||||||
const { key, direction } = queueSortState;
|
const { key, direction } = queueSortState;
|
||||||
const factor = direction === 'asc' ? 1 : -1;
|
const factor = direction === 'asc' ? 1 : -1;
|
||||||
const canCache = _STATIC_SORT_KEYS.has(key);
|
|
||||||
const sig = canCache ? `${key}|${direction}|${jobs.length}` : '';
|
|
||||||
if (sig && _queueSortCache.sig === sig) return _queueSortCache.result;
|
|
||||||
|
|
||||||
const sorted = jobs.slice().sort((a, b) => {
|
return jobs.slice().sort((a, b) => {
|
||||||
let cmp = 0;
|
let cmp = 0;
|
||||||
if (key === 'filename') cmp = _collatorDE.compare(a.fileName, b.fileName);
|
if (key === 'filename') cmp = _collatorDE.compare(a.fileName, b.fileName);
|
||||||
else if (key === 'size') cmp = (a.bytesTotal || 0) - (b.bytesTotal || 0);
|
else if (key === 'size') cmp = (a.bytesTotal || 0) - (b.bytesTotal || 0);
|
||||||
@ -1040,8 +1013,6 @@ function sortQueueJobs(jobs) {
|
|||||||
else if (key === 'progress') cmp = (a.progress || 0) - (b.progress || 0);
|
else if (key === 'progress') cmp = (a.progress || 0) - (b.progress || 0);
|
||||||
return cmp * factor;
|
return cmp * factor;
|
||||||
});
|
});
|
||||||
if (sig) _queueSortCache = { sig, result: sorted };
|
|
||||||
return sorted;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function getStatusOrder(status) {
|
function getStatusOrder(status) {
|
||||||
@ -1997,14 +1968,7 @@ function applySummaryResults(summary) {
|
|||||||
|
|
||||||
// Single-pass queue stats computation (shared by status bar + stats panel).
|
// Single-pass queue stats computation (shared by status bar + stats panel).
|
||||||
// Also tracks inProgressBytes so the status bar doesn't need a second scan.
|
// Also tracks inProgressBytes so the status bar doesn't need a second scan.
|
||||||
//
|
|
||||||
// Memoized within a single tick: back-to-back calls (updateStatusBar +
|
|
||||||
// updateStatsPanel fire together 4×/sec during upload) share one scan. The
|
|
||||||
// cache is cleared on microtask so the next tick picks up fresh state.
|
|
||||||
let _queueStatsCache = null;
|
|
||||||
function _computeQueueStats() {
|
function _computeQueueStats() {
|
||||||
if (_queueStatsCache) return _queueStatsCache;
|
|
||||||
|
|
||||||
let remaining = 0, inProgress = 0, done = 0, errors = 0;
|
let remaining = 0, inProgress = 0, done = 0, errors = 0;
|
||||||
let bytesRemaining = 0, totalSize = 0, remainingSize = 0, inProgressBytes = 0;
|
let bytesRemaining = 0, totalSize = 0, remainingSize = 0, inProgressBytes = 0;
|
||||||
const total = queueJobs.length;
|
const total = queueJobs.length;
|
||||||
@ -2035,9 +1999,7 @@ function _computeQueueStats() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_queueStatsCache = { total, remaining, inProgress, done, errors, bytesRemaining, totalSize, remainingSize, inProgressBytes };
|
return { total, remaining, inProgress, done, errors, bytesRemaining, totalSize, remainingSize, inProgressBytes };
|
||||||
queueMicrotask(() => { _queueStatsCache = null; });
|
|
||||||
return _queueStatsCache;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function updateStatusBar() {
|
function updateStatusBar() {
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user