From 6efe3c0f5c517889e9126a7940e3c969842f4960 Mon Sep 17 00:00:00 2001 From: DanS Date: Sat, 17 Oct 2026 16:37:28 -0500 Subject: [PATCH] feat(send,peers): show full recipient + contact label on confirm; actionable peers empty state MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - send confirm: the FROM/TO cards now show the FULL address (wrapped) instead of a middle-truncated preview, and the saved-contact label when the address matches the address book ("TO · Alice") — the strongest human check against a swapped recipient on the one screen meant to catch it. Cards auto-grow. - peers tab: the "No connected peers" empty state now carries the same actionable hint as the node-status banner instead of being a bare dead-end. Co-Authored-By: Claude Opus 4.8 --- src/ui/windows/peers_tab.cpp | 5 ++++- src/ui/windows/send_tab.cpp | 41 ++++++++++++++++++------------------ 2 files changed, 24 insertions(+), 22 deletions(-) diff --git a/src/ui/windows/peers_tab.cpp b/src/ui/windows/peers_tab.cpp index da91c5b..238d316 100644 --- a/src/ui/windows/peers_tab.cpp +++ b/src/ui/windows/peers_tab.cpp @@ -626,7 +626,10 @@ void RenderPeersTab(App* app) if (!app->isConnected()) { material::DrawEmptyState(ICON_MD_CLOUD_OFF, TR("not_connected")); } else if (state.peers.empty()) { - material::DrawEmptyState(ICON_MD_WIFI_TETHERING, TR("peers_no_connected")); + // Connected to the daemon but zero peers — mirror the node-status banner's actionable + // hint so this isn't just a bare "No connected peers" dead-end. + material::DrawEmptyState(ICON_MD_WIFI_TETHERING, TR("peers_no_connected"), + TR("node_banner_no_peers_detail")); } else { const float dp = ui::Layout::dpiScale(); float rowH = body2->LegacySize + capFont->LegacySize + Layout::spacingLg(); diff --git a/src/ui/windows/send_tab.cpp b/src/ui/windows/send_tab.cpp index 60c734f..7f26843 100644 --- a/src/ui/windows/send_tab.cpp +++ b/src/ui/windows/send_tab.cpp @@ -761,33 +761,32 @@ void RenderSendConfirmPopup(App* app) { float addrCardH = std::max(schema::UI().drawElement("tabs.send", "confirm-addr-card-min-height").size, schema::UI().drawElement("tabs.send", "confirm-addr-card-height").size * popVs); float popGlassRound = Layout::glassRounding() * S.drawElement("tabs.send", "confirm-glass-rounding-ratio").size; - // FROM card - { - Type().textColored(TypeStyle::Overline, OnSurfaceMedium(), TR("from_upper")); + // Address cards: show the FULL address (wrapped), not a middle-truncated preview — this is the + // one screen meant to catch a swapped recipient — plus the address-book label when the address + // matches a saved contact ("TO · Alice"), the strongest human-readable check against sending + // to the wrong place. The card grows to fit the wrapped text, and the dialog auto-sizes to it. + const float addrWrapW = popW - Layout::spacingMd() * 2.0f; + auto drawAddrCard = [&](const char* hdrKey, const char* addr) { + std::string hdr = TR(hdrKey); + std::string label = app->getAddressLabel(addr); + if (!label.empty()) { hdr += " \xC2\xB7 "; hdr += label; } // "·" separator + Type().textColored(TypeStyle::Overline, OnSurfaceMedium(), hdr.c_str()); ImVec2 cMin = ImGui::GetCursorScreenPos(); - ImVec2 cMax(cMin.x + popW, cMin.y + addrCardH); + ImVec2 txtSz = body2->CalcTextSizeA(body2->LegacySize, FLT_MAX, addrWrapW, addr); + float cardH = std::max(addrCardH, txtSz.y + Layout::spacingSm() * 2.0f); + ImVec2 cMax(cMin.x + popW, cMin.y + cardH); GlassPanelSpec gs; gs.rounding = popGlassRound; DrawGlassPanel(popDl, cMin, cMax, gs); popDl->AddText(body2, body2->LegacySize, ImVec2(cMin.x + Layout::spacingMd(), cMin.y + Layout::spacingSm()), - Success(), util::truncateMiddle(s_from_address, (int)S.drawElement("tabs.send", "confirm-addr-trunc-len").size).c_str()); - ImGui::Dummy(ImVec2(popW, addrCardH)); - ImGui::Dummy(ImVec2(0, Layout::spacingSm())); - } + Success(), addr, nullptr, addrWrapW); + ImGui::Dummy(ImVec2(popW, cardH)); + }; - // TO card - { - Type().textColored(TypeStyle::Overline, OnSurfaceMedium(), TR("to_upper")); - ImVec2 cMin = ImGui::GetCursorScreenPos(); - ImVec2 cMax(cMin.x + popW, cMin.y + addrCardH); - GlassPanelSpec gs; gs.rounding = popGlassRound; - DrawGlassPanel(popDl, cMin, cMax, gs); - popDl->AddText(body2, body2->LegacySize, - ImVec2(cMin.x + Layout::spacingMd(), cMin.y + Layout::spacingSm()), - Success(), util::truncateMiddle(s_to_address, (int)S.drawElement("tabs.send", "confirm-addr-trunc-len").size).c_str()); - ImGui::Dummy(ImVec2(popW, addrCardH)); - ImGui::Dummy(ImVec2(0, Layout::spacingMd())); - } + drawAddrCard("from_upper", s_from_address); + ImGui::Dummy(ImVec2(0, Layout::spacingSm())); + drawAddrCard("to_upper", s_to_address); + ImGui::Dummy(ImVec2(0, Layout::spacingMd())); // Fee tier selector {