feat(market): per-group configurable price data

Each portfolio group can now configure how it is valued and which price
fields its card shows:

- Price basis: Market · USD, Market · BTC, DRGX only, or Manual (a custom
  price-per-DRGX + currency label). Manual mode values the group independently
  of the live DRGX market price.
- Field toggles: show DRGX amount / show value / show 24h change (24h enabled
  only for the live-market bases; value disabled for DRGX-only).
- The editor's left "Appearance" column gains a Price section (basis combo,
  manual price + currency inputs, field checkboxes); the live preview and the
  group cards both render through one pfBuildDisplay() helper so they stay in
  sync. Defaults preserve the prior behavior (DRGX + USD).

Persisted in settings.json (price_basis / manual_price / manual_currency /
show_drgx / show_value / show_24h).

Note: "price source per exchange/pair" is limited to USD/BTC/Manual — the app
only fetches the aggregate DRGX price (USD + BTC); ExchangePair carries no
price, so valuing against an arbitrary pair's live price would need a new
market fetch (can be added separately).

Full-node + Lite build clean; ctest 1/1; hygiene clean. Rendering change —
needs a screenshot check.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-07-03 00:10:42 -05:00
parent ae4e6486c6
commit 301b3df77e
4 changed files with 183 additions and 30 deletions

View File

@@ -1124,6 +1124,16 @@ void I18n::loadBuiltinEnglish()
strings_["portfolio_color"] = "Color";
strings_["portfolio_no_icon"] = "None";
strings_["portfolio_custom_color"] = "Custom color\xE2\x80\xA6";
strings_["portfolio_price"] = "Price";
strings_["portfolio_price_usd"] = "Market \xC2\xB7 USD";
strings_["portfolio_price_btc"] = "Market \xC2\xB7 BTC";
strings_["portfolio_price_drgx"] = "DRGX only";
strings_["portfolio_price_manual"] = "Manual";
strings_["portfolio_manual_price"] = "Price / DRGX";
strings_["portfolio_currency"] = "Currency";
strings_["portfolio_show"] = "Show:";
strings_["portfolio_show_value"] = "Value";
strings_["portfolio_show_24h"] = "24h";
strings_["portfolio_appearance"] = "APPEARANCE";
strings_["portfolio_addresses_hdr"] = "ADDRESSES";
strings_["portfolio_search"] = "Search addresses\xE2\x80\xA6";