feat(transfer): add Send-tab guards, a correct TxID label + copy, inline reasons
The address-transfer dialog (own-address moves) enabled Confirm on amount alone, so a disconnected / syncing / locked wallet failed only at submit. It now mirrors the Send tab's guards (strictly more restrictive — the transfer logic is unchanged) and re-checks live state before broadcast, shows an inline reason when blocked (enter amount / not connected / syncing / locked), and labels the result as a "Transaction ID" (not "Operation ID") with a copy button. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -141,6 +141,14 @@ public:
|
||||
double newFromBal = s_info.fromBalance - totalDeduct;
|
||||
double newToBal = s_info.toBalance + amount;
|
||||
bool amountValid = amount > 0 && totalDeduct <= s_info.fromBalance;
|
||||
// Mirror the Send tab's guards (this dialog previously enabled Confirm on amount alone, so a
|
||||
// disconnected / syncing / locked wallet would fail only at submit). These are own-address
|
||||
// moves, but gating is strictly more restrictive — the transfer logic below is unchanged.
|
||||
const auto& ws = s_app->getWalletState();
|
||||
const bool connected = s_app->isConnected();
|
||||
const bool syncing = ws.sync.syncing;
|
||||
const bool liteLocked = s_app->liteWallet() && ws.isLocked();
|
||||
const bool canTransfer = amountValid && !s_sending && connected && !syncing && !liteLocked;
|
||||
|
||||
ImGui::Separator();
|
||||
ImGui::Spacing();
|
||||
@@ -167,6 +175,19 @@ public:
|
||||
ImGui::TextWrapped("%s", TR("insufficient_funds"));
|
||||
ImGui::PopStyleColor();
|
||||
}
|
||||
if (amount <= 0.0) {
|
||||
ImGui::Spacing();
|
||||
ImGui::PushStyleColor(ImGuiCol_Text, ImGui::ColorConvertU32ToFloat4(Error()));
|
||||
ImGui::TextWrapped("%s", TR("send_tooltip_enter_amount"));
|
||||
ImGui::PopStyleColor();
|
||||
} else if (amountValid && (!connected || syncing || liteLocked)) {
|
||||
ImGui::Spacing();
|
||||
ImGui::PushStyleColor(ImGuiCol_Text, ImGui::ColorConvertU32ToFloat4(Warning()));
|
||||
ImGui::TextWrapped("%s", !connected ? TR("send_tooltip_not_connected")
|
||||
: syncing ? TR("send_tooltip_syncing")
|
||||
: TR("transfer_tooltip_locked"));
|
||||
ImGui::PopStyleColor();
|
||||
}
|
||||
if (amountValid && newFromBal < 1e-9) {
|
||||
ImGui::Spacing();
|
||||
// Full-balance send: same warning-icon treatment as the de-shielding header above,
|
||||
@@ -204,13 +225,13 @@ public:
|
||||
bool outConfirm = false;
|
||||
bool outClose = false;
|
||||
DialogActionFooter(s_sending ? sendingLabel : confirmLabel,
|
||||
amountValid && !s_sending,
|
||||
canTransfer,
|
||||
cancelLabel, outConfirm, outClose, btnW);
|
||||
|
||||
if (outClose) {
|
||||
s_open = false;
|
||||
}
|
||||
if (outConfirm) {
|
||||
if (outConfirm && canTransfer) { // re-check live state (the dialog persists across frames)
|
||||
s_sending = true;
|
||||
s_app->sendTransaction(s_info.fromAddr, s_info.toAddr,
|
||||
amount, s_fee, "",
|
||||
@@ -296,12 +317,19 @@ private:
|
||||
Type().textColored(TypeStyle::Caption, OnSurfaceMedium(), TR("transfer_sent_desc"));
|
||||
ImGui::Spacing();
|
||||
{
|
||||
char buf[128];
|
||||
snprintf(buf, sizeof(buf), TR("shield_operation_id"),
|
||||
s_resultMsg.size() > 40
|
||||
? (s_resultMsg.substr(0, 20) + "..." + s_resultMsg.substr(s_resultMsg.size() - 10)).c_str()
|
||||
: s_resultMsg.c_str());
|
||||
// The result is a TRANSACTION id, not an "Operation ID" — label it correctly and make
|
||||
// it copyable.
|
||||
std::string disp = s_resultMsg.size() > 40
|
||||
? (s_resultMsg.substr(0, 20) + "..." + s_resultMsg.substr(s_resultMsg.size() - 10))
|
||||
: s_resultMsg;
|
||||
char buf[160];
|
||||
snprintf(buf, sizeof(buf), TR("transfer_txid_label"), disp.c_str());
|
||||
Type().textColored(TypeStyle::Caption, OnSurfaceDisabled(), buf);
|
||||
ImGui::SameLine();
|
||||
if (ImGui::SmallButton(TR("grpb_copy"))) {
|
||||
ImGui::SetClipboardText(s_resultMsg.c_str());
|
||||
Notifications::instance().info(TR("copied_to_clipboard"));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
ImGui::Spacing();
|
||||
|
||||
@@ -1118,6 +1118,8 @@ void I18n::loadBuiltinEnglish()
|
||||
strings_["confirm_transfer"] = "Confirm Transfer";
|
||||
strings_["transfer_sent"] = "Transfer Sent";
|
||||
strings_["transfer_sent_desc"] = "Your transfer has been submitted to the network.";
|
||||
strings_["transfer_txid_label"] = "Transaction ID: %s";
|
||||
strings_["transfer_tooltip_locked"] = "Wallet is locked — unlock it to transfer";
|
||||
strings_["transfer_failed"] = "Transfer Failed";
|
||||
|
||||
// Misc dialog strings
|
||||
|
||||
Reference in New Issue
Block a user