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:
@@ -166,9 +166,12 @@ void ShieldDialog::render(App* app)
|
||||
ImGui::Spacing();
|
||||
}
|
||||
|
||||
// Buttons
|
||||
bool can_submit = !s_operation_pending && s_to_address[0] != '\0';
|
||||
|
||||
// Buttons — guard on connection/sync like the Send tab (a disconnected or mid-sync submit just
|
||||
// fails at the daemon with a raw error).
|
||||
bool sh_connected = app->isConnected();
|
||||
bool sh_syncing = state.sync.syncing;
|
||||
bool can_submit = !s_operation_pending && s_to_address[0] != '\0' && sh_connected && !sh_syncing;
|
||||
|
||||
if (!can_submit) ImGui::BeginDisabled();
|
||||
|
||||
const char* btn_label = (s_mode == Mode::ShieldCoinbase) ? TR("shield_funds") : TR("merge_funds");
|
||||
@@ -244,7 +247,12 @@ void ShieldDialog::render(App* app)
|
||||
}
|
||||
|
||||
if (!can_submit) ImGui::EndDisabled();
|
||||
|
||||
if (!can_submit && ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled)) {
|
||||
if (!sh_connected) material::Tooltip("%s", TR("send_tooltip_not_connected"));
|
||||
else if (sh_syncing) material::Tooltip("%s", TR("send_tooltip_syncing"));
|
||||
else if (s_to_address[0]=='\0') material::Tooltip("%s", TR("shield_select_z"));
|
||||
}
|
||||
|
||||
ImGui::SameLine();
|
||||
|
||||
if (material::StyledButton(TR("cancel"), ImVec2(cancelBtn.width, 0), S.resolveFont(cancelBtn.font))) {
|
||||
|
||||
Reference in New Issue
Block a user