Update checker dialog

This commit is contained in:
sentientstardust
2026-05-09 17:27:16 +01:00
parent fd67e4a421
commit 6ab2e96c0a
5 changed files with 215 additions and 6 deletions

View File

@@ -21,6 +21,7 @@
#include <boost/property_tree/ini_parser.hpp>
#include <boost/property_tree/ptree_fwd.hpp>
#include <boost/algorithm/string/predicate.hpp>
#include <boost/algorithm/string.hpp>
#include <boost/format/format_fwd.hpp>
#include <boost/log/trivial.hpp>
#include <boost/uuid/uuid.hpp>
@@ -39,7 +40,10 @@ using namespace nlohmann;
namespace Slic3r {
static const std::string VERSION_CHECK_URL = "https://check-version.orcaslicer.com/latest";
static const std::string VERSION_CHECK_URL = "https://gradients.garden/orcaslicer_imagemap/current_version.json";
static const std::string VERSION_CHECK_URL_LEGACY = "https://check-version.orcaslicer.com/latest";
static const std::string VERSION_CHECK_MODE = "platform_json";
static const std::string VERSION_DOWNLOAD_URL = "https://gitlab.com/sentient_stardust/orcaslicer-imagemap/-/packages";
static const std::string PROFILE_UPDATE_URL = "https://api.github.com/repos/OrcaSlicer/orcaslicer-profiles/releases/tags";
static const std::string MODELS_STR = "models";
@@ -1604,7 +1608,26 @@ std::string AppConfig::config_path()
std::string AppConfig::version_check_url() const
{
auto from_settings = get("version_check_url");
return from_settings.empty() ? VERSION_CHECK_URL : from_settings;
if (!from_settings.empty())
return from_settings;
auto mode = version_check_mode();
boost::algorithm::to_lower(mode);
if (mode == "platform_json" || mode == "json_platform")
return VERSION_CHECK_URL;
return VERSION_CHECK_URL_LEGACY;
}
std::string AppConfig::version_check_mode() const
{
auto from_settings = get("version_check_mode");
return from_settings.empty() ? VERSION_CHECK_MODE : from_settings;
}
std::string AppConfig::version_download_url() const
{
auto from_settings = get("version_download_url");
return from_settings.empty() ? VERSION_DOWNLOAD_URL : from_settings;
}
std::string AppConfig::profile_update_url() const

View File

@@ -311,6 +311,8 @@ public:
// Get the Slic3r version check url.
// This returns a hardcoded string unless it is overriden by "version_check_url" in the ini file.
std::string version_check_url() const;
std::string version_check_mode() const;
std::string version_download_url() const;
// Get the Orca profile update url.
std::string profile_update_url() const;

View File

@@ -22,6 +22,7 @@
#include <iterator>
#include <exception>
#include <cstdlib>
#include <optional>
#include <regex>
#include <thread>
#include <string_view>
@@ -2965,9 +2966,16 @@ bool GUI_App::on_init_inner()
if (!skip_this_version
|| evt.GetInt() != 0) {
UpdateVersionDialog dialog(this->mainframe);
wxString extmsg = wxString::FromUTF8(version_info.description);
dialog.update_version_info(extmsg, version_info.version_str);
//dialog.update_version_info(version_info.description);
std::string version_check_mode = app_config->version_check_mode();
boost::algorithm::to_lower(version_check_mode);
const bool simple_update_dialog = version_check_mode == "platform_json" || version_check_mode == "json_platform";
if (simple_update_dialog) {
dialog.update_version_info_simple(SoftFever_VERSION, version_info.version_str);
} else {
wxString extmsg = wxString::FromUTF8(version_info.description);
dialog.update_version_info(extmsg, version_info.version_str);
//dialog.update_version_info(version_info.description);
}
if (evt.GetInt() != 0) {
dialog.m_button_skip_version->Hide();
}
@@ -5349,11 +5357,133 @@ void maybe_attach_updater_signature(Http& http, const std::string& canonical_que
void GUI_App::check_new_version_sf(bool show_tips, int by_user)
{
return;
(void) show_tips;
AppConfig* app_config = wxGetApp().app_config;
bool check_stable_only = app_config->get_bool("check_stable_update_only");
auto version_check_url = app_config->version_check_url();
auto version_check_mode = app_config->version_check_mode();
boost::algorithm::to_lower(version_check_mode);
const bool platform_json_mode = version_check_mode == "platform_json" || version_check_mode == "json_platform";
if (platform_json_mode) {
auto http = Http::get(version_check_url);
http.header("accept", "application/json")
.timeout_connect(5)
.timeout_max(10)
.on_error([](std::string body, std::string error, unsigned http_status) {
(void)body;
BOOST_LOG_TRIVIAL(error) << format("Error getting: `%1%`: HTTP %2%, %3%", "check_new_version_sf", http_status, error);
})
.on_complete([this, by_user, app_config](std::string body, unsigned http_status) {
if (http_status != 200)
return;
try {
boost::trim(body);
if (body.empty()) {
if (by_user != 0)
this->no_new_version();
return;
}
std::regex matcher("[0-9]+\\.[0-9]+(\\.[0-9]+)*(-[A-Za-z0-9.]+)?(\\+[A-Za-z0-9.]+)?");
std::string remote_version_str;
json root = json::parse(body);
std::vector<std::string> os_keys;
const std::string os = detect_updater_os();
const std::string arch = detect_updater_arch();
if (os == "win") {
os_keys.push_back("windows_" + arch);
} else if (os == "macos") {
os_keys.push_back("macos_" + arch);
} else if (os == "linux") {
os_keys.push_back("linux_" + arch);
}
os_keys.push_back(os);
auto read_version = [arch](const json& value) -> std::optional<std::string> {
if (value.is_string())
return value.get<std::string>();
if (!value.is_object())
return std::nullopt;
if (value.contains(arch)) {
const json& arch_value = value.at(arch);
if (arch_value.is_string())
return arch_value.get<std::string>();
if (arch_value.is_object() && arch_value.contains("version") && arch_value.at("version").is_string())
return arch_value.at("version").get<std::string>();
}
if (value.contains("version") && value.at("version").is_string())
return value.at("version").get<std::string>();
return std::nullopt;
};
auto find_version = [&os_keys, &read_version](const json& container) -> std::optional<std::string> {
if (!container.is_object())
return std::nullopt;
for (const std::string& key : os_keys) {
if (container.contains(key)) {
auto version = read_version(container.at(key));
if (version)
return version;
}
}
return std::nullopt;
};
std::optional<std::string> platform_version = find_version(root);
if (!platform_version && root.is_object() && root.contains("platforms"))
platform_version = find_version(root.at("platforms"));
if (!platform_version && root.is_object() && root.contains("versions"))
platform_version = find_version(root.at("versions"));
if (!platform_version && root.is_object() && root.contains("version"))
platform_version = read_version(root.at("version"));
if (!platform_version) {
if (by_user != 0)
this->no_new_version();
return;
}
remote_version_str = *platform_version;
boost::trim(remote_version_str);
if (remote_version_str.empty()) {
if (by_user != 0)
this->no_new_version();
return;
}
if (remote_version_str.front() == 'v')
remote_version_str.erase(0, 1);
Semver current_version = get_version(SoftFever_VERSION, matcher);
Semver remote_version = get_version(remote_version_str, matcher);
if (!remote_version.valid()) {
if (by_user != 0)
this->no_new_version();
return;
}
if (current_version.valid() && remote_version <= current_version) {
if (by_user != 0)
this->no_new_version();
return;
}
version_info.url = app_config->version_download_url();
version_info.version_str = remote_version.to_string_sf();
version_info.description = "";
version_info.force_upgrade = false;
this->request_new_version(by_user);
} catch (...) {}
});
http.perform();
return;
}
UpdaterQuery query{
detect_updater_iid(app_config),

View File

@@ -330,6 +330,7 @@ UpdateVersionDialog::UpdateVersionDialog(wxWindow *parent)
stable_only_label->SetFont(Label::Body_13);
stable_only_label->SetForegroundColour(wxColour(38, 46, 48));
stable_only_label->SetFont(Label::Body_12);
m_stable_only_label = stable_only_label;
m_button_cancel = new Button(this, _L("Cancel"));
m_button_cancel->SetStyle(ButtonStyle::Regular, ButtonType::Choice);
@@ -479,6 +480,7 @@ void UpdateVersionDialog::update_version_info(wxString release_note, wxString ve
// m_vebview_release_note->LoadURL(from_u8(url_line));
// }
// else {
m_button_download->SetLabel(_L("Download"));
m_simplebook_release_note->SetMaxSize(wxSize(FromDIP(560), FromDIP(430)));
m_simplebook_release_note->SetSelection(1);
m_text_up_info->SetLabel(wxString::Format(_L("Click to download new version in default browser: %s"), version));
@@ -503,6 +505,56 @@ void UpdateVersionDialog::update_version_info(wxString release_note, wxString ve
Fit();
}
void UpdateVersionDialog::update_version_info_simple(wxString current_version, wxString available_version)
{
m_text_up_info->Hide();
m_button_download->SetLabel(_L("Open Downloads"));
m_cb_stable_only->Hide();
m_stable_only_label->Hide();
m_simplebook_release_note->SetSelection(0);
const wxSize compact_note_size(FromDIP(360), FromDIP(110));
m_simplebook_release_note->SetSize(compact_note_size);
m_simplebook_release_note->SetMinSize(compact_note_size);
m_simplebook_release_note->SetMaxSize(compact_note_size);
m_scrollwindows_release_note->SetSize(compact_note_size);
m_scrollwindows_release_note->SetMinSize(compact_note_size);
m_scrollwindows_release_note->SetMaxSize(compact_note_size);
auto content_sizer = new wxBoxSizer(wxVERTICAL);
auto versions = new wxFlexGridSizer(2, 0, FromDIP(14));
versions->AddGrowableCol(1);
auto current_label = new Label(m_scrollwindows_release_note, _L("Current version:"));
current_label->SetFont(Label::Body_13);
current_label->SetForegroundColour(wxColour(38, 46, 48));
auto current_value = new Label(m_scrollwindows_release_note, current_version);
current_value->SetFont(Label::Body_13);
current_value->SetForegroundColour(wxColour(38, 46, 48));
auto available_label = new Label(m_scrollwindows_release_note, _L("Available version:"));
available_label->SetFont(Label::Body_13);
available_label->SetForegroundColour(wxColour(38, 46, 48));
auto available_value = new Label(m_scrollwindows_release_note, available_version);
available_value->SetFont(Label::Body_13);
available_value->SetForegroundColour(wxColour(38, 46, 48));
versions->Add(current_label, 0, wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL);
versions->Add(current_value, 1, wxEXPAND);
versions->Add(available_label, 0, wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL);
versions->Add(available_value, 1, wxEXPAND);
content_sizer->Add(versions, 0, wxALL | wxEXPAND, FromDIP(24));
m_scrollwindows_release_note->SetSizer(content_sizer);
m_scrollwindows_release_note->Layout();
wxGetApp().UpdateDlgDarkUI(this);
SetMinSize(wxDefaultSize);
SetMaxSize(wxDefaultSize);
Layout();
Fit();
SetMinSize(GetSize());
Centre(wxBOTH);
}
SecondaryCheckDialog::SecondaryCheckDialog(wxWindow* parent, wxWindowID id, const wxString& title, enum VisibleButtons btn_style, const wxPoint& pos, const wxSize& size, long style, bool not_show_again_check) // ORCA VisibleButtons instead ButtonStyle
:DPIFrame(parent, id, title, pos, size, style)
{

View File

@@ -92,6 +92,7 @@ public:
void RunScript(std::string script);
void on_dpi_changed(const wxRect& suggested_rect) override;
void update_version_info(wxString release_note, wxString version);
void update_version_info_simple(wxString current_version, wxString available_version);
std::vector<std::string> splitWithStl(std::string str, std::string pattern);
wxStaticBitmap* m_brand{nullptr};
@@ -104,6 +105,7 @@ public:
wxStaticBitmap* m_bitmap_open_in_browser;
Button* m_button_skip_version;
CheckBox* m_cb_stable_only;
Label* m_stable_only_label{nullptr};
Button* m_button_download;
Button* m_button_cancel;
std::string url_line;