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:
122
scripts/expand_themes.py
Normal file
122
scripts/expand_themes.py
Normal file
@@ -0,0 +1,122 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Build-time theme expander — merges layout sections from ui.toml into skin files.
|
||||
|
||||
Called by CMake during build. Reads source skin files + ui.toml, writes merged
|
||||
output files to the build directory. Source files are never modified.
|
||||
|
||||
Usage:
|
||||
python3 expand_themes.py <source_themes_dir> <output_themes_dir>
|
||||
|
||||
For each .toml file in source_themes_dir (except ui.toml), the script:
|
||||
1. Copies the skin file contents (theme/palette/backdrop/effects)
|
||||
2. Appends all layout sections from ui.toml (fonts, tabs, components, etc.)
|
||||
3. Writes the merged result to output_themes_dir/<filename>
|
||||
|
||||
ui.toml itself is copied unchanged.
|
||||
"""
|
||||
|
||||
import re
|
||||
import sys
|
||||
import os
|
||||
|
||||
# Sections to SKIP when extracting from ui.toml (theme-specific, already in skins)
|
||||
SKIP_SECTIONS = {"theme", "theme.palette", "backdrop", "effects"}
|
||||
|
||||
|
||||
def extract_layout_sections(ui_toml_path):
|
||||
"""Extract non-theme sections from ui.toml as a string."""
|
||||
sections = []
|
||||
current_section = None
|
||||
current_lines = []
|
||||
section_re = re.compile(r'^\[{1,2}([^\]]+)\]{1,2}\s*$')
|
||||
|
||||
with open(ui_toml_path, 'r') as f:
|
||||
for line in f:
|
||||
m = section_re.match(line.strip())
|
||||
if m:
|
||||
if current_section is not None or current_lines:
|
||||
sections.append((current_section, current_lines))
|
||||
current_section = m.group(1).strip()
|
||||
current_lines = [line]
|
||||
else:
|
||||
current_lines.append(line)
|
||||
if current_section is not None or current_lines:
|
||||
sections.append((current_section, current_lines))
|
||||
|
||||
layout_parts = []
|
||||
for section_name, lines in sections:
|
||||
if section_name is None:
|
||||
# Preamble: only include top-level key=value lines
|
||||
kv_lines = [l for l in lines
|
||||
if l.strip() and not l.strip().startswith('#') and '=' in l]
|
||||
if kv_lines:
|
||||
layout_parts.append(''.join(kv_lines))
|
||||
continue
|
||||
if section_name in SKIP_SECTIONS:
|
||||
continue
|
||||
layout_parts.append(''.join(lines))
|
||||
|
||||
return '\n'.join(layout_parts)
|
||||
|
||||
|
||||
def main():
|
||||
if len(sys.argv) != 3:
|
||||
print(f"Usage: {sys.argv[0]} <source_themes_dir> <output_themes_dir>")
|
||||
sys.exit(1)
|
||||
|
||||
src_dir = sys.argv[1]
|
||||
out_dir = sys.argv[2]
|
||||
ui_toml = os.path.join(src_dir, "ui.toml")
|
||||
|
||||
if not os.path.exists(ui_toml):
|
||||
print(f"ERROR: ui.toml not found at {ui_toml}")
|
||||
sys.exit(1)
|
||||
|
||||
os.makedirs(out_dir, exist_ok=True)
|
||||
|
||||
layout_content = extract_layout_sections(ui_toml)
|
||||
|
||||
separator = (
|
||||
"\n# ===========================================================================\n"
|
||||
"# Layout & Component Properties\n"
|
||||
"# All values below can be customized per-theme. Edit and save to see\n"
|
||||
"# changes reflected in the app in real time via hot-reload.\n"
|
||||
"# ===========================================================================\n\n"
|
||||
)
|
||||
|
||||
for fname in sorted(os.listdir(src_dir)):
|
||||
if not fname.endswith('.toml'):
|
||||
continue
|
||||
src_path = os.path.join(src_dir, fname)
|
||||
dst_path = os.path.join(out_dir, fname)
|
||||
|
||||
if fname == "ui.toml":
|
||||
# Copy ui.toml unchanged
|
||||
with open(src_path, 'r') as f:
|
||||
content = f.read()
|
||||
with open(dst_path, 'w') as f:
|
||||
f.write(content)
|
||||
print(f" COPY {fname}")
|
||||
continue
|
||||
|
||||
# Skin file — append layout sections
|
||||
with open(src_path, 'r') as f:
|
||||
skin = f.read()
|
||||
if not skin.endswith('\n'):
|
||||
skin += '\n'
|
||||
|
||||
merged = skin + separator + layout_content
|
||||
if not merged.endswith('\n'):
|
||||
merged += '\n'
|
||||
|
||||
with open(dst_path, 'w') as f:
|
||||
f.write(merged)
|
||||
lines = merged.count('\n')
|
||||
print(f" MERGE {fname} → {lines} lines")
|
||||
|
||||
print("Done.")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user