feat(ui): migrate Explorer detail/loading + daemon-update prompt to reference design
Presentation-only reference-design migration: - Explorer loading modal -> struct-form overlay (idSuffix explorerloading); block- detail modal loses its header divider; the search button + the prev/next nav become TactileButton; TR() the hardcoded "Previous block"/"Next block" tooltips, "TxID:", and the "shielded" output fallback (3 new explorer_* keys + reuse the existing `shielded` key), all 8 langs. Block-fetch RPC path untouched. - Daemon-update startup prompt -> struct-form overlay (idSuffix daemonupdprompt), 2 StyledButton -> TactileButton, drop the footer divider. The reinstall/ prompted-size persistence logic is unchanged. Build + ctest + hygiene clean; "DRGX" ticker left hardcoded per convention. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
11
src/app.cpp
11
src/app.cpp
@@ -3368,7 +3368,11 @@ void App::maybeOfferDaemonUpdate()
|
||||
|
||||
void App::renderDaemonUpdatePrompt()
|
||||
{
|
||||
if (!ui::material::BeginOverlayDialog(TR("daemon_update_title"), &show_daemon_update_prompt_, 520.0f, 0.94f))
|
||||
ui::material::OverlayDialogSpec ov;
|
||||
ov.title = TR("daemon_update_title"); ov.p_open = &show_daemon_update_prompt_;
|
||||
ov.style = ui::material::OverlayStyle::BlurFloat;
|
||||
ov.cardWidth = 520.0f; ov.idSuffix = "daemonupdprompt";
|
||||
if (!ui::material::BeginOverlayDialog(ov))
|
||||
return;
|
||||
const float dp = ui::Layout::dpiScale();
|
||||
ImGui::TextWrapped("%s", TR("daemon_update_body"));
|
||||
@@ -3377,13 +3381,12 @@ void App::renderDaemonUpdatePrompt()
|
||||
ImGui::TextWrapped("%s", TR("daemon_update_safe"));
|
||||
ImGui::PopStyleColor();
|
||||
ImGui::Spacing();
|
||||
ImGui::Separator();
|
||||
if (ui::material::StyledButton(TR("daemon_update_now"), ImVec2(170 * dp, 0))) {
|
||||
if (ui::material::TactileButton(TR("daemon_update_now"), ImVec2(170 * dp, 0))) {
|
||||
show_daemon_update_prompt_ = false;
|
||||
reinstallBundledDaemon(); // stops the node (managed or external), overwrites, restarts
|
||||
}
|
||||
ImGui::SameLine();
|
||||
if (ui::material::StyledButton(TR("daemon_update_keep"), ImVec2(150 * dp, 0))) {
|
||||
if (ui::material::TactileButton(TR("daemon_update_keep"), ImVec2(150 * dp, 0))) {
|
||||
show_daemon_update_prompt_ = false;
|
||||
}
|
||||
ui::material::EndOverlayDialog();
|
||||
|
||||
@@ -483,7 +483,7 @@ static void renderSearchBar(App* app, float availWidth) {
|
||||
|
||||
// Search button — same height as input
|
||||
ImGui::SetCursorScreenPos(ImVec2(ImGui::GetCursorScreenPos().x, cursorY));
|
||||
bool clicked = material::StyledButton(TR("explorer_search"),
|
||||
bool clicked = material::TactileButton(TR("explorer_search"),
|
||||
ImVec2(btnW, barH));
|
||||
|
||||
std::string query(s_search_buf);
|
||||
@@ -1012,7 +1012,11 @@ static void renderBlockDetailModal(App* app) {
|
||||
|
||||
if (s_detail_loading && !s_show_detail_modal) {
|
||||
// Show a loading modal while fetching
|
||||
if (BeginOverlayDialog(TR("loading"), &s_detail_loading, 300.0f, 0.85f)) {
|
||||
OverlayDialogSpec lov;
|
||||
lov.title = TR("loading"); lov.p_open = &s_detail_loading;
|
||||
lov.style = OverlayStyle::BlurFloat;
|
||||
lov.cardWidth = 300.0f; lov.idSuffix = "explorerloading";
|
||||
if (BeginOverlayDialog(lov)) {
|
||||
ImGui::Spacing();
|
||||
char loadBuf[64];
|
||||
snprintf(loadBuf, sizeof(loadBuf), "%s%s", TR("loading"), material::LoadingDots());
|
||||
@@ -1055,7 +1059,7 @@ static void renderBlockDetailModal(App* app) {
|
||||
if (app->rpc() && app->rpc()->isConnected())
|
||||
fetchBlockDetail(app, s_detail_height - 1);
|
||||
}
|
||||
if (ImGui::IsItemHovered()) material::Tooltip("Previous block");
|
||||
if (ImGui::IsItemHovered()) material::Tooltip("%s", TR("explorer_prev_block"));
|
||||
ImGui::PopID();
|
||||
ImGui::PopFont();
|
||||
ImGui::SameLine();
|
||||
@@ -1069,7 +1073,7 @@ static void renderBlockDetailModal(App* app) {
|
||||
if (app->rpc() && app->rpc()->isConnected())
|
||||
fetchBlockDetail(app, s_detail_height + 1);
|
||||
}
|
||||
if (ImGui::IsItemHovered()) material::Tooltip("Next block");
|
||||
if (ImGui::IsItemHovered()) material::Tooltip("%s", TR("explorer_next_block"));
|
||||
ImGui::PopID();
|
||||
ImGui::PopFont();
|
||||
}
|
||||
@@ -1077,7 +1081,6 @@ static void renderBlockDetailModal(App* app) {
|
||||
ImGui::EndDisabled();
|
||||
}
|
||||
|
||||
ImGui::Separator();
|
||||
ImGui::Spacing();
|
||||
|
||||
// Show loading state inside the modal when navigating between blocks
|
||||
@@ -1253,7 +1256,7 @@ static void renderBlockDetailModal(App* app) {
|
||||
|
||||
// Full TxID with copy
|
||||
ImGui::PushFont(capFont);
|
||||
ImGui::TextColored(ImGui::ColorConvertU32ToFloat4(OnSurfaceMedium()), "TxID:");
|
||||
ImGui::TextColored(ImGui::ColorConvertU32ToFloat4(OnSurfaceMedium()), "%s", TR("explorer_txid"));
|
||||
ImGui::PopFont();
|
||||
ImGui::PushFont(body2);
|
||||
ImGui::PushStyleColor(ImGuiCol_Text, ImGui::ColorConvertU32ToFloat4(linkCol));
|
||||
@@ -1282,7 +1285,7 @@ static void renderBlockDetailModal(App* app) {
|
||||
for (const auto& vout : s_tx_detail["vout"]) {
|
||||
double val = vout.value("value", 0.0);
|
||||
int n = vout.value("n", 0);
|
||||
std::string addr = "shielded";
|
||||
std::string addr = TR("shielded");
|
||||
if (vout.contains("scriptPubKey") && vout["scriptPubKey"].contains("addresses") &&
|
||||
vout["scriptPubKey"]["addresses"].is_array() && !vout["scriptPubKey"]["addresses"].empty()) {
|
||||
addr = vout["scriptPubKey"]["addresses"][0].get<std::string>();
|
||||
|
||||
@@ -1937,6 +1937,9 @@ void I18n::loadBuiltinEnglish()
|
||||
strings_["explorer_block_merkle"] = "Merkle Root";
|
||||
strings_["explorer_tx_outputs"] = "Outputs";
|
||||
strings_["explorer_tx_size"] = "Size";
|
||||
strings_["explorer_txid"] = "TxID:";
|
||||
strings_["explorer_prev_block"] = "Previous block";
|
||||
strings_["explorer_next_block"] = "Next block";
|
||||
strings_["explorer_invalid_query"] = "Enter a block height or 64-character hash";
|
||||
strings_["explorer_invalid_response"] = "Invalid response from daemon";
|
||||
strings_["explorer_hash_not_found"] = "No block or transaction found for this hash";
|
||||
|
||||
Reference in New Issue
Block a user