add retry + adaptive V2
This commit is contained in:
@@ -66,7 +66,10 @@ function render(){
|
|||||||
${it.message ? `<span>${it.message}</span>` : ''}
|
${it.message ? `<span>${it.message}</span>` : ''}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="text-sm">${it.status}</div>
|
<div class="flex items-center gap-2 text-sm">
|
||||||
|
<span>${it.status}</span>
|
||||||
|
${it.status==='error' ? `<button class="btnRetry rounded-xl border px-3 py-1 text-xs dark:border-gray-600 dark:hover:bg-gray-700 hover:bg-gray-100 transition-colors" data-id="${it.id}" aria-label="Retry upload">Retry</button>` : ''}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="mt-3 h-2 w-full overflow-hidden rounded-full bg-gray-100 dark:bg-gray-700">
|
<div class="mt-3 h-2 w-full overflow-hidden rounded-full bg-gray-100 dark:bg-gray-700">
|
||||||
<div class="h-full ${it.status==='done'?'bg-green-500':it.status==='duplicate'?'bg-amber-500':it.status==='error'?'bg-red-500':'bg-blue-500'}" style="width:${Math.max(it.progress, (it.status==='done'||it.status==='duplicate'||it.status==='error')?100:it.progress)}%"></div>
|
<div class="h-full ${it.status==='done'?'bg-green-500':it.status==='duplicate'?'bg-amber-500':it.status==='error'?'bg-red-500':'bg-blue-500'}" style="width:${Math.max(it.progress, (it.status==='done'||it.status==='duplicate'||it.status==='error')?100:it.progress)}%"></div>
|
||||||
@@ -77,6 +80,23 @@ function render(){
|
|||||||
</div>
|
</div>
|
||||||
`).join('');
|
`).join('');
|
||||||
|
|
||||||
|
// Attach retry handlers for errored items
|
||||||
|
try {
|
||||||
|
itemsEl.querySelectorAll('.btnRetry').forEach(btn => {
|
||||||
|
btn.addEventListener('click', (e) => {
|
||||||
|
e.preventDefault();
|
||||||
|
const id = btn.getAttribute('data-id');
|
||||||
|
const it = items.find(x => x.id === id);
|
||||||
|
if (!it) return;
|
||||||
|
it.status = 'queued';
|
||||||
|
it.progress = 0;
|
||||||
|
try { delete it.message; } catch {}
|
||||||
|
render();
|
||||||
|
runQueue();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
} catch {}
|
||||||
|
|
||||||
const c = {queued:0,uploading:0,done:0,dup:0,err:0};
|
const c = {queued:0,uploading:0,done:0,dup:0,err:0};
|
||||||
for(const it of items){
|
for(const it of items){
|
||||||
if(['queued','checking'].includes(it.status)) c.queued++;
|
if(['queued','checking'].includes(it.status)) c.queued++;
|
||||||
|
|||||||
@@ -62,18 +62,20 @@
|
|||||||
|
|
||||||
<!-- Queue summary -->
|
<!-- Queue summary -->
|
||||||
<section id="summary" class="rounded-2xl border bg-white p-4 shadow-sm dark:bg-gray-800 dark:border-gray-700 transition-colors">
|
<section id="summary" class="rounded-2xl border bg-white p-4 shadow-sm dark:bg-gray-800 dark:border-gray-700 transition-colors">
|
||||||
<div class="flex items-center justify-between text-sm">
|
<div class="flex flex-wrap items-end justify-between gap-2 text-sm">
|
||||||
<div class="flex gap-4">
|
<!-- Buttons: on small screens show on their own row above -->
|
||||||
<span>Queued/Processing: <b id="countQueued">0</b></span>
|
<div class="order-1 w-full md:order-2 md:w-auto flex gap-2 justify-end">
|
||||||
<span>Uploading: <b id="countUploading">0</b></span>
|
|
||||||
<span>Done: <b id="countDone">0</b></span>
|
|
||||||
<span>Duplicates: <b id="countDup">0</b></span>
|
|
||||||
<span>Errors: <b id="countErr">0</b></span>
|
|
||||||
</div>
|
|
||||||
<div class="flex gap-2">
|
|
||||||
<button id="btnClearFinished" class="rounded-xl border px-3 py-1 text-sm dark:border-gray-600 dark:hover:bg-gray-700 hover:bg-gray-100 transition-colors">Clear finished</button>
|
<button id="btnClearFinished" class="rounded-xl border px-3 py-1 text-sm dark:border-gray-600 dark:hover:bg-gray-700 hover:bg-gray-100 transition-colors">Clear finished</button>
|
||||||
<button id="btnClearAll" class="rounded-xl border px-3 py-1 text-sm dark:border-gray-600 dark:hover:bg-gray-700 hover:bg-gray-100 transition-colors">Clear all</button>
|
<button id="btnClearAll" class="rounded-xl border px-3 py-1 text-sm dark:border-gray-600 dark:hover:bg-gray-700 hover:bg-gray-100 transition-colors">Clear all</button>
|
||||||
</div>
|
</div>
|
||||||
|
<!-- Counters: wrap cleanly, keep number with its label and align bottoms -->
|
||||||
|
<div class="order-2 w-full md:order-1 md:w-auto flex flex-wrap items-end gap-x-4 gap-y-1">
|
||||||
|
<span class="whitespace-nowrap">Queued/Processing: <b id="countQueued">0</b></span>
|
||||||
|
<span class="whitespace-nowrap">Uploading: <b id="countUploading">0</b></span>
|
||||||
|
<span class="whitespace-nowrap">Done: <b id="countDone">0</b></span>
|
||||||
|
<span class="whitespace-nowrap">Duplicates: <b id="countDup">0</b></span>
|
||||||
|
<span class="whitespace-nowrap">Errors: <b id="countErr">0</b></span>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
|
|||||||
@@ -72,13 +72,19 @@
|
|||||||
</section>
|
</section>
|
||||||
|
|
||||||
<section id="summary" class="rounded-2xl border bg-white p-4 shadow-sm dark:bg-gray-800 dark:border-gray-700">
|
<section id="summary" class="rounded-2xl border bg-white p-4 shadow-sm dark:bg-gray-800 dark:border-gray-700">
|
||||||
<div class="flex items-center justify-between text-sm">
|
<div class="flex flex-wrap items-end justify-between gap-2 text-sm">
|
||||||
<div class="flex gap-4">
|
<!-- Buttons: ensure present on invite page and visible on small screens -->
|
||||||
<span>Queued/Processing: <b id="countQueued">0</b></span>
|
<div class="order-1 w-full md:order-2 md:w-auto flex gap-2 justify-end">
|
||||||
<span>Uploading: <b id="countUploading">0</b></span>
|
<button id="btnClearFinished" class="rounded-xl border px-3 py-1 text-sm dark:border-gray-600 dark:hover:bg-gray-700 hover:bg-gray-100 transition-colors">Clear finished</button>
|
||||||
<span>Done: <b id="countDone">0</b></span>
|
<button id="btnClearAll" class="rounded-xl border px-3 py-1 text-sm dark:border-gray-600 dark:hover:bg-gray-700 hover:bg-gray-100 transition-colors">Clear all</button>
|
||||||
<span>Duplicates: <b id="countDup">0</b></span>
|
</div>
|
||||||
<span>Errors: <b id="countErr">0</b></span>
|
<!-- Counters: wrap cleanly, keep number with its label and align bottoms -->
|
||||||
|
<div class="order-2 w-full md:order-1 md:w-auto flex flex-wrap items-end gap-x-4 gap-y-1">
|
||||||
|
<span class="whitespace-nowrap">Queued/Processing: <b id="countQueued">0</b></span>
|
||||||
|
<span class="whitespace-nowrap">Uploading: <b id="countUploading">0</b></span>
|
||||||
|
<span class="whitespace-nowrap">Done: <b id="countDone">0</b></span>
|
||||||
|
<span class="whitespace-nowrap">Duplicates: <b id="countDup">0</b></span>
|
||||||
|
<span class="whitespace-nowrap">Errors: <b id="countErr">0</b></span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|||||||
Reference in New Issue
Block a user