refactor(console): phase 2 — channel-as-semantic key; decouple executor from UI colors

Make ConsoleChannel the canonical semantic classification of every console
line. Producers (command executor, app log forwarders, result formatter) tag
each line with a channel; the UI derives both the text color and the left
accent-bar color from it at draw time, and the output filter keys off it.

This replaces the prior scheme of storing an ImU32 color per line and then
reverse-engineering the source from color-equality plus a "[daemon] "/"[xmrig] "
/"[app] "/"[rpc] " text prefix. Consequences:

- ConsoleLine now stores {text, ConsoleChannel} — no per-line color.
- addLine()/addRpcTraceLine() take a channel; the redundant text prefixes are
  gone (the accent bar carries the origin).
- The executor's ConsoleAddLineFn hands a channel, not an ImU32, so the backend
  no longer depends on ConsoleTab::COLOR_* — FullNode/Lite executors emit clean
  text + channel.
- The theme-remap loop that rewrote stored colors on light/dark flip is deleted;
  colors are resolved per-channel each frame (refreshColors on flip only).
- ConsoleOutputFilter drops its color fields; consoleLinePassesFilter() keys off
  the channel. Test updated to the channel-based API.
- Added a Warning channel (amber severity peer of Error/Success) so the
  notification + logger warning forwarders keep their color.

Full-node + lite build clean; ctest green; source hygiene clean.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-07-01 18:22:35 -05:00
parent 19e83eb12a
commit 33735b1d52
9 changed files with 219 additions and 175 deletions

View File

@@ -396,37 +396,39 @@ bool App::init()
worker_->start();
network_refresh_.markDue(services::NetworkRefreshService::Timer::Price);
// Forward error/warning notifications to the console tab
// Use ConsoleTab colors so the Errors filter works correctly
// Forward error/warning notifications to the console tab. The channel is the semantic
// key — the Errors filter keys off ConsoleChannel::Error, and the color/accent bar are
// derived from the channel at draw time.
ui::Notifications::instance().setConsoleCallback(
[this](const std::string& msg, bool is_error) {
ImU32 color = is_error ? ui::ConsoleTab::COLOR_ERROR : ui::material::Warning();
console_tab_.addLine(msg, color);
console_tab_.addLine(msg, is_error ? ui::ConsoleChannel::Error
: ui::ConsoleChannel::Warning);
});
// Forward all app-level log messages (DEBUG_LOGF, LOGF, etc.) to the
// console tab so they are visible in the UI, not just in the log file.
util::Logger::instance().setCallback(
[this](const std::string& msg) {
// Classify by content: errors in red, warnings in warning color,
// everything else in the default info color.
ImU32 color = ui::ConsoleTab::COLOR_INFO;
// Classify by content into a severity channel: errors, warnings, else the App
// channel (the routine wallet log stream, controlled by the App messages filter).
ui::ConsoleChannel channel = ui::ConsoleChannel::App;
if (msg.find("[ERROR]") != std::string::npos ||
msg.find("error") != std::string::npos ||
msg.find("Error") != std::string::npos ||
msg.find("failed") != std::string::npos ||
msg.find("Failed") != std::string::npos) {
color = ui::ConsoleTab::COLOR_ERROR;
channel = ui::ConsoleChannel::Error;
} else if (msg.find("[WARN]") != std::string::npos ||
msg.find("warn") != std::string::npos) {
color = ui::material::Warning();
channel = ui::ConsoleChannel::Warning;
}
// Strip trailing newline so console tab lines look clean
// Strip trailing newline so console tab lines look clean. The App channel
// supplies the accent bar; no "[app] " text prefix needed.
std::string trimmed = msg;
while (!trimmed.empty() && (trimmed.back() == '\n' || trimmed.back() == '\r'))
trimmed.pop_back();
if (!trimmed.empty())
console_tab_.addLine("[app] " + trimmed, color);
console_tab_.addLine(trimmed, channel);
});
// Check for first-run wizard — also re-run if blockchain data is missing