From cf3d7c74c2e96ebe27f3a89cb479020d3df3298b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Osman=20=C3=87a=C4=9Fr=C4=B1=20GEN=C3=87?= Date: Tue, 29 Sep 2026 01:00:18 +0300 Subject: [PATCH] feat(l10n): localize memory, history, watchdog and security screens Co-Authored-By: Claude Opus 5.5 --- .../MacOptimizer/App/MacOptimizerApp.swift | 2 +- Sources/MacOptimizer/Models/SystemStats.swift | 21 +++++- .../Resources/en.lproj/dashboard.strings | 70 +++++++++++++++++++ .../Resources/en.lproj/dashboard.stringsdict | 2 +- .../Resources/tr.lproj/dashboard.strings | 70 +++++++++++++++++++ .../Resources/tr.lproj/dashboard.stringsdict | 2 +- .../Autonomous/AutonomousGuardView.swift | 32 ++++----- .../Views/Dashboard/DashboardView.swift | 4 +- .../Views/History/HistoryView.swift | 42 +++++------ .../Views/Memory/MemoryView.swift | 38 +++++----- .../Views/Security/PrivacyAuditView.swift | 16 ++--- 11 files changed, 229 insertions(+), 70 deletions(-) diff --git a/Sources/MacOptimizer/App/MacOptimizerApp.swift b/Sources/MacOptimizer/App/MacOptimizerApp.swift index 325f937..d7d8468 100644 --- a/Sources/MacOptimizer/App/MacOptimizerApp.swift +++ b/Sources/MacOptimizer/App/MacOptimizerApp.swift @@ -63,7 +63,7 @@ struct MenuBarView: View { Spacer() MetricBadge( - text: metrics.cpuStats.thermalState.rawValue, + text: metrics.cpuStats.thermalState.localizedTitle, colorName: metrics.cpuStats.thermalState.colorName ) } diff --git a/Sources/MacOptimizer/Models/SystemStats.swift b/Sources/MacOptimizer/Models/SystemStats.swift index a03c0d0..9cea816 100644 --- a/Sources/MacOptimizer/Models/SystemStats.swift +++ b/Sources/MacOptimizer/Models/SystemStats.swift @@ -22,6 +22,15 @@ public struct MemoryStats: Sendable, Equatable { case warning = "Uyarı" case critical = "Kritik" + /// Localized display label. Raw values are kept stable and must not be shown in the UI. + public var localizedTitle: String { + switch self { + case .normal: return L10n.string("Normal", table: .dashboard) + case .warning: return L10n.string("Warning", table: .dashboard) + case .critical: return L10n.string("Critical", table: .dashboard) + } + } + public var colorName: String { switch self { case .normal: return "green" @@ -71,6 +80,16 @@ public struct CPUStats: Sendable, Equatable { case serious = "Yüksek Sıcaklık (Kısılma Riski)" case critical = "Kritik Sıcaklık (Fanlar Maksimumda)" + /// Localized display label. Raw values are kept stable and must not be shown in the UI. + public var localizedTitle: String { + switch self { + case .nominal: return L10n.string("Normal (Cool)", table: .dashboard) + case .fair: return L10n.string("Slightly Warm", table: .dashboard) + case .serious: return L10n.string("High Temperature (Throttling Risk)", table: .dashboard) + case .critical: return L10n.string("Critical Temperature (Fans at Maximum)", table: .dashboard) + } + } + public var colorName: String { switch self { case .nominal: return "green" @@ -122,7 +141,7 @@ public struct BatteryStats: Sendable, Equatable { public var temperatureCelsius: Double = 28.0 public var designCapacityMah: Int = 0 public var timeRemainingFormatted: String = "" - public var powerSource: String = "AC Gücü" + public var powerSource: String = L10n.string("AC Power", table: .dashboard) public var isOverheating: Bool { temperatureCelsius > 38.0 diff --git a/Sources/MacOptimizer/Resources/en.lproj/dashboard.strings b/Sources/MacOptimizer/Resources/en.lproj/dashboard.strings index 3d93f85..2323744 100644 --- a/Sources/MacOptimizer/Resources/en.lproj/dashboard.strings +++ b/Sources/MacOptimizer/Resources/en.lproj/dashboard.strings @@ -58,3 +58,73 @@ "PID: %lld" = "PID: %lld"; "Protected macOS system process (cannot be terminated)" = "Protected macOS system process (cannot be terminated)"; "Terminate process (PID: %lld)" = "Terminate process (PID: %lld)"; +"Terminate Process" = "Terminate Process"; +"Quit %@ (PID: %lld)? Unsaved data may be lost." = "Quit %@ (PID: %lld)? Unsaved data may be lost."; +"Selected process" = "Selected process"; +"Force Quit" = "Force Quit"; +"Cancel" = "Cancel"; +"Memory Usage" = "Memory Usage"; +"RAM Memory Management" = "RAM Memory Management"; +"Pressure: %@" = "Pressure: %@"; +"If memory pressure is high, you can quit memory-heavy apps from the list below." = "If memory pressure is high, you can quit memory-heavy apps from the list below."; +"Running Processes & Task Manager" = "Running Processes & Task Manager"; +"Apps Only" = "Apps Only"; +"App / Process" = "App / Process"; +"Action" = "Action"; +"System" = "System"; +"Protected macOS system process" = "Protected macOS system process"; +"Quit" = "Quit"; +"Process name or PID..." = "Process name or PID..."; +"Optimization History & SQLite Telemetry" = "Optimization History & SQLite Telemetry"; +"Total RAM Recovered: %@" = "Total RAM Recovered: %@"; +"Total Disk Recovered: %@" = "Total Disk Recovered: %@"; +"RAM Recovered: %@" = "RAM Recovered: %@"; +"Disk Recovered: %@" = "Disk Recovered: %@"; +"Clear History" = "Clear History"; +"System Performance History (SQLite)" = "System Performance History (SQLite)"; +"Time Range" = "Time Range"; +"Last 1 Hour" = "Last 1 Hour"; +"Last 24 Hours" = "Last 24 Hours"; +"Last 48 Hours" = "Last 48 Hours"; +"Time" = "Time"; +"Metric" = "Metric"; +"Not enough SQLite telemetry records were found in this time range." = "Not enough SQLite telemetry records were found in this time range."; +"CPU Usage" = "CPU Usage"; +"RAM Usage" = "RAM Usage"; +"%lld data points (SQLite WAL)" = "%lld data points (SQLite WAL)"; +"No Optimization Records Yet" = "No Optimization Records Yet"; +"Your file cleanup operations will be listed here." = "Your file cleanup operations will be listed here."; +"Autonomous System Protection & Watchdog" = "Autonomous System Protection & Watchdog"; +"Enabled" = "Enabled"; +"Disabled" = "Disabled"; +"Continuously monitors memory pressure, frozen background processes, and disk congestion; intervenes automatically when needed." = "Continuously monitors memory pressure, frozen background processes, and disk congestion; intervenes automatically when needed."; +"Auto-Healing" = "Auto-Healing"; +"%lld events" = "%lld events"; +"Pending Alerts" = "Pending Alerts"; +"%lld pending" = "%lld pending"; +"Resolved Events" = "Resolved Events"; +"%lld resolved" = "%lld resolved"; +"Autonomous Monitoring & Anomaly Log" = "Autonomous Monitoring & Anomaly Log"; +"Clear Log" = "Clear Log"; +"No Anomalies Detected" = "No Anomalies Detected"; +"The background monitor is watching the system. Any unusual activity or memory pressure will be listed here." = "The background monitor is watching the system. Any unusual activity or memory pressure will be listed here."; +"Auto-Healed" = "Auto-Healed"; +"Resolved" = "Resolved"; +"Active Alert" = "Active Alert"; +"Security & Privacy Audit" = "Security & Privacy Audit"; +"Audit macOS System Integrity Protection (SIP), Gatekeeper, the Firewall, and system permissions." = "Audit macOS System Integrity Protection (SIP), Gatekeeper, the Firewall, and system permissions."; +"Auditing..." = "Auditing..."; +"Audit Again" = "Audit Again"; +"/100 Points" = "/100 Points"; +"Native macOS security mechanisms were inspected. Core system integrity and resistance to unauthorized tampering were measured." = "Native macOS security mechanisms were inspected. Core system integrity and resistance to unauthorized tampering were measured."; +"Auditing macOS Security Settings..." = "Auditing macOS Security Settings..."; +"Security Audit Not Started" = "Security Audit Not Started"; +"Start Audit" = "Start Audit"; +"Normal" = "Normal"; +"Warning" = "Warning"; +"Critical" = "Critical"; +"Normal (Cool)" = "Normal (Cool)"; +"Slightly Warm" = "Slightly Warm"; +"High Temperature (Throttling Risk)" = "High Temperature (Throttling Risk)"; +"Critical Temperature (Fans at Maximum)" = "Critical Temperature (Fans at Maximum)"; +"AC Power" = "AC Power"; diff --git a/Sources/MacOptimizer/Resources/en.lproj/dashboard.stringsdict b/Sources/MacOptimizer/Resources/en.lproj/dashboard.stringsdict index ed2b868..efb8be1 100644 --- a/Sources/MacOptimizer/Resources/en.lproj/dashboard.stringsdict +++ b/Sources/MacOptimizer/Resources/en.lproj/dashboard.stringsdict @@ -6,4 +6,4 @@ countNSStringFormatSpecTypeKeyNSStringPluralRuleTypeNSStringFormatValueTypeKeylld one%lld anomaly awaiting reviewother%lld anomalies awaiting review -%lld cyclesNSStringLocalizedFormatKey%#@count@countNSStringFormatSpecTypeKeyNSStringPluralRuleTypeNSStringFormatValueTypeKeylldone%lld cycleother%lld cyclesLast %lld samples (Live Darwin API)NSStringLocalizedFormatKey%#@count@countNSStringFormatSpecTypeKeyNSStringPluralRuleTypeNSStringFormatValueTypeKeylldoneLast %lld sample (Live Darwin API)otherLast %lld samples (Live Darwin API) +%lld cyclesNSStringLocalizedFormatKey%#@count@countNSStringFormatSpecTypeKeyNSStringPluralRuleTypeNSStringFormatValueTypeKeylldone%lld cycleother%lld cyclesLast %lld samples (Live Darwin API)NSStringLocalizedFormatKey%#@count@countNSStringFormatSpecTypeKeyNSStringPluralRuleTypeNSStringFormatValueTypeKeylldoneLast %lld sample (Live Darwin API)otherLast %lld samples (Live Darwin API)%lld eventsNSStringLocalizedFormatKey%#@count@countNSStringFormatSpecTypeKeyNSStringPluralRuleTypeNSStringFormatValueTypeKeylldone%lld eventother%lld events%lld data points (SQLite WAL)NSStringLocalizedFormatKey%#@count@countNSStringFormatSpecTypeKeyNSStringPluralRuleTypeNSStringFormatValueTypeKeylldone%lld data point (SQLite WAL)other%lld data points (SQLite WAL) diff --git a/Sources/MacOptimizer/Resources/tr.lproj/dashboard.strings b/Sources/MacOptimizer/Resources/tr.lproj/dashboard.strings index eb54265..ed7ec69 100644 --- a/Sources/MacOptimizer/Resources/tr.lproj/dashboard.strings +++ b/Sources/MacOptimizer/Resources/tr.lproj/dashboard.strings @@ -58,3 +58,73 @@ "PID: %lld" = "PID: %lld"; "Protected macOS system process (cannot be terminated)" = "Korunan macOS sistem süreci (sonlandırılamaz)"; "Terminate process (PID: %lld)" = "İşlemi kapat (PID: %lld)"; +"Terminate Process" = "İşlemi Sonlandır"; +"Quit %@ (PID: %lld)? Unsaved data may be lost." = "%@ (PID: %lld) kapatılsın mı? Kaydedilmemiş veriler kaybolabilir."; +"Selected process" = "Seçili işlem"; +"Force Quit" = "Zorla Kapat"; +"Cancel" = "Vazgeç"; +"Memory Usage" = "Bellek Kullanımı"; +"RAM Memory Management" = "RAM Bellek Yönetimi"; +"Pressure: %@" = "Basınç: %@"; +"If memory pressure is high, you can quit memory-heavy apps from the list below." = "Bellek baskısı yüksekse, aşağıdaki listeden yoğun bellek kullanan uygulamaları kapatabilirsiniz."; +"Running Processes & Task Manager" = "Çalışan Süreçler & Görev Yöneticisi"; +"Apps Only" = "Yalnızca Uygulamalar"; +"App / Process" = "Uygulama / İşlem"; +"Action" = "Eylem"; +"System" = "Sistem"; +"Protected macOS system process" = "macOS Korunan Sistem Süreci"; +"Quit" = "Kapat"; +"Process name or PID..." = "Süreç adı veya PID..."; +"Optimization History & SQLite Telemetry" = "Optimizasyon Geçmişi & SQLite Telemetri"; +"Total RAM Recovered: %@" = "Toplam Kazanılan RAM: %@"; +"Total Disk Recovered: %@" = "Toplam Kazanılan Disk: %@"; +"RAM Recovered: %@" = "Kazanılan RAM: %@"; +"Disk Recovered: %@" = "Kazanılan Disk: %@"; +"Clear History" = "Geçmişi Temizle"; +"System Performance History (SQLite)" = "Sistem Performans Geçmişi (SQLite)"; +"Time Range" = "Zaman Aralığı"; +"Last 1 Hour" = "Son 1 Saat"; +"Last 24 Hours" = "Son 24 Saat"; +"Last 48 Hours" = "Son 48 Saat"; +"Time" = "Zaman"; +"Metric" = "Metrik"; +"Not enough SQLite telemetry records were found in this time range." = "Bu zaman aralığında yeterli SQLite telemetri kaydı bulunamadı."; +"CPU Usage" = "CPU Kullanımı"; +"RAM Usage" = "RAM Kullanımı"; +"%lld data points (SQLite WAL)" = "%lld Veri Noktası (SQLite WAL)"; +"No Optimization Records Yet" = "Henüz Optimizasyon Kaydı Yok"; +"Your file cleanup operations will be listed here." = "Yaptığınız dosya temizleme işlemleri burada listelenecektir."; +"Autonomous System Protection & Watchdog" = "Otonom Sistem Koruması & Watchdog"; +"Enabled" = "Aktif"; +"Disabled" = "Devre Dışı"; +"Continuously monitors memory pressure, frozen background processes, and disk congestion; intervenes automatically when needed." = "Bellek baskılarını, donan arka plan süreçlerini ve disk tıkanıklıklarını sürekli gözlemler; gerektiğinde otomatik müdahale eder."; +"Auto-Healing" = "Otomatik İyileştirme"; +"%lld events" = "%lld Olay"; +"Pending Alerts" = "Bekleyen Uyarılar"; +"%lld pending" = "%lld Bekliyor"; +"Resolved Events" = "Çözülen Olaylar"; +"%lld resolved" = "%lld Çözüldü"; +"Autonomous Monitoring & Anomaly Log" = "Otonom İzleme & Anomali Günlüğü"; +"Clear Log" = "Günlüğü Temizle"; +"No Anomalies Detected" = "Sistemde Herhangi Bir Anomali Yok"; +"The background monitor is watching the system. Any unusual activity or memory pressure will be listed here." = "Arka plan denetleyicisi sistemi izliyor. Olağandışı bir durum veya bellek baskısı olduğunda burada listelenecektir."; +"Auto-Healed" = "Otomatik İyileştirildi"; +"Resolved" = "Çözüldü"; +"Active Alert" = "Aktif Uyarı"; +"Security & Privacy Audit" = "Güvenlik & Gizlilik Denetimi"; +"Audit macOS System Integrity Protection (SIP), Gatekeeper, the Firewall, and system permissions." = "macOS çekirdek koruma durumu (SIP), Gatekeeper, Güvenlik Duvarı ve sistem izinlerini denetleyin."; +"Auditing..." = "Denetleniyor..."; +"Audit Again" = "Yeniden Denetle"; +"/100 Points" = "/100 Puan"; +"Native macOS security mechanisms were inspected. Core system integrity and resistance to unauthorized tampering were measured." = "macOS yerel güvenlik mekanizmaları incelendi. Sistemin temel bütünlüğü ve yetkisiz müdahale direnci ölçüldü."; +"Auditing macOS Security Settings..." = "macOS Güvenlik Ayarları Denetleniyor..."; +"Security Audit Not Started" = "Güvenlik Denetimi Başlatılmadı"; +"Start Audit" = "Denetimi Başlat"; +"Normal" = "Normal"; +"Warning" = "Uyarı"; +"Critical" = "Kritik"; +"Normal (Cool)" = "Normal (Serin)"; +"Slightly Warm" = "Hafif Isınma"; +"High Temperature (Throttling Risk)" = "Yüksek Sıcaklık (Kısılma Riski)"; +"Critical Temperature (Fans at Maximum)" = "Kritik Sıcaklık (Fanlar Maksimumda)"; +"AC Power" = "AC Gücü"; diff --git a/Sources/MacOptimizer/Resources/tr.lproj/dashboard.stringsdict b/Sources/MacOptimizer/Resources/tr.lproj/dashboard.stringsdict index ef931c5..d771393 100644 --- a/Sources/MacOptimizer/Resources/tr.lproj/dashboard.stringsdict +++ b/Sources/MacOptimizer/Resources/tr.lproj/dashboard.stringsdict @@ -6,4 +6,4 @@ countNSStringFormatSpecTypeKeyNSStringPluralRuleTypeNSStringFormatValueTypeKeylld oneİncelenmeyi bekleyen anomali sayısı: %lldotherİncelenmeyi bekleyen anomali sayısı: %lld -%lld cyclesNSStringLocalizedFormatKey%#@count@countNSStringFormatSpecTypeKeyNSStringPluralRuleTypeNSStringFormatValueTypeKeylldone%lld döngüother%lld döngüLast %lld samples (Live Darwin API)NSStringLocalizedFormatKey%#@count@countNSStringFormatSpecTypeKeyNSStringPluralRuleTypeNSStringFormatValueTypeKeylldoneSon %lld örnek (Canlı Darwin API)otherSon %lld örnek (Canlı Darwin API) +%lld cyclesNSStringLocalizedFormatKey%#@count@countNSStringFormatSpecTypeKeyNSStringPluralRuleTypeNSStringFormatValueTypeKeylldone%lld döngüother%lld döngüLast %lld samples (Live Darwin API)NSStringLocalizedFormatKey%#@count@countNSStringFormatSpecTypeKeyNSStringPluralRuleTypeNSStringFormatValueTypeKeylldoneSon %lld örnek (Canlı Darwin API)otherSon %lld örnek (Canlı Darwin API)%lld eventsNSStringLocalizedFormatKey%#@count@countNSStringFormatSpecTypeKeyNSStringPluralRuleTypeNSStringFormatValueTypeKeylldone%lld Olayother%lld Olay%lld data points (SQLite WAL)NSStringLocalizedFormatKey%#@count@countNSStringFormatSpecTypeKeyNSStringPluralRuleTypeNSStringFormatValueTypeKeylldone%lld Veri Noktası (SQLite WAL)other%lld Veri Noktası (SQLite WAL) diff --git a/Sources/MacOptimizer/Views/Autonomous/AutonomousGuardView.swift b/Sources/MacOptimizer/Views/Autonomous/AutonomousGuardView.swift index 7de54c4..0443c0c 100644 --- a/Sources/MacOptimizer/Views/Autonomous/AutonomousGuardView.swift +++ b/Sources/MacOptimizer/Views/Autonomous/AutonomousGuardView.swift @@ -71,17 +71,17 @@ public struct AutonomousGuardView: View { VStack(alignment: .leading, spacing: 3) { HStack(spacing: 8) { - Text("Otonom Sistem Koruması & Watchdog") + Text(l10n: "Autonomous System Protection & Watchdog", table: .dashboard) .font(.system(size: 16, weight: .bold)) .lineLimit(1) MetricBadge( - text: appState.autonomousConfig.isWatchdogActive ? "Aktif" : "Devre Dışı", + text: appState.autonomousConfig.isWatchdogActive ? L10n.string("Enabled", table: .dashboard) : L10n.string("Disabled", table: .dashboard), colorName: appState.autonomousConfig.isWatchdogActive ? "green" : "gray" ) } - Text("Bellek baskılarını, donan arka plan süreçlerini ve disk tıkanıklıklarını sürekli gözlemler; gerektiğinde otomatik müdahale eder.") + Text(l10n: "Continuously monitors memory pressure, frozen background processes, and disk congestion; intervenes automatically when needed.", table: .dashboard) .font(.system(size: 12)) .foregroundColor(.secondary) .lineLimit(2) @@ -111,11 +111,11 @@ public struct AutonomousGuardView: View { HStack { Image(systemName: "wand.and.stars") .foregroundColor(.green) - Text("Otomatik İyileştirme") + Text(l10n: "Auto-Healing", table: .dashboard) .font(.system(size: 12)) .foregroundColor(.secondary) } - Text("\(autoHealedCount) Olay") + Text(L10n.string("%lld events", table: .dashboard, Int64(autoHealedCount))) .font(.system(size: 20, weight: .bold, design: .rounded)) .foregroundColor(.green) } @@ -127,11 +127,11 @@ public struct AutonomousGuardView: View { HStack { Image(systemName: "exclamationmark.triangle.fill") .foregroundColor(.orange) - Text("Bekleyen Uyarılar") + Text(l10n: "Pending Alerts", table: .dashboard) .font(.system(size: 12)) .foregroundColor(.secondary) } - Text("\(appState.unresolvedAlertsCount) Bekliyor") + Text(L10n.string("%lld pending", table: .dashboard, Int64(appState.unresolvedAlertsCount))) .font(.system(size: 20, weight: .bold, design: .rounded)) .foregroundColor(appState.unresolvedAlertsCount > 0 ? .orange : .secondary) } @@ -143,11 +143,11 @@ public struct AutonomousGuardView: View { HStack { Image(systemName: "checkmark.circle.fill") .foregroundColor(.blue) - Text("Çözülen Olaylar") + Text(l10n: "Resolved Events", table: .dashboard) .font(.system(size: 12)) .foregroundColor(.secondary) } - Text("\(resolvedCount) Çözüldü") + Text(L10n.string("%lld resolved", table: .dashboard, Int64(resolvedCount))) .font(.system(size: 20, weight: .bold, design: .rounded)) .foregroundColor(.blue) } @@ -161,13 +161,13 @@ public struct AutonomousGuardView: View { GlassCard(cornerRadius: 16, padding: 16) { VStack(alignment: .leading, spacing: 14) { HStack { - Label("Otonom İzleme & Anomali Günlüğü", systemImage: "waveform.path.ecg") + Label(L10n.string("Autonomous Monitoring & Anomaly Log", table: .dashboard), systemImage: "waveform.path.ecg") .font(.system(size: 14, weight: .bold)) Spacer() if !appState.autonomousAlerts.isEmpty { - Button("Günlüğü Temizle") { + Button(L10n.string("Clear Log", table: .dashboard)) { appState.clearAutonomousAlerts() } .buttonStyle(.plain) @@ -182,10 +182,10 @@ public struct AutonomousGuardView: View { .font(.system(size: 40)) .foregroundColor(.green.opacity(0.8)) - Text("Sistemde Herhangi Bir Anomali Yok") + Text(l10n: "No Anomalies Detected", table: .dashboard) .font(.system(size: 14, weight: .bold)) - Text("Arka plan denetleyicisi sistemi izliyor. Olağandışı bir durum veya bellek baskısı olduğunda burada listelenecektir.") + Text(l10n: "The background monitor is watching the system. Any unusual activity or memory pressure will be listed here.", table: .dashboard) .font(.system(size: 12)) .foregroundColor(.secondary) .multilineTextAlignment(.center) @@ -210,11 +210,11 @@ public struct AutonomousGuardView: View { .lineLimit(1) if alert.autoHealed { - MetricBadge(text: "Otomatik İyileştirildi", colorName: "green") + MetricBadge(text: L10n.string("Auto-Healed", table: .dashboard), colorName: "green") } else if alert.isResolved { - MetricBadge(text: "Çözüldü", colorName: "blue") + MetricBadge(text: L10n.string("Resolved", table: .dashboard), colorName: "blue") } else { - MetricBadge(text: "Aktif Uyarı", colorName: "orange") + MetricBadge(text: L10n.string("Active Alert", table: .dashboard), colorName: "orange") } } diff --git a/Sources/MacOptimizer/Views/Dashboard/DashboardView.swift b/Sources/MacOptimizer/Views/Dashboard/DashboardView.swift index 294542a..2ab90a8 100644 --- a/Sources/MacOptimizer/Views/Dashboard/DashboardView.swift +++ b/Sources/MacOptimizer/Views/Dashboard/DashboardView.swift @@ -351,7 +351,7 @@ private struct DashboardHardwareHeader: View { } private var thermalBadge: some View { - MetricBadge(text: metrics.cpuStats.thermalState.rawValue, colorName: metrics.cpuStats.thermalState.colorName) + MetricBadge(text: metrics.cpuStats.thermalState.localizedTitle, colorName: metrics.cpuStats.thermalState.colorName) } } @@ -380,7 +380,7 @@ private struct DashboardGaugesGrid: View { percentage: metrics.cpuStats.totalUsage / 100.0, title: L10n.string("Processor (CPU)", table: .dashboard), valueText: String(format: "%.1f%%", metrics.cpuStats.totalUsage), - subText: L10n.string("%lld cores • %@", table: .dashboard, metrics.cpuStats.physicalCores, metrics.cpuStats.thermalState.rawValue), + subText: L10n.string("%lld cores • %@", table: .dashboard, metrics.cpuStats.physicalCores, metrics.cpuStats.thermalState.localizedTitle), gradient: SystemTheme.primaryGradient, size: 115 ) diff --git a/Sources/MacOptimizer/Views/History/HistoryView.swift b/Sources/MacOptimizer/Views/History/HistoryView.swift index e2d6d4a..7a542d3 100644 --- a/Sources/MacOptimizer/Views/History/HistoryView.swift +++ b/Sources/MacOptimizer/Views/History/HistoryView.swift @@ -57,29 +57,29 @@ public struct HistoryView: View { } VStack(alignment: .leading, spacing: 3) { - Text("Optimizasyon Geçmişi & SQLite Telemetri") + Text(l10n: "Optimization History & SQLite Telemetry", table: .dashboard) .font(.system(size: 16, weight: .bold)) .lineLimit(1) ViewThatFits(in: .horizontal) { HStack(spacing: 8) { - Text("Toplam Kazanılan RAM: \(ByteFormatter.formatMemory(totalFreedRAM))") + Text(L10n.string("Total RAM Recovered: %@", table: .dashboard, ByteFormatter.formatMemory(totalFreedRAM))) .font(.system(size: 12, weight: .semibold)) .foregroundColor(.green) Text("•") .foregroundColor(.secondary) - Text("Toplam Kazanılan Disk: \(ByteFormatter.format(totalFreedDisk))") + Text(L10n.string("Total Disk Recovered: %@", table: .dashboard, ByteFormatter.format(totalFreedDisk))) .font(.system(size: 12, weight: .semibold)) .foregroundColor(.purple) } VStack(alignment: .leading, spacing: 2) { - Text("Kazanılan RAM: \(ByteFormatter.formatMemory(totalFreedRAM))") + Text(L10n.string("RAM Recovered: %@", table: .dashboard, ByteFormatter.formatMemory(totalFreedRAM))) .font(.system(size: 11, weight: .semibold)) .foregroundColor(.green) - Text("Kazanılan Disk: \(ByteFormatter.format(totalFreedDisk))") + Text(L10n.string("Disk Recovered: %@", table: .dashboard, ByteFormatter.format(totalFreedDisk))) .font(.system(size: 11, weight: .semibold)) .foregroundColor(.purple) } @@ -89,7 +89,7 @@ public struct HistoryView: View { Spacer(minLength: 12) if !appState.optimizationHistory.isEmpty { - Button("Geçmişi Temizle") { + Button(L10n.string("Clear History", table: .dashboard)) { appState.clearHistory() } .buttonStyle(.plain) @@ -109,15 +109,15 @@ public struct HistoryView: View { GlassCard(cornerRadius: 16, padding: 18) { VStack(alignment: .leading, spacing: 14) { HStack { - Label("Sistem Performans Geçmişi (SQLite)", systemImage: "waveform.path.ecg") + Label(L10n.string("System Performance History (SQLite)", table: .dashboard), systemImage: "waveform.path.ecg") .font(.system(size: 14, weight: .bold)) Spacer() - Picker("Zaman Aralığı", selection: $timeRangeHours) { - Text("Son 1 Saat").tag(1) - Text("Son 24 Saat").tag(24) - Text("Son 48 Saat").tag(48) + Picker(L10n.string("Time Range", table: .dashboard), selection: $timeRangeHours) { + Text(l10n: "Last 1 Hour", table: .dashboard).tag(1) + Text(l10n: "Last 24 Hours", table: .dashboard).tag(24) + Text(l10n: "Last 48 Hours", table: .dashboard).tag(48) } .pickerStyle(.segmented) .labelsHidden() @@ -131,17 +131,17 @@ public struct HistoryView: View { Chart { ForEach(historyPoints) { point in LineMark( - x: .value("Zaman", point.timestamp), + x: .value(L10n.string("Time", table: .dashboard), point.timestamp), y: .value("CPU %", point.cpuUsage), - series: .value("Metrik", "CPU") + series: .value(L10n.string("Metric", table: .dashboard), "CPU") ) .foregroundStyle(Color.orange) .interpolationMethod(.catmullRom) LineMark( - x: .value("Zaman", point.timestamp), + x: .value(L10n.string("Time", table: .dashboard), point.timestamp), y: .value("RAM %", (Double(point.ramUsedBytes) / Double(max(1, ProcessInfo.processInfo.physicalMemory))) * 100.0), - series: .value("Metrik", "RAM") + series: .value(L10n.string("Metric", table: .dashboard), "RAM") ) .foregroundStyle(Color.blue) .interpolationMethod(.catmullRom) @@ -176,7 +176,7 @@ public struct HistoryView: View { Image(systemName: "circle.dotted") .font(.system(size: 28)) .foregroundColor(.secondary) - Text("Bu zaman aralığında yeterli SQLite telemetri kaydı bulunamadı.") + Text(l10n: "Not enough SQLite telemetry records were found in this time range.", table: .dashboard) .font(.system(size: 11)) .foregroundColor(.secondary) } @@ -188,17 +188,17 @@ public struct HistoryView: View { HStack(spacing: 16) { HStack(spacing: 6) { Circle().fill(Color.orange).frame(width: 8, height: 8) - Text("CPU Kullanımı").font(.system(size: 11, weight: .semibold)) + Text(l10n: "CPU Usage", table: .dashboard).font(.system(size: 11, weight: .semibold)) } HStack(spacing: 6) { Circle().fill(Color.blue).frame(width: 8, height: 8) - Text("RAM Kullanımı").font(.system(size: 11, weight: .semibold)) + Text(l10n: "RAM Usage", table: .dashboard).font(.system(size: 11, weight: .semibold)) } Spacer() - Text("\(historyPoints.count) Veri Noktası (SQLite WAL)") + Text(L10n.string("%lld data points (SQLite WAL)", table: .dashboard, Int64(historyPoints.count))) .font(.system(size: 10)) .foregroundColor(.secondary) } @@ -260,10 +260,10 @@ public struct HistoryView: View { .font(.system(size: 40)) .foregroundColor(.secondary.opacity(0.5)) - Text("Henüz Optimizasyon Kaydı Yok") + Text(l10n: "No Optimization Records Yet", table: .dashboard) .font(.system(size: 15, weight: .semibold)) - Text("Yaptığınız dosya temizleme işlemleri burada listelenecektir.") + Text(l10n: "Your file cleanup operations will be listed here.", table: .dashboard) .font(.system(size: 12)) .foregroundColor(.secondary) .multilineTextAlignment(.center) diff --git a/Sources/MacOptimizer/Views/Memory/MemoryView.swift b/Sources/MacOptimizer/Views/Memory/MemoryView.swift index e950dd9..02d9394 100644 --- a/Sources/MacOptimizer/Views/Memory/MemoryView.swift +++ b/Sources/MacOptimizer/Views/Memory/MemoryView.swift @@ -44,14 +44,14 @@ public struct MemoryView: View { .background(Color(NSColor.windowBackgroundColor).opacity(0.5)) .alert(isPresented: $showKillConfirmation) { Alert( - title: Text("İşlemi Sonlandır"), - message: Text("\(processToKill?.name ?? "Seçili işlem") (PID: \(processToKill?.pid ?? 0)) kapatılsın mı? Kaydedilmemiş veriler kaybolabilir."), - primaryButton: .destructive(Text("Zorla Kapat")) { + title: Text(l10n: "Terminate Process", table: .dashboard), + message: Text(L10n.string("Quit %@ (PID: %lld)? Unsaved data may be lost.", table: .dashboard, processToKill?.name ?? L10n.string("Selected process", table: .dashboard), Int64(processToKill?.pid ?? 0))), + primaryButton: .destructive(Text(l10n: "Force Quit", table: .dashboard)) { if let pid = processToKill?.pid { appState.killProcess(pid: pid, force: true) } }, - secondaryButton: .cancel(Text("Vazgeç")) + secondaryButton: .cancel(Text(l10n: "Cancel", table: .dashboard)) ) } } @@ -63,7 +63,7 @@ public struct MemoryView: View { // Circular Gauge CircularGaugeView( percentage: metrics.memoryStats.usedPercentage, - title: "Bellek Kullanımı", + title: L10n.string("Memory Usage", table: .dashboard), valueText: String(format: "%.0f%%", metrics.memoryStats.usedPercentage * 100), subText: "\(ByteFormatter.formatMemory(metrics.memoryStats.actualUsedBytes)) / \(ByteFormatter.formatMemory(metrics.memoryStats.totalBytes))", gradient: SystemTheme.memoryGradient, @@ -73,17 +73,17 @@ public struct MemoryView: View { VStack(alignment: .leading, spacing: 5) { HStack(spacing: 8) { - Text("RAM Bellek Yönetimi") + Text(l10n: "RAM Memory Management", table: .dashboard) .font(.system(size: 16, weight: .bold)) .lineLimit(1) MetricBadge( - text: "Basınç: \(metrics.memoryStats.pressureLevel.rawValue)", + text: L10n.string("Pressure: %@", table: .dashboard, metrics.memoryStats.pressureLevel.localizedTitle), colorName: metrics.memoryStats.pressureLevel.colorName ) } - Text("Bellek baskısı yüksekse, aşağıdaki listeden yoğun bellek kullanan uygulamaları kapatabilirsiniz.") + Text(l10n: "If memory pressure is high, you can quit memory-heavy apps from the list below.", table: .dashboard) .font(.system(size: 12)) .foregroundColor(.secondary) .lineLimit(2) @@ -103,12 +103,12 @@ public struct MemoryView: View { // Responsive Table Toolbar ViewThatFits(in: .horizontal) { HStack(spacing: 12) { - Label("Çalışan Süreçler & Görev Yöneticisi", systemImage: "cpu") + Label(L10n.string("Running Processes & Task Manager", table: .dashboard), systemImage: "cpu") .font(.system(size: 14, weight: .bold)) Spacer() - Toggle("Yalnızca Uygulamalar", isOn: $filterUserAppsOnly) + Toggle(L10n.string("Apps Only", table: .dashboard), isOn: $filterUserAppsOnly) .toggleStyle(.checkbox) .font(.system(size: 12)) @@ -117,11 +117,11 @@ public struct MemoryView: View { } VStack(alignment: .leading, spacing: 8) { - Label("Çalışan Süreçler & Görev Yöneticisi", systemImage: "cpu") + Label(L10n.string("Running Processes & Task Manager", table: .dashboard), systemImage: "cpu") .font(.system(size: 14, weight: .bold)) HStack(spacing: 12) { - Toggle("Yalnızca Uygulamalar", isOn: $filterUserAppsOnly) + Toggle(L10n.string("Apps Only", table: .dashboard), isOn: $filterUserAppsOnly) .toggleStyle(.checkbox) .font(.system(size: 12)) @@ -135,7 +135,7 @@ public struct MemoryView: View { // Table Header HStack { - Text("Uygulama / İşlem") + Text(l10n: "App / Process", table: .dashboard) .font(.system(size: 11, weight: .semibold)) .foregroundColor(.secondary) .frame(maxWidth: .infinity, alignment: .leading) @@ -150,12 +150,12 @@ public struct MemoryView: View { .foregroundColor(.secondary) .frame(width: 65, alignment: .trailing) - Text("Bellek (RAM)") + Text(l10n: "Memory (RAM)", table: .dashboard) .font(.system(size: 11, weight: .semibold)) .foregroundColor(.secondary) .frame(width: 95, alignment: .trailing) - Text("Eylem") + Text(l10n: "Action", table: .dashboard) .font(.system(size: 11, weight: .semibold)) .foregroundColor(.secondary) .frame(width: 80, alignment: .trailing) @@ -199,16 +199,16 @@ public struct MemoryView: View { HStack(spacing: 4) { if proc.isProtected { - Text("Sistem") + Text(l10n: "System", table: .dashboard) .font(.system(size: 10, weight: .semibold)) .foregroundColor(.secondary) .padding(.horizontal, 6) .padding(.vertical, 2) .background(Color.secondary.opacity(0.1)) .clipShape(RoundedRectangle(cornerRadius: 6)) - .help("macOS Korunan Sistem Süreci") + .help(L10n.string("Protected macOS system process", table: .dashboard)) } else { - Button("Kapat") { + Button(L10n.string("Quit", table: .dashboard)) { processToKill = proc showKillConfirmation = true } @@ -242,7 +242,7 @@ public struct MemoryView: View { Image(systemName: "magnifyingglass") .foregroundColor(.secondary) .font(.system(size: 11)) - TextField("Süreç adı veya PID...", text: $searchText) + TextField(L10n.string("Process name or PID...", table: .dashboard), text: $searchText) .textFieldStyle(.plain) .font(.system(size: 11)) } diff --git a/Sources/MacOptimizer/Views/Security/PrivacyAuditView.swift b/Sources/MacOptimizer/Views/Security/PrivacyAuditView.swift index 3c8a33b..054a710 100644 --- a/Sources/MacOptimizer/Views/Security/PrivacyAuditView.swift +++ b/Sources/MacOptimizer/Views/Security/PrivacyAuditView.swift @@ -53,11 +53,11 @@ public struct PrivacyAuditView: View { } VStack(alignment: .leading, spacing: 3) { - Text("Güvenlik & Gizlilik Denetimi") + Text(l10n: "Security & Privacy Audit", table: .dashboard) .font(.system(size: 16, weight: .bold)) .lineLimit(1) - Text("macOS çekirdek koruma durumu (SIP), Gatekeeper, Güvenlik Duvarı ve sistem izinlerini denetleyin.") + Text(l10n: "Audit macOS System Integrity Protection (SIP), Gatekeeper, the Firewall, and system permissions.", table: .dashboard) .font(.system(size: 12)) .foregroundColor(.secondary) .lineLimit(2) @@ -66,7 +66,7 @@ public struct PrivacyAuditView: View { Spacer(minLength: 12) ActionButton( - title: appState.isLoadingSecurityAudit ? "Denetleniyor..." : "Yeniden Denetle", + title: appState.isLoadingSecurityAudit ? L10n.string("Auditing...", table: .dashboard) : L10n.string("Audit Again", table: .dashboard), iconName: "arrow.clockwise", gradient: SystemTheme.successGradient, isLoading: appState.isLoadingSecurityAudit @@ -105,10 +105,10 @@ public struct PrivacyAuditView: View { Text(report.ratingDescription) .font(.system(size: 15, weight: .bold)) - MetricBadge(text: "/100 Puan", colorName: report.ratingColorName) + MetricBadge(text: L10n.string("/100 Points", table: .dashboard), colorName: report.ratingColorName) } - Text("macOS yerel güvenlik mekanizmaları incelendi. Sistemin temel bütünlüğü ve yetkisiz müdahale direnci ölçüldü.") + Text(l10n: "Native macOS security mechanisms were inspected. Core system integrity and resistance to unauthorized tampering were measured.", table: .dashboard) .font(.system(size: 11)) .foregroundColor(.secondary) } @@ -165,7 +165,7 @@ public struct PrivacyAuditView: View { GlassCard(cornerRadius: 16, padding: 36) { VStack(spacing: 12) { ProgressView() - Text("macOS Güvenlik Ayarları Denetleniyor...") + Text(l10n: "Auditing macOS Security Settings...", table: .dashboard) .font(.system(size: 13)) .foregroundColor(.secondary) } @@ -180,11 +180,11 @@ public struct PrivacyAuditView: View { .font(.system(size: 44)) .foregroundStyle(SystemTheme.successGradient) - Text("Güvenlik Denetimi Başlatılmadı") + Text(l10n: "Security Audit Not Started", table: .dashboard) .font(.system(size: 16, weight: .bold)) ActionButton( - title: "Denetimi Başlat", + title: L10n.string("Start Audit", table: .dashboard), iconName: "play.fill", gradient: SystemTheme.successGradient ) {