feat(peers): success toasts for ban/unban/clear + confirm the bulk Clear-All

Peer ban actions only toasted on failure; success was silent. Added success
toasts for ban/unban/clear-all, and the bulk "Clear All Bans" now takes a
confirming second click (per-row unban stays one-click). The setban/clearbanned
RPC calls are unchanged.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-10-18 23:35:32 -05:00
co-authored by Claude Opus 4.8
parent a90aa29478
commit 534120d3de
2 changed files with 21 additions and 4 deletions
+3 -2
View File
@@ -3772,7 +3772,7 @@ void App::banPeer(const std::string& ip, int duration_seconds)
}
return [this, err]() {
if (!err.empty()) ui::Notifications::instance().error(std::string(TR("toast_ban_failed")) + util::friendlyRpcError(err));
else refreshPeerInfo();
else { ui::Notifications::instance().success(TR("toast_peer_banned")); refreshPeerInfo(); }
};
});
}
@@ -3790,7 +3790,7 @@ void App::unbanPeer(const std::string& ip)
}
return [this, err]() {
if (!err.empty()) ui::Notifications::instance().error(std::string(TR("toast_unban_failed")) + util::friendlyRpcError(err));
else refreshPeerInfo();
else { ui::Notifications::instance().success(TR("toast_peer_unbanned")); refreshPeerInfo(); }
};
});
}
@@ -3809,6 +3809,7 @@ void App::clearBans()
return [this, err]() {
if (!err.empty()) { ui::Notifications::instance().error(std::string(TR("toast_clear_bans_failed")) + util::friendlyRpcError(err)); return; }
state_.banned_peers.clear();
ui::Notifications::instance().success(TR("toast_bans_cleared"));
refreshPeerInfo();
};
});
+18 -2
View File
@@ -33,6 +33,7 @@ using namespace material;
// Track selected peer for ban action
static int s_selected_peer_idx = -1;
static int s_selected_banned_idx = -1;
static bool s_confirm_clear_bans = false; // inline confirm for the bulk Clear-All-Bans action
// Helper: Extract IP without port
static std::string ExtractIP(const std::string& addr)
@@ -931,10 +932,25 @@ void RenderPeersTab(App* app)
// ================================================================
if (s_show_banned && !state.bannedPeers.empty()) {
ImGui::BeginDisabled(!app->isConnected());
if (TactileSmallButton(TR("peers_clear_all_bans"), S.resolveFont("button"))) {
app->clearBans();
if (!s_confirm_clear_bans) {
if (TactileSmallButton(TR("peers_clear_all_bans"), S.resolveFont("button")))
s_confirm_clear_bans = true; // bulk action takes a confirming second click
} else {
char cb[96];
snprintf(cb, sizeof(cb), TR("peers_clear_bans_confirm"), (int)state.bannedPeers.size());
ImGui::TextColored(material::WarningVec4(), "%s", cb);
ImGui::SameLine();
if (TactileSmallButton(TR("peers_clear_bans_confirm_yes"), S.resolveFont("button"))) {
app->clearBans();
s_confirm_clear_bans = false;
}
ImGui::SameLine();
if (TactileSmallButton(TR("cancel"), S.resolveFont("button")))
s_confirm_clear_bans = false;
}
ImGui::EndDisabled();
} else {
s_confirm_clear_bans = false; // no stale confirm across tab toggles / after bans clear
}
ImGui::EndChild(); // ##PeersScroll