refactor(market): resolve exchange/pair selection through one helper
The chart fetch and the Market tab both resolved the saved exchange and pair names into the registry, with their own near-identical scans and slightly different fallbacks. Keeping two copies risked the chart and the chips disagreeing about which pair was selected. - A single resolver maps the saved names to a registry index, matching the exchange name (any exchange when none is saved) then the pair display name, and falling back to the registry's first pair, the UI default. The chart fetch and the Market tab both call it. - The Market tab now derives its selection indices from the saved names against the current registry every frame, so the indices stay correct when the live exchange list replaces the fallback; a steady-state fast path skips the scan once the indices already name the saved selection. Tests: the resolver returns the right index for a matched exchange/pair, an empty-exchange match, and the first-pair fallback on misses. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -56,28 +56,12 @@ static const std::vector<data::ExchangeInfo>& EffectiveRegistry(const MarketInfo
|
||||
return market.exchanges.empty() ? data::getExchangeRegistry() : market.exchanges;
|
||||
}
|
||||
|
||||
// Helper: load selected exchange/pair from settings
|
||||
static void LoadMarketState(config::Settings* settings, const std::vector<data::ExchangeInfo>& registry)
|
||||
// One-shot restore of the persisted chart range + style (idempotent: both are re-persisted on click).
|
||||
static void LoadMarketState(config::Settings* settings)
|
||||
{
|
||||
if (s_mkt.stateLoaded || !settings) return;
|
||||
s_mkt.stateLoaded = true;
|
||||
|
||||
std::string savedExchange = settings->getSelectedExchange();
|
||||
std::string savedPair = settings->getSelectedPair();
|
||||
|
||||
for (int ei = 0; ei < (int)registry.size(); ei++) {
|
||||
if (registry[ei].name == savedExchange) {
|
||||
s_mkt.exchangeIdx = ei;
|
||||
for (int pi = 0; pi < (int)registry[ei].pairs.size(); pi++) {
|
||||
if (registry[ei].pairs[pi].displayName == savedPair) {
|
||||
s_mkt.pairIdx = pi;
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Restore the chart range + style (validated).
|
||||
int iv = settings->getChartInterval();
|
||||
if (iv >= 0 && iv <= 4) s_mkt.chartInterval = iv;
|
||||
@@ -85,6 +69,25 @@ static void LoadMarketState(config::Settings* settings, const std::vector<data::
|
||||
if (st == 0 || st == 1) s_mkt.chartStyle = st;
|
||||
}
|
||||
|
||||
// Derive the selected exchange/pair INDICES from the persisted NAMES against the CURRENT registry, every frame.
|
||||
// The registry changes identity when the live CoinGecko list replaces the 2-entry fallback; names are the
|
||||
// source of truth (the chip click and refreshExchangeChart both use them), indices are just a view.
|
||||
static void ResolveMarketSelection(config::Settings* settings, const std::vector<data::ExchangeInfo>& registry)
|
||||
{
|
||||
if (!settings || registry.empty()) return;
|
||||
const std::string selEx = settings->getSelectedExchange();
|
||||
const std::string selPair = settings->getSelectedPair();
|
||||
// Steady state: the current indices already name the saved selection -> no scan.
|
||||
if (s_mkt.exchangeIdx >= 0 && s_mkt.exchangeIdx < (int)registry.size()) {
|
||||
const auto& ex = registry[s_mkt.exchangeIdx];
|
||||
if (ex.name == selEx && s_mkt.pairIdx >= 0 && s_mkt.pairIdx < (int)ex.pairs.size() &&
|
||||
ex.pairs[s_mkt.pairIdx].displayName == selPair) return;
|
||||
}
|
||||
const auto sel = data::resolveExchangeSelection(registry, selEx, selPair);
|
||||
s_mkt.exchangeIdx = sel.exchangeIdx;
|
||||
s_mkt.pairIdx = sel.pairIdx;
|
||||
}
|
||||
|
||||
// Helper: format compact currency
|
||||
static std::string FormatCompactUSD(double val)
|
||||
{
|
||||
@@ -2242,7 +2245,8 @@ void RenderMarketTab(App* app)
|
||||
const auto& registry = EffectiveRegistry(market);
|
||||
|
||||
// Load persisted exchange/pair on first frame
|
||||
LoadMarketState(app->settings(), registry);
|
||||
LoadMarketState(app->settings());
|
||||
ResolveMarketSelection(app->settings(), registry);
|
||||
|
||||
if (s_mkt.exchangeIdx >= (int)registry.size()) s_mkt.exchangeIdx = 0;
|
||||
const auto& currentExchange = registry[s_mkt.exchangeIdx];
|
||||
|
||||
Reference in New Issue
Block a user