feat(bootstrap,validate): Retry keeps the mirror; Validate works offline
- Bootstrap: Retry now reuses the source the user actually started (was always the default), and a "Try mirror" button offers the alternate server on failure (s_lastUrl remembered on start, cleared on a fresh Confirm). - Validate Address: classification + checksum are local, so the dialog no longer requires a node connection — offline/lite now validate and show the type, with ownership reported as "Unknown — node offline / not checkable in the lite wallet" instead of a dead "not connected" screen. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -45,6 +45,7 @@ public:
|
||||
s_state = State::Confirm;
|
||||
s_bootstrap.reset();
|
||||
s_errorMsg.clear();
|
||||
s_lastUrl.clear();
|
||||
s_wasDaemonRunning = false;
|
||||
}
|
||||
|
||||
@@ -314,9 +315,15 @@ private:
|
||||
|
||||
float btnW = 120.0f * dp;
|
||||
if (TactileButton(TR("retry"), ImVec2(btnW, 0))) {
|
||||
startDownload("");
|
||||
startDownload(s_lastUrl); // keep the user's source/mirror choice (was startDownload(""))
|
||||
}
|
||||
ImGui::SameLine();
|
||||
{
|
||||
const std::string mirrorUrl = std::string(util::Bootstrap::kMirrorUrl) + "/" + util::Bootstrap::kZipName;
|
||||
if (s_lastUrl != mirrorUrl && TactileButton(TR("bootstrap_try_mirror"), ImVec2(130.0f * dp, 0)))
|
||||
startDownload(mirrorUrl);
|
||||
ImGui::SameLine();
|
||||
}
|
||||
if (TactileButton(TR("close"), ImVec2(90.0f * dp, 0))) {
|
||||
s_app->setBootstrapDownloading(false);
|
||||
s_open = false;
|
||||
@@ -336,6 +343,7 @@ private:
|
||||
s_bootstrap->start(dataDir);
|
||||
else
|
||||
s_bootstrap->start(dataDir, url);
|
||||
s_lastUrl = url; // remember what we started (set only after the guards passed)
|
||||
s_state = State::Downloading;
|
||||
s_errorMsg.clear();
|
||||
s_cancelling = false;
|
||||
@@ -347,6 +355,7 @@ private:
|
||||
static inline std::unique_ptr<util::Bootstrap> s_bootstrap;
|
||||
static inline bool s_wasDaemonRunning = false;
|
||||
static inline bool s_cancelling = false; // cancel requested; disables the Cancel button until the worker stops
|
||||
static inline std::string s_lastUrl; // last source started ("" = default); so Retry keeps the mirror choice
|
||||
static inline std::string s_errorMsg;
|
||||
};
|
||||
|
||||
|
||||
@@ -91,7 +91,8 @@ void ValidateAddressDialog::render(App* app)
|
||||
ImGui::Spacing();
|
||||
|
||||
// Validate button
|
||||
bool can_validate = strlen(s_address_input) > 0 && !s_validating && app->isConnected();
|
||||
// Classification + checksum are LOCAL, so allow validating offline (the is-mine check needs the node).
|
||||
bool can_validate = strlen(s_address_input) > 0 && !s_validating;
|
||||
|
||||
if (!can_validate) {
|
||||
ImGui::BeginDisabled();
|
||||
@@ -123,8 +124,9 @@ void ValidateAddressDialog::render(App* app)
|
||||
s_address_type.clear();
|
||||
s_validated = true;
|
||||
s_validating = false;
|
||||
} else if (app->isLiteBuild()) {
|
||||
// Lite has no node to ask: the checksum verdict is the answer, ownership is unknown (hidden).
|
||||
} else if (app->isLiteBuild() || !app->isConnected()) {
|
||||
// No node to ask (lite, or full-node offline): the checksum verdict is the answer; ownership
|
||||
// is unknown. The result block shows why.
|
||||
s_is_valid = true;
|
||||
s_is_mine = false;
|
||||
s_ownership_known = false;
|
||||
@@ -209,15 +211,17 @@ void ValidateAddressDialog::render(App* app)
|
||||
ImGui::SameLine(lbl.position);
|
||||
ImGui::Text("%s", s_address_type.c_str());
|
||||
|
||||
// Is mine? (not shown when no node was asked - lite)
|
||||
if (s_ownership_known) {
|
||||
ImGui::Text("%s", TR("validate_ownership"));
|
||||
ImGui::SameLine(lbl.position);
|
||||
if (s_is_mine) {
|
||||
ImGui::TextColored(ImVec4(0.3f, 0.8f, 0.3f, 1.0f), "%s", TR("validate_is_mine"));
|
||||
} else {
|
||||
ImGui::TextDisabled("%s", TR("validate_not_mine"));
|
||||
}
|
||||
// Is mine? When no node was asked (lite / offline) say why ownership is unknown rather
|
||||
// than silently omitting it.
|
||||
ImGui::Text("%s", TR("validate_ownership"));
|
||||
ImGui::SameLine(lbl.position);
|
||||
if (!s_ownership_known) {
|
||||
ImGui::TextDisabled("%s", TR(app->isLiteBuild() ? "validate_ownership_unknown_lite"
|
||||
: "validate_ownership_unknown_offline"));
|
||||
} else if (s_is_mine) {
|
||||
ImGui::TextColored(ImVec4(0.3f, 0.8f, 0.3f, 1.0f), "%s", TR("validate_is_mine"));
|
||||
} else {
|
||||
ImGui::TextDisabled("%s", TR("validate_not_mine"));
|
||||
}
|
||||
if (s_is_mining) { // valid, but not for payments
|
||||
ImGui::Spacing();
|
||||
@@ -227,8 +231,6 @@ void ValidateAddressDialog::render(App* app)
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (!app->isConnected()) {
|
||||
ImGui::TextColored(ImVec4(1.0f, 0.6f, 0.0f, 1.0f), "%s", TR("not_connected"));
|
||||
} else {
|
||||
// Pre-interaction placeholder: keeps the results area from reading as a large
|
||||
// dead gap between the Validate/Paste row and the Close button until a result exists.
|
||||
|
||||
@@ -688,6 +688,7 @@ void I18n::loadBuiltinEnglish()
|
||||
strings_["wiz_bootstrap_desc"] = "Download a blockchain bootstrap to dramatically speed up initial sync.\n\nYour existing wallet.dat will NOT be modified or replaced.";
|
||||
strings_["wiz_skip"] = "Skip";
|
||||
strings_["wiz_bootstrap_failed"] = "Bootstrap failed";
|
||||
strings_["bootstrap_try_mirror"] = "Try mirror";
|
||||
strings_["wiz_download_failed"] = "Download Failed";
|
||||
strings_["wiz_ext_daemon_running"] = "External daemon running";
|
||||
strings_["wiz_ext_daemon_warning"] = "It must be stopped before downloading a bootstrap, otherwise chain data could be corrupted.";
|
||||
@@ -2723,6 +2724,8 @@ void I18n::loadBuiltinEnglish()
|
||||
strings_["validate_invalid"] = "INVALID";
|
||||
strings_["validate_is_mine"] = "This wallet owns this address";
|
||||
strings_["validate_not_mine"] = "Not owned by this wallet";
|
||||
strings_["validate_ownership_unknown_offline"] = "Unknown — node offline";
|
||||
strings_["validate_ownership_unknown_lite"] = "Unknown — not checkable in the lite wallet";
|
||||
strings_["validate_ownership"] = "Ownership:";
|
||||
strings_["validate_results"] = "Results:";
|
||||
strings_["validate_results_placeholder"] = "Results will appear here";
|
||||
|
||||
Reference in New Issue
Block a user