@@ -170,6 +170,7 @@ const state = {
170170 repeaters : new Map ( ) , // Map<repeaterId, {snr, seenCount}>
171171 listenTimeout : null , // Timeout handle for 7-second window
172172 rxLogHandler : null , // Handler function for rx_log events
173+ currentLogEntry : null , // Current log entry being updated (for incremental UI updates)
173174 }
174175} ;
175176
@@ -1667,6 +1668,9 @@ async function handleRxLogEvent(data, originalPayload, channelIdx, expectedChann
16671668 snr : data . lastSnr ,
16681669 seenCount : existing . seenCount + 1
16691670 } ) ;
1671+
1672+ // Trigger incremental UI update since SNR changed
1673+ updateCurrentLogEntryWithLiveRepeaters ( ) ;
16701674 } else {
16711675 debugLog ( `Deduplication decision: keeping existing SNR for path ${ pathHex } (existing ${ existing . snr } >= new ${ data . lastSnr } )` ) ;
16721676 // Still increment seen count
@@ -1679,6 +1683,9 @@ async function handleRxLogEvent(data, originalPayload, channelIdx, expectedChann
16791683 snr : data . lastSnr ,
16801684 seenCount : 1
16811685 } ) ;
1686+
1687+ // Trigger incremental UI update for the new repeater
1688+ updateCurrentLogEntryWithLiveRepeaters ( ) ;
16821689 }
16831690 } catch ( error ) {
16841691 debugError ( `Error processing rx_log entry: ${ error . message } ` , error ) ;
@@ -1725,6 +1732,7 @@ function stopRepeaterTracking() {
17251732 state . repeaterTracking . sentPayload = null ;
17261733 state . repeaterTracking . repeaters . clear ( ) ;
17271734 state . repeaterTracking . rxLogHandler = null ;
1735+ state . repeaterTracking . currentLogEntry = null ;
17281736
17291737 return repeaters ;
17301738}
@@ -1903,10 +1911,10 @@ function updateLogSummary() {
19031911 debugLog ( `Session log summary updated: ${ count } total pings, latest ping heard ${ heardCount } repeats` ) ;
19041912
19051913 if ( heardCount > 0 ) {
1906- logLastSnr . textContent = `Heard ${ heardCount } `;
1914+ logLastSnr . textContent = heardCount === 1 ? '1 Repeat' : ` ${ heardCount } Repeats `;
19071915 logLastSnr . className = 'text-xs font-mono text-slate-300' ;
19081916 } else {
1909- logLastSnr . textContent = 'Heard 0 ' ;
1917+ logLastSnr . textContent = '0 Repeats ' ;
19101918 logLastSnr . className = 'text-xs font-mono text-slate-500' ;
19111919 }
19121920}
@@ -2168,6 +2176,33 @@ function updatePingLogWithRepeaters(logData, repeaters) {
21682176 debugLog ( `Updated ping log entry with repeater telemetry: ${ repeaterStr } ` ) ;
21692177}
21702178
2179+ /**
2180+ * Incrementally update the current ping log entry as repeaters are detected
2181+ * This provides real-time updates during the RX listening window
2182+ */
2183+ function updateCurrentLogEntryWithLiveRepeaters ( ) {
2184+ // Only update if we're actively listening and have a current log entry
2185+ if ( ! state . repeaterTracking . isListening || ! state . repeaterTracking . currentLogEntry ) {
2186+ return ;
2187+ }
2188+
2189+ const logData = state . repeaterTracking . currentLogEntry ;
2190+
2191+ // Convert current repeaters Map to array format
2192+ const repeaters = Array . from ( state . repeaterTracking . repeaters . entries ( ) ) . map ( ( [ id , data ] ) => ( {
2193+ repeaterId : id ,
2194+ snr : data . snr
2195+ } ) ) ;
2196+
2197+ // Sort by repeater ID for deterministic output
2198+ repeaters . sort ( ( a , b ) => a . repeaterId . localeCompare ( b . repeaterId ) ) ;
2199+
2200+ // Reuse the existing updatePingLogWithRepeaters function
2201+ updatePingLogWithRepeaters ( logData , repeaters ) ;
2202+
2203+ debugLog ( `Incrementally updated ping log entry: ${ repeaters . length } repeater(s) detected so far` ) ;
2204+ }
2205+
21712206/**
21722207 * Send a wardrive ping with current GPS coordinates
21732208 * @param {boolean } manual - Whether this is a manual ping (true) or auto ping (false)
@@ -2300,6 +2335,9 @@ async function sendPing(manual = false) {
23002335 // Create UI log entry with placeholder for repeater data
23012336 const logEntry = logPingToUI ( payload , lat , lon ) ;
23022337
2338+ // Store log entry in repeater tracking state for incremental updates
2339+ state . repeaterTracking . currentLogEntry = logEntry ;
2340+
23032341 // Start RX listening countdown
23042342 // The minimum 500ms visibility of "Ping sent" is enforced by setStatus()
23052343 if ( state . connection ) {
0 commit comments