[fix](trx-rs): limit aprs live bar to one hour
Attach replay timestamps to APRS history and filter the APRS live bar so it only shows the last hour of valid entries. Co-authored-by: OpenAI Codex <codex@openai.com> Signed-off-by: Stan Grams <sjg@haxx.space>
This commit is contained in:
@@ -4,6 +4,7 @@ const aprsPacketsEl = document.getElementById("aprs-packets");
|
||||
const aprsFilterInput = document.getElementById("aprs-filter");
|
||||
const aprsBarOverlay = document.getElementById("aprs-bar-overlay");
|
||||
const APRS_MAX_PACKETS = 100;
|
||||
const APRS_BAR_WINDOW_MS = 60 * 60 * 1000;
|
||||
let aprsFilterText = "";
|
||||
let aprsPacketHistory = [];
|
||||
|
||||
@@ -105,7 +106,8 @@ function applyAprsFilterToAll() {
|
||||
function updateAprsBar() {
|
||||
if (!aprsBarOverlay) return;
|
||||
const isPkt = (document.getElementById("mode")?.value || "").toUpperCase() === "PKT";
|
||||
const okFrames = aprsPacketHistory.filter((p) => p.crcOk);
|
||||
const cutoffMs = Date.now() - APRS_BAR_WINDOW_MS;
|
||||
const okFrames = aprsPacketHistory.filter((p) => p.crcOk && p._tsMs >= cutoffMs);
|
||||
if (!isPkt || okFrames.length === 0) {
|
||||
aprsBarOverlay.style.display = "none";
|
||||
return;
|
||||
@@ -143,8 +145,9 @@ function addAprsPacket(pkt) {
|
||||
console.log(tag, `${pkt.srcCall}>${pkt.destCall}${pkt.path ? "," + pkt.path : ""}: ${pkt.info}`, pkt);
|
||||
|
||||
// Stamp timestamp for persistence
|
||||
pkt._ts = new Date().toLocaleTimeString([], { hour: "2-digit", minute: "2-digit", second: "2-digit" });
|
||||
pkt._tsMs = Date.now();
|
||||
const tsMs = Number.isFinite(pkt.ts_ms) ? Number(pkt.ts_ms) : Date.now();
|
||||
pkt._tsMs = tsMs;
|
||||
pkt._ts = new Date(tsMs).toLocaleTimeString([], { hour: "2-digit", minute: "2-digit", second: "2-digit" });
|
||||
|
||||
aprsPacketHistory.unshift(pkt);
|
||||
if (aprsPacketHistory.length > APRS_MAX_PACKETS) aprsPacketHistory.length = APRS_MAX_PACKETS;
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
use std::collections::VecDeque;
|
||||
use std::sync::atomic::Ordering;
|
||||
use std::sync::Arc;
|
||||
use std::time::{Duration, Instant};
|
||||
use std::time::{Duration, Instant, SystemTime, UNIX_EPOCH};
|
||||
|
||||
use actix_web::{get, web, Error, HttpRequest, HttpResponse};
|
||||
use actix_ws::Message;
|
||||
@@ -103,7 +103,14 @@ pub fn snapshot_aprs_history(context: &FrontendRuntimeContext) -> Vec<AprsPacket
|
||||
.lock()
|
||||
.expect("aprs history mutex poisoned");
|
||||
prune_aprs_history(&mut history);
|
||||
history.iter().map(|(_, pkt)| pkt.clone()).collect()
|
||||
history
|
||||
.iter()
|
||||
.map(|(ts, pkt)| {
|
||||
let mut pkt = pkt.clone();
|
||||
pkt.ts_ms = Some(timestamp_ms_for_elapsed(ts.elapsed()));
|
||||
pkt
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
|
||||
pub fn snapshot_cw_history(context: &FrontendRuntimeContext) -> Vec<CwEvent> {
|
||||
@@ -141,6 +148,17 @@ pub fn clear_aprs_history(context: &FrontendRuntimeContext) {
|
||||
history.clear();
|
||||
}
|
||||
|
||||
fn timestamp_ms_for_elapsed(elapsed: Duration) -> i64 {
|
||||
let wall_clock = SystemTime::now()
|
||||
.checked_sub(elapsed)
|
||||
.unwrap_or(UNIX_EPOCH);
|
||||
let millis = wall_clock
|
||||
.duration_since(UNIX_EPOCH)
|
||||
.unwrap_or_default()
|
||||
.as_millis();
|
||||
i64::try_from(millis).unwrap_or(i64::MAX)
|
||||
}
|
||||
|
||||
pub fn clear_cw_history(context: &FrontendRuntimeContext) {
|
||||
let mut history = context
|
||||
.cw_history
|
||||
|
||||
Reference in New Issue
Block a user