v1.1.0: explorer tab, bootstrap fixes, full theme overlay merge

Explorer tab:
- New block explorer tab with search, chain stats, mempool info,
  recent blocks table, block detail modal with tx expansion
- Sidebar nav entry, i18n strings, ui.toml layout values

Bootstrap fixes:
- Move wizard Done handler into render() — was dead code, preventing
  startEmbeddedDaemon() and tryConnect() from firing post-wizard
- Stop deleting BDB database/ dir during cleanup — caused LSN mismatch
  that salvaged wallet.dat into wallet.{timestamp}.bak
- Add banlist.dat, db.log, .lock to cleanup file list
- Fatal extraction failure for blocks/ and chainstate/ files
- Verification progress: split SHA-256 (0-50%) and MD5 (50-100%)

Theme system:
- Expand overlay merge to apply ALL sections (tabs, dialogs, components,
  screens, flat sections), not just theme+backdrop+effects
- Add screens and security section parsing to UISchema
- Build-time theme expansion via expand_themes.py (CMake + build.sh)

Other:
- Version bump to 1.1.0
- WalletState::clear() resets all fields (sync, daemon info, etc.)
- Sidebar item-height 42 → 36
This commit is contained in:
2026-03-17 18:49:46 -05:00
parent 40dd6d45b2
commit 474250bb50
16 changed files with 1388 additions and 60 deletions

View File

@@ -17,6 +17,7 @@
#include "ui/windows/transactions_tab.h"
#include "ui/windows/mining_tab.h"
#include "ui/windows/peers_tab.h"
#include "ui/windows/explorer_tab.h"
#include "ui/windows/market_tab.h"
#include "ui/windows/settings_window.h"
#include "ui/windows/about_dialog.h"
@@ -705,6 +706,19 @@ void App::render()
return;
}
// Handle wizard completion — start daemon and connect
if (wizard_phase_ == WizardPhase::Done) {
wizard_phase_ = WizardPhase::None;
if (!state_.connected) {
if (isUsingEmbeddedDaemon() && !isEmbeddedDaemonRunning()) {
startEmbeddedDaemon();
}
tryConnect();
}
settings_->setWizardCompleted(true);
settings_->save();
}
// Process deferred encryption from wizard (runs in background)
processDeferredEncryption();
@@ -1069,6 +1083,9 @@ void App::render()
case ui::NavPage::Peers:
ui::RenderPeersTab(this);
break;
case ui::NavPage::Explorer:
ui::RenderExplorerTab(this);
break;
case ui::NavPage::Market:
ui::RenderMarketTab(this);
break;
@@ -1892,10 +1909,11 @@ void App::setCurrentTab(int tab) {
ui::NavPage::Receive, // 2 = Receive
ui::NavPage::History, // 3 = Transactions
ui::NavPage::Mining, // 4 = Mining
ui::NavPage::Peers, // 5 = Peers
ui::NavPage::Market, // 6 = Market
ui::NavPage::Console, // 7 = Console
ui::NavPage::Settings, // 8 = Settings
ui::NavPage::Peers, // 5 = Peers
ui::NavPage::Market, // 6 = Market
ui::NavPage::Console, // 7 = Console
ui::NavPage::Explorer, // 8 = Explorer
ui::NavPage::Settings, // 9 = Settings
};
if (tab >= 0 && tab < static_cast<int>(sizeof(kTabMap)/sizeof(kTabMap[0])))
current_page_ = kTabMap[tab];