Loading html/admin.html +15 −1 Original line number Diff line number Diff line Loading @@ -184,6 +184,7 @@ function fmtSize(b) { const previewQueue = []; let previewActive = 0; const MAX_CONCURRENT_PREVIEWS = 6; const PREVIEW_TIMEOUT_MS = 45000; function drainPreviewQueue() { while (previewActive < MAX_CONCURRENT_PREVIEWS && previewQueue.length > 0) { Loading @@ -191,6 +192,7 @@ function drainPreviewQueue() { previewActive++; const ctrl = new AbortController(); job.img._previewAbort = ctrl; const timer = setTimeout(() => ctrl.abort(), PREVIEW_TIMEOUT_MS); fetch(job.url, {credentials:'same-origin', headers:{'Authorization':'Bearer '+token}, signal: ctrl.signal}).then(r => { if (r.status === 200) { return r.blob().then(blob => { Loading @@ -206,7 +208,19 @@ function drainPreviewQueue() { job.img.style.opacity = '.5'; job.img.title = 'Preview failed (HTTP ' + r.status + ')'; } }).catch(() => {}).finally(() => { previewActive--; drainPreviewQueue(); }); }).catch(err => { if (err.name === 'AbortError') { // Timeout or manual abort — re-queue with delay job.retries = (job.retries || 0) + 1; if (job.retries < 3) { setTimeout(() => { previewQueue.push(job); drainPreviewQueue(); }, 2000); } else { job.img.alt = '\u26a0'; job.img.style.opacity = '.5'; job.img.title = 'Preview timeout'; } } }).finally(() => { clearTimeout(timer); previewActive--; drainPreviewQueue(); }); } } Loading html/gallery.html +10 −1 Original line number Diff line number Diff line Loading @@ -54,12 +54,14 @@ const API = ''; const galQueue = []; let galActive = 0; const GAL_MAX_CONCURRENT = 6; const GAL_TIMEOUT_MS = 45000; function galDrain() { while (galActive < GAL_MAX_CONCURRENT && galQueue.length > 0) { const job = galQueue.shift(); galActive++; const ctrl = new AbortController(); const timer = setTimeout(() => ctrl.abort(), GAL_TIMEOUT_MS); fetch(job.url, {signal: ctrl.signal}).then(r => { if (r.ok) return r.blob().then(blob => { job.img.src = URL.createObjectURL(blob); Loading @@ -68,7 +70,14 @@ function galDrain() { if (r.status === 503) { setTimeout(() => { galQueue.push(job); galDrain(); }, 2000); } }).catch(() => {}).finally(() => { galActive--; galDrain(); }); }).catch(err => { if (err.name === 'AbortError') { job.retries = (job.retries || 0) + 1; if (job.retries < 3) { setTimeout(() => { galQueue.push(job); galDrain(); }, 2000); } } }).finally(() => { clearTimeout(timer); galActive--; galDrain(); }); } } Loading Loading
html/admin.html +15 −1 Original line number Diff line number Diff line Loading @@ -184,6 +184,7 @@ function fmtSize(b) { const previewQueue = []; let previewActive = 0; const MAX_CONCURRENT_PREVIEWS = 6; const PREVIEW_TIMEOUT_MS = 45000; function drainPreviewQueue() { while (previewActive < MAX_CONCURRENT_PREVIEWS && previewQueue.length > 0) { Loading @@ -191,6 +192,7 @@ function drainPreviewQueue() { previewActive++; const ctrl = new AbortController(); job.img._previewAbort = ctrl; const timer = setTimeout(() => ctrl.abort(), PREVIEW_TIMEOUT_MS); fetch(job.url, {credentials:'same-origin', headers:{'Authorization':'Bearer '+token}, signal: ctrl.signal}).then(r => { if (r.status === 200) { return r.blob().then(blob => { Loading @@ -206,7 +208,19 @@ function drainPreviewQueue() { job.img.style.opacity = '.5'; job.img.title = 'Preview failed (HTTP ' + r.status + ')'; } }).catch(() => {}).finally(() => { previewActive--; drainPreviewQueue(); }); }).catch(err => { if (err.name === 'AbortError') { // Timeout or manual abort — re-queue with delay job.retries = (job.retries || 0) + 1; if (job.retries < 3) { setTimeout(() => { previewQueue.push(job); drainPreviewQueue(); }, 2000); } else { job.img.alt = '\u26a0'; job.img.style.opacity = '.5'; job.img.title = 'Preview timeout'; } } }).finally(() => { clearTimeout(timer); previewActive--; drainPreviewQueue(); }); } } Loading
html/gallery.html +10 −1 Original line number Diff line number Diff line Loading @@ -54,12 +54,14 @@ const API = ''; const galQueue = []; let galActive = 0; const GAL_MAX_CONCURRENT = 6; const GAL_TIMEOUT_MS = 45000; function galDrain() { while (galActive < GAL_MAX_CONCURRENT && galQueue.length > 0) { const job = galQueue.shift(); galActive++; const ctrl = new AbortController(); const timer = setTimeout(() => ctrl.abort(), GAL_TIMEOUT_MS); fetch(job.url, {signal: ctrl.signal}).then(r => { if (r.ok) return r.blob().then(blob => { job.img.src = URL.createObjectURL(blob); Loading @@ -68,7 +70,14 @@ function galDrain() { if (r.status === 503) { setTimeout(() => { galQueue.push(job); galDrain(); }, 2000); } }).catch(() => {}).finally(() => { galActive--; galDrain(); }); }).catch(err => { if (err.name === 'AbortError') { job.retries = (job.retries || 0) + 1; if (job.retries < 3) { setTimeout(() => { galQueue.push(job); galDrain(); }, 2000); } } }).finally(() => { clearTimeout(timer); galActive--; galDrain(); }); } } Loading