From d7fc7606eccd71bcd6e2ef1117a8f4dc0f1b2717 Mon Sep 17 00:00:00 2001 From: Hermes Agent Date: Mon, 4 May 2026 14:36:39 +0000 Subject: [PATCH] fix(receiver): revert indicator to framesWithQR/accepted/needed with correct math - framesWithQR now counts ALL frames with a valid QR (including duplicates), not just deduplicated ones. Moved increment before dedup check. - acceptedPackets already correctly counts linearly-independent packets (rank increase), capped at K per generation by the decoder. - neededPackets = K * sourceGenerations, computed from constants. - Keep generation count (solvedGens/sourceGens) as secondary indicator. This gives an honest rough progress bar: useful can approach or briefly touch required while some generations are still partially filled, but the generation count is the definitive completion signal. --- src/app/routes/receiver.tsx | 20 ++++++++++++-------- src/workers/decode.worker.ts | 6 ++++-- 2 files changed, 16 insertions(+), 10 deletions(-) diff --git a/src/app/routes/receiver.tsx b/src/app/routes/receiver.tsx index 28c27a7..36d9db3 100644 --- a/src/app/routes/receiver.tsx +++ b/src/app/routes/receiver.tsx @@ -155,6 +155,7 @@ export function ReceiverPage() { const [totalFrames, setTotalFrames] = useState(0); const [framesWithQR, setFramesWithQR] = useState(0); const [acceptedPackets, setAcceptedPackets] = useState(0); + const [neededPackets, setNeededPackets] = useState(0); const [receivedFile, setReceivedFile] = useState(null); const [receivedText, setReceivedText] = useState(''); const [error, setError] = useState(''); @@ -181,6 +182,7 @@ export function ReceiverPage() { setTotalFrames(msg.totalFrames ?? 0); setFramesWithQR(msg.framesWithQR ?? 0); setAcceptedPackets(msg.acceptedPackets ?? 0); + setNeededPackets(msg.neededPackets ?? 0); setSolvedGens(msg.solvedGenerations ?? 0); setSourceGens(msg.sourceGenerations ?? 0); if (msg.dataLength) { @@ -281,6 +283,7 @@ export function ReceiverPage() { setTotalFrames(0); setFramesWithQR(0); setAcceptedPackets(0); + setNeededPackets(0); setElapsedMs(0); setThroughputKbps(0); setSolvedGens(0); @@ -354,6 +357,7 @@ export function ReceiverPage() { setTotalFrames(0); setFramesWithQR(0); setAcceptedPackets(0); + setNeededPackets(0); setElapsedMs(0); setThroughputKbps(0); setSolvedGens(0); @@ -548,13 +552,13 @@ export function ReceiverPage() { {scanning && (
+ QRs{' '} - {framesWithQR}/{solvedGens}/{sourceGens} - {' '} - gens + {framesWithQR}/{acceptedPackets}/{neededPackets || '?'} + - pkts {acceptedPackets} + gens {solvedGens}/{sourceGens} time {formatDuration(elapsedMs)} @@ -615,13 +619,13 @@ export function ReceiverPage() { {scanning && (
+ QRs{' '} - {framesWithQR}/{solvedGens}/{sourceGens} - {' '} - gens + {framesWithQR}/{acceptedPackets}/{neededPackets || '?'} + - pkts {acceptedPackets} + gens {solvedGens}/{sourceGens} time {formatDuration(elapsedMs)} diff --git a/src/workers/decode.worker.ts b/src/workers/decode.worker.ts index b9a3b9a..0ad9930 100644 --- a/src/workers/decode.worker.ts +++ b/src/workers/decode.worker.ts @@ -112,12 +112,12 @@ function handleFrame(imageData: ImageData): void { current.isCompressed = h.compressed; current.stats.totalFrames++; + current.stats.framesWithQR++; // Dedup: generationIndex:symbolIndex const dedupKey = `${h.generationIndex}:${h.symbolIndex}`; if (current.dedup.has(dedupKey)) return; current.dedup.add(dedupKey); - current.stats.framesWithQR++; // Feed to decoder const gen = h.generationIndex; @@ -251,12 +251,14 @@ function reconstructData(state: DecodeState): void { function reportProgress(state: DecodeState): void { const totalGens = state.totalGenerations; const solvedGens = state.solvedGenerations.size; + const needed = state.sourceGenerations > 0 ? K * state.sourceGenerations : 0; - self.postMessage({ + self.postMessage({ type: 'progress', totalFrames: state.stats.totalFrames, framesWithQR: state.stats.framesWithQR, acceptedPackets: state.stats.acceptedPackets, + neededPackets: needed, receivedPackets: state.receivedPackets, solvedGenerations: solvedGens, totalGenerations: totalGens,