diff --git a/src/graphics/draw/NodeListRenderer.cpp b/src/graphics/draw/NodeListRenderer.cpp index 98d9996a5..bec26be3e 100644 --- a/src/graphics/draw/NodeListRenderer.cpp +++ b/src/graphics/draw/NodeListRenderer.cpp @@ -113,35 +113,6 @@ int calculateMaxScroll(int totalEntries, int visibleRows) return std::max(0, (totalEntries - 1) / (visibleRows * 2)); } -void retrieveAndSortNodes(std::vector &nodeList) -{ - size_t numNodes = nodeDB->getNumMeshNodes(); - for (size_t i = 0; i < numNodes; i++) { - meshtastic_NodeInfoLite *node = nodeDB->getMeshNodeByIndex(i); - if (!node || node->num == nodeDB->getNodeNum()) - continue; - - NodeEntry entry; - entry.node = node; - entry.sortValue = sinceLastSeen(node); - - nodeList.push_back(entry); - } - - // Sort nodes: favorites first, then by last heard (most recent first) - std::sort(nodeList.begin(), nodeList.end(), [](const NodeEntry &a, const NodeEntry &b) { - bool aFav = a.node->is_favorite; - bool bFav = b.node->is_favorite; - if (aFav != bFav) - return aFav; - if (a.sortValue == 0 || a.sortValue == UINT32_MAX) - return false; - if (b.sortValue == 0 || b.sortValue == UINT32_MAX) - return true; - return a.sortValue < b.sortValue; - }); -} - void drawColumnSeparator(OLEDDisplay *display, int16_t x, int16_t yStart, int16_t yEnd) { int columnWidth = display->getWidth() / 2; @@ -440,17 +411,14 @@ void drawNodeListScreen(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t // Space below header y += COMMON_HEADER_HEIGHT; - // Fetch and display sorted node list - std::vector nodeList; - retrieveAndSortNodes(nodeList); - - int totalEntries = nodeList.size(); + int totalEntries = nodeDB->getNumMeshNodes(); int totalRowsAvailable = (display->getHeight() - y) / rowYOffset; int visibleNodeRows = totalRowsAvailable; int totalColumns = 2; int startIndex = scrollIndex * visibleNodeRows * totalColumns; + startIndex++; // skip own node int endIndex = std::min(startIndex + visibleNodeRows * totalColumns, totalEntries); int yOffset = 0; @@ -462,10 +430,10 @@ void drawNodeListScreen(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t for (int i = startIndex; i < endIndex; ++i) { int xPos = x + (col * columnWidth); int yPos = y + yOffset; - renderer(display, nodeList[i].node, xPos, yPos, columnWidth); + renderer(display, nodeDB->getMeshNodeByIndex(i), xPos, yPos, columnWidth); if (extras) { - extras(display, nodeList[i].node, xPos, yPos, columnWidth, heading, lat, lon); + extras(display, nodeDB->getMeshNodeByIndex(i), xPos, yPos, columnWidth, heading, lat, lon); } lastNodeY = std::max(lastNodeY, yPos + FONT_HEIGHT_SMALL); diff --git a/src/graphics/draw/NodeListRenderer.h b/src/graphics/draw/NodeListRenderer.h index 63f0d1c69..ea8df8bd9 100644 --- a/src/graphics/draw/NodeListRenderer.h +++ b/src/graphics/draw/NodeListRenderer.h @@ -23,12 +23,6 @@ namespace NodeListRenderer typedef void (*EntryRenderer)(OLEDDisplay *, meshtastic_NodeInfoLite *, int16_t, int16_t, int); typedef void (*NodeExtrasRenderer)(OLEDDisplay *, meshtastic_NodeInfoLite *, int16_t, int16_t, int, float, double, double); -// Node entry structure -struct NodeEntry { - meshtastic_NodeInfoLite *node; - uint32_t sortValue; -}; - // Node list mode enumeration enum NodeListMode { MODE_LAST_HEARD = 0, MODE_HOP_SIGNAL = 1, MODE_DISTANCE = 2, MODE_COUNT = 3 }; @@ -57,7 +51,6 @@ void drawNodeListWithCompasses(OLEDDisplay *display, OLEDDisplayUiState *state, // Utility functions const char *getCurrentModeTitle(int screenWidth); -void retrieveAndSortNodes(std::vector &nodeList); const char *getSafeNodeName(meshtastic_NodeInfoLite *node); void drawColumns(OLEDDisplay *display, int16_t x, int16_t y, const char **fields); diff --git a/src/mesh/NodeDB.cpp b/src/mesh/NodeDB.cpp index d13864bd9..a30a54e99 100644 --- a/src/mesh/NodeDB.cpp +++ b/src/mesh/NodeDB.cpp @@ -1337,6 +1337,24 @@ bool NodeDB::saveNodeDatabaseToDisk() return saveProto(nodeDatabaseFileName, nodeDatabaseSize, &meshtastic_NodeDatabase_msg, &nodeDatabase, false); } +void NodeDB::sortMeshDB() +{ + std::sort(meshNodes->begin(), meshNodes->end(), [](const meshtastic_NodeInfoLite a, const meshtastic_NodeInfoLite b) { + if (a.num == myNodeInfo.my_node_num) { + return true; + } + bool aFav = a.is_favorite; + bool bFav = b.is_favorite; + if (aFav != bFav) + return aFav; + if (a.last_heard == 0 || a.last_heard == UINT32_MAX) + return false; + if (b.last_heard == 0 || b.last_heard == UINT32_MAX) + return true; + return a.last_heard > b.last_heard; + }); +} + bool NodeDB::saveToDiskNoRetry(int saveWhat) { bool success = true; @@ -1558,6 +1576,7 @@ void NodeDB::addFromContact(meshtastic_SharedContact contact) // Mark the node's key as manually verified to indicate trustworthiness. updateGUIforNode = info; // powerFSM.trigger(EVENT_NODEDB_UPDATED); This event has been retired + sortMeshDB(); notifyObservers(true); // Force an update whether or not our node counts have changed } saveNodeDatabaseToDisk(); @@ -1661,6 +1680,7 @@ void NodeDB::updateFrom(const meshtastic_MeshPacket &mp) info->has_hops_away = true; info->hops_away = mp.hop_start - mp.hop_limit; } + sortMeshDB(); } } diff --git a/src/mesh/NodeDB.h b/src/mesh/NodeDB.h index 90ca5aefd..4d4fb883d 100644 --- a/src/mesh/NodeDB.h +++ b/src/mesh/NodeDB.h @@ -310,6 +310,7 @@ class NodeDB bool saveChannelsToDisk(); bool saveDeviceStateToDisk(); bool saveNodeDatabaseToDisk(); + void sortMeshDB(); }; extern NodeDB *nodeDB;