diff --git a/src/islands/network/OpticalTransfer.tsx b/src/islands/network/OpticalTransfer.tsx index 8644ff6..7fa2edc 100644 --- a/src/islands/network/OpticalTransfer.tsx +++ b/src/islands/network/OpticalTransfer.tsx @@ -128,7 +128,6 @@ function Receiver({ onBack }: { onBack: () => void }) { useEffect(() => { if (!stream) return; if (!captureRef.current) captureRef.current = document.createElement('canvas'); - let collected = 0; const scan = () => { const video = videoRef.current; @@ -149,13 +148,9 @@ function Receiver({ onBack }: { onBack: () => void }) { decoderRef.current = new LtDecoder(frame.k, BLOCK_SIZE); } if (frame.session === metaRef.current.session && decoderRef.current) { - const before = decoderRef.current.solvedCount; const done = decoderRef.current.addFrame(frame.seq, frame.payload); - if (decoderRef.current.solvedCount !== before || decoderRef.current.progress() > 0) { - collected++; - setFrames(collected); - setProgress(decoderRef.current.progress()); - } + setFrames(decoderRef.current.framesSeen); + setProgress(decoderRef.current.progress()); if (done) finish(); } } diff --git a/src/tools/optical/fountain.lib.ts b/src/tools/optical/fountain.lib.ts index 364b759..1c45bf7 100644 --- a/src/tools/optical/fountain.lib.ts +++ b/src/tools/optical/fountain.lib.ts @@ -127,8 +127,20 @@ export class LtDecoder { return this.solvedCount >= this.k; } + /** Unique frames received so far. */ + get framesSeen(): number { + return this.seenSeq.size; + } + + /** + * Collection progress 0..1. LT codes solve almost nothing until they avalanche + * near the end, so reporting solved-blocks looks stuck at 0%. Report frames + * collected vs. the ~k×1.15 typically needed instead (capped below 1 until done). + */ progress(): number { - return this.k === 0 ? 1 : this.solvedCount / this.k; + if (this.done) return 1; + if (this.k === 0) return 1; + return Math.min(0.99, this.framesSeen / (this.k * 1.15)); } /** Feed one frame. Returns true once the whole file is solved. */