feat(updater): in-app dragonxd updater + browse-all-releases
Add a full-node daemon updater (util/DaemonUpdater + daemon_download_dialog) reachable from Settings -> NODE & SECURITY: downloads/verifies (SHA-256 + enforced ed25519 signature) and atomically installs the latest dragonxd from the project Gitea, with a "Restart daemon now" step. Add a shared "Browse all releases..." picker (release_list_view) to both the miner and daemon updaters so users can pin older/pre-release builds. Pure no-I/O cores (daemon_updater_core / xmrig_updater_core) are unit-tested; sign-daemon-release.sh signs release archives offline. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
87
src/ui/windows/release_list_view.h
Normal file
87
src/ui/windows/release_list_view.h
Normal file
@@ -0,0 +1,87 @@
|
||||
// DragonX Wallet - ImGui Edition
|
||||
// Copyright 2024-2026 The Hush Developers
|
||||
// Released under the GPLv3
|
||||
//
|
||||
// Shared "Browse all releases" picker, used by both the miner updater (XmrigDownloadDialog) and the
|
||||
// node updater (DaemonUpdateDialog). Renders a scrollable list of releases (tag, title, date, with
|
||||
// pre-release / installed badges) inside the current overlay dialog; the caller maps its updater's
|
||||
// release list into ReleaseRow values and acts on the clicked index.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "../../util/i18n.h"
|
||||
#include "../material/colors.h"
|
||||
#include "../material/draw_helpers.h"
|
||||
#include "../material/type.h"
|
||||
#include "imgui.h"
|
||||
|
||||
namespace dragonx {
|
||||
namespace ui {
|
||||
|
||||
struct ReleaseRow {
|
||||
std::string tag; // version tag, e.g. "v1.0.2"
|
||||
std::string title; // human title (release "name"), shown dimmed
|
||||
std::string date; // YYYY-MM-DD (already trimmed)
|
||||
bool prerelease = false; // show a pre-release badge
|
||||
bool hasAsset = true; // a build exists for this platform (else the row's Install is disabled)
|
||||
bool installed = false; // matches the currently-installed version (Install -> Reinstall)
|
||||
};
|
||||
|
||||
// Renders the picker. Returns the row index whose Install button was clicked this frame, or -1.
|
||||
// Sets *back when the Back button is clicked. If `globalDisabledTooltip` is non-null, every Install
|
||||
// button is disabled and shows that tooltip (e.g. "stop mining before updating the miner").
|
||||
inline int RenderReleaseList(const std::vector<ReleaseRow>& rows, float dp, bool* back,
|
||||
const char* globalDisabledTooltip = nullptr) {
|
||||
using namespace material;
|
||||
int clicked = -1;
|
||||
|
||||
Type().text(TypeStyle::Subtitle2, TR("upd_select_version"));
|
||||
ImGui::Spacing();
|
||||
|
||||
const float listH = 300.0f * dp;
|
||||
if (ImGui::BeginChild("##release_list", ImVec2(0, listH), true)) {
|
||||
const ImVec4 dim = ImGui::ColorConvertU32ToFloat4(OnSurfaceMedium());
|
||||
const ImVec4 warn = ImVec4(1.0f, 0.78f, 0.25f, 1.0f);
|
||||
const ImVec4 succ = ImGui::ColorConvertU32ToFloat4(Success());
|
||||
for (int i = 0; i < static_cast<int>(rows.size()); ++i) {
|
||||
const ReleaseRow& r = rows[i];
|
||||
ImGui::PushID(i);
|
||||
|
||||
ImGui::TextUnformatted(r.tag.c_str());
|
||||
if (r.prerelease) { ImGui::SameLine(); ImGui::TextColored(warn, "[%s]", TR("upd_prerelease")); }
|
||||
if (r.installed) { ImGui::SameLine(); ImGui::TextColored(succ, "[%s]", TR("upd_installed_badge")); }
|
||||
|
||||
if (!r.title.empty() || !r.date.empty()) {
|
||||
std::string meta = r.title;
|
||||
if (!r.title.empty() && !r.date.empty()) meta += " · ";
|
||||
meta += r.date;
|
||||
ImGui::TextColored(dim, "%s", meta.c_str());
|
||||
}
|
||||
|
||||
const char* lbl = r.installed ? TR("upd_reinstall") : TR("upd_install");
|
||||
const bool disabled = !r.hasAsset || globalDisabledTooltip != nullptr;
|
||||
ImGui::BeginDisabled(disabled);
|
||||
if (TactileButton(lbl, ImVec2(140.0f * dp, 0))) clicked = i;
|
||||
ImGui::EndDisabled();
|
||||
if (disabled && ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled))
|
||||
material::Tooltip("%s", globalDisabledTooltip ? globalDisabledTooltip
|
||||
: TR("upd_no_build_platform"));
|
||||
|
||||
ImGui::Spacing();
|
||||
ImGui::Separator();
|
||||
ImGui::Spacing();
|
||||
ImGui::PopID();
|
||||
}
|
||||
}
|
||||
ImGui::EndChild();
|
||||
|
||||
ImGui::Spacing();
|
||||
if (TactileButton(TR("upd_back"), ImVec2(ImGui::GetContentRegionAvail().x, 0))) *back = true;
|
||||
return clicked;
|
||||
}
|
||||
|
||||
} // namespace ui
|
||||
} // namespace dragonx
|
||||
Reference in New Issue
Block a user