Files
ReSkate/Launcher/gui_changelog.cpp
AyeZeeBB 310922556c Launcher: a setting to test pre-releases
Settings > Launcher > "Test pre-releases" (off by default). On, the update
check takes the newest GitHub release that is not a draft and carries a
launcher.json, pre-release or not, in place of the latest full release:
a pre-release newer than the last release is installed, pinned by size
and SHA-256 as any release is. Turned off, the next check goes back to
the latest release, whose files then replace the pre-release's.

- The update notice says "Pre-release" for one, and the log names which
  kind of release was taken.
- The changelog shows the release the setting picks, marked as a
  pre-release, and is fetched again when the setting changes.
- --no-gui launches follow the same setting.
2026-10-15 14:23:06 -05:00

89 lines
3.6 KiB
C++

#include "gui_internal.h"
#include "Engine/Core/Log/logging.h"
// The CHANGELOGS panel: what the newest ReSkate release changed, as its GitHub release says.
namespace dingosdk::launcher_gui::detail {
namespace {
void start_fetch(Changelog& log) {
if (log.loading.exchange(true)) return;
if (log.worker.joinable()) log.worker.join();
log.error.clear();
log.fetched_prereleases = log.prereleases;
log.worker = std::thread([&log, prereleases = log.prereleases] {
update::ReleaseNote notes;
std::string error;
try {
notes = update::fetch_release_note(prereleases);
} catch (const std::exception& failure) {
error = failure.what();
logging::write(logging::Level::warning, logging::Channel::launcher,
std::string("Could not get the changelogs: ") + failure.what());
}
std::lock_guard lock(log.mutex);
log.incoming = std::move(notes);
log.incoming_error = std::move(error);
log.arrived = true;
log.loading = false;
});
}
} // namespace
void changelog_window(const Fonts& fonts, ImVec2 size, Ui& ui) {
auto& log = ui.notes;
{
std::lock_guard lock(log.mutex);
if (log.arrived) {
log.arrived = false;
log.error = std::move(log.incoming_error);
if (log.error.empty()) {
log.note = std::move(log.incoming);
log.text = thunderstore::readme_lines(log.note.notes);
log.loaded = true;
}
log.incoming = {};
}
}
// (The pre-release setting changed since: the notes are fetched again for it.)
if (log.loaded && !log.loading && log.fetched_prereleases != log.prereleases) log.loaded = false;
if (!log.loaded && !log.loading && log.error.empty()) start_fetch(log);
const auto panel = begin_panel("##changelog_panel", size, ImVec2(S(880), S(680)));
panel_title(fonts, "CHANGELOGS");
const float footer = ImGui::GetFrameHeight() + S(24) + S(12);
ImGui::BeginChild("##changelog_body", ImVec2(0, panel.y - ImGui::GetCursorPosY() - footer), ImGuiChildFlags_NavFlattened);
if (log.loading && !log.loaded) {
ImGui::TextDisabled("Loading the changelogs...");
} else if (!log.loaded) {
ImGui::PushTextWrapPos(0);
ImGui::TextDisabled("Could not load the changelogs: %s", log.error.c_str());
ImGui::PopTextWrapPos();
if (ImGui::Button("Try again", ImVec2(S(120), 0))) start_fetch(log);
} else {
const auto& note = log.note;
const auto label = note.title.empty() || note.title == note.tag ? note.tag : note.tag + " - " + note.title;
ImGui::PushFont(fonts.heading);
ImGui::TextUnformatted(label.c_str());
ImGui::PopFont();
if (!note.date.empty()) ImGui::TextDisabled("%s %s", note.prerelease ? "Pre-release," : "Released", note.date.c_str());
ImGui::Dummy(ImVec2(0, S(6)));
if (log.text.lines.empty()) ImGui::TextDisabled("This release has no patch notes.");
else draw_readme(fonts, log.text);
if (log.text.cut) ImGui::TextDisabled("The rest is on the release's GitHub page.");
}
ImGui::EndChild();
ImGui::SetCursorPosY(panel.y - S(24) - ImGui::GetFrameHeight());
if (ImGui::Button("Open on GitHub", ImVec2(S(160), 0))) open_url(update::releases_page());
ImGui::SameLine();
ImGui::SetCursorPosX(panel.x - S(28) - S(110));
const bool close = ImGui::Button("CLOSE", ImVec2(S(110), 0));
default_focus();
if (close || ImGui::IsKeyPressed(ImGuiKey_Escape, false)) ui.changelog = false;
ImGui::End();
}
} // namespace dingosdk::launcher_gui::detail