diff --git a/src/ui/pages/settings_page.cpp b/src/ui/pages/settings_page.cpp index 5274840..9ccd623 100644 --- a/src/ui/pages/settings_page.cpp +++ b/src/ui/pages/settings_page.cpp @@ -2009,57 +2009,6 @@ void RenderSettingsPage(App* app) { // Node maintenance buttons (full-node build only) if (app->supportsFullNodeLifecycleActions()) { ImFont* btnFont = S.resolveFont("button"); - float nodeBtnW; - { - if (btnFont) ImGui::PushFont(btnFont); - nodeBtnW = rowBtnW({TR("test_connection"), TR("rescan"), - TR("delete_blockchain"), TR("repair_wallet")}); - if (btnFont) ImGui::PopFont(/* btnFont */); - } - ImGui::SetCursorScreenPos(ImVec2(leftX, ImGui::GetCursorScreenPos().y)); - ImGui::BeginDisabled(!app->isConnected()); - if (TactileButton(TR("test_connection"), ImVec2(nodeBtnW, 0), btnFont)) { - if (app->rpc() && app->rpc()->isConnected() && app->worker()) { - app->worker()->post([rpc = app->rpc()]() -> rpc::RPCWorker::MainCb { - try { - rpc::RPCClient::TraceScope trace("Settings / Test connection"); - rpc->call("getinfo"); - return []() { - Notifications::instance().success("RPC connection OK"); - }; - } catch (const std::exception& e) { - std::string err = e.what(); - return [err]() { - Notifications::instance().error("RPC error: " + err); - }; - } - }); - } else { - Notifications::instance().warning("Not connected to daemon"); - } - } - if (ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled)) ImGui::SetTooltip("%s", TR("tt_test_conn")); - ImGui::SameLine(0, Layout::spacingMd()); - if (TactileButton(TR("rescan"), ImVec2(nodeBtnW, 0), btnFont)) { - s_settingsState.confirm_rescan = true; - } - if (ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled)) ImGui::SetTooltip("%s", TR("tt_rescan")); - ImGui::EndDisabled(); - - // Row 2: Delete blockchain | Repair wallet (embedded daemon only) — paired on - // one line with the same width/style as the Test connection | Rescan row above. - ImGui::SetCursorScreenPos(ImVec2(leftX, ImGui::GetCursorScreenPos().y + Layout::spacingSm())); - ImGui::BeginDisabled(!app->isUsingEmbeddedDaemon()); - if (TactileButton(TR("delete_blockchain"), ImVec2(nodeBtnW, 0), btnFont)) { - s_settingsState.confirm_delete_blockchain = true; - } - if (ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled)) ImGui::SetTooltip("%s", TR("tt_delete_blockchain")); - ImGui::SameLine(0, Layout::spacingMd()); - if (TactileButton(TR("repair_wallet"), ImVec2(nodeBtnW, 0), btnFont)) { - s_settingsState.confirm_repair_wallet = true; - } - if (ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled)) ImGui::SetTooltip("%s", TR("tt_repair_wallet")); - ImGui::EndDisabled(); // ---- Daemon binary: installed vs bundled, with explicit reinstall ---- // The wallet only auto-places dragonxd when it's missing (never overwrites a @@ -2136,18 +2085,66 @@ void RenderSettingsPage(App* app) { } ImGui::Dummy(ImVec2(0, Layout::spacingXs())); - // Install bundled daemon | Refresh — paired, same width/style as the rows above. + // One toolbar row of all node actions: the daemon-binary actions first + // (Install bundled | Refresh), then the maintenance actions right after + // (Test connection | Rescan | Delete blockchain | Repair wallet). Auto-sized so + // they pack onto a single line. ImGui::SetCursorScreenPos(ImVec2(leftX, ImGui::GetCursorScreenPos().y)); + // Install bundled (embedded daemon + a bundled daemon present) ImGui::BeginDisabled(!app->isUsingEmbeddedDaemon() || !bun.available); - if (TactileButton(TR("daemon_install_bundled"), ImVec2(nodeBtnW, 0), btnFont)) { + if (TactileButton(TR("daemon_install_bundled"), ImVec2(0, 0), btnFont)) { s_settingsState.confirm_reinstall_daemon = true; } if (ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled)) ImGui::SetTooltip("%s", TR("tt_daemon_install_bundled")); ImGui::EndDisabled(); ImGui::SameLine(0, Layout::spacingMd()); - if (TactileButton(TR("refresh"), ImVec2(nodeBtnW, 0), btnFont)) { + // Refresh (always available) + if (TactileButton(TR("refresh"), ImVec2(0, 0), btnFont)) { s_settingsState.daemon_info_loaded = false; // recompute next frame } + ImGui::SameLine(0, Layout::spacingMd()); + // Test connection | Rescan blockchain (need an active RPC connection) + ImGui::BeginDisabled(!app->isConnected()); + if (TactileButton(TR("test_connection"), ImVec2(0, 0), btnFont)) { + if (app->rpc() && app->rpc()->isConnected() && app->worker()) { + app->worker()->post([rpc = app->rpc()]() -> rpc::RPCWorker::MainCb { + try { + rpc::RPCClient::TraceScope trace("Settings / Test connection"); + rpc->call("getinfo"); + return []() { + Notifications::instance().success("RPC connection OK"); + }; + } catch (const std::exception& e) { + std::string err = e.what(); + return [err]() { + Notifications::instance().error("RPC error: " + err); + }; + } + }); + } else { + Notifications::instance().warning("Not connected to daemon"); + } + } + if (ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled)) ImGui::SetTooltip("%s", TR("tt_test_conn")); + ImGui::SameLine(0, Layout::spacingMd()); + if (TactileButton(TR("rescan"), ImVec2(0, 0), btnFont)) { + s_settingsState.confirm_rescan = true; + } + if (ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled)) ImGui::SetTooltip("%s", TR("tt_rescan")); + ImGui::EndDisabled(); + ImGui::SameLine(0, Layout::spacingMd()); + // Delete blockchain | Repair wallet (embedded daemon only) + ImGui::BeginDisabled(!app->isUsingEmbeddedDaemon()); + if (TactileButton(TR("delete_blockchain"), ImVec2(0, 0), btnFont)) { + s_settingsState.confirm_delete_blockchain = true; + } + if (ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled)) ImGui::SetTooltip("%s", TR("tt_delete_blockchain")); + ImGui::SameLine(0, Layout::spacingMd()); + if (TactileButton(TR("repair_wallet"), ImVec2(0, 0), btnFont)) { + s_settingsState.confirm_repair_wallet = true; + } + if (ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled)) ImGui::SetTooltip("%s", TR("tt_repair_wallet")); + ImGui::EndDisabled(); } }