Commit Graph
22 Commits
Author SHA1 Message Date
DanSandClaude Opus 4.8 a99f71a0cd fix(ux): land quick-win UX audit fixes across settings, exports, toasts, nav
Batch of safe, isolated fixes from the 10-surface UX audit:

- settings: Auto-shield / Save-z-transactions toggles now persist on change
  (they discarded CB()'s return and relied on a Save button that only renders
  on the About tab, so the choice was silently lost on relaunch).
- exports: show the resolved Platform::getConfigDir() instead of a hardcoded
  ~/.config path (wrong on Windows/macOS) in both the all-keys and CSV
  dialogs; all-keys also reveals the file path on a partial export.
- notifications: error/warning toasts last 9s/7s (were 4s/3.5s) so failures
  are readable.
- qr popup / tx-details: copy-to-clipboard now confirms with a toast.
- about: Escape-to-close + readable heading contrast via OnSurfaceMedium().
- sidebar: suppress single-key nav (J/K/arrows/[) while an overlay dialog or
  ImGui popup is open, so it no longer switches the tab behind a modal.
- i18n: strip the stale hardcoded path out of file_save_location in i18n.cpp
  and all eight res/lang/*.json locales (additive, one key each).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-10-17 16:27:58 -05:00
DanSandClaude Opus 4.8 95605dd7e9 fix(ui): stop global shortcuts auto-repeating; skip invalid skins
The global keyboard shortcuts tested keys without disabling key-repeat,
so holding one down fired it every frame: the theme cycle, balance and
market layout cycles, the effects and background toggles, the settings
and sidebar-collapse keys all re-triggered on a held key. Cycling themes
also stepped onto skins that had failed to load and wrote the broken
pick into settings.

- Every one-shot shortcut now checks for a fresh key press only, so a
  held key fires once.
- Theme cycling skips over invalid skins and only applies, persists, and
  shows the toast when a skin actually loads; if none can load, settings
  are left untouched and no toast appears.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-10-13 17:42:29 -05:00
DanSandClaude Opus 4.8 a60a2f8e39 fix(ui): stop sidebar badges from displacing button text
The Chat/History nav buttons centered their icon+label in a region that
shrank when a badge (unread count / mining dot) was present, and the
"has badge" test read the LIVE count — so the text jumped sideways the
moment a count toggled (e.g. a new chat message arrived). Reserve badge
clearance by whether the page CAN show a badge (constant per item), center
in the full button width regardless, and cap the label with symmetric
clearance so a long label still can't run under the corner badge.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-09-01 22:54:36 -05:00
DanSandClaude Opus 4.8 d27f387d6d feat(ui): in-app FAQ, DPI-scaling audit fixes, mining/stratum polish + localize strings
Bundles the session's UI work (the touched files carry several of these
changes together, so they are committed as one coherent UI batch):

- FAQ: new RenderFaqDialog + data-driven faq_content, opened from a
  status-bar "?" (and the Windows title bar), styled like the Wallets
  modal with search, Wallet/Daemon tabs, and smooth scroll.
- DPI/font-scale audit: multiply hand-drawn absolute geometry by
  Layout::dpiScale() across ~30 files so nothing renders native-size at
  HiDPI / font_scale 1.5 (verified with a full sweep at 1.5x).
- Mining: chart now fills the horizontal space; thread stepper +/- buttons
  match the input-box height; move the stratum-host toggle into
  Node & Security (v1.3.0+).
- Settings: fix the auto-shield status text overlapping the grid.
- Sidebar: drop the peer-count badge on the Network button.
- i18n: wrap 193 hardcoded literals with TR() (keys/translations added in
  the preceding i18n commit), so the security/PIN/lock flow, seed-backup
  wizard, and witness-rebuild dialog localize.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-09-01 19:37:16 -05:00
DanSandClaude Opus 4.8 d0bd55b9c1 feat(ui): settings polish — button retune, daemon card, RPC 2-row, chat preview
Settings tabs brought closer to the approved mockup:
- ActionButton/renderCardButton retune (settings-scoped): 7px radius, 9px
  padX, Primary → accent-outline chip, Secondary/card buttons more defined.
- Daemon-binary card: compact status right-aligned on the DAEMON BINARY
  heading (Up to date / Version differs / Not installed), filled/rounded
  status box, neutral danger divider (was alarming red), roomier spacing.
- RPC Connection: two-row column-aligned layout (Host | Port, then
  Username | Password) so the password no longer clips off the card edge.
- Chat settings tab: live conversation preview below the Appearance /
  Messaging cards; "Focus input on open" checkbox reflowed onto the console
  color-toggle row.
- Debug Options: "Current theme only" toggle restricts either screenshot
  sweep to the active theme instead of cycling every skin.
- Tabs fill the full content width (content-max-width cap disabled) and the
  sidebar nav panel centers within the true visible area.
- i18n: new keys for the above (untranslated keys fall back to English).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-08-20 16:59:03 -05:00
DanSandClaude Opus 4.8 a598217975 fix(ui): cut-off/clipping — recent-tx collisions, updater note wrap, request-payment URI, console filter, icon-grid scroll
Fixes the cut-off/clipping bugs from the layout audit (all visible at the default
1280/1024 window sizes):

- Receive "Recent Received" rows: the amount collided with the relative-time
  ("+15.7500 DRGX14 days ago") and the type label touched the address at narrow
  widths. Use the shared short time format (formatTimeAgoShort, matching Overview),
  chain the amount's right edge off the measured time width, and start the address
  after the measured type-label width — so neither pair can collide.
- Daemon & xmrig updater verify-note: drawn unwrapped and clipped at the card's right
  edge; wrap it (PushTextWrapPos) within the already-reserved height.
- Request Payment: the three footer buttons shared one fixed width (clipping "Copy
  Full Address"); size each to its own label. The Payment URI overflowed a plain
  field; render it in a bordered read-only box (bounded, un-chunked).
- Console: the filter input shrank below its own placeholder (gone entirely at 1024);
  give it a min width >= the placeholder and drop the "N lines" count when the row
  can't fit both.
- Address-label "Choose Icon" grid: had NoScrollbar hiding most of the catalog with
  no cue; give it a real scrollbar.
- Overview "Recent Transactions": drop the 4th row at 1024 (it clipped off-screen) by
  capping to rows that fully fit the reserved height.
- Sidebar: reserve the unread-badge width in the nav-label centering so History/Chat
  labels no longer collide with their badge.

Verified at 1024 and 1280 across full-node + Lite + Windows (ctest green) and an
adversarial diff review (clean). Skipped the legacy settings_window overlay footer
(dead code / removal candidate).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-08-19 10:11:55 -05:00
DanSandClaude Opus 4.8 e24ca015d1 feat(ui): implement UI/UX audit — i18n, HiDPI, theme, destructive-action & overflow fixes
Implements all 26 confirmed UI/UX audit findings plus the 4 dashboard/timeline
tile labels. Verified across full-node + Lite + Windows builds (ctest green) and
an adversarial diff review (one market-tab delete regression caught + fixed).

i18n coverage:
- Balance hero/quick-actions/toasts + dashboard & timeline tiles (Total Balance,
  Shielded, Transparent, Quick Send, Quick Receive, Click to open, Market)
- Send: Review Send / Cancel / Paste / view-only tooltip / memo byte counter
- Settings: Lite lifecycle errors, plaintext-RPC security warning, 8 toasts
- Mining pool-payout tooltip
- Resolve daemon_update_title double-assignment collision (new daemon_update_prompt_title)
- 23 new keys translated into all 8 locales; CJK subset font rebuilt

HiDPI: DPI-scale the Send amount bar, mining thread-tile clamp bounds, receive
loading skeleton, and sidebar notification-badge insets.

Light theme: theme-aware material::SurfaceOverlay() for balance bar tracks and
row-hover highlights; contacts active-pill foreground uses OnPrimary().

Destructive actions: arm/confirm for portfolio-group delete, saved pool/worker
remove, and avatar-image delete.

Interaction/overflow: route balance star/eye buttons and the console fold-toggle
through popup-safe guards; clip peer addr/subver; truncate the balance custom
label; measure Settings tool-button widths; mining stepper disabled-state
feedback; +/- stepper buttons restyled to match the thread tiles.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-08-18 17:54:15 -05:00
DanSandClaude Opus 4.8 100ed01469 feat(chat): unread count + sidebar badge (Q1)
Track a per-conversation "last seen" watermark (message timestamp) on App:
- chatUnreadCount() sums incoming messages newer than each conversation's
  watermark; surfaced as SidebarStatus.chatUnreadCount → a badge on the Chat nav
  item (mirrors the History/Peers badges).
- Viewing a thread marks it seen (markChatConversationSeen while displayed).
- Baseline on load: existing stored messages are marked seen, so only messages
  that arrive while the app is open badge as unread.
- Wiped in resetChatSession so unread state never leaks across a wallet switch.
In-memory only (resets on app restart); persistence is a later refinement.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-16 15:56:58 -05:00
DanSandClaude Opus 4.8 980a100edd feat(chat): read-only Chat sidebar tab (Phase 3)
Add the first user-visible HushChat surface: a Chat tab in the sidebar with a
two-pane, read-only conversation view — a conversation list on the left and the
selected thread on the right — reading from the App-owned ChatService store.

- New src/ui/windows/chat_tab.{h,cpp} (RenderChatTab(App*), mirroring the
  Contacts tab). Conversations are sorted by most-recent activity; peer
  z-addresses resolve to contact names via the address book when known; each
  message shows sender + timestamp + wrapped body, with a contact-request tag
  and a read-only footer (composing arrives in a later phase). Empty states
  cover "wallet locked / identity not ready" and "no conversations yet".
- Sidebar wiring: NavPage::Chat + registry entry (static_assert stays balanced),
  NavPageSurface + GetNavIconMD (ICON_MD_CHAT), dispatch in app.cpp, trace/sweep
  page names, and App::chatService() accessor. The tab is gated on the new
  WalletUiSurface::Chat, which returns DRAGONX_ENABLE_CHAT != 0 — so it only
  appears in chat-enabled builds and is hidden (and unreachable) by default.
- i18n: English defaults for the chat nav label + hint strings.

Verified: Linux + Windows(mingw) build with chat ON, ctest 100%, hygiene clean;
caches restored to the OFF default. The screenshot sweep now includes the Chat
tab (sweepPageName "chat") for per-theme visual review.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-06 15:05:40 -05:00
DanSandClaude Opus 4.8 ee59a9e2cd feat(ui): promote the address book to a Contacts sidebar tab
Phase 0b. The address book was buried in Settings behind a modal dialog.
Make it a first-class "Contacts" tab (which will also become the chat
roster), rendered inline in the main content area.

- New NavPage::Contacts (after History; ICON_MD_CONTACTS) +
  WalletUiSurface::Contacts. isUiSurfaceAvailable's `default: return true`
  shows it in BOTH variants; uiSurfaceNeedsWalletData's default keeps it
  usable before wallet data loads. All the touchpoints wired: NavPageSurface,
  GetNavIconMD, the app.cpp dispatch case, the app_network.cpp tracePageName
  case, and the `contacts` i18n label.
- New src/ui/windows/contacts_tab.{h,cpp}: RenderContactsTab lifts the
  toolbar + table + add/edit modal out of address_book_dialog, rendered in a
  BeginChild scroll region (peers_tab pattern) instead of an overlay; the
  add/edit form stays a modal layered over the tab. Reuses the existing
  address_book_* i18n keys and the dialogs.address-book schema.
- Delete address_book_dialog.{h,cpp}; remove its app.cpp render pump and the
  dead App::show_address_book_. The Settings "Address Book…" button now
  navigates to the tab (setCurrentPage) instead of opening the modal, so the
  Tools & Actions grid layout is untouched.
- CMake: swap the dialog sources for contacts_tab.

Behavior-preserving move; search/sort/keyboard/contrast land in 0d. Visual
check pending the per-theme screenshot sweep.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-05 16:59:34 -05:00
DanSandClaude Opus 4.8 2e8e214689 refactor(ui): app-wide compact, translucent tooltips
Add material::Tooltip / BeginTooltip / EndTooltip wrappers (tooltip_style.h)
that scope a small window padding (8x4, dpi-scaled) and ~85% opacity to
tooltips only, then route the tooltip call sites through them. Menus and combo
dropdowns are untouched (they keep the global opaque PopupBg).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-27 21:26:52 -05:00
DanSandClaude Opus 4.8 85a1080b52 feat(lite): Console tab with connection + open/create diagnostics
The lite variant had no visibility into why a wallet failed to open — just a
"disconnected" spinner. Add a lite-only Console tab (full-node keeps its RPC
console) that shows a live diagnostic log.

- LiteDiagnostics: a small thread-safe, bounded ring buffer (header-only). The
  controller writes to it from its background threads: each failover server
  attempt and result, wallet open/create/restore outcomes, sync start, and
  blocked-open reasons. The App logs controller (re)builds with the preferred
  server.
- lite_console_tab: a terminal-styled, read-only view of the log (newest at the
  bottom, error/success lines coloured) with Clear / Copy / Auto-scroll. Reachable
  even when the wallet is locked (it's diagnostics, no secrets). Registered as
  NavPage::LiteConsole, gated lite-only via WalletUiSurface::LiteConsole.

A unit test drives an open-with-failover and asserts the log records the
connection attempt and the successful open. Built clean for full-node, lite, and
Windows cross-compile.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-07 18:46:25 -05:00
DanSandClaude Opus 4.8 732d892d4d feat(lite): ObsidianDragonLite Network tab — server browser
A lite-wallet-only "Network" tab (full-node keeps the Peers tab; exactly one shows per variant)
to manage lightwalletd servers, replacing the basic selector that was in Settings.

- Card list of servers with per-server latency + status dot, DNS host + resolved IP, and an
  Official/Custom pill. Official DragonX servers get a glowing outline.
- Pick a server (Sticky) by clicking its card, or toggle "use a random server" (Random mode);
  selection applies immediately (App::rebuildLiteWallet(force=true) tears down + rebuilds the
  controller against the new server and resyncs — its dtor detaches the uninterruptible sync
  thread, so this doesn't block).
- Add custom servers; hide/unhide servers (persisted set, revealed by a "Show hidden" toggle).
- Latency/IP come from a new background probe (util/LiteServerProbe): libcurl CONNECT_ONLY does
  the TCP+TLS handshake (works for gRPC lightwalletd, no HTTP response needed), recording
  APPCONNECT_TIME as latency and CURLINFO_PRIMARY_IP. Auto-runs on tab open + a Refresh button.

Wiring: WalletUiSurface::LiteNetwork (gated !fullNodePagesAvailable) + NavPage::LiteNetwork in
the sidebar + app.cpp dispatch; settings gains a hidden-servers set; isOfficialLiteServer() added
to lite_connection_service. The Settings page lite-server selector + its plumbing are removed
(single source of truth = the tab).

Reuses the existing server model (LiteServerPreference, Sticky/Random, selectLiteServer) and UI
primitives (DrawGlassPanel, ThemeEffects glow, peers-tab ping-dot idiom). Unit-tested
(liteServerHost, isOfficialLiteServer) + an env-gated live probe (verified vs lite.dragonx.is:
online, latency, IP). Both variants + lite-backend build; suite passes; hygiene clean; GUI
smoke-launched without crash.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-07 11:09:27 -05:00
DanSandClaude Opus 4.8 863d015628 feat(lite): lite wallet foundation (inherited working-tree state)
Preserve the previously-uncommitted lite wallet implementation and related dev WIP
under version control:
- src/wallet/ lite services: client bridge, bridge runtime, connection, lifecycle,
  sync, gateway, result parsers, state mapper, artifact contract/resolver, refresh
  services, UI adapters, wallet_backend/capabilities. (Includes two small M1 fixes:
  lifecycle walletReady now parses the response; default chain name -> "main".)
- src/chat/ chat protocol; tests/fixtures/ (lite + hushchat); tools/hushchat_fixture_check.cpp;
  scripts/build-lite-backend-artifact.sh.
- Pre-existing modified app_network/security/wizard, network_refresh_service, sidebar,
  mining_tab, bootstrap dialog, and version headers captured as-is.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-04 21:15:28 -05:00
DanS e95ad50e41 feat(lite): add ObsidianDragonLite build mode and gate full-node features
Add --lite build flow and ObsidianDragonLite target naming, hide full-node pages/features in lite mode, enforce pool-only mining in lite, and include chat port feasibility audit documentation.
2026-05-06 03:42:05 -05:00
DanS aa26ab5fbd fix: sidebar nav text overflow for long translations
- Add text scaling for section labels (TOOLS, ADVANCED) in sidebar
- Separate explorer_section key from explorer nav label to fix ALL CAPS
- Shorten long sidebar translations: es/pt settings, pt overview, ru tools/advanced
- Fix explorer translations from ALL CAPS to proper case in all languages
2026-04-12 18:45:48 -05:00
DanS dbe6546f9f refactor: rewrite sidebar layout with two-pass architecture
Replace fragile Dummy()-based cursor flow with a deterministic two-pass
layout system:
- Pass 1: compute exact Y positions for all elements (pure math)
- Pass 2: render at computed positions using SetCursorScreenPos + draw list

Eliminates the dual-coordinate mismatch that caused persistent centering
and overflow bugs. Height is computed once, not estimated then measured.

Also tune sidebar spacing via ui.toml:
- button-spacing: 4 → 6
- section-gap: 4 → 8
- Add section-label-pad-bottom (4px) below category labels
- bottom-padding: 0 → 4
2026-04-12 16:34:31 -05:00
DanS ddca8b2e43 v1.2.0: UX audit — security fixes, accessibility, and polish
Security (P0):
- Fix sidebar remaining interactive behind lock screen
- Extend auto-lock idle detection to include active widget interactions
- Distinguish missing PIN vault from wrong PIN; auto-switch to passphrase

Blocking UX (P1):
- Add 15s timeout for encryption state check to prevent indefinite loading
- Show restart reason in loading overlay after wallet encryption
- Add Force Quit button on shutdown screen after 10s
- Warn user if embedded daemon fails to start during wizard completion

Polish (P2):
- Use configured explorer URL in Receive tab instead of hardcoded URL
- Increase request memo buffer from 256 to 512 bytes to match Send tab
- Extend notification duration to 5s for critical operations (tx sent,
  wallet encrypted, key import, backup, export)
- Add Reduce Motion accessibility setting (disables page fade + balance lerp)
- Show estimated remaining time during mining thread benchmark
- Add staleness indicator to market price data (warning after 5 min)

New i18n keys: incorrect_pin, incorrect_passphrase, pin_not_set,
restarting_after_encryption, force_quit, reduce_motion, tt_reduce_motion,
ago, wizard_daemon_start_failed
2026-04-04 19:10:58 -05:00
DanS 474250bb50 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
2026-03-17 18:49:46 -05:00
DanS 2c5a658ea5 feat: Full UI internationalization, pool hashrate stats, and layout caching
- Replace all hardcoded English strings with TR() translation keys across
  every tab, dialog, and component (~20 UI files)
- Expand all 8 language files (de, es, fr, ja, ko, pt, ru, zh) with
  complete translations (~37k lines added)
- Improve i18n loader with exe-relative path fallback and English base
  fallback for missing keys
- Add pool-side hashrate polling via pool stats API in xmrig_manager
- Introduce Layout::beginFrame() per-frame caching and refresh balance
  layout config only on schema generation change
- Offload daemon output parsing to worker thread
- Add CJK subset fallback font for Chinese/Japanese/Korean glyphs
2026-03-11 00:40:50 -05:00
DanS f5378a55ed UX improvements 2026-02-28 00:58:43 -06:00
DanS 3aee55b49c ObsidianDragon - DragonX ImGui Wallet
Full-node GUI wallet for DragonX cryptocurrency.
Built with Dear ImGui, SDL3, and OpenGL3/DX11.

Features:
- Send/receive shielded and transparent transactions
- Autoshield with merged transaction display
- Built-in CPU mining (xmrig)
- Peer management and network monitoring
- Wallet encryption with PIN lock
- QR code generation for receive addresses
- Transaction history with pagination
- Console for direct RPC commands
- Cross-platform (Linux, Windows)
2026-02-27 00:26:01 -06:00