
- 替换多个视图中的硬编码文本为本地化字符串,增强多语言支持。 - 修复编译错误,包括删除重复文件和修复作用域问题。 - 更新本地化文件,新增40+个本地化键值对,确保文本正确显示。 - 添加语言切换测试区域,验证文本实时更新功能。
238 lines
10 KiB
Swift
238 lines
10 KiB
Swift
import SwiftUI
|
||
import ComposableArchitecture
|
||
|
||
struct LanguageSettingsView: View {
|
||
@ObservedObject private var localizationManager = LocalizationManager.shared
|
||
@StateObject private var cosManager = COSManager.shared
|
||
@Binding var isPresented: Bool
|
||
|
||
// 使用 TCA 的依赖注入获取 API 服务
|
||
@Dependency(\.apiService) private var apiService
|
||
|
||
// 添加缺失的状态变量
|
||
@State private var cosTokenData: TcTokenData?
|
||
|
||
// 计算属性:格式化日期
|
||
private func formatDate(_ date: Date) -> String {
|
||
let formatter = DateFormatter()
|
||
formatter.dateStyle = .medium
|
||
return formatter.string(from: date)
|
||
}
|
||
|
||
init(isPresented: Binding<Bool> = .constant(true)) {
|
||
self._isPresented = isPresented
|
||
}
|
||
|
||
var body: some View {
|
||
NavigationStack {
|
||
List {
|
||
Section {
|
||
ForEach(LocalizationManager.SupportedLanguage.allCases, id: \.rawValue) { language in
|
||
LanguageRow(
|
||
language: language,
|
||
isSelected: localizationManager.currentLanguage == language
|
||
) {
|
||
localizationManager.switchLanguage(to: language)
|
||
}
|
||
}
|
||
} header: {
|
||
Text("选择语言 / Select Language")
|
||
.font(.caption)
|
||
.foregroundColor(.secondary)
|
||
}
|
||
|
||
Section {
|
||
HStack {
|
||
Text(LocalizedString("language_settings.current_language", comment: ""))
|
||
.font(.body)
|
||
|
||
Spacer()
|
||
|
||
Text(localizationManager.currentLanguage.localizedDisplayName)
|
||
.font(.body)
|
||
.foregroundColor(.blue)
|
||
}
|
||
} header: {
|
||
Text(LocalizedString("language_settings.language_info", comment: ""))
|
||
.font(.caption)
|
||
.foregroundColor(.secondary)
|
||
}
|
||
|
||
// 语言切换测试区域
|
||
Section {
|
||
VStack(alignment: .leading, spacing: 8) {
|
||
Text(LocalizedString("language_settings.test_area", comment: ""))
|
||
.font(.headline)
|
||
|
||
VStack(alignment: .leading, spacing: 4) {
|
||
Text(LocalizedString("language_settings.test_region", comment: ""))
|
||
.font(.subheadline)
|
||
.foregroundColor(.secondary)
|
||
|
||
Text("应用标题: \(LocalizedString("login.app_title", comment: ""))")
|
||
.font(.caption)
|
||
|
||
Text("登录按钮: \(LocalizedString("login.id_login", comment: ""))")
|
||
.font(.caption)
|
||
|
||
Text("当前语言代码: \(localizationManager.currentLanguage.rawValue)")
|
||
.font(.caption)
|
||
.foregroundColor(.blue)
|
||
}
|
||
.padding(.leading, 8)
|
||
}
|
||
} header: {
|
||
Text(LocalizedString("language_settings.test_region", comment: ""))
|
||
.font(.caption)
|
||
.foregroundColor(.secondary)
|
||
}
|
||
|
||
// 腾讯云 COS Token 测试区域
|
||
Section {
|
||
VStack(alignment: .leading, spacing: 8) {
|
||
Button(LocalizedString("language_settings.test_cos_token", comment: "")) {
|
||
Task {
|
||
await testCOToken()
|
||
}
|
||
}
|
||
.buttonStyle(.borderedProminent)
|
||
|
||
if let tokenData = cosTokenData {
|
||
VStack(alignment: .leading, spacing: 4) {
|
||
Text(LocalizedString("language_settings.token_success", comment: ""))
|
||
.font(.headline)
|
||
.foregroundColor(.green)
|
||
|
||
Text(String(format: LocalizedString("language_settings.bucket", comment: ""), tokenData.bucket))
|
||
.font(.caption)
|
||
|
||
Text(String(format: LocalizedString("language_settings.region", comment: ""), tokenData.region))
|
||
.font(.caption)
|
||
|
||
Text(String(format: LocalizedString("language_settings.app_id", comment: ""), tokenData.appId))
|
||
.font(.caption)
|
||
|
||
Text(String(format: LocalizedString("language_settings.custom_domain", comment: ""), tokenData.customDomain))
|
||
.font(.caption)
|
||
|
||
Text(String(format: LocalizedString("language_settings.accelerate_status", comment: ""),
|
||
tokenData.accelerate ?
|
||
LocalizedString("language_settings.accelerate_enabled", comment: "") :
|
||
LocalizedString("language_settings.accelerate_disabled", comment: "")))
|
||
.font(.caption)
|
||
|
||
Text(String(format: LocalizedString("language_settings.expiration_date", comment: ""), formatDate(tokenData.expirationDate)))
|
||
.font(.caption)
|
||
|
||
Text(String(format: LocalizedString("language_settings.remaining_time", comment: ""), tokenData.remainingTime))
|
||
.font(.caption)
|
||
}
|
||
.padding(.leading, 8)
|
||
}
|
||
}
|
||
} header: {
|
||
Text(LocalizedString("language_settings.test_region", comment: ""))
|
||
.font(.caption)
|
||
.foregroundColor(.secondary)
|
||
}
|
||
|
||
#if DEBUG
|
||
Section("调试功能") {
|
||
Button("测试腾讯云 COS Token") {
|
||
Task {
|
||
await testCOToken()
|
||
}
|
||
}
|
||
.foregroundColor(.blue)
|
||
|
||
if let tokenData = cosManager.token {
|
||
VStack(alignment: .leading, spacing: 8) {
|
||
Text("✅ Token 获取成功")
|
||
.font(.headline)
|
||
.foregroundColor(.green)
|
||
|
||
Group {
|
||
Text("存储桶: \(tokenData.bucket)")
|
||
Text("地域: \(tokenData.region)")
|
||
Text("应用ID: \(tokenData.appId)")
|
||
Text("自定义域名: \(tokenData.customDomain)")
|
||
Text("加速: \(tokenData.accelerate ? "启用" : "禁用")")
|
||
Text("过期时间: \(formatDate(tokenData.expirationDate))")
|
||
Text("剩余时间: \(tokenData.remainingTime)秒")
|
||
}
|
||
.font(.caption)
|
||
.foregroundColor(.secondary)
|
||
}
|
||
.padding(.vertical, 4)
|
||
}
|
||
}
|
||
#endif
|
||
}
|
||
.navigationTitle(LocalizedString("language_settings.title", comment: ""))
|
||
.navigationBarTitleDisplayMode(.inline)
|
||
.navigationBarBackButtonHidden(true)
|
||
.onAppear {
|
||
#if DEBUG
|
||
// 调试环境下,页面显示时自动调用 tcToken API
|
||
Task {
|
||
await cosManager.testTokenRetrieval(apiService: apiService)
|
||
}
|
||
#endif
|
||
}
|
||
}
|
||
}
|
||
|
||
private func testCOToken() async {
|
||
let token = await cosManager.getToken(apiService: apiService)
|
||
if let token = token {
|
||
print("✅ Token 测试成功")
|
||
print(" - 存储桶: \(token.bucket)")
|
||
print(" - 地域: \(token.region)")
|
||
print(" - 剩余时间: \(token.remainingTime)秒")
|
||
|
||
// 更新状态变量
|
||
cosTokenData = token
|
||
} else {
|
||
print("❌ Token 测试失败: 未能获取 Token")
|
||
cosTokenData = nil
|
||
}
|
||
}
|
||
}
|
||
|
||
struct LanguageRow: View {
|
||
let language: LocalizationManager.SupportedLanguage
|
||
let isSelected: Bool
|
||
let onTap: () -> Void
|
||
|
||
var body: some View {
|
||
Button(action: onTap) {
|
||
HStack {
|
||
VStack(alignment: .leading, spacing: 4) {
|
||
Text(language.localizedDisplayName)
|
||
.font(.body)
|
||
.foregroundColor(.primary)
|
||
|
||
Text(language.displayName)
|
||
.font(.caption)
|
||
.foregroundColor(.secondary)
|
||
}
|
||
|
||
Spacer()
|
||
|
||
if isSelected {
|
||
Image(systemName: "checkmark.circle.fill")
|
||
.foregroundColor(.blue)
|
||
.font(.system(size: 20))
|
||
}
|
||
}
|
||
.contentShape(Rectangle())
|
||
}
|
||
.buttonStyle(PlainButtonStyle())
|
||
}
|
||
}
|
||
|
||
// MARK: - Preview
|
||
//#Preview {
|
||
// LanguageSettingsView(isPresented: .constant(true))
|
||
//}
|