mirror of
https://github.com/clash-verge-rev/clash-verge-rev.git
synced 2026-04-13 05:20:28 +08:00
fix: handle edge cases and add missing i18n
This commit is contained in:
parent
05fba11baa
commit
b7ae5f0ac9
@ -26,6 +26,11 @@ notifications:
|
||||
appHidden:
|
||||
title: تم إخفاء التطبيق
|
||||
body: Clash Verge يعمل في الخلفية.
|
||||
updateReady:
|
||||
title: Clash Verge Update
|
||||
body: A new version (v{version}) has been downloaded and is ready to install.
|
||||
installNow: Install Now
|
||||
later: Later
|
||||
service:
|
||||
adminInstallPrompt: يتطلب تثبيت خدمة Clash Verge صلاحيات المسؤول.
|
||||
adminUninstallPrompt: يتطلب إلغاء تثبيت خدمة Clash Verge صلاحيات المسؤول.
|
||||
|
||||
@ -26,6 +26,11 @@ notifications:
|
||||
appHidden:
|
||||
title: Anwendung ausgeblendet
|
||||
body: Clash Verge läuft im Hintergrund.
|
||||
updateReady:
|
||||
title: Clash Verge Update
|
||||
body: A new version (v{version}) has been downloaded and is ready to install.
|
||||
installNow: Install Now
|
||||
later: Later
|
||||
service:
|
||||
adminInstallPrompt: Für die Installation des Clash-Verge-Dienstes sind Administratorrechte erforderlich.
|
||||
adminUninstallPrompt: Für die Deinstallation des Clash-Verge-Dienstes sind Administratorrechte erforderlich.
|
||||
|
||||
@ -26,6 +26,11 @@ notifications:
|
||||
appHidden:
|
||||
title: Application Hidden
|
||||
body: Clash Verge is running in the background.
|
||||
updateReady:
|
||||
title: Clash Verge Update
|
||||
body: A new version (v{version}) has been downloaded and is ready to install.
|
||||
installNow: Install Now
|
||||
later: Later
|
||||
service:
|
||||
adminInstallPrompt: Installing the Clash Verge service requires administrator privileges.
|
||||
adminUninstallPrompt: Uninstalling the Clash Verge service requires administrator privileges.
|
||||
|
||||
@ -26,6 +26,11 @@ notifications:
|
||||
appHidden:
|
||||
title: Aplicación oculta
|
||||
body: Clash Verge se está ejecutando en segundo plano.
|
||||
updateReady:
|
||||
title: Clash Verge Update
|
||||
body: A new version (v{version}) has been downloaded and is ready to install.
|
||||
installNow: Install Now
|
||||
later: Later
|
||||
service:
|
||||
adminInstallPrompt: Instalar el servicio de Clash Verge requiere privilegios de administrador.
|
||||
adminUninstallPrompt: Desinstalar el servicio de Clash Verge requiere privilegios de administrador.
|
||||
|
||||
@ -26,6 +26,11 @@ notifications:
|
||||
appHidden:
|
||||
title: برنامه پنهان شد
|
||||
body: Clash Verge در پسزمینه در حال اجراست.
|
||||
updateReady:
|
||||
title: Clash Verge Update
|
||||
body: A new version (v{version}) has been downloaded and is ready to install.
|
||||
installNow: Install Now
|
||||
later: Later
|
||||
service:
|
||||
adminInstallPrompt: نصب سرویس Clash Verge به دسترسی مدیر نیاز دارد.
|
||||
adminUninstallPrompt: حذف سرویس Clash Verge به دسترسی مدیر نیاز دارد.
|
||||
|
||||
@ -26,6 +26,11 @@ notifications:
|
||||
appHidden:
|
||||
title: Aplikasi Disembunyikan
|
||||
body: Clash Verge berjalan di latar belakang.
|
||||
updateReady:
|
||||
title: Clash Verge Update
|
||||
body: A new version (v{version}) has been downloaded and is ready to install.
|
||||
installNow: Install Now
|
||||
later: Later
|
||||
service:
|
||||
adminInstallPrompt: Menginstal layanan Clash Verge memerlukan hak administrator.
|
||||
adminUninstallPrompt: Menghapus instalasi layanan Clash Verge memerlukan hak administrator.
|
||||
|
||||
@ -26,6 +26,11 @@ notifications:
|
||||
appHidden:
|
||||
title: アプリが非表示
|
||||
body: Clash Verge はバックグラウンドで実行中です。
|
||||
updateReady:
|
||||
title: Clash Verge Update
|
||||
body: A new version (v{version}) has been downloaded and is ready to install.
|
||||
installNow: Install Now
|
||||
later: Later
|
||||
service:
|
||||
adminInstallPrompt: Clash Verge サービスのインストールには管理者権限が必要です。
|
||||
adminUninstallPrompt: Clash Verge サービスのアンインストールには管理者権限が必要です。
|
||||
|
||||
@ -26,6 +26,11 @@ notifications:
|
||||
appHidden:
|
||||
title: 앱이 숨겨짐
|
||||
body: Clash Verge가 백그라운드에서 실행 중입니다.
|
||||
updateReady:
|
||||
title: Clash Verge Update
|
||||
body: A new version (v{version}) has been downloaded and is ready to install.
|
||||
installNow: Install Now
|
||||
later: Later
|
||||
service:
|
||||
adminInstallPrompt: Clash Verge 서비스 설치에는 관리자 권한이 필요합니다.
|
||||
adminUninstallPrompt: Clash Verge 서비스 제거에는 관리자 권한이 필요합니다.
|
||||
|
||||
@ -26,6 +26,11 @@ notifications:
|
||||
appHidden:
|
||||
title: Приложение скрыто
|
||||
body: Clash Verge работает в фоновом режиме.
|
||||
updateReady:
|
||||
title: Clash Verge Update
|
||||
body: A new version (v{version}) has been downloaded and is ready to install.
|
||||
installNow: Install Now
|
||||
later: Later
|
||||
service:
|
||||
adminInstallPrompt: Для установки службы Clash Verge требуются права администратора.
|
||||
adminUninstallPrompt: Для удаления службы Clash Verge требуются права администратора.
|
||||
|
||||
@ -26,6 +26,11 @@ notifications:
|
||||
appHidden:
|
||||
title: Uygulama Gizlendi
|
||||
body: Clash Verge arka planda çalışıyor.
|
||||
updateReady:
|
||||
title: Clash Verge Update
|
||||
body: A new version (v{version}) has been downloaded and is ready to install.
|
||||
installNow: Install Now
|
||||
later: Later
|
||||
service:
|
||||
adminInstallPrompt: Clash Verge hizmetini kurmak için yönetici ayrıcalıkları gerekir.
|
||||
adminUninstallPrompt: Clash Verge hizmetini kaldırmak için yönetici ayrıcalıkları gerekir.
|
||||
|
||||
@ -26,6 +26,11 @@ notifications:
|
||||
appHidden:
|
||||
title: Кушымта яшерелде
|
||||
body: Clash Verge фон режимында эшли.
|
||||
updateReady:
|
||||
title: Clash Verge Update
|
||||
body: A new version (v{version}) has been downloaded and is ready to install.
|
||||
installNow: Install Now
|
||||
later: Later
|
||||
service:
|
||||
adminInstallPrompt: Clash Verge хезмәтен урнаштыру өчен администратор хокуклары кирәк.
|
||||
adminUninstallPrompt: Clash Verge хезмәтен бетерү өчен администратор хокуклары кирәк.
|
||||
|
||||
@ -26,6 +26,11 @@ notifications:
|
||||
appHidden:
|
||||
title: 应用已隐藏
|
||||
body: Clash Verge 正在后台运行。
|
||||
updateReady:
|
||||
title: Clash Verge 更新
|
||||
body: 新版本 (v{version}) 已下载完成,是否立即安装?
|
||||
installNow: 立即安装
|
||||
later: 稍后
|
||||
service:
|
||||
adminInstallPrompt: 安装 Clash Verge 服务需要管理员权限
|
||||
adminUninstallPrompt: 卸载 Clash Verge 服务需要管理员权限
|
||||
|
||||
@ -26,6 +26,11 @@ notifications:
|
||||
appHidden:
|
||||
title: 應用已隱藏
|
||||
body: Clash Verge 正在背景執行。
|
||||
updateReady:
|
||||
title: Clash Verge Update
|
||||
body: A new version (v{version}) has been downloaded and is ready to install.
|
||||
installNow: Install Now
|
||||
later: Later
|
||||
service:
|
||||
adminInstallPrompt: 安裝 Clash Verge 服務需要管理員權限
|
||||
adminUninstallPrompt: 卸载 Clash Verge 服務需要管理員權限
|
||||
|
||||
@ -158,11 +158,18 @@ impl SilentUpdater {
|
||||
logging!(
|
||||
info,
|
||||
Type::System,
|
||||
"Update cache version ({}) > current ({}), attempting startup install",
|
||||
"Update cache version ({}) > current ({}), asking user to install",
|
||||
cached_version,
|
||||
current_version
|
||||
);
|
||||
|
||||
// Ask user for confirmation — they can skip and use the app normally.
|
||||
// The cache is preserved so next launch will ask again.
|
||||
if !Self::ask_user_to_install(app_handle, cached_version).await {
|
||||
logging!(info, Type::System, "User skipped update install, starting normally");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Read cached bytes
|
||||
let bytes = match Self::read_cache_bytes() {
|
||||
Ok(b) => b,
|
||||
@ -177,8 +184,8 @@ impl SilentUpdater {
|
||||
}
|
||||
};
|
||||
|
||||
// Need a fresh Update object from the server to call install()
|
||||
// Network should be available at startup (user just booted)
|
||||
// Need a fresh Update object from the server to call install().
|
||||
// This is a lightweight HTTP request (< 1s), not a re-download.
|
||||
let update = match app_handle.updater() {
|
||||
Ok(updater) => match updater.check().await {
|
||||
Ok(Some(u)) => u,
|
||||
@ -210,6 +217,20 @@ impl SilentUpdater {
|
||||
}
|
||||
};
|
||||
|
||||
// Verify the server's version matches the cached version.
|
||||
// If server now has a newer version, our cached bytes are stale.
|
||||
if update.version != *cached_version {
|
||||
logging!(
|
||||
info,
|
||||
Type::System,
|
||||
"Server version ({}) != cached version ({}), cache is stale, cleaning up",
|
||||
update.version,
|
||||
cached_version
|
||||
);
|
||||
Self::delete_cache();
|
||||
return false;
|
||||
}
|
||||
|
||||
let version = update.version.clone();
|
||||
logging!(info, Type::System, "Installing cached update v{version} at startup...");
|
||||
|
||||
@ -231,18 +252,15 @@ impl SilentUpdater {
|
||||
true
|
||||
}
|
||||
Ok(Ok(Err(e))) => {
|
||||
logging!(warn, Type::System, "Startup install failed: {e}, cleaning up");
|
||||
Self::delete_cache();
|
||||
logging!(warn, Type::System, "Startup install failed: {e}, will retry next launch");
|
||||
false
|
||||
}
|
||||
Ok(Err(e)) => {
|
||||
logging!(warn, Type::System, "Startup install task panicked: {e}, cleaning up");
|
||||
Self::delete_cache();
|
||||
logging!(warn, Type::System, "Startup install task panicked: {e}, will retry next launch");
|
||||
false
|
||||
}
|
||||
Err(_) => {
|
||||
logging!(warn, Type::System, "Startup install timed out (30s), cleaning up");
|
||||
Self::delete_cache();
|
||||
logging!(warn, Type::System, "Startup install timed out (30s), will retry next launch");
|
||||
false
|
||||
}
|
||||
};
|
||||
@ -256,6 +274,36 @@ impl SilentUpdater {
|
||||
}
|
||||
}
|
||||
|
||||
// ─── User Confirmation Dialog ────────────────────────────────────────────────
|
||||
|
||||
impl SilentUpdater {
|
||||
/// Show a native dialog asking the user to install or skip the update.
|
||||
/// Returns true if user chose to install, false if they chose to skip.
|
||||
async fn ask_user_to_install(app_handle: &tauri::AppHandle, version: &str) -> bool {
|
||||
use tauri_plugin_dialog::{DialogExt as _, MessageDialogButtons, MessageDialogKind};
|
||||
|
||||
let title = clash_verge_i18n::t!("notifications.updateReady.title").to_string();
|
||||
let body = clash_verge_i18n::t!("notifications.updateReady.body")
|
||||
.replace("{version}", version);
|
||||
let install_now = clash_verge_i18n::t!("notifications.updateReady.installNow").to_string();
|
||||
let later = clash_verge_i18n::t!("notifications.updateReady.later").to_string();
|
||||
|
||||
let (tx, rx) = tokio::sync::oneshot::channel();
|
||||
|
||||
app_handle
|
||||
.dialog()
|
||||
.message(body)
|
||||
.title(title)
|
||||
.buttons(MessageDialogButtons::OkCancelCustom(install_now, later))
|
||||
.kind(MessageDialogKind::Info)
|
||||
.show(move |confirmed| {
|
||||
let _ = tx.send(confirmed);
|
||||
});
|
||||
|
||||
rx.await.unwrap_or(false)
|
||||
}
|
||||
}
|
||||
|
||||
// ─── Update Splash Window ────────────────────────────────────────────────────
|
||||
|
||||
impl SilentUpdater {
|
||||
@ -513,7 +561,7 @@ mod tests {
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_cache_meta_missing_field() {
|
||||
fn test_cache_meta_missing_required_field() {
|
||||
let result = serde_json::from_str::<UpdateCacheMeta>(r#"{"version":"2.5.0"}"#);
|
||||
assert!(result.is_err()); // missing downloaded_at
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user