Add node sort preferences (#102)

* Add node sort preferences

Now supports 'lastHeard', 'name', and 'hops'. There's probably a way to
make this a multi-select type input instead of requiring the user to
type exactly the right string but it wasn't immediately obvious how to
do that.

* Select node sort from list, refresh on change

---------

Co-authored-by: pdxlocations <benlipsey@gmail.com>
This commit is contained in:
Russell Schmidt
2025-02-02 11:43:04 -06:00
committed by GitHub
parent c62965a94f
commit d019c6371c
5 changed files with 33 additions and 11 deletions
+4 -1
View File
@@ -118,7 +118,8 @@ def initialize_config():
"theme": "dark",
"COLOR_CONFIG_DARK": COLOR_CONFIG_DARK,
"COLOR_CONFIG_LIGHT": COLOR_CONFIG_LIGHT,
"COLOR_CONFIG_GREEN": COLOR_CONFIG_GREEN
"COLOR_CONFIG_GREEN": COLOR_CONFIG_GREEN,
"node_sort": "lastHeard"
}
if not os.path.exists(json_file_path):
@@ -148,6 +149,7 @@ def assign_config_variables(loaded_config):
global db_file_path, log_file_path, message_prefix, sent_message_prefix
global notification_symbol, ack_implicit_str, ack_str, nak_str, ack_unknown_str
global theme, COLOR_CONFIG
global node_sort
db_file_path = loaded_config["db_file_path"]
log_file_path = loaded_config["log_file_path"]
@@ -165,6 +167,7 @@ def assign_config_variables(loaded_config):
COLOR_CONFIG = loaded_config["COLOR_CONFIG_LIGHT"]
elif theme == "green":
COLOR_CONFIG = loaded_config["COLOR_CONFIG_GREEN"]
node_sort = loaded_config["node_sort"]
# Call the function when the script is imported
+5 -5
View File
@@ -1,6 +1,7 @@
import logging
import time
from utilities.utils import get_node_list
from utilities.utils import refresh_node_list
from datetime import datetime
from ui.curses_ui import draw_packetlog_win, draw_node_list, draw_messages_window, draw_channel_list, add_notification
from db_handler import save_message_to_db, maybe_store_nodeinfo_in_db, get_name_from_database
import default_config as config
@@ -24,9 +25,8 @@ def on_receive(packet, interface):
return
# Assume any incoming packet could update the last seen time for a node
new_node_list = get_node_list()
if new_node_list != globals.node_list:
globals.node_list = new_node_list
changed = refresh_node_list()
if(changed):
draw_node_list()
if packet['decoded']['portnum'] == 'NODEINFO_APP':
@@ -99,4 +99,4 @@ def on_receive(packet, interface):
save_message_to_db(globals.channel_list[channel_number], message_from_id, message_string)
except KeyError as e:
logging.error(f"Error processing packet: {e}")
logging.error(f"Error processing packet: {e}")
+2 -1
View File
@@ -1,6 +1,6 @@
import curses
import textwrap
from utilities.utils import get_channels, get_time_ago
from utilities.utils import get_channels, get_time_ago, refresh_node_list
from settings import settings_menu
from message_handlers.tx_handler import send_message, send_traceroute
from ui.colors import setup_colors, get_color
@@ -608,6 +608,7 @@ def main_ui(stdscr):
curses.curs_set(0)
settings_menu(stdscr, globals.interface)
curses.curs_set(1)
refresh_node_list()
handle_resize(stdscr, False)
elif char == chr(16):
+3
View File
@@ -49,6 +49,9 @@ def edit_value(key, current_value):
# Load theme names dynamically from the JSON
theme_options = [k.split("_", 2)[2].lower() for k in loaded_config.keys() if k.startswith("COLOR_CONFIG")]
return select_from_list("Select Theme", current_value, theme_options)
elif key == "node_sort":
sort_options = ['lastHeard', 'name', 'hops']
return select_from_list("Sort By", current_value, sort_options)
# Standard Input Mode (Scrollable)
edit_win.addstr(7, 2, "New Value: ", get_color("settings_default"))
+19 -4
View File
@@ -1,6 +1,7 @@
import globals
from datetime import datetime
from meshtastic.protobuf import config_pb2
import default_config as config
def get_channels():
"""Retrieve channels from the node and update globals.channel_list and globals.all_messages."""
@@ -36,14 +37,28 @@ def get_channels():
def get_node_list():
if globals.interface.nodes:
my_node_num = globals.myNodeNum
sorted_nodes = sorted(
globals.interface.nodes.values(),
key = lambda node: (node['lastHeard'] if ('lastHeard' in node and isinstance(node['lastHeard'], int)) else 0),
reverse = True)
def node_sort(node):
if(config.node_sort == 'lastHeard'):
return -node['lastHeard'] if ('lastHeard' in node and isinstance(node['lastHeard'], int)) else 0
elif(config.node_sort == "name"):
return node['user']['longName']
elif(config.node_sort == "hops"):
return node['hopsAway'] if 'hopsAway' in node else 100
else:
return node
sorted_nodes = sorted(globals.interface.nodes.values(), key = node_sort)
node_list = [node['num'] for node in sorted_nodes if node['num'] != my_node_num]
return [my_node_num] + node_list # Ensuring your node is always first
return []
def refresh_node_list():
new_node_list = get_node_list()
if new_node_list != globals.node_list:
globals.node_list = new_node_list
return True
return False
def get_nodeNum():
myinfo = globals.interface.getMyNodeInfo()
myNodeNum = myinfo['num']