fix: Tier-2 UX robustness — action guards, in-progress guards, input trimming
The app-wide "import-key pattern" fixes (missing guards / untrimmed input / no
re-entrancy protection), from the robustness audit:
- Import-key dialog: unify the type indicator and the RPC dispatch on one
classifier (classifyPrivateKey is now prefix-aware — an "SK..." shielded key no
longer misroutes to the transparent RPC), trim manual input (not just Paste),
and gate both the indicator and the Import button on a shared
isRecognizedPrivateKey() so unrecognized/empty input can't be submitted.
- Shield: guard the submit button on connected + !syncing (like Send), with a
disabled tooltip, instead of firing into a raw daemon error.
- Mining: disable the pool Mine button when the payout address is empty
("enter a payout address first"), and trim the pool URL/worker on persist.
- Console: track in-flight RPC commands (atomic counter + busy() override) so the
input is disabled while a command runs instead of piling up on the worker.
- Maintenance (rescan/repair/delete-chain/reinstall-daemon): re-entrancy guard —
bail with "already in progress" instead of launching a duplicate destructive op.
- Bootstrap dialog: re-attach to an in-flight download on reopen instead of
resetting state and orphaning the running worker.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -199,8 +199,19 @@ static void RenderMiningTabContent(App* app)
|
||||
|
||||
// Persist pool settings when dirty and no field is active
|
||||
if (s_pool_settings_dirty && !ImGui::IsAnyItemActive()) {
|
||||
app->settings()->setPoolUrl(s_pool_url);
|
||||
app->settings()->setPoolWorker(s_pool_worker);
|
||||
// Trim whitespace/newlines (a pasted URL or payout address often carries a trailing newline)
|
||||
// before persisting and feeding it to xmrig; write the trimmed value back so the field agrees.
|
||||
auto trimmed = [](const char* b) {
|
||||
std::string s(b);
|
||||
while (!s.empty() && (s.front()==' '||s.front()=='\t'||s.front()=='\n'||s.front()=='\r')) s.erase(s.begin());
|
||||
while (!s.empty() && (s.back()==' '||s.back()=='\t'||s.back()=='\n'||s.back()=='\r')) s.pop_back();
|
||||
return s;
|
||||
};
|
||||
std::string poolUrl = trimmed(s_pool_url), poolWorker = trimmed(s_pool_worker);
|
||||
snprintf(s_pool_url, sizeof(s_pool_url), "%s", poolUrl.c_str());
|
||||
snprintf(s_pool_worker, sizeof(s_pool_worker), "%s", poolWorker.c_str());
|
||||
app->settings()->setPoolUrl(poolUrl);
|
||||
app->settings()->setPoolWorker(poolWorker);
|
||||
app->settings()->save();
|
||||
s_pool_settings_dirty = false;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user