ui: fix stale peer age display

This commit is contained in:
DeFiDude
2026-05-04 02:11:30 -06:00
parent c4e5610408
commit e87cef3fb3
5 changed files with 23 additions and 32 deletions
+10 -9
View File
@@ -150,7 +150,8 @@ void AnnounceManager::received_announce(
auto it = _hashIndex.find(key);
if (it != _hashIndex.end()) {
auto& node = _nodes[it->second];
if (now - node.lastSeen < ANNOUNCE_MIN_INTERVAL_MS) return;
if (node.lastSeen != 0 && now >= node.lastSeen &&
now - node.lastSeen < ANNOUNCE_MIN_INTERVAL_MS) return;
if (!name.empty()) node.name = name;
if (!idHex.empty()) node.identityHex = idHex;
node.lastSeen = now;
@@ -253,7 +254,7 @@ int AnnounceManager::nodesOnlineSince(unsigned long maxAgeMs) const {
unsigned long now = millis();
int count = 0;
for (const auto& n : _nodes) {
if (now - n.lastSeen <= maxAgeMs) count++;
if (n.lastSeen != 0 && now >= n.lastSeen && now - n.lastSeen <= maxAgeMs) count++;
}
return count;
}
@@ -307,7 +308,7 @@ void AnnounceManager::evictStale(unsigned long maxAgeMs) {
unsigned long now = millis();
_nodes.erase(std::remove_if(_nodes.begin(), _nodes.end(),
[now, maxAgeMs](const DiscoveredNode& n) {
return !n.saved && (now - n.lastSeen > maxAgeMs);
return !n.saved && (n.lastSeen == 0 || now < n.lastSeen || now - n.lastSeen > maxAgeMs);
}), _nodes.end());
rebuildIndex();
}
@@ -343,8 +344,6 @@ void AnnounceManager::saveContact(const DiscoveredNode& node) {
std::string hexHash = node.hash.toHex();
JsonDocument doc;
doc["hash"] = hexHash; doc["name"] = node.name;
doc["rssi"] = node.rssi; doc["snr"] = node.snr;
doc["hops"] = node.hops; doc["lastSeen"] = node.lastSeen;
String json;
serializeJson(doc, json);
String filename = hexHash.substr(0, 16).c_str();
@@ -392,10 +391,12 @@ void AnnounceManager::loadContacts() {
node.hash = hash;
node.name = sanitizeName(doc["name"] | "");
if (node.name.empty()) node.name = hexHash.substr(0, 12);
node.rssi = doc["rssi"] | 0;
node.snr = doc["snr"] | 0.0f;
node.hops = doc["hops"] | 0;
node.lastSeen = doc["lastSeen"] | (unsigned long)millis();
// Contacts persist address-book data only. Radio/path state
// is boot-relative and becomes misleading after restart.
node.rssi = 0;
node.snr = 0.0f;
node.hops = 0;
node.lastSeen = 0;
node.saved = true;
_hashIndex[key] = (int)_nodes.size();
_nodes.push_back(node);
+6 -10
View File
@@ -50,14 +50,8 @@ std::string compactAge(unsigned long ageMs) {
return buf;
}
std::string contactMetaFor(const DiscoveredNode& node, unsigned long ageMs) {
std::string age = compactAge(ageMs);
if (node.hops > 0 && node.hops < 128) {
char buf[24];
snprintf(buf, sizeof(buf), "%uH %s", (unsigned)node.hops, age.c_str());
return buf;
}
return age;
std::string contactMetaFor(unsigned long ageMs) {
return compactAge(ageMs);
}
lv_obj_t* createEmptyState(lv_obj_t* parent) {
@@ -132,15 +126,17 @@ void LvContactsScreen::onEnter() {
void LvContactsScreen::refreshUI() {
if (!_am) return;
unsigned long now = millis();
int contacts = 0;
for (const auto& n : _am->nodes()) { if (n.saved) contacts++; }
if (contacts != _lastContactCount) {
if (contacts != _lastContactCount || now - _lastRebuild >= REBUILD_INTERVAL_MS) {
rebuildList();
}
}
void LvContactsScreen::rebuildList() {
if (!_am || !_list) return;
_lastRebuild = millis();
_contactIndices.clear();
lv_obj_clean(_list);
@@ -224,7 +220,7 @@ void LvContactsScreen::rebuildList() {
lv_obj_set_style_text_align(metaLbl, LV_TEXT_ALIGN_RIGHT, 0);
lv_label_set_long_mode(metaLbl, LV_LABEL_LONG_CLIP);
lv_obj_set_width(metaLbl, 64);
std::string meta = contactMetaFor(node, age);
std::string meta = contactMetaFor(age);
lv_label_set_text(metaLbl, meta.c_str());
lv_obj_set_pos(metaLbl, Theme::CONTENT_W - 72, 5);
+2
View File
@@ -33,6 +33,8 @@ private:
bool _focusActive = false;
int _deleteIdx = -1;
int _lastContactCount = -1;
unsigned long _lastRebuild = 0;
static constexpr unsigned long REBUILD_INTERVAL_MS = 30000;
std::vector<int> _contactIndices;
std::vector<std::vector<uint8_t>> _avatarBuffers;
+4 -13
View File
@@ -48,19 +48,8 @@ std::string compactAge(unsigned long ageMs) {
return buf;
}
std::string hopTextFor(const DiscoveredNode& node) {
if (node.hops > 0 && node.hops < 128) {
char buf[12];
snprintf(buf, sizeof(buf), "%uhop", (unsigned)node.hops);
return buf;
}
return "";
}
std::string peerMetaFor(const DiscoveredNode& node, unsigned long ageMs, bool devMode) {
std::string meta = hopTextFor(node);
if (!meta.empty()) meta += " ";
meta += compactAge(ageMs);
std::string meta = compactAge(ageMs);
if (devMode && node.rssi != 0) {
char buf[14];
snprintf(buf, sizeof(buf), " %ddB", node.rssi);
@@ -242,7 +231,8 @@ void LvNodesScreen::refreshUI() {
for (const auto& n : _am->nodes()) { if (n.saved) contacts++; }
int countDelta = abs(_am->nodeCount() - _lastNodeCount);
int contactDelta = abs(contacts - _lastContactCount);
if (countDelta > 0 || contactDelta > 0) {
bool ageRefresh = now - _lastRebuild >= AGE_REBUILD_INTERVAL_MS;
if (countDelta > 0 || contactDelta > 0 || ageRefresh) {
_lastRebuild = now;
rebuildList();
}
@@ -250,6 +240,7 @@ void LvNodesScreen::refreshUI() {
void LvNodesScreen::rebuildList() {
if (!_am || !_list) return;
_lastRebuild = millis();
// Preserve scroll position across rebuilds
lv_coord_t scrollY = lv_obj_get_scroll_y(_list);
lv_obj_clean(_list);
+1
View File
@@ -71,6 +71,7 @@ private:
unsigned long _lastRebuild = 0;
static constexpr unsigned long REBUILD_INTERVAL_MS = 5000;
static constexpr unsigned long AGE_REBUILD_INTERVAL_MS = 30000;
lv_obj_t* _list = nullptr;
lv_obj_t* _emptyState = nullptr;