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:
dan_s
2026-03-17 18:49:46 -05:00
parent 4a841fd032
commit 9e94952e0a
16 changed files with 1388 additions and 60 deletions

View File

@@ -75,12 +75,18 @@ bool UISchema::loadFromFile(const std::string& path) {
parseSections(static_cast<const void*>(components), "components");
}
// Parse screens as a 3-level section (screens.loading, screens.first-run, etc.)
if (auto* screens = root["screens"].as_table()) {
parseSections(static_cast<const void*>(screens), "screens");
}
// Parse flat sections (2-level: sectionName.elementName → {style object})
for (const auto& flatSection : {"business", "animations", "console",
"backdrop", "shutdown", "notifications", "status-bar",
"qr-code", "content-area", "style", "responsive",
"spacing", "spacing-tokens", "button", "input", "fonts",
"inline-dialogs", "sidebar", "panels", "typography", "effects"}) {
"inline-dialogs", "sidebar", "panels", "typography",
"effects", "security"}) {
if (auto* sec = root[flatSection].as_table()) {
parseFlatSection(static_cast<const void*>(sec), flatSection);
}
@@ -157,12 +163,18 @@ bool UISchema::loadFromString(const std::string& tomlStr, const std::string& lab
parseSections(static_cast<const void*>(components), "components");
}
// Parse screens as a 3-level section (screens.loading, screens.first-run, etc.)
if (auto* screens = root["screens"].as_table()) {
parseSections(static_cast<const void*>(screens), "screens");
}
// Parse flat sections (2-level: sectionName.elementName → {style object})
for (const auto& flatSection : {"business", "animations", "console",
"backdrop", "shutdown", "notifications", "status-bar",
"qr-code", "content-area", "style", "responsive",
"spacing", "spacing-tokens", "button", "input", "fonts",
"inline-dialogs", "sidebar", "panels", "typography", "effects"}) {
"inline-dialogs", "sidebar", "panels", "typography",
"effects", "security"}) {
if (auto* sec = root[flatSection].as_table()) {
parseFlatSection(static_cast<const void*>(sec), flatSection);
}
@@ -183,7 +195,7 @@ bool UISchema::loadFromString(const std::string& tomlStr, const std::string& lab
}
// ============================================================================
// Overlay merge (visual-only: theme + backdrop)
// Overlay merge — all sections (theme + layout + effects)
// ============================================================================
bool UISchema::mergeOverlayFromFile(const std::string& path) {
@@ -211,14 +223,40 @@ bool UISchema::mergeOverlayFromFile(const std::string& path) {
parseTheme(static_cast<const void*>(theme));
}
// Merge backdrop section (gradient colors, alpha/transparency values)
if (auto* sec = root["backdrop"].as_table()) {
parseFlatSection(static_cast<const void*>(sec), "backdrop");
// Merge breakpoints + globals
if (auto* bp = root["breakpoints"].as_table()) {
parseBreakpoints(static_cast<const void*>(bp));
}
if (auto* globals = root["globals"].as_table()) {
parseGlobals(static_cast<const void*>(globals));
}
// Merge effects section (theme visual effects configuration)
if (auto* sec = root["effects"].as_table()) {
parseFlatSection(static_cast<const void*>(sec), "effects");
// Merge tabs, dialogs, components (3-level sections)
if (auto* tabs = root["tabs"].as_table()) {
parseSections(static_cast<const void*>(tabs), "tabs");
}
if (auto* dialogs = root["dialogs"].as_table()) {
parseSections(static_cast<const void*>(dialogs), "dialogs");
}
if (auto* components = root["components"].as_table()) {
parseSections(static_cast<const void*>(components), "components");
}
// Merge screens (3-level section)
if (auto* screens = root["screens"].as_table()) {
parseSections(static_cast<const void*>(screens), "screens");
}
// Merge all flat sections (2-level)
for (const auto& flatSection : {"business", "animations", "console",
"backdrop", "shutdown", "notifications", "status-bar",
"qr-code", "content-area", "style", "responsive",
"spacing", "spacing-tokens", "button", "input", "fonts",
"inline-dialogs", "sidebar", "panels", "typography",
"effects", "security"}) {
if (auto* sec = root[flatSection].as_table()) {
parseFlatSection(static_cast<const void*>(sec), flatSection);
}
}
overlayPath_ = path;