refactor(market): lift portfolio-editor lambdas to file-static functions
Convert the four [&]-capturing lambdas (persist / buildWorking / workingMatches / commitIfNeeded) into file-static pfPersist / pfBuildWorking / pfWorkingMatches / pfCommitIfNeeded that operate on the s_pfEdit struct + take Settings*. Removes the per-frame closure setup and lets the upcoming section helpers reuse them. No behavior change. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -386,6 +386,51 @@ static void PortfolioBeginEdit(App* app, int index)
|
|||||||
s_pfEdit.fundedOnly = false;
|
s_pfEdit.fundedOnly = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ---- Portfolio-editor persistence helpers (operate on the s_pfEdit working state) ----
|
||||||
|
|
||||||
|
// Build a PortfolioEntry from the working set, preserving off-form fields (grid geometry) from base.
|
||||||
|
static config::Settings::PortfolioEntry pfBuildWorking(const config::Settings::PortfolioEntry& base)
|
||||||
|
{
|
||||||
|
config::Settings::PortfolioEntry e = base;
|
||||||
|
e.label = s_pfEdit.label; e.addresses = s_pfEdit.addrs; e.icon = s_pfEdit.icon;
|
||||||
|
e.color = s_pfEdit.color; e.outlineOpacity = s_pfEdit.outlineOpacity;
|
||||||
|
e.priceBasis = s_pfEdit.priceBasis; e.manualPrice = s_pfEdit.manualPrice; e.manualCurrency = s_pfEdit.manualCcy;
|
||||||
|
e.showDrgx = s_pfEdit.showDrgx; e.showValue = s_pfEdit.showValue; e.show24h = s_pfEdit.show24h;
|
||||||
|
e.showSparkline = s_pfEdit.showSparkline; e.sparklineInterval = s_pfEdit.sparkInterval;
|
||||||
|
return e;
|
||||||
|
}
|
||||||
|
|
||||||
|
// True when the working set matches a stored entry (i.e. there are no uncommitted edits).
|
||||||
|
static bool pfWorkingMatches(const config::Settings::PortfolioEntry& e)
|
||||||
|
{
|
||||||
|
return e.label == std::string(s_pfEdit.label) && e.addresses == s_pfEdit.addrs && e.icon == s_pfEdit.icon
|
||||||
|
&& e.color == s_pfEdit.color && e.outlineOpacity == s_pfEdit.outlineOpacity
|
||||||
|
&& e.priceBasis == s_pfEdit.priceBasis && e.manualPrice == s_pfEdit.manualPrice
|
||||||
|
&& e.manualCurrency == std::string(s_pfEdit.manualCcy)
|
||||||
|
&& e.showDrgx == s_pfEdit.showDrgx && e.showValue == s_pfEdit.showValue && e.show24h == s_pfEdit.show24h
|
||||||
|
&& e.showSparkline == s_pfEdit.showSparkline && e.sparklineInterval == s_pfEdit.sparkInterval;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void pfPersist(config::Settings* settings, const std::vector<config::Settings::PortfolioEntry>& entries)
|
||||||
|
{
|
||||||
|
settings->setPortfolioEntries(entries);
|
||||||
|
settings->save();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Persist the working group when it is named and actually changed; unnamed drafts are dropped.
|
||||||
|
static void pfCommitIfNeeded(config::Settings* settings)
|
||||||
|
{
|
||||||
|
if (s_pfEdit.label[0] == '\0') return;
|
||||||
|
auto entries = settings->getPortfolioEntries();
|
||||||
|
bool existing = (s_pfEdit.sel >= 0 && s_pfEdit.sel < (int)entries.size());
|
||||||
|
config::Settings::PortfolioEntry base;
|
||||||
|
if (existing) { base = entries[s_pfEdit.sel]; if (pfWorkingMatches(base)) return; }
|
||||||
|
auto e = pfBuildWorking(base);
|
||||||
|
if (existing) entries[s_pfEdit.sel] = e;
|
||||||
|
else { entries.push_back(e); s_pfEdit.sel = (int)entries.size() - 1; }
|
||||||
|
pfPersist(settings, entries);
|
||||||
|
}
|
||||||
|
|
||||||
// The "Manage portfolio" modal: list/add/edit/delete entries, each a label tied to a group
|
// The "Manage portfolio" modal: list/add/edit/delete entries, each a label tied to a group
|
||||||
// of wallet addresses. Persists to Settings on every mutation (like the address book).
|
// of wallet addresses. Persists to Settings on every mutation (like the address book).
|
||||||
static void RenderPortfolioEditor(App* app)
|
static void RenderPortfolioEditor(App* app)
|
||||||
@@ -401,40 +446,7 @@ static void RenderPortfolioEditor(App* app)
|
|||||||
ImFont* iconFont = Type().iconSmall();
|
ImFont* iconFont = Type().iconSmall();
|
||||||
float iconFsz = iconFont->LegacySize;
|
float iconFsz = iconFont->LegacySize;
|
||||||
|
|
||||||
auto persist = [&](const std::vector<config::Settings::PortfolioEntry>& entries) {
|
// Persistence helpers are file-static (pfBuildWorking / pfWorkingMatches / pfCommitIfNeeded).
|
||||||
settings->setPortfolioEntries(entries);
|
|
||||||
settings->save();
|
|
||||||
};
|
|
||||||
// Build a PortfolioEntry from the working set, preserving off-form fields (grid geometry) from base.
|
|
||||||
auto buildWorking = [&](const config::Settings::PortfolioEntry& base) {
|
|
||||||
config::Settings::PortfolioEntry e = base;
|
|
||||||
e.label = s_pfEdit.label; e.addresses = s_pfEdit.addrs; e.icon = s_pfEdit.icon;
|
|
||||||
e.color = s_pfEdit.color; e.outlineOpacity = s_pfEdit.outlineOpacity;
|
|
||||||
e.priceBasis = s_pfEdit.priceBasis; e.manualPrice = s_pfEdit.manualPrice; e.manualCurrency = s_pfEdit.manualCcy;
|
|
||||||
e.showDrgx = s_pfEdit.showDrgx; e.showValue = s_pfEdit.showValue; e.show24h = s_pfEdit.show24h;
|
|
||||||
e.showSparkline = s_pfEdit.showSparkline; e.sparklineInterval = s_pfEdit.sparkInterval;
|
|
||||||
return e;
|
|
||||||
};
|
|
||||||
auto workingMatches = [&](const config::Settings::PortfolioEntry& e) {
|
|
||||||
return e.label == std::string(s_pfEdit.label) && e.addresses == s_pfEdit.addrs && e.icon == s_pfEdit.icon
|
|
||||||
&& e.color == s_pfEdit.color && e.outlineOpacity == s_pfEdit.outlineOpacity
|
|
||||||
&& e.priceBasis == s_pfEdit.priceBasis && e.manualPrice == s_pfEdit.manualPrice
|
|
||||||
&& e.manualCurrency == std::string(s_pfEdit.manualCcy)
|
|
||||||
&& e.showDrgx == s_pfEdit.showDrgx && e.showValue == s_pfEdit.showValue && e.show24h == s_pfEdit.show24h
|
|
||||||
&& e.showSparkline == s_pfEdit.showSparkline && e.sparklineInterval == s_pfEdit.sparkInterval;
|
|
||||||
};
|
|
||||||
// Persist the working group when it is named and actually changed; unnamed drafts are dropped.
|
|
||||||
auto commitIfNeeded = [&]() {
|
|
||||||
if (s_pfEdit.label[0] == '\0') return;
|
|
||||||
auto entries = settings->getPortfolioEntries();
|
|
||||||
bool existing = (s_pfEdit.sel >= 0 && s_pfEdit.sel < (int)entries.size());
|
|
||||||
config::Settings::PortfolioEntry base;
|
|
||||||
if (existing) { base = entries[s_pfEdit.sel]; if (workingMatches(base)) return; }
|
|
||||||
auto e = buildWorking(base);
|
|
||||||
if (existing) entries[s_pfEdit.sel] = e;
|
|
||||||
else { entries.push_back(e); s_pfEdit.sel = (int)entries.size() - 1; }
|
|
||||||
persist(entries);
|
|
||||||
};
|
|
||||||
|
|
||||||
// ---------------- Full-window overlay frame ----------------
|
// ---------------- Full-window overlay frame ----------------
|
||||||
material::MarkOverlayDialogActive();
|
material::MarkOverlayDialogActive();
|
||||||
@@ -526,7 +538,7 @@ static void RenderPortfolioEditor(App* app)
|
|||||||
bool selDirty = false;
|
bool selDirty = false;
|
||||||
{
|
{
|
||||||
const auto& es = settings->getPortfolioEntries();
|
const auto& es = settings->getPortfolioEntries();
|
||||||
if (s_pfEdit.sel >= 0 && s_pfEdit.sel < (int)es.size()) selDirty = !workingMatches(es[s_pfEdit.sel]);
|
if (s_pfEdit.sel >= 0 && s_pfEdit.sel < (int)es.size()) selDirty = !pfWorkingMatches(es[s_pfEdit.sel]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ================= MASTER: scrollable group list + a pinned Add button below it =================
|
// ================= MASTER: scrollable group list + a pinned Add button below it =================
|
||||||
@@ -601,7 +613,7 @@ static void RenderPortfolioEditor(App* app)
|
|||||||
auto es = settings->getPortfolioEntries();
|
auto es = settings->getPortfolioEntries();
|
||||||
if (delRow < (int)es.size()) {
|
if (delRow < (int)es.size()) {
|
||||||
es.erase(es.begin() + delRow);
|
es.erase(es.begin() + delRow);
|
||||||
persist(es);
|
pfPersist(settings, es);
|
||||||
if (es.empty()) s_pfEdit.sel = -1;
|
if (es.empty()) s_pfEdit.sel = -1;
|
||||||
else if (delRow < s_pfEdit.sel) s_pfEdit.sel -= 1;
|
else if (delRow < s_pfEdit.sel) s_pfEdit.sel -= 1;
|
||||||
else if (delRow == s_pfEdit.sel) s_pfEdit.sel = std::min(delRow, (int)es.size() - 1);
|
else if (delRow == s_pfEdit.sel) s_pfEdit.sel = std::min(delRow, (int)es.size() - 1);
|
||||||
@@ -620,7 +632,7 @@ static void RenderPortfolioEditor(App* app)
|
|||||||
config::Settings::PortfolioEntry ne;
|
config::Settings::PortfolioEntry ne;
|
||||||
ne.label = TR("portfolio_untitled");
|
ne.label = TR("portfolio_untitled");
|
||||||
es.push_back(ne);
|
es.push_back(ne);
|
||||||
persist(es);
|
pfPersist(settings, es);
|
||||||
s_pfEdit.sel = (int)es.size() - 1;
|
s_pfEdit.sel = (int)es.size() - 1;
|
||||||
PortfolioBeginEdit(app, s_pfEdit.sel);
|
PortfolioBeginEdit(app, s_pfEdit.sel);
|
||||||
}
|
}
|
||||||
@@ -1077,7 +1089,7 @@ static void RenderPortfolioEditor(App* app)
|
|||||||
PortfolioBeginEdit(app, s_pfEdit.sel); // reload the working set from the stored entry
|
PortfolioBeginEdit(app, s_pfEdit.sel); // reload the working set from the stored entry
|
||||||
ImGui::SameLine(0, sp);
|
ImGui::SameLine(0, sp);
|
||||||
ImGui::BeginDisabled(s_pfEdit.label[0] == '\0');
|
ImGui::BeginDisabled(s_pfEdit.label[0] == '\0');
|
||||||
if (ImGui::Button(TR("portfolio_save"), ImVec2(bw, addH))) commitIfNeeded();
|
if (ImGui::Button(TR("portfolio_save"), ImVec2(bw, addH))) pfCommitIfNeeded(settings);
|
||||||
ImGui::EndDisabled();
|
ImGui::EndDisabled();
|
||||||
ImGui::EndDisabled();
|
ImGui::EndDisabled();
|
||||||
}
|
}
|
||||||
@@ -1088,7 +1100,7 @@ static void RenderPortfolioEditor(App* app)
|
|||||||
{
|
{
|
||||||
float bh = 40.0f * dp, bw = 120.0f * dp;
|
float bh = 40.0f * dp, bw = 120.0f * dp;
|
||||||
pfRightAlignX(bw);
|
pfRightAlignX(bw);
|
||||||
if (ImGui::Button(TR("portfolio_close"), ImVec2(bw, bh))) { commitIfNeeded(); s_pfEdit.open = false; }
|
if (ImGui::Button(TR("portfolio_close"), ImVec2(bw, bh))) { pfCommitIfNeeded(settings); s_pfEdit.open = false; }
|
||||||
}
|
}
|
||||||
|
|
||||||
ImGui::EndChild(); // ##pfCard
|
ImGui::EndChild(); // ##pfCard
|
||||||
|
|||||||
Reference in New Issue
Block a user