diff --git a/src/main.c b/src/main.c index 335b2d4..e038936 100644 --- a/src/main.c +++ b/src/main.c @@ -11,8 +11,8 @@ */ #define NT_VERSION_MAJOR 0 #define NT_VERSION_MINOR 0 -#define NT_VERSION_PATCH 22 -#define NT_VERSION "v0.0.22" +#define NT_VERSION_PATCH 23 +#define NT_VERSION "v0.0.23" #include #include diff --git a/src/menu_login.c b/src/menu_login.c index 35982bc..61058df 100644 --- a/src/menu_login.c +++ b/src/menu_login.c @@ -314,10 +314,8 @@ void menu_login(void) { nt_log("Signed in via n_signer URL (%s) npub: %s", endpoint_url, g_state.npub_bech32); - if (state_load_user_info_async() != 0) { - nt_log("Failed to start background user-info load."); - } else { - nt_log("Loading profile/relay data in background..."); + if (state_load_user_info() != 0) { + nt_log("Failed to load profile/relay data after login."); } return; @@ -393,10 +391,8 @@ void menu_login(void) { nt_log("Signed in via qrexec n_signer (%s:%s) npub: %s", target_qube, service_name, g_state.npub_bech32); - if (state_load_user_info_async() != 0) { - nt_log("Failed to start background user-info load."); - } else { - nt_log("Loading profile/relay data in background..."); + if (state_load_user_info() != 0) { + nt_log("Failed to load profile/relay data after login."); } return; diff --git a/src/net.c b/src/net.c index f95e848..46b8caa 100644 --- a/src/net.c +++ b/src/net.c @@ -727,6 +727,9 @@ int nt_query_sync_verbose(const char *filter_json, char **events = NULL; int events_n = 0; int events_cap = 0; + char **seen_ids = NULL; + int seen_n = 0; + int seen_cap = 0; int i; if (!events_out || !event_count || !filter_json || !relay_urls || relay_count <= 0) { @@ -743,6 +746,73 @@ int nt_query_sync_verbose(const char *filter_json, return -1; } + if (verbose && phase_label) { + nt_log("%s: querying %d relays with per-relay diagnostics", + phase_label, + relay_count); + + for (i = 0; i < relay_count; i++) { + nt_log("%s: relay %d/%d target: %s", + phase_label, + i + 1, + relay_count, + relay_urls[i] ? relay_urls[i] : "(null)"); + } + + for (i = 0; i < relay_count; i++) { + const char *reason = "unknown"; + int before_count = events_n; + int relay_ok = nt_query_one_relay(relay_urls[i], + filter, + timeout_ms, + verbose, + phase_label, + &events, + &events_n, + &events_cap, + &seen_ids, + &seen_n, + &seen_cap, + &reason); + int added = events_n - before_count; + + if (relay_ok < 0) { + nt_log("%s: relay %d/%d %s -> error (%s)", + phase_label, + i + 1, + relay_count, + relay_urls[i] ? relay_urls[i] : "(null)", + reason ? reason : "unknown"); + nt_free_string_array(events, events_n); + nt_free_string_array(seen_ids, seen_n); + cJSON_Delete(filter); + return -1; + } + + nt_log("%s: relay %d/%d %s -> %s (reason=%s, new_events=%d, total=%d)", + phase_label, + i + 1, + relay_count, + relay_urls[i] ? relay_urls[i] : "(null)", + relay_ok ? "connected" : "no_data_or_error", + reason ? reason : "unknown", + added, + events_n); + } + + nt_free_string_array(seen_ids, seen_n); + cJSON_Delete(filter); + + if (events_n <= 0) { + return -1; + } + + nt_log("%s: collected %d unique events total", phase_label, events_n); + *events_out = events; + *event_count = events_n; + return 0; + } + pool = nostr_relay_pool_create(NULL); if (!pool) { cJSON_Delete(filter); @@ -750,12 +820,6 @@ int nt_query_sync_verbose(const char *filter_json, return -1; } - if (verbose && phase_label) { - nt_log("%s: querying %d relays via nostr_core relay pool", - phase_label, - relay_count); - } - pool_events = nostr_relay_pool_query_sync(pool, relay_urls, relay_count, @@ -790,12 +854,6 @@ int nt_query_sync_verbose(const char *filter_json, } free(pool_events); - if (verbose && phase_label) { - nt_log("%s: relay pool collected %d unique events", - phase_label, - events_n); - } - nostr_relay_pool_destroy(pool); *events_out = events; *event_count = events_n; diff --git a/src/nt_tui_adapter.c b/src/nt_tui_adapter.c index bc37c41..d381e51 100644 --- a/src/nt_tui_adapter.c +++ b/src/nt_tui_adapter.c @@ -17,16 +17,46 @@ static int g_body_row = 0; static char g_app_name[128] = "NOSTR TERMINAL"; static char g_app_version[64] = ""; static char g_user[256] = ""; +static char g_composed_title[512] = "NOSTR TERMINAL"; static char g_status_line[512] = ""; static NtLogEntry g_log_entries[NT_LOG_MAX]; static int g_log_head = 0; static int g_log_count = 0; static pthread_mutex_t g_log_mutex = PTHREAD_MUTEX_INITIALIZER; +static unsigned long g_log_version = 0; +static unsigned long g_rendered_status_version = 0; +static int g_idle_callback_registered = 0; static WINDOW *nt_body_window(void) { return (WINDOW *)tuin_body_window(); } +static void nt_tui_idle_callback(void) { + unsigned long log_version_snapshot; + unsigned long rendered_snapshot; + TuiStatus status; + + pthread_mutex_lock(&g_log_mutex); + log_version_snapshot = g_log_version; + rendered_snapshot = g_rendered_status_version; + pthread_mutex_unlock(&g_log_mutex); + + if (log_version_snapshot == rendered_snapshot) { + return; + } + + status = nt_status(); + tuin_render_footer(&status); + doupdate(); +} + +static void nt_register_idle_callback_once(void) { + if (!g_idle_callback_registered) { + tuin_set_idle_callback(nt_tui_idle_callback); + g_idle_callback_registered = 1; + } +} + void nt_print(const char *fmt, ...) { WINDOW *body = nt_body_window(); char line[8192]; @@ -89,17 +119,20 @@ int nt_run_external_editor(int (*spawn)(void *user), void *user) { return result; } +static void nt_refresh_composed_title(void) { + if (g_user[0] != '\0') { + snprintf(g_composed_title, sizeof(g_composed_title), "%s - %s - %s", g_app_name, g_app_version, g_user); + } else { + snprintf(g_composed_title, sizeof(g_composed_title), "%s - %s", g_app_name, g_app_version); + } +} + TuiFrame nt_frame(const char *breadcrumb) { - static char composed_title[512]; TuiFrame frame; - if (g_user[0] != '\0') { - snprintf(composed_title, sizeof(composed_title), "%s - %s - %s", g_app_name, g_app_version, g_user); - } else { - snprintf(composed_title, sizeof(composed_title), "%s - %s", g_app_name, g_app_version); - } + nt_refresh_composed_title(); - frame.app_name = composed_title; + frame.app_name = g_composed_title; frame.app_version = ""; frame.breadcrumb = breadcrumb; return frame; @@ -114,6 +147,7 @@ TuiStatus nt_status(void) { snprintf(g_status_line, sizeof(g_status_line), "%s", g_log_entries[idx].text); } status.text = g_status_line; + g_rendered_status_version = g_log_version; pthread_mutex_unlock(&g_log_mutex); return status; @@ -122,6 +156,8 @@ TuiStatus nt_status(void) { void nt_set_app_info(const char *name, const char *version) { snprintf(g_app_name, sizeof(g_app_name), "%s", (name && name[0] != '\0') ? name : "NOSTR TERMINAL"); snprintf(g_app_version, sizeof(g_app_version), "%s", (version && version[0] != '\0') ? version : ""); + nt_refresh_composed_title(); + nt_register_idle_callback_once(); } void nt_set_window_title(const char *title) { @@ -134,6 +170,7 @@ void nt_set_window_title(const char *title) { void nt_set_user(const char *user) { snprintf(g_user, sizeof(g_user), "%s", (user && user[0] != '\0') ? user : ""); + nt_refresh_composed_title(); } void nt_log(const char *fmt, ...) { @@ -170,6 +207,7 @@ void nt_log(const char *fmt, ...) { if (g_log_count < NT_LOG_MAX) { g_log_count++; } + g_log_version++; pthread_mutex_unlock(&g_log_mutex); } @@ -207,6 +245,7 @@ void nt_log_clear(void) { g_log_head = 0; g_log_count = 0; g_status_line[0] = '\0'; + g_log_version++; pthread_mutex_unlock(&g_log_mutex); } diff --git a/src/state.c b/src/state.c index 3cda592..cc0aa69 100644 --- a/src/state.c +++ b/src/state.c @@ -483,6 +483,8 @@ int state_load_user_info(void) { snprintf(g_state.user_name, sizeof(g_state.user_name), "%s", g_state.npub_bech32); } + nt_set_user(g_state.user_name); + return 0; }