Commit Graph

19 Commits

Author SHA1 Message Date
davide 96b6a7e291 feat(ui): Help overlay with Info/Donate tabs, fixed dimensions
Help button now shows a fixed-size two-tab overlay:

Info tab: app name + version, one-line description, thin separator,
  © 2026 Davide Grilli — MIT License, Built with .NET 10 · Avalonia 12 · NBitcoin.

Donate tab: dev address (plm1qdq3…) read-only display, free amount
  input, prepare-preview row, confirm-and-broadcast button.

Overlay dimensions are stable across tabs and between desktop/mobile:
- TabControl Height=320 (fixed, never resizes on tab switch)
- HorizontalAlignment=Stretch + MaxWidth=440 on the card (always fills
  available width; previously Center caused the card to shrink to content
  width, which differed between Info and Donate)
- Each tab content wrapped in ScrollViewer for safe overflow handling

New MainWindowViewModel.Donate.cs: PrepareDonate / ConfirmDonate /
ResetDonate (called on overlay close). Six-language Loc keys added for
all donate strings.
2026-06-17 09:01:06 +02:00
davide b13b66160c feat(ui): donate tab in Help overlay
Help button now shows a two-tab overlay:
- Info: existing about/version content
- Donate: donate flow to the dev address (plm1qdq3…) with free amount
  input, prepare preview, and confirm-and-broadcast button

New MainWindowViewModel.Donate.cs partial: DonateAmount / DonatePreview
/ HasPendingDonate observable properties, PrepareDonateCommand (builds
the tx with hardcoded dev address via the existing TransactionFactory),
ConfirmDonateCommand (broadcasts and syncs). Donate state is reset on
overlay close. Six-language Loc keys added (help.tab.info/donate,
donate.desc/dev.address/amount/prepare/confirm).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-17 08:40:02 +02:00
davide 9744619eb4 fix(ui): mobile tab bar — uniform sizing, indicator overlap, spacing
- UniformGrid Columns="5" on TabStrip so all 5 tabs always stay on one
  row on Android (Rows="1" alone did not auto-calculate columns at
  measure time on the Android Avalonia renderer)
- Contacts tab header was using hardcoded FontSize=13/Width=24/Spacing=4
  instead of the TabFontSize/TabIconSize/TabSpacing ViewModel bindings,
  making it visually larger than the other four tabs on mobile
- ContentPresenter Margin="0,0,0,4" in Controls.axaml pushes the tab
  header content above the 2 px selection indicator, which is drawn at
  the absolute bottom of the template Panel and was overlapping the label
- TabItem horizontal padding 4→8 px and TabSpacing 2→4 for both
  desktop and mobile to give more breathing room between tab items
2026-06-17 08:17:56 +02:00
davide 5d2d0ad312 feat(ui): two-column desktop layout for Send/Receive, fixed window size
Send tab: Recipient and Amount cards side-by-side on desktop using a
two-column Grid, making full use of the available window width.
Summary card and action buttons remain full-width below both columns.
Mobile retains the original vertical stack.

Receive tab: QR card on the left (auto-width), address card expands
to fill the right column on desktop — standard fintech wallet pattern.
Mobile retains QR above, address below.

Window enlarged to 1020×680 (from 900×620) and fixed with CanResize=False;
Min/Max dimensions match so the resize handle never appears.
2026-06-16 15:04:10 +02:00
davide 3d5a226a5a docs: translate all code comments to English (language policy)
Translate every Italian /// XML doc comment, <!-- --> XAML comment, and
// inline comment to English across all source files (Core, App, tests).
Add the language policy to CLAUDE.md (conversation Italian; all code
and docs English). Update one test assertion that checked an Italian
exception message that was also translated.
2026-06-16 14:40:11 +02:00
davide 4b82a0852c feat(ui): restructure transaction details + clearer coinbase identification
Transaction details overlay redesigned from a flat 12-row grid into a
scannable layout: a header with the net amount in focus plus SPV/status
badges, then three labeled cards (Overview, Amounts & fees, Technical
details), with inputs/outputs as carded rows. Adds a .section heading
style and tx.sect.* localization keys (6 languages).

Coinbase transactions are now explicitly identified: an amber "Coinbase"
badge in the header, and the misleading "From: —" / "coinbase —" replaced
with "Newly generated (mining)" (localized). Exposes IsCoinbase on the
details view model; no consensus/logic change, presentation only.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-16 10:21:50 +02:00
davide 41eb1bb788 feat(ui): centralized design system — blue/green tokens, gradient hero, SVG tab icons
Replace raw Fluent defaults + inline hex with a semantic design system,
themed for both light/dark (follows system variant).

- Styles/Theme.axaml: semantic brushes (surface/text/border/status) per
  variant via ThemeDictionaries; override Fluent SystemAccentColor to brand
  blue (#2563EB) and ControlCornerRadius=8; blue->indigo balance gradient.
- Styles/Controls.axaml: reusable classes (card, balance-hero, chip, ghost),
  type scale (amount with tabular figures, mono, h1, label), button/input
  polish, tab selected-in-blue, list hover/selected tints, card hover-lift.
- MainView: balance shown as gradient hero card; dashboard tabs use Material
  SVG Path icons (Fill tracks TabItem selection) instead of Unicode glyphs;
  all hardcoded colors (LimeGreen/IndianRed/Orange/Gray/#99000000) and
  generic Fluent surface brushes mapped to semantic tokens; app background,
  stronger modal scrim, status bar top border.

Palette derived from the logo (blue=trust, green=money). Build clean, app
starts with no binding errors.
2026-06-16 10:08:39 +02:00
davide 14ae39c5aa feat(ui): wallet name field in creation wizard
The last wizard step (password) now shows an optional name field.
The name becomes the filename: <name>.wallet.json in the wallets
directory. Invalid filename characters are replaced with '_'.

If left empty, the existing auto-name logic applies (default.wallet.json,
wallet-2.wallet.json, …). If the chosen name already exists the wizard
shows an error instead of overwriting.

The name field is visually separated from the encryption section by a
distinct background panel and a horizontal divider.
2026-06-15 15:05:53 +02:00
davide 4dc37f1b42 feat(ui): wizard flows for xpub/xprv and WIF import
Add two new import paths to the setup wizard:

- "Importa xpub / xprv": accepts any SLIP-132 key (xpub/ypub/zpub or
  xprv/yprv/zprv), auto-detects script type from the version prefix,
  and saves a watch-only or fully-spendable HD account accordingly.

- "Importa chiave WIF": accepts one or more WIF private keys (one per
  line), goes through script-type selection, and saves an ImportedKeyAccount.

WizardFlowKind enum (New, Restore, ImportXkey, ImportWif) governs which
steps are shown; WizardBack() updated for all four flows. OpenLoaded()
updated to accept IWalletAccount and display wallet kind tags
(watch-only / imported) in the network info line.

Localization keys added for all six languages (it/en/es/fr/pt/de).
ViewModel._account changed from HdAccount? to IWalletAccount?.
2026-06-15 14:23:08 +02:00
davide 002c854497 feat(wallet): add P2PKH, P2SH-P2WPKH, and P2TR (Taproot/BIP86) address types
- ScriptKind.Taproot (BIP86, purpose 86', P2WPKH → witness v1 bech32m plm1p)
  derivation wired in DerivationPaths and ChainProfiles (xprv/xpub headers,
  no SLIP-132 standard for P2TR); NBitcoin ScriptPubKeyType.TaprootBIP86
- Wizard step StepScriptType inserted between passphrase and password: 4 radio
  buttons (Legacy / Wrapped SegWit / Native SegWit★ / Taproot), localized in
  6 languages; CreateOrRestore now uses SelectedScriptKind instead of hardcoded
  NativeSegwit; back navigation updated accordingly
- BIP86 golden-vector tests (Bip86TaprootTests): output key verified against
  official Bitcoin BIP86 addresses, plm1p prefix asserted
2026-06-15 12:03:52 +02:00
davide 8b960458ee feat(ui): server overlay full-screen on mobile, larger touch targets
On mobile the server settings panel now fills the entire screen
(no MaxWidth/MaxHeight/Margin constraints, no rounded corners) using
a desktop-only Border.desktop-overlay style so inline values never
fight the style system. Input font sizes increased (11→13/15px),
known-server list taller (200→300px) and server hostname larger (13→15px).
Desktop layout unchanged.
2026-06-15 10:59:12 +02:00
davide 1b784a6c73 fix(ui): prevent text overflow on mobile
UnconfirmedText (pending/unconfirmed balance) now wraps instead of
clipping horizontally. Contact name in mobile list gets CharacterEllipsis
trimming for arbitrarily long user-defined names.
2026-06-15 10:58:42 +02:00
davide 200c12651b feat(ui): hardcode mainnet, remove network selector
Drop the mainnet/testnet/regtest ComboBox from the wizard and fix
Net to always return NetKind.Mainnet. Core profiles and CLI --net
flag are untouched; the wallet file still records the network name.
2026-06-15 10:35:40 +02:00
davide 5f983ca84e feat(ui): replace emoji camera button with vector path icon
Uses a Material Design outline camera path (body + lens) inside a Viewbox
so the icon scales cleanly and inherits the theme foreground color.
2026-06-15 10:25:46 +02:00
davide 53ecd701c0 feat(ui): unified tab bar with icons on desktop and mobile
Replace the mobile-only custom bottom Grid nav bar with a single styled
TabStrip that works the same on both platforms: icon + label headers,
gray background, UniformGrid for equal-width columns.
Also adds the 📷 scan button in the Send address field (visible on mobile,
triggers ScanQrCommand wired in the previous commit).
2026-06-15 10:19:41 +02:00
davide 1914d9462b feat(ui): replace mobile tab strip with custom full-width nav bar
Avalonia's TabStrip ignores HorizontalAlignment overrides when placed at
Bottom, causing the items to cluster left. Replace it with a dedicated
Grid (ColumnDefinitions="*,*,*,*,*") that guarantees 5 equal columns
across the full width. The built-in TabStrip is hidden on mobile; buttons
in the custom bar call SelectTabCommand to drive SelectedTabIndex on the
TabControl.
2026-06-15 08:49:44 +02:00
davide 4c0edde4f7 feat(ui): mobile polish — tab bar icons, server overlay, status text
Tab bar: replace plain Header strings with icon+label StackPanels
(≡ ↑ ↓ ⊙ ⊕); style TabStrip with UniformGrid so all five tabs share
the full width equally; center content and add touch padding. Icons
are visible only on mobile (IsMobile binding); desktop keeps text only.

Server settings overlay: dual layout for host/port/TLS input (vertical
on mobile: host full-width, port+TLS side by side) and for action
buttons (stacked full-width on mobile). Known-server list item shows
host on one line and tcp/ssl ports on the line below on mobile.

Connection status bar: simplify to "connesso" / "non connesso" —
remove the "a host:port" suffix from the connected state and
consolidate all disconnected/error/cert-changed states to conn.none.
2026-06-14 22:05:30 +02:00
davide cfc48ff86f feat(ui): responsive layout for portrait mobile (Android)
Add IsMobile property and BoolToTabPlacementConverter; wire
TabStripPlacement to move tabs to the bottom on mobile (standard
Android pattern). Hide the desktop menu bar on mobile and expose
Settings/Help via a compact header row instead.

Replace fixed-width multi-column grids with dual desktop/mobile
templates in History, Addresses and Contacts lists; adapt Send,
Receive and the add-contact form for narrow screens. Remove hard-coded
Width from all five overlays (560–640 px) in favour of MaxWidth +
Margin="16" so they never overflow a 360 px screen; add ScrollViewer
to Address info, Server settings and Settings overlays.

Desktop layout is unchanged: all differences are gated on the
IsMobile/IsDesktop bool, which is a platform constant (false on desktop).
2026-06-14 19:54:11 +02:00
davide e94eaf7700 refactor(arch): split App into shared library + Desktop + Android heads
The Avalonia UI code (App, Views, ViewModels, Localization, Assets) now
lives in src/App as a plain library (no OutputType). Two thin heads
reference it:

- src/App.Desktop/ — WinExe, Avalonia.Desktop, hosts MainView in a
  MainWindow; carries Program.cs and app.manifest (moved from src/App)
- src/App.Android/ — net10.0-android, Avalonia.Android, MainActivity/
  MainApplication; targets API 23+, EmbedAssembliesIntoApk=true so the
  apk is self-contained for sideloading

All event handlers and TopLevel-dependent calls (file picker, clipboard,
folder picker) moved from MainWindow.axaml.cs into the new shared
MainView.axaml.cs (UserControl), using TopLevel.GetTopLevel(this) so
they work on both platforms. Esc/Back key handling is also in MainView.
MainWindow becomes a thin shell that hosts MainView.

Framework bump: all projects move to net10.0; Cli and Tests follow.
2026-06-12 16:06:46 +02:00