feat(settings): confirmation modals for rescan and restart-daemon
The Rescan blockchain and Restart daemon buttons fired immediately on click — both are disruptive (long offline rescan / connection drop) and easy to hit by accident. Route them through confirmation modals, matching the existing delete-blockchain / clear-ztx confirmations: the button now sets a confirm flag and an overlay dialog performs the action only on explicit confirm. New i18n strings added with English defaults. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -145,6 +145,8 @@ struct SettingsPageState {
|
|||||||
bool tools_expanded = false;
|
bool tools_expanded = false;
|
||||||
bool confirm_clear_ztx = false;
|
bool confirm_clear_ztx = false;
|
||||||
bool confirm_delete_blockchain = false;
|
bool confirm_delete_blockchain = false;
|
||||||
|
bool confirm_rescan = false;
|
||||||
|
bool confirm_restart_daemon = false;
|
||||||
effects::ScrollFadeShader fade_shader;
|
effects::ScrollFadeShader fade_shader;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -1993,7 +1995,7 @@ void RenderSettingsPage(App* app) {
|
|||||||
if (ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled)) ImGui::SetTooltip("%s", TR("tt_test_conn"));
|
if (ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled)) ImGui::SetTooltip("%s", TR("tt_test_conn"));
|
||||||
ImGui::SameLine(0, Layout::spacingMd());
|
ImGui::SameLine(0, Layout::spacingMd());
|
||||||
if (TactileButton(TR("rescan"), ImVec2(nodeBtnW, 0), btnFont)) {
|
if (TactileButton(TR("rescan"), ImVec2(nodeBtnW, 0), btnFont)) {
|
||||||
app->rescanBlockchain();
|
s_settingsState.confirm_rescan = true;
|
||||||
}
|
}
|
||||||
if (ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled)) ImGui::SetTooltip("%s", TR("tt_rescan"));
|
if (ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled)) ImGui::SetTooltip("%s", TR("tt_rescan"));
|
||||||
ImGui::EndDisabled();
|
ImGui::EndDisabled();
|
||||||
@@ -2451,8 +2453,7 @@ void RenderSettingsPage(App* app) {
|
|||||||
ImGui::PopStyleColor();
|
ImGui::PopStyleColor();
|
||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
if (TactileButton(TR("settings_restart_daemon"), ImVec2(0, 0), S.resolveFont("button"))) {
|
if (TactileButton(TR("settings_restart_daemon"), ImVec2(0, 0), S.resolveFont("button"))) {
|
||||||
s_settingsState.debug_cats_dirty = false;
|
s_settingsState.confirm_restart_daemon = true;
|
||||||
app->restartDaemon();
|
|
||||||
}
|
}
|
||||||
if (ImGui::IsItemHovered()) ImGui::SetTooltip("%s", TR("tt_restart_daemon"));
|
if (ImGui::IsItemHovered()) ImGui::SetTooltip("%s", TR("tt_restart_daemon"));
|
||||||
}
|
}
|
||||||
@@ -2580,6 +2581,65 @@ void RenderSettingsPage(App* app) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Confirm: rescan blockchain (restarts the daemon, re-scans the whole chain — long but safe)
|
||||||
|
if (s_settingsState.confirm_rescan) {
|
||||||
|
if (BeginOverlayDialog(TR("confirm_rescan_title"), &s_settingsState.confirm_rescan, 500.0f, 0.94f)) {
|
||||||
|
ImGui::PushFont(Type().iconLarge());
|
||||||
|
ImGui::TextColored(ImVec4(1.0f, 0.8f, 0.2f, 1.0f), ICON_MD_WARNING);
|
||||||
|
ImGui::PopFont();
|
||||||
|
ImGui::SameLine();
|
||||||
|
ImGui::TextColored(ImVec4(1.0f, 0.8f, 0.2f, 1.0f), "%s", TR("warning"));
|
||||||
|
|
||||||
|
ImGui::Spacing();
|
||||||
|
ImGui::TextWrapped("%s", TR("confirm_rescan_msg"));
|
||||||
|
ImGui::Spacing();
|
||||||
|
ImGui::TextColored(ImVec4(0.3f, 0.8f, 0.3f, 1.0f), "%s", TR("confirm_rescan_safe"));
|
||||||
|
ImGui::Spacing();
|
||||||
|
ImGui::Separator();
|
||||||
|
ImGui::Spacing();
|
||||||
|
|
||||||
|
float btnW = (ImGui::GetContentRegionAvail().x - ImGui::GetStyle().ItemSpacing.x) * 0.5f;
|
||||||
|
if (ImGui::Button(TrId("cancel", "rescan_cancel").c_str(), ImVec2(btnW, 40))) {
|
||||||
|
s_settingsState.confirm_rescan = false;
|
||||||
|
}
|
||||||
|
ImGui::SameLine();
|
||||||
|
if (ImGui::Button(TrId("rescan", "rescan_confirm").c_str(), ImVec2(btnW, 40))) {
|
||||||
|
app->rescanBlockchain();
|
||||||
|
s_settingsState.confirm_rescan = false;
|
||||||
|
}
|
||||||
|
EndOverlayDialog();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Confirm: restart daemon (briefly drops the connection to apply changed options)
|
||||||
|
if (s_settingsState.confirm_restart_daemon) {
|
||||||
|
if (BeginOverlayDialog(TR("confirm_restart_daemon_title"), &s_settingsState.confirm_restart_daemon, 500.0f, 0.94f)) {
|
||||||
|
ImGui::PushFont(Type().iconLarge());
|
||||||
|
ImGui::TextColored(ImVec4(1.0f, 0.8f, 0.2f, 1.0f), ICON_MD_WARNING);
|
||||||
|
ImGui::PopFont();
|
||||||
|
ImGui::SameLine();
|
||||||
|
ImGui::TextColored(ImVec4(1.0f, 0.8f, 0.2f, 1.0f), "%s", TR("warning"));
|
||||||
|
|
||||||
|
ImGui::Spacing();
|
||||||
|
ImGui::TextWrapped("%s", TR("confirm_restart_daemon_msg"));
|
||||||
|
ImGui::Spacing();
|
||||||
|
ImGui::Separator();
|
||||||
|
ImGui::Spacing();
|
||||||
|
|
||||||
|
float btnW = (ImGui::GetContentRegionAvail().x - ImGui::GetStyle().ItemSpacing.x) * 0.5f;
|
||||||
|
if (ImGui::Button(TrId("cancel", "restartd_cancel").c_str(), ImVec2(btnW, 40))) {
|
||||||
|
s_settingsState.confirm_restart_daemon = false;
|
||||||
|
}
|
||||||
|
ImGui::SameLine();
|
||||||
|
if (ImGui::Button(TrId("settings_restart_daemon", "restartd_confirm").c_str(), ImVec2(btnW, 40))) {
|
||||||
|
s_settingsState.debug_cats_dirty = false;
|
||||||
|
app->restartDaemon();
|
||||||
|
s_settingsState.confirm_restart_daemon = false;
|
||||||
|
}
|
||||||
|
EndOverlayDialog();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace ui
|
} // namespace ui
|
||||||
|
|||||||
@@ -413,6 +413,11 @@ void I18n::loadBuiltinEnglish()
|
|||||||
strings_["confirm_delete_blockchain_title"] = "Delete Blockchain Data";
|
strings_["confirm_delete_blockchain_title"] = "Delete Blockchain Data";
|
||||||
strings_["confirm_delete_blockchain_msg"] = "This will stop the daemon, delete all blockchain data (blocks, chainstate, peers), and start a fresh sync from scratch. This can take several hours to complete.";
|
strings_["confirm_delete_blockchain_msg"] = "This will stop the daemon, delete all blockchain data (blocks, chainstate, peers), and start a fresh sync from scratch. This can take several hours to complete.";
|
||||||
strings_["confirm_delete_blockchain_safe"] = "Your wallet.dat, config, and transaction history are safe and will not be deleted.";
|
strings_["confirm_delete_blockchain_safe"] = "Your wallet.dat, config, and transaction history are safe and will not be deleted.";
|
||||||
|
strings_["confirm_rescan_title"] = "Rescan Blockchain";
|
||||||
|
strings_["confirm_rescan_msg"] = "This restarts the daemon and re-scans the entire blockchain for your wallet's transactions. It can take a long time and the wallet stays offline until it finishes.";
|
||||||
|
strings_["confirm_rescan_safe"] = "Your wallet.dat and blockchain data are not deleted — only re-scanned.";
|
||||||
|
strings_["confirm_restart_daemon_title"] = "Restart Daemon";
|
||||||
|
strings_["confirm_restart_daemon_msg"] = "This stops and restarts the daemon to apply the changed options. The wallet will briefly disconnect and reconnect.";
|
||||||
strings_["tt_encrypt"] = "Encrypt wallet.dat with a passphrase";
|
strings_["tt_encrypt"] = "Encrypt wallet.dat with a passphrase";
|
||||||
strings_["tt_change_pass"] = "Change the wallet encryption passphrase";
|
strings_["tt_change_pass"] = "Change the wallet encryption passphrase";
|
||||||
strings_["tt_lock"] = "Lock the wallet immediately";
|
strings_["tt_lock"] = "Lock the wallet immediately";
|
||||||
|
|||||||
Reference in New Issue
Block a user