fix(i18n): 完善国际化并迁移 WLOC 脚本

This commit is contained in:
xweiba
2026-09-11 02:39:00 +08:00
parent 908ac8f734
commit 05949703af
42 changed files with 2006 additions and 160 deletions
+2 -2
View File
@@ -13,8 +13,8 @@ enum CertificateAuthorityStoreError: LocalizedError {
var errorDescription: String? {
switch self {
case .invalidAuthority: return "本地 CA 证书或私钥无效"
case let .keychain(status): return "无法写入设备钥匙串(\(status)"
case .invalidAuthority: return String(localized: "本地 CA 证书或私钥无效")
case let .keychain(status): return String(localized: "无法写入设备钥匙串(\(status)")
}
}
}
+2 -2
View File
@@ -12,8 +12,8 @@ enum CoreBridgeError: LocalizedError {
var errorDescription: String? {
switch self {
case .generationFailed: return "无法生成本地证书"
case .serverStartFailed: return "无法启动本地证书服务"
case .generationFailed: return String(localized: "无法生成本地证书")
case .serverStartFailed: return String(localized: "无法启动本地证书服务")
}
}
}
+28 -3
View File
@@ -38,10 +38,35 @@ struct RuntimeLogEntry: Codable, Identifiable, Equatable {
var renderedText: String {
let formatter = ISO8601DateFormatter()
formatter.formatOptions = [.withInternetDateTime, .withFractionalSeconds]
let suffix = details.isEmpty
let localizedDetails = details.map {
(localizedDiagnosticText($0.key), localizedDiagnosticValue($0.value))
}
let suffix = localizedDetails.isEmpty
? ""
: " " + details.sorted(by: { $0.key < $1.key }).map { "\($0.key)=\($0.value)" }.joined(separator: " ")
return "\(formatter.string(from: timestamp)) [\(source)] [\(level.rawValue.uppercased())] [\(category)] \(message)\(suffix)"
: " " + localizedDetails.sorted(by: { $0.0 < $1.0 }).map { "\($0.0)=\($0.1)" }.joined(separator: " ")
return "\(formatter.string(from: timestamp)) [\(source)] [\(level.rawValue.uppercased())] [\(localizedCategory)] \(localizedMessage)\(suffix)"
}
var localizedCategory: String { localizedDiagnosticText(category) }
var localizedMessage: String { localizedDiagnosticText(message) }
var localizedDetailsText: String {
details.map { (localizedDiagnosticText($0.key), localizedDiagnosticValue($0.value)) }
.sorted(by: { $0.0 < $1.0 })
.map { "\($0.0): \($0.1)" }
.joined(separator: "\n")
}
private func localizedDiagnosticText(_ text: String) -> String {
String(localized: String.LocalizationValue(text))
}
private func localizedDiagnosticValue(_ value: String) -> String {
switch value {
case "true": return String(localized: "")
case "false": return String(localized: "")
default: return localizedDiagnosticText(value)
}
}
}
+15 -16
View File
@@ -170,7 +170,10 @@ final class ThirdPartyProxyManager: ObservableObject {
URLQueryItem(name: "lon", value: String(format: "%.8f", locale: Locale(identifier: "en_US_POSIX"), longitude)),
URLQueryItem(name: "lat", value: String(format: "%.8f", locale: Locale(identifier: "en_US_POSIX"), latitude)),
URLQueryItem(name: "acc", value: String(accuracy)),
URLQueryItem(name: "randomRadius", value: String(randomRadius))
URLQueryItem(
name: "randomRadius",
value: String(format: "%g", locale: Locale(identifier: "en_US_POSIX"), randomRadius)
)
]
}
guard let url = components.url else { throw ThirdPartyProxyError.invalidResponse }
@@ -203,6 +206,9 @@ final class ThirdPartyProxyManager: ObservableObject {
}
enum ThirdPartyProxyClient: String, CaseIterable, Identifiable {
/// Bump when a hosted module or script changes to invalidate proxy-client caches.
static let moduleSubscriptionVersion = "1.0.7"
case shadowrocket
case surge
case quantumultX
@@ -239,21 +245,14 @@ enum ThirdPartyProxyClient: String, CaseIterable, Identifiable {
@MainActor
var subscriptionURL: URL {
// Third-party modules are served directly from the upstream Yu9191/wloc
// repository (mirror via gh-proxy when enabled). We no longer maintain
// project-owned module copies, so the URL tracks upstream releases.
let fileName: String
switch self {
case .surge, .egern: fileName = "wloc.sgmodule"
case .quantumultX: fileName = "wloc.conf"
case .loon: fileName = "wloc.lpx"
case .stash: fileName = "wloc.stoverride"
case .shadowrocket: fileName = "wloc.module"
}
let base = ThirdPartyModuleSourceStore.shared.useMirror
? "https://gh-proxy.org/https://raw.githubusercontent.com/Yu9191/wloc/refs/heads/main/modules/\(fileName)"
: "https://raw.githubusercontent.com/Yu9191/wloc/refs/heads/main/modules/\(fileName)"
return URL(string: base)!
let directory = ThirdPartyModuleSourceStore.shared.useMirror
? "Resources/ThirdPartyProxyModules"
: "ThirdParty/WlocScripts/modules/direct"
let prefix = ThirdPartyModuleSourceStore.shared.useMirror
? "https://gh-proxy.org/https://raw.githubusercontent.com/xweiba/location-spoofer/main/"
: "https://raw.githubusercontent.com/xweiba/location-spoofer/main/"
let base = "\(prefix)\(directory)/\(moduleFileName)"
return URL(string: "\(base)?v=\(Self.moduleSubscriptionVersion)")!
}
var launchURL: URL? {