frontend: report-screen exhaustion fix — local decision map drives section progress; show report on local exhaust with rate-limited resync (verified headless: full 25-card section loop, forge, trends, tanks)

This commit is contained in:
Torres
2026-11-10 23:28:06 -04:00
parent c205d315b7
commit b6e1851b11

View File

@@ -366,8 +366,13 @@ async function runQueue(){
}finally{ qRunning=false; }
if(pend.size){ qTimer=setTimeout(runQueue,Math.max(minDelay||15000,1000)); }
}
/* optimistic decision set for list/matches + deck commits share this */
/* optimistic decision set for list/matches + deck commits share this.
localDecisions remembers the latest intent per listing so section
progress stays correct while the persistence queue is mid-flight. */
const localDecisions=new Map(); // listing_id -> action|null
let lastResyncAt=0;
function setDecision(id, act, secId=null){
localDecisions.set(id, act);
updateRowDecision(id, act); // optimistic paint
enqueue(id, act, secId);
}
@@ -553,9 +558,17 @@ function maybeRefill(){
return;
}
if(!pile.length&&!buffer.length&&!deckLoading){
if(section&&(section.exhausted||(section.progress&&section.progress.undecided===0))){
if(section&&sectDecided>=sectTotal){
// locally exhausted (last POSTs may still be flushing — the report
// shows from localDecisions; a quiet resync freshens counts and the
// server's report flip, rate-limited so a failing last POST can't
// cause a resync loop)
$('report').classList.add('on');
$('empty').classList.remove('on');
if(!section.exhausted&&Date.now()-lastResyncAt>2000){
lastResyncAt=Date.now();
loadSection();
}
}else if(section){
$('empty').classList.remove('on'); $('report').classList.remove('on');
}
@@ -921,7 +934,13 @@ function paintMode(){
else if(!forgeBusy) btn.disabled=false;
}
function updateSectionUI(body){
sectDecided=body.progress.decided; sectTotal=body.progress.total;
sectTotal=body.progress.total;
let decided=0;
for(const it of (body.items||[])){
const local=localDecisions.get(it.id);
if(local===undefined? it.decision!=null : local!=null) decided++;
}
sectDecided=decided;
paintSect();
paintMode();
const c=body.counts||{};