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:
@@ -318,6 +318,18 @@ bool Settings::load(const std::string& path)
|
||||
entry.icon = e["icon"].get<std::string>();
|
||||
if (e.contains("color") && e["color"].is_number())
|
||||
entry.color = e["color"].get<unsigned int>();
|
||||
if (e.contains("price_basis") && e["price_basis"].is_number_integer())
|
||||
entry.priceBasis = e["price_basis"].get<int>();
|
||||
if (e.contains("manual_price") && e["manual_price"].is_number())
|
||||
entry.manualPrice = e["manual_price"].get<double>();
|
||||
if (e.contains("manual_currency") && e["manual_currency"].is_string())
|
||||
entry.manualCurrency = e["manual_currency"].get<std::string>();
|
||||
if (e.contains("show_drgx") && e["show_drgx"].is_boolean())
|
||||
entry.showDrgx = e["show_drgx"].get<bool>();
|
||||
if (e.contains("show_value") && e["show_value"].is_boolean())
|
||||
entry.showValue = e["show_value"].get<bool>();
|
||||
if (e.contains("show_24h") && e["show_24h"].is_boolean())
|
||||
entry.show24h = e["show_24h"].get<bool>();
|
||||
if (!entry.label.empty()) portfolio_entries_.push_back(std::move(entry));
|
||||
}
|
||||
}
|
||||
@@ -469,6 +481,12 @@ bool Settings::save(const std::string& path)
|
||||
for (const auto& a : e.addresses) entry["addresses"].push_back(a);
|
||||
entry["icon"] = e.icon;
|
||||
entry["color"] = e.color;
|
||||
entry["price_basis"] = e.priceBasis;
|
||||
entry["manual_price"] = e.manualPrice;
|
||||
entry["manual_currency"] = e.manualCurrency;
|
||||
entry["show_drgx"] = e.showDrgx;
|
||||
entry["show_value"] = e.showValue;
|
||||
entry["show_24h"] = e.show24h;
|
||||
j["portfolio_entries"].push_back(std::move(entry));
|
||||
}
|
||||
j["font_scale"] = font_scale_;
|
||||
|
||||
Reference in New Issue
Block a user