feat(update): 应用内更新提示支持英文 release notes

This commit is contained in:
t8y2 committed 2026-07-07 00:26:56 +08:00
1 parent f45011977f
commit 9cbe857a2a
11 files changed
+214 -20

No files matched your search

+2 -1
View File
@@ -363,7 +363,8 @@ fn build_plugin_status(
}
async fn latest_jdbc_plugin() -> Option<JdbcPluginLatest> {
fetch_latest_release().await.ok().and_then(|release| release.jdbc_plugin)
// 只需 jdbc_plugin,不关心 release notes;传中文 locale 跳过英文 notes 拉取
fetch_latest_release("zh-CN").await.ok().and_then(|release| release.jdbc_plugin)
}
async fn download_jdbc_plugin_zip_with_progress(progress: &impl Fn(AgentProgressEvent)) -> Result<Vec<u8>, String> {
+64 -3
View File
@@ -2,6 +2,7 @@ use serde::{Deserialize, Serialize};
const LATEST_JSON_PATH: &str = "https://github.com/t8y2/dbx/releases/latest/download/latest.json";
const LATEST_JSON_R2_PATH: &str = "releases/latest/latest.json";
const LATEST_EN_NOTES_R2_PATH: &str = "changelog/latest-en.json";
const GITHUB_RELEASE_API_PREFIX: &str = "https://api.github.com/repos/t8y2/dbx/releases/tags/v";
const RELEASE_URL_PREFIX: &str = "https://github.com/t8y2/dbx/releases/tag/v";
@@ -14,6 +15,10 @@ pub struct TauriRelease {
pub jdbc_plugin: Option<JdbcPluginLatest>,
#[serde(skip)]
pub github: Option<GithubReleaseMetadata>,
// 英文 release notes,由 R2 latest-en.json 填充(latest.json 不含此字段)。
// 仅当用户界面非中文时拉取,build_update_info 优先用它作为 release_notes。
#[serde(skip)]
pub notes_en: Option<String>,
}
#[derive(Debug, Clone, Deserialize)]
@@ -41,7 +46,7 @@ pub struct UpdateInfo {
pub release_notes: String,
}
pub async fn fetch_latest_release() -> Result<TauriRelease, String> {
pub async fn fetch_latest_release(locale: &str) -> Result<TauriRelease, String> {
let client = build_update_http_client()?;
let resp = crate::race_download(&client, LATEST_JSON_PATH, LATEST_JSON_R2_PATH, "dbx-update-checker")
@@ -52,9 +57,44 @@ pub async fn fetch_latest_release() -> Result<TauriRelease, String> {
if let Ok(github) = fetch_github_release_metadata(&client, &release.version).await {
release.github = Some(github);
}
// 非中文界面用户额外拉取英文 release notes;失败/版本不匹配则保持 None,上层回退中文。
if !is_chinese_locale(locale) {
if let Ok(notes_en) = fetch_latest_release_notes_en(&client, &release.version).await {
release.notes_en = Some(notes_en);
}
}
Ok(release)
}
// 拉取 R2 上的英文 release notes(仅最新版本)。version 必须与 latest.json 的 version 一致才采用,
// 防止 sync-changelog 尚未更新时拿到旧版本英文 notes。
async fn fetch_latest_release_notes_en(client: &reqwest::Client, expected_version: &str) -> Result<String, String> {
let url = format!("{}{LATEST_EN_NOTES_R2_PATH}", crate::R2_CDN_BASE);
let resp = client
.get(&url)
.header(reqwest::header::USER_AGENT, "dbx-update-checker")
.send()
.await
.and_then(|r| r.error_for_status())
.map_err(|e| format!("Failed to fetch English release notes: {e}"))?;
let data: LatestEnNotes = resp.json().await.map_err(|e| format!("Failed to parse English release notes: {e}"))?;
if normalize_version(&data.version) == normalize_version(expected_version) {
Ok(data.notes)
} else {
Err(format!("English release notes version {} mismatch expected {}", data.version, expected_version))
}
}
fn is_chinese_locale(locale: &str) -> bool {
locale == "zh-CN" || locale == "zh-TW"
}
#[derive(Debug, Deserialize)]
struct LatestEnNotes {
version: String,
notes: String,
}
fn build_update_http_client() -> Result<reqwest::Client, String> {
let mut builder =
reqwest::Client::builder().timeout(std::time::Duration::from_secs(10)).user_agent("dbx-update-checker");
@@ -212,9 +252,9 @@ async fn fetch_github_release_metadata(
pub fn build_update_info(release: TauriRelease, current_version: &str) -> UpdateInfo {
let latest_version = normalize_version(&release.version);
let github = release.github.as_ref();
let release_notes = github
.and_then(|metadata| non_empty(metadata.body.as_deref()))
let release_notes = non_empty(release.notes_en.as_deref())
.map(ToOwned::to_owned)
.or_else(|| github.and_then(|metadata| non_empty(metadata.body.as_deref())).map(ToOwned::to_owned))
.or(release.notes)
.unwrap_or_default();
let release_name = github
@@ -386,6 +426,7 @@ HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Internet Settings
html_url: Some("https://github.com/t8y2/dbx/releases/tag/v0.5.3".to_string()),
body: Some("### 新功能\n\n真实发布说明".to_string()),
}),
notes_en: None,
};
let info = build_update_info(release, "0.5.2");
@@ -395,4 +436,24 @@ HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Internet Settings
assert_eq!(info.release_notes, "### 新功能\n\n真实发布说明");
assert!(!info.portable_mode);
}
#[test]
fn update_info_prefers_english_notes_when_present() {
// 非中文界面用户:notes_en 命中时优先于 GitHub 中文 body,应用内更新提示展示英文
let release = TauriRelease {
version: "0.5.3".to_string(),
notes: Some("See the assets below to download and install.".to_string()),
jdbc_plugin: None,
github: Some(GithubReleaseMetadata {
name: Some("DBX v0.5.3".to_string()),
html_url: Some("https://github.com/t8y2/dbx/releases/tag/v0.5.3".to_string()),
body: Some("### 新功能\n\n真实发布说明".to_string()),
}),
notes_en: Some("### New Features\n\nReal release notes".to_string()),
};
let info = build_update_info(release, "0.5.2");
assert_eq!(info.release_notes, "### New Features\n\nReal release notes");
}
}