diff --git a/default_config.py b/default_config.py index 3c5c208..1d42e92 100644 --- a/default_config.py +++ b/default_config.py @@ -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 diff --git a/message_handlers/rx_handler.py b/message_handlers/rx_handler.py index 4e0e311..d8dc31e 100644 --- a/message_handlers/rx_handler.py +++ b/message_handlers/rx_handler.py @@ -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}") \ No newline at end of file + logging.error(f"Error processing packet: {e}") diff --git a/ui/curses_ui.py b/ui/curses_ui.py index ace7f2a..1b413c9 100644 --- a/ui/curses_ui.py +++ b/ui/curses_ui.py @@ -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): diff --git a/user_config.py b/user_config.py index 4bed606..a7abdc9 100644 --- a/user_config.py +++ b/user_config.py @@ -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")) diff --git a/utilities/utils.py b/utilities/utils.py index 02a1e72..738d80d 100644 --- a/utilities/utils.py +++ b/utilities/utils.py @@ -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']