diff --git a/UPDATELOG.md b/UPDATELOG.md index a448523f..6fe8f8f1 100644 --- a/UPDATELOG.md +++ b/UPDATELOG.md @@ -11,6 +11,7 @@ - 新增批量选择配置文件功能 - 新增本地备份功能 - 主界面“当前节点”卡片新增自动延迟检测开关(默认关闭) +- 允许独立控制订阅自动更新 ### 🚀 优化改进 diff --git a/src-tauri/src/config/prfitem.rs b/src-tauri/src/config/prfitem.rs index f978260a..bb9ff7a6 100644 --- a/src-tauri/src/config/prfitem.rs +++ b/src-tauri/src/config/prfitem.rs @@ -101,6 +101,10 @@ pub struct PrfOption { #[serde(skip_serializing_if = "Option::is_none")] pub danger_accept_invalid_certs: Option, + #[serde(default = "default_allow_auto_update")] + #[serde(skip_serializing_if = "Option::is_none")] + pub allow_auto_update: Option, + pub merge: Option, pub script: Option, @@ -122,6 +126,7 @@ impl PrfOption { a.danger_accept_invalid_certs = b .danger_accept_invalid_certs .or(a.danger_accept_invalid_certs); + a.allow_auto_update = b.allow_auto_update.or(a.allow_auto_update); a.update_interval = b.update_interval.or(a.update_interval); a.merge = b.merge.or(a.merge); a.script = b.script.or(a.script); @@ -246,6 +251,7 @@ impl PrfItem { let self_proxy = opt_ref.is_some_and(|o| o.self_proxy.unwrap_or(false)); let accept_invalid_certs = opt_ref.is_some_and(|o| o.danger_accept_invalid_certs.unwrap_or(false)); + let allow_auto_update = opt_ref.map(|o| o.allow_auto_update.unwrap_or(true)); let user_agent = opt_ref.and_then(|o| o.user_agent.clone()); let update_interval = opt_ref.and_then(|o| o.update_interval); let timeout = opt_ref.and_then(|o| o.timeout_seconds).unwrap_or(20); @@ -404,6 +410,7 @@ impl PrfItem { rules, proxies, groups, + allow_auto_update, ..PrfOption::default() }), home, @@ -547,3 +554,8 @@ impl PrfItem { fs::write(path, data.as_bytes()).context("failed to save the file") } } + +// 向前兼容,默认为订阅启用自动更新 +fn default_allow_auto_update() -> Option { + Some(true) +} diff --git a/src-tauri/src/feat/profile.rs b/src-tauri/src/feat/profile.rs index 3728a067..625bdfb2 100644 --- a/src-tauri/src/feat/profile.rs +++ b/src-tauri/src/feat/profile.rs @@ -45,6 +45,14 @@ pub async fn update_profile( } else if item.url.is_none() { log::warn!(target: "app", "[订阅更新] {uid} 缺少URL,无法更新"); bail!("failed to get the profile item url"); + } else if !item + .option + .as_ref() + .and_then(|o| o.allow_auto_update) + .unwrap_or(true) + { + log::info!(target: "app", "[订阅更新] {} 禁止自动更新,跳过更新", uid); + None } else { log::info!(target: "app", "[订阅更新] {} 是远程订阅,URL: {}", diff --git a/src/components/profile/profile-viewer.tsx b/src/components/profile/profile-viewer.tsx index 7c7ca377..e714507c 100644 --- a/src/components/profile/profile-viewer.tsx +++ b/src/components/profile/profile-viewer.tsx @@ -377,6 +377,17 @@ export function ProfileViewer({ onChange, ref }: ProfileViewerProps) { )} /> + + ( + + {t("Allow Auto Update")} + + + )} + /> )} diff --git a/src/locales/en.json b/src/locales/en.json index 4b3fb239..a39be05c 100644 --- a/src/locales/en.json +++ b/src/locales/en.json @@ -706,5 +706,6 @@ "Selected profiles deleted successfully": "Selected profiles deleted successfully", "Prefer System Titlebar": "Prefer System Titlebar", "App Log Max Size": "App Log Max Size", - "App Log Max Count": "App Log Max Count" + "App Log Max Count": "App Log Max Count", + "Allow Auto Update": "Allow Auto Update" } diff --git a/src/locales/zh.json b/src/locales/zh.json index 16f5a6bd..2ccdec10 100644 --- a/src/locales/zh.json +++ b/src/locales/zh.json @@ -706,5 +706,6 @@ "Selected profiles deleted successfully": "选中的订阅已成功删除", "Prefer System Titlebar": "优先使用系统标题栏", "App Log Max Size": "应用日志最大大小", - "App Log Max Count": "应用日志最大数量" + "App Log Max Count": "应用日志最大数量", + "Allow Auto Update": "允许自动更新" } diff --git a/src/services/types.d.ts b/src/services/types.d.ts index d3b5fd27..1a2a2926 100644 --- a/src/services/types.d.ts +++ b/src/services/types.d.ts @@ -270,6 +270,7 @@ interface IProfileOption { update_interval?: number; timeout_seconds?: number; danger_accept_invalid_certs?: boolean; + allow_auto_update?: boolean; merge?: string; script?: string; rules?: string;