From 5167b52cbd7b8c81cc81c081dd995658e1ace594 Mon Sep 17 00:00:00 2001 From: DanS Date: Sat, 13 Jun 2026 12:52:42 -0500 Subject: [PATCH] feat(console): add an "App" toggle to show/hide [app] log lines The console mixed RPC traces, daemon output, and the wallet's own "[app] ..." log lines with no way to hide the latter. Add an "App" checkbox alongside the existing Daemon/Errors/RPC toggles. Since [app] lines share COLOR_INFO with other info text, the filter matches them by their "[app] " prefix rather than by color. Default on; unit test + i18n added. Co-Authored-By: Claude Opus 4.8 --- src/ui/windows/console_output_model.cpp | 2 ++ src/ui/windows/console_output_model.h | 1 + src/ui/windows/console_tab.cpp | 26 ++++++++++++++++++++++--- src/ui/windows/console_tab.h | 3 +++ src/util/i18n.cpp | 2 ++ tests/test_phase4.cpp | 10 +++++++++- 6 files changed, 40 insertions(+), 4 deletions(-) diff --git a/src/ui/windows/console_output_model.cpp b/src/ui/windows/console_output_model.cpp index ba1175f..53d531c 100644 --- a/src/ui/windows/console_output_model.cpp +++ b/src/ui/windows/console_output_model.cpp @@ -21,6 +21,8 @@ bool consoleLinePassesFilter(const std::string& lineText, { if (!filter.daemonMessagesEnabled && lineColor == filter.daemonColor) return false; if (!filter.rpcTraceEnabled && lineColor == filter.rpcTraceColor) return false; + // "[app] ..." lines share COLOR_INFO with other info text, so match them by prefix. + if (!filter.appMessagesEnabled && lineText.rfind("[app] ", 0) == 0) return false; if (filter.errorsOnly && lineColor != filter.errorColor) return false; if (!filter.text.empty()) { std::string needle = lowerCopy(filter.text); diff --git a/src/ui/windows/console_output_model.h b/src/ui/windows/console_output_model.h index cd98880..431d13b 100644 --- a/src/ui/windows/console_output_model.h +++ b/src/ui/windows/console_output_model.h @@ -12,6 +12,7 @@ struct ConsoleOutputFilter { bool daemonMessagesEnabled = true; bool errorsOnly = false; bool rpcTraceEnabled = false; + bool appMessagesEnabled = true; // "[app] ..." wallet log lines (matched by prefix, not color) ImU32 daemonColor = 0; ImU32 errorColor = 0; ImU32 rpcTraceColor = 0; diff --git a/src/ui/windows/console_tab.cpp b/src/ui/windows/console_tab.cpp index b29749b..064c754 100644 --- a/src/ui/windows/console_tab.cpp +++ b/src/ui/windows/console_tab.cpp @@ -46,6 +46,7 @@ float ConsoleTab::s_console_zoom = 1.0f; bool ConsoleTab::s_daemon_messages_enabled = true; bool ConsoleTab::s_errors_only_enabled = false; bool ConsoleTab::s_rpc_trace_enabled = false; +bool ConsoleTab::s_app_messages_enabled = true; namespace { @@ -531,11 +532,28 @@ void ConsoleTab::renderToolbar(daemon::EmbeddedDaemon* daemon) if (ImGui::IsItemHovered()) { ImGui::SetTooltip("%s", TR("console_show_rpc_trace")); } - + ImGui::SameLine(); ImGui::Spacing(); ImGui::SameLine(); - + + // App messages toggle — "[app] ..." wallet log lines + { + static bool s_prev_app_enabled = true; + ImGui::Checkbox(TR("console_app"), &s_app_messages_enabled); + if (s_prev_app_enabled != s_app_messages_enabled && auto_scroll_) { + scroll_to_bottom_ = true; + } + s_prev_app_enabled = s_app_messages_enabled; + } + if (ImGui::IsItemHovered()) { + ImGui::SetTooltip("%s", TR("console_show_app_output")); + } + + ImGui::SameLine(); + ImGui::Spacing(); + ImGui::SameLine(); + // Clear button if (TactileButton(TR("console_clear"), ImVec2(0, 0), schema::UI().resolveFont("button"))) { clear(); @@ -651,10 +669,12 @@ void ConsoleTab::renderOutput() // Build filtered line index list BEFORE mouse handling (so screenToTextPos works) ConsoleOutputFilter outputFilter{filter_text_, s_daemon_messages_enabled, s_errors_only_enabled, s_rpc_trace_enabled, + s_app_messages_enabled, COLOR_DAEMON, COLOR_ERROR, COLOR_RPC}; bool has_text_filter = !outputFilter.text.empty(); bool has_filter = has_text_filter || !outputFilter.daemonMessagesEnabled || - !outputFilter.rpcTraceEnabled || outputFilter.errorsOnly; + !outputFilter.rpcTraceEnabled || !outputFilter.appMessagesEnabled || + outputFilter.errorsOnly; visible_indices_.clear(); if (has_filter) { for (int i = 0; i < static_cast(lines_.size()); i++) { diff --git a/src/ui/windows/console_tab.h b/src/ui/windows/console_tab.h index 8360719..0dae1f1 100644 --- a/src/ui/windows/console_tab.h +++ b/src/ui/windows/console_tab.h @@ -73,6 +73,9 @@ public: // Show app RPC calls made through RPCClient (method/source only) static bool s_rpc_trace_enabled; + // Show "[app] ..." wallet log lines + static bool s_app_messages_enabled; + /// Refresh console text colors for current theme (call after theme switch) static void refreshColors(); diff --git a/src/util/i18n.cpp b/src/util/i18n.cpp index 99688a4..7148c77 100644 --- a/src/util/i18n.cpp +++ b/src/util/i18n.cpp @@ -945,6 +945,8 @@ void I18n::loadBuiltinEnglish() strings_["console_not_connected"] = "Error: Not connected to daemon"; strings_["console_rpc_reference"] = "RPC Command Reference"; strings_["console_rpc_trace"] = "RPC"; + strings_["console_app"] = "App"; + strings_["console_show_app_output"] = "Show [app] wallet log lines"; strings_["console_search_commands"] = "Search commands..."; strings_["console_select_all"] = "Select All"; strings_["console_show_daemon_output"] = "Show daemon output"; diff --git a/tests/test_phase4.cpp b/tests/test_phase4.cpp index 426b041..f065c16 100644 --- a/tests/test_phase4.cpp +++ b/tests/test_phase4.cpp @@ -2298,7 +2298,7 @@ void testRendererHelpers() EXPECT_FALSE(dragonx::ui::IsPoolMiningActive(true, false, true)); EXPECT_TRUE(dragonx::ui::IsPoolMiningActive(false, false, true)); - dragonx::ui::ConsoleOutputFilter filter{"error", false, false, false, 10, 20, 30}; + dragonx::ui::ConsoleOutputFilter filter{"error", false, false, false, true, 10, 20, 30}; EXPECT_TRUE(dragonx::ui::consoleLinePassesFilter("RPC Error", 20, filter)); EXPECT_FALSE(dragonx::ui::consoleLinePassesFilter("daemon line", 10, filter)); filter.text.clear(); @@ -2311,6 +2311,14 @@ void testRendererHelpers() EXPECT_TRUE(dragonx::ui::consoleLinePassesFilter("error line", 20, filter)); EXPECT_FALSE(dragonx::ui::consoleLinePassesFilter("info line", 30, filter)); + // "[app] ..." lines are filtered by prefix (they share the info color), not by color. + filter.errorsOnly = false; + filter.appMessagesEnabled = false; + EXPECT_FALSE(dragonx::ui::consoleLinePassesFilter("[app] Price updated", 30, filter)); + EXPECT_TRUE(dragonx::ui::consoleLinePassesFilter("[rpc] trace", 30, filter)); + filter.appMessagesEnabled = true; + EXPECT_TRUE(dragonx::ui::consoleLinePassesFilter("[app] Price updated", 30, filter)); + std::vector poolAddresses; poolAddresses.push_back({"R-transparent", 0.0, "transparent", true}); poolAddresses.push_back({"zs-default-worker", 0.0, "shielded", true});