Add update notice and require release build secrets
All checks were successful
Release App / release-app (push) Successful in 58s

This commit is contained in:
2026-04-24 14:55:36 +03:00
parent 94fc240086
commit 5a5677a994
8 changed files with 153 additions and 11 deletions

View File

@@ -1,5 +1,9 @@
#include "app.h"
#include <array>
#include <cstdio>
#include <future>
#include <curses.h>
#include "build_config.h"
@@ -14,6 +18,66 @@ bool is_truthy_env_value(const std::string &value) {
value == "YES" || value == "on" || value == "ON";
}
std::string shell_quote(const std::string &value) {
std::string quoted = "'";
for (char ch : value) {
if (ch == '\'') {
quoted += "'\\''";
} else {
quoted.push_back(ch);
}
}
quoted.push_back('\'');
return quoted;
}
std::string run_command_capture(const std::string &command) {
FILE *pipe = popen(command.c_str(), "r");
if (pipe == nullptr) {
return {};
}
std::string output;
std::array<char, 4096> buffer{};
while (std::fgets(buffer.data(), static_cast<int>(buffer.size()), pipe) != nullptr) {
output += buffer.data();
}
if (pclose(pipe) != 0) {
return {};
}
return output;
}
std::optional<std::string> fetch_update_notice() {
static constexpr const char *kLatestReleaseApiUrl =
"https://git.mshq.dev/api/v1/repos/AxiFisk/shinoa/releases/tags/latest";
if (std::string(TELEGRAM_TUI_BUILD_COMMIT).empty()) {
return std::nullopt;
}
const std::string response =
run_command_capture("curl -fsSL " + shell_quote(kLatestReleaseApiUrl) + " 2>/dev/null");
if (response.empty()) {
return std::nullopt;
}
try {
const json release = json::parse(response, nullptr, true, true);
const std::string target_commit = safe_string(release, "target_commitish");
if (target_commit.empty()) {
return std::nullopt;
}
const std::string current_commit = TELEGRAM_TUI_BUILD_COMMIT;
if (target_commit == current_commit || target_commit.rfind(current_commit, 0) == 0) {
return std::nullopt;
}
return std::string("Update available");
} catch (const json::exception &) {
return std::nullopt;
}
}
} // namespace
App::App() {
@@ -49,6 +113,8 @@ App::App() {
if (use_test_dc_) {
status_line_ = "Starting TDLib in test DC mode...";
}
start_update_check();
}
int App::run() {
@@ -80,6 +146,27 @@ int App::run() {
return 0;
}
void App::start_update_check() {
update_check_future_ =
std::async(std::launch::async, []() { return fetch_update_notice(); });
}
bool App::refresh_update_check_result() {
if (!update_check_future_.valid()) {
return false;
}
if (update_check_future_.wait_for(std::chrono::seconds(0)) != std::future_status::ready) {
return false;
}
const auto notice = update_check_future_.get();
if (notice == update_notice_) {
return false;
}
update_notice_ = notice.value_or(std::string());
return true;
}
std::optional<std::int64_t> App::highlighted_chat_id() const {
if (sorted_chat_ids_.empty()) {
return std::nullopt;