refactor: replace hardcoded strings with localized strings

This commit is contained in:
StellarSea 2026-03-28 13:52:11 +09:00
commit 806e246b2a
9 changed files with 1378 additions and 626 deletions

File diff suppressed because it is too large Load diff

View file

@ -615,11 +615,11 @@ private struct DurationInputRow: View {
var body: some View {
HStack(alignment: .center, spacing: 8) {
DurationField(label: "HH", value: $hours, range: 0...23, width: fieldWidth)
DurationField(label: String(localized: "HH"), value: $hours, range: 0...23, width: fieldWidth)
colon
DurationField(label: "MM", value: $minutes, range: 0...59, width: fieldWidth)
DurationField(label: String(localized: "MM"), value: $minutes, range: 0...59, width: fieldWidth)
colon
DurationField(label: "SS", value: $seconds, range: 0...59, width: fieldWidth)
DurationField(label: String(localized: "SS"), value: $seconds, range: 0...59, width: fieldWidth)
}
}

File diff suppressed because it is too large Load diff

View file

@ -29,7 +29,7 @@ struct CPUStatsDetailView: View {
var body: some View {
ScrollView {
VStack(spacing: 16) {
StatsCard(title: "CPU Overview") {
StatsCard(title: String(localized: "CPU Overview")) {
CPUUsageDashboard(
breakdown: statsManager.cpuBreakdown,
loadAverage: statsManager.cpuLoadAverage,
@ -43,12 +43,12 @@ struct CPUStatsDetailView: View {
)
}
StatsCard(title: "Top Processes") {
StatsCard(title: String(localized: "Top Processes")) {
CPUProcessList(processes: topProcesses, accentColor: userColor)
}
if !statsManager.cpuCoreUsage.isEmpty {
StatsCard(title: "Per-Core Usage") {
StatsCard(title: String(localized: "Per-Core Usage")) {
CPUCoreUsageGrid(cores: statsManager.cpuCoreUsage, accentColor: userColor)
}
}

View file

@ -88,12 +88,12 @@ struct CPUUsageDashboard: View {
Text("System")
.font(.caption)
.foregroundColor(.secondary)
DetailRow(color: nil, label: "Logical cores", value: "\(max(coreCount, 1))")
DetailRow(color: nil, label: "Uptime", value: StatsFormatting.abbreviatedDuration(uptime))
DetailRow(color: nil, label: String(localized: "Logical cores"), value: "\(max(coreCount, 1))")
DetailRow(color: nil, label: String(localized: "Uptime"), value: StatsFormatting.abbreviatedDuration(uptime))
Divider().padding(.vertical, 4)
DetailRow(color: nil, label: "Load 1m", value: String(format: "%.2f", loadAverage.oneMinute))
DetailRow(color: nil, label: "Load 5m", value: String(format: "%.2f", loadAverage.fiveMinutes))
DetailRow(color: nil, label: "Load 15m", value: String(format: "%.2f", loadAverage.fifteenMinutes))
DetailRow(color: nil, label: String(localized: "Load 1m"), value: String(format: "%.2f", loadAverage.oneMinute))
DetailRow(color: nil, label: String(localized: "Load 5m"), value: String(format: "%.2f", loadAverage.fiveMinutes))
DetailRow(color: nil, label: String(localized: "Load 15m"), value: String(format: "%.2f", loadAverage.fifteenMinutes))
}
.frame(maxWidth: .infinity, alignment: .leading)
@ -205,7 +205,7 @@ private struct CPUFrequencyGauge: View {
var body: some View {
CircularGaugeView(
title: "Frequency",
title: String(localized: "Frequency"),
value: normalizedValue,
tint: tint,
centerPrimaryText: centerPrimary,
@ -264,7 +264,7 @@ private struct CPUSegmentDonut: View {
VStack(spacing: 4) {
Text(StatsFormatting.percentage(breakdown.activeUsage))
.font(.system(size: 30, weight: .bold, design: .rounded))
Text("Active")
Text(String(localized: "stats_resource_active", defaultValue: "Active"))
.font(.footnote)
.foregroundColor(.secondary)
}
@ -335,9 +335,9 @@ struct LoadAverageRow: View {
.font(.caption)
.foregroundColor(.secondary)
HStack(spacing: 12) {
LoadAverageValue(label: "1m", value: loadAverage.oneMinute)
LoadAverageValue(label: "5m", value: loadAverage.fiveMinutes)
LoadAverageValue(label: "15m", value: loadAverage.fifteenMinutes)
LoadAverageValue(label: String(localized: "1m"), value: loadAverage.oneMinute)
LoadAverageValue(label: String(localized: "5m"), value: loadAverage.fiveMinutes)
LoadAverageValue(label: String(localized: "15m"), value: loadAverage.fifteenMinutes)
}
}
}
@ -455,10 +455,10 @@ struct CPUDetailsGrid: View {
Text("Usage Breakdown")
.font(.caption)
.foregroundColor(.secondary)
DetailRow(color: nil, label: "Total", value: StatsFormatting.percentage(breakdown.activeUsage))
DetailRow(color: systemColor, label: "System", value: StatsFormatting.percentage(breakdown.system))
DetailRow(color: userColor, label: "User", value: StatsFormatting.percentage(breakdown.user))
DetailRow(color: Color.gray.opacity(0.4), label: "Idle", value: StatsFormatting.percentage(breakdown.idle))
DetailRow(color: nil, label: String(localized: "Total"), value: StatsFormatting.percentage(breakdown.activeUsage))
DetailRow(color: systemColor, label: String(localized: "System"), value: StatsFormatting.percentage(breakdown.system))
DetailRow(color: userColor, label: String(localized: "User"), value: StatsFormatting.percentage(breakdown.user))
DetailRow(color: Color.gray.opacity(0.4), label: String(localized: "Idle"), value: StatsFormatting.percentage(breakdown.idle))
}
Divider().padding(.vertical, 4)
@ -467,8 +467,8 @@ struct CPUDetailsGrid: View {
Text("System")
.font(.caption)
.foregroundColor(.secondary)
DetailRow(color: nil, label: "Logical cores", value: "\(max(coreCount, 1))")
DetailRow(color: nil, label: "Uptime", value: StatsFormatting.abbreviatedDuration(uptime))
DetailRow(color: nil, label: String(localized: "Logical cores"), value: "\(max(coreCount, 1))")
DetailRow(color: nil, label: String(localized: "Uptime"), value: StatsFormatting.abbreviatedDuration(uptime))
}
if showLoadAverage {

View file

@ -28,7 +28,7 @@ struct DiskStatsDetailView: View {
var body: some View {
ScrollView {
VStack(spacing: 16) {
StatsCard(title: "Disk Overview", padding: 16, background: cardBackground, cornerRadius: 12) {
StatsCard(title: String(localized: "Disk Overview"), padding: 16, background: cardBackground, cornerRadius: 12) {
DiskOverview(
readSpeed: statsManager.diskRead,
writeSpeed: statsManager.diskWrite,
@ -39,11 +39,11 @@ struct DiskStatsDetailView: View {
)
}
StatsCard(title: "Storage Devices", padding: 16, background: cardBackground, cornerRadius: 12) {
StatsCard(title: String(localized: "Storage Devices"), padding: 16, background: cardBackground, cornerRadius: 12) {
DiskDevicesCard(devices: statsManager.diskDevices, accentColor: readColor)
}
StatsCard(title: "Session Totals", padding: 16, background: cardBackground, cornerRadius: 12) {
StatsCard(title: String(localized: "Session Totals"), padding: 16, background: cardBackground, cornerRadius: 12) {
DiskTotalsView(totals: statsManager.diskTotals, readColor: readColor, writeColor: writeColor)
}
}
@ -99,8 +99,8 @@ private struct DiskTotalsView: View {
var body: some View {
VStack(spacing: 10) {
DetailRow(color: readColor.opacity(0.75), label: "Read", value: formattedBytes(totals.readMB))
DetailRow(color: writeColor.opacity(0.75), label: "Written", value: formattedBytes(totals.writtenMB))
DetailRow(color: readColor.opacity(0.75), label: String(localized: "Read"), value: formattedBytes(totals.readMB))
DetailRow(color: writeColor.opacity(0.75), label: String(localized: "Written"), value: formattedBytes(totals.writtenMB))
}
}

View file

@ -29,7 +29,7 @@ struct GPUStatsDetailView: View {
var body: some View {
ScrollView {
VStack(spacing: 16) {
StatsCard(title: "GPU Overview", padding: 16, background: cardBackground, cornerRadius: 12) {
StatsCard(title: String(localized: "GPU Overview"), padding: 16, background: cardBackground, cornerRadius: 12) {
GPUUsageDashboard(
usage: statsManager.gpuUsage,
breakdown: statsManager.gpuBreakdown,
@ -40,12 +40,12 @@ struct GPUStatsDetailView: View {
)
}
StatsCard(title: "Top Processes", padding: 16, background: cardBackground, cornerRadius: 12) {
StatsCard(title: String(localized: "Top Processes"), padding: 16, background: cardBackground, cornerRadius: 12) {
CPUProcessList(processes: topProcesses, accentColor: accentColor, displayLimit: processDisplayLimit)
}
if !statsManager.gpuDevices.isEmpty {
StatsCard(title: "Devices", padding: 16, background: cardBackground, cornerRadius: 12) {
StatsCard(title: String(localized: "Devices"), padding: 16, background: cardBackground, cornerRadius: 12) {
GPUDeviceList(devices: statsManager.gpuDevices, accentColor: accentColor)
}
}
@ -119,10 +119,10 @@ private struct GPUUsageDashboard: View {
private var breakdownSection: some View {
VStack(alignment: .leading, spacing: 12) {
DetailRow(color: accentColor.opacity(0.9), label: "Render", value: StatsFormatting.percentage(breakdown.render))
DetailRow(color: accentColor.opacity(0.7), label: "Compute", value: StatsFormatting.percentage(breakdown.compute))
DetailRow(color: accentColor.opacity(0.55), label: "Video", value: StatsFormatting.percentage(breakdown.video))
DetailRow(color: accentColor.opacity(0.45), label: "Other", value: StatsFormatting.percentage(breakdown.other))
DetailRow(color: accentColor.opacity(0.9), label: String(localized: "Render"), value: StatsFormatting.percentage(breakdown.render))
DetailRow(color: accentColor.opacity(0.7), label: String(localized: "Compute"), value: StatsFormatting.percentage(breakdown.compute))
DetailRow(color: accentColor.opacity(0.55), label: String(localized: "Video"), value: StatsFormatting.percentage(breakdown.video))
DetailRow(color: accentColor.opacity(0.45), label: String(localized: "Other"), value: StatsFormatting.percentage(breakdown.other))
}
.frame(maxWidth: .infinity, alignment: .leading)
}
@ -132,15 +132,15 @@ private struct GPUUsageDashboard: View {
Text("Averages")
.font(.caption)
.foregroundColor(.secondary)
DetailRow(color: nil, label: "Session Avg", value: StatsFormatting.percentage(averageUsage))
DetailRow(color: nil, label: "Last Update", value: formattedTimestamp(lastUpdated))
DetailRow(color: nil, label: String(localized: "Session Avg"), value: StatsFormatting.percentage(averageUsage))
DetailRow(color: nil, label: String("localized: Last Update"), value: formattedTimestamp(lastUpdated))
if let device = primaryDevice {
Divider().padding(.vertical, 4)
DetailRow(color: nil, label: "Active GPU", value: device.formattedVendorModel)
DetailRow(color: nil, label: "Status", value: device.isActive ? "Active" : "Idle")
DetailRow(color: nil, label: "Temperature", value: device.temperatureText)
DetailRow(color: nil, label: String(localized: "Active GPU"), value: device.formattedVendorModel)
DetailRow(color: nil, label: String(localized: "Status"), value: device.isActive ? String(localized: "Active") : String(localized: "Idle"))
DetailRow(color: nil, label: String(localized: "Temperature"), value: device.temperatureText)
if let cores = device.cores {
DetailRow(color: nil, label: "Cores", value: "\(cores)")
DetailRow(color: nil, label: String(localized: "Cores"), value: "\(cores)")
}
}
}
@ -170,9 +170,9 @@ private struct GPUEngineGauges: View {
.font(.caption)
.foregroundColor(.secondary)
HStack(alignment: .center, spacing: 18) {
EngineGaugeView(title: "Render", value: render, tint: accentColor, size: 72)
EngineGaugeView(title: String(localized: "Render"), value: render, tint: accentColor, size: 72)
GPUUsageRing(usage: usage, accentColor: accentColor, diameter: ringDiameter, lineWidth: ringLineWidth)
EngineGaugeView(title: "Tiler", value: tiler, tint: accentColor.opacity(0.75), size: 72)
EngineGaugeView(title: String(localized: "Tiler"), value: tiler, tint: accentColor.opacity(0.75), size: 72)
}
.frame(maxWidth: .infinity, alignment: .center)
}
@ -193,7 +193,7 @@ private struct GPUUsageRing: View {
VStack(spacing: 4) {
Text(StatsFormatting.percentage(usage))
.font(.system(size: 26, weight: .bold, design: .rounded))
Text("Active")
Text(String(localized: "stats_resource_active", defaultValue: "Active"))
.font(.footnote)
.foregroundColor(.secondary)
}
@ -272,7 +272,7 @@ private struct GPUDeviceRow: View {
VStack(alignment: .leading, spacing: 2) {
Text(device.formattedVendorModel)
.font(.system(size: 13, weight: .semibold))
Text(device.isActive ? "Active" : "Idle")
Text(device.isActive ? String(localized: "stats_resource_active", defaultValue: "Active") : String(localized: "Idle"))
.font(.caption2)
.foregroundColor(device.isActive ? .green : .secondary)
}
@ -288,25 +288,25 @@ private struct GPUDeviceRow: View {
}
VStack(spacing: 8) {
if let render = device.renderUtilization {
DetailRow(color: accentColor.opacity(0.9), label: "Renderer", value: StatsFormatting.percentage(render))
DetailRow(color: accentColor.opacity(0.9), label: String(localized: "Renderer"), value: StatsFormatting.percentage(render))
}
if let tiler = device.tilerUtilization {
DetailRow(color: accentColor.opacity(0.6), label: "Tiler", value: StatsFormatting.percentage(tiler))
DetailRow(color: accentColor.opacity(0.6), label: String(localized: "Tiler"), value: StatsFormatting.percentage(tiler))
}
if let temp = device.temperature {
DetailRow(color: nil, label: "Temperature", value: String(format: "%.0f°C", temp))
DetailRow(color: nil, label: String(localized: "Temperature"), value: String(format: "%.0f°C", temp))
}
if let fan = device.fanSpeed {
DetailRow(color: nil, label: "Fan Speed", value: "\(fan)%")
DetailRow(color: nil, label: String(localized: "Fan Speed"), value: "\(fan)%")
}
if let coreClock = device.coreClock {
DetailRow(color: nil, label: "Core Clock", value: "\(coreClock) MHz")
DetailRow(color: nil, label: String(localized: "Core Clock"), value: "\(coreClock) MHz")
}
if let memoryClock = device.memoryClock {
DetailRow(color: nil, label: "Memory Clock", value: "\(memoryClock) MHz")
DetailRow(color: nil, label: String(localized: "Memory Clock"), value: "\(memoryClock) MHz")
}
if let cores = device.cores {
DetailRow(color: nil, label: "Cores", value: "\(cores)")
DetailRow(color: nil, label: String(localized: "Cores"), value: "\(cores)")
}
}
}

View file

@ -29,15 +29,15 @@ struct MemoryStatsDetailView: View {
var body: some View {
ScrollView {
VStack(spacing: 16) {
StatsCard(title: "Memory Overview", padding: 16, background: cardBackground, cornerRadius: 12) {
StatsCard(title: String(localized: "Memory Overview"), padding: 16, background: cardBackground, cornerRadius: 12) {
MemoryUsageDashboard(breakdown: statsManager.memoryBreakdown, accentColor: accentColor)
}
StatsCard(title: "Top Processes", padding: 16, background: cardBackground, cornerRadius: 12) {
StatsCard(title: String(localized: "Top Processes"), padding: 16, background: cardBackground, cornerRadius: 12) {
CPUProcessList(processes: topProcesses, accentColor: accentColor, displayLimit: processDisplayLimit)
}
StatsCard(title: "Pressure & Swap", padding: 16, background: cardBackground, cornerRadius: 12) {
StatsCard(title: String(localized: "Pressure & Swap"), padding: 16, background: cardBackground, cornerRadius: 12) {
MemoryHealthView(breakdown: statsManager.memoryBreakdown, accentColor: accentColor)
}
}
@ -64,9 +64,9 @@ private struct MemoryUsageDashboard: View {
var body: some View {
let totalsSection = VStack(alignment: .leading, spacing: 12) {
DetailRow(color: accentColor.opacity(0.8), label: "Used", value: formattedBytes(breakdown.usedBytes))
DetailRow(color: freeColor.opacity(0.9), label: "Free", value: formattedBytes(breakdown.freeBytes))
DetailRow(color: nil, label: "Total", value: formattedBytes(breakdown.totalBytes))
DetailRow(color: accentColor.opacity(0.8), label: String(localized: "Used"), value: formattedBytes(breakdown.usedBytes))
DetailRow(color: freeColor.opacity(0.9), label: String(localized: "Free"), value: formattedBytes(breakdown.freeBytes))
DetailRow(color: nil, label: String(localized: "Total"), value: formattedBytes(breakdown.totalBytes))
}
.frame(maxWidth: .infinity, alignment: .leading)
@ -74,10 +74,10 @@ private struct MemoryUsageDashboard: View {
Text("Breakdown")
.font(.caption)
.foregroundColor(.secondary)
MemoryBreakdownRow(label: "App", value: breakdown.appBytes, total: breakdown.totalBytes, color: accentColor.opacity(0.85))
MemoryBreakdownRow(label: "Cached", value: breakdown.cacheBytes, total: breakdown.totalBytes, color: accentColor.opacity(0.65))
MemoryBreakdownRow(label: "Wired", value: breakdown.wiredBytes, total: breakdown.totalBytes, color: accentColor.opacity(0.45))
MemoryBreakdownRow(label: "Compressed", value: breakdown.compressedBytes, total: breakdown.totalBytes, color: accentColor.opacity(0.35))
MemoryBreakdownRow(label: String(localized: "App"), value: breakdown.appBytes, total: breakdown.totalBytes, color: accentColor.opacity(0.85))
MemoryBreakdownRow(label: String(localized: "Cached"), value: breakdown.cacheBytes, total: breakdown.totalBytes, color: accentColor.opacity(0.65))
MemoryBreakdownRow(label: String(localized: "Wired"), value: breakdown.wiredBytes, total: breakdown.totalBytes, color: accentColor.opacity(0.45))
MemoryBreakdownRow(label: String(localized: "Compressed"), value: breakdown.compressedBytes, total: breakdown.totalBytes, color: accentColor.opacity(0.35))
}
.frame(maxWidth: .infinity, alignment: .leading)
@ -170,11 +170,11 @@ private struct MemoryPressureIndicator: View {
private var status: (title: String, color: Color, description: String) {
switch pressure.level {
case .normal:
return ("Normal", Color.green, "System memory pressure is nominal.")
return (String(localized: "Normal"), Color.green, String(localized: "System memory pressure is nominal."))
case .warning:
return ("Warning", Color.orange, "Memory pressure is elevated. Closing apps may help.")
return (String(localized: "Warning"), Color.orange, String(localized: "Memory pressure is elevated. Closing apps may help."))
case .critical:
return ("Critical", Color.red, "Memory pressure is critical; the system may purge aggressively.")
return (String(localized: "Critical"), Color.red, String(localized: "Memory pressure is critical; the system may purge aggressively."))
}
}
@ -220,9 +220,9 @@ private struct SwapUsageView: View {
.foregroundColor(.secondary)
if swap.totalBytes > 0 {
DetailRow(color: accentColor.opacity(0.85), label: "Used", value: StatsFormatting.bytes(swap.usedBytes))
DetailRow(color: accentColor.opacity(0.55), label: "Free", value: StatsFormatting.bytes(swap.freeBytes))
DetailRow(color: nil, label: "Total", value: StatsFormatting.bytes(swap.totalBytes))
DetailRow(color: accentColor.opacity(0.85), label: String(localized: "Used"), value: StatsFormatting.bytes(swap.usedBytes))
DetailRow(color: accentColor.opacity(0.55), label: String(localized: "Free"), value: StatsFormatting.bytes(swap.freeBytes))
DetailRow(color: nil, label: String(localized: "Total"), value: StatsFormatting.bytes(swap.totalBytes))
SwapUsageBar(usedBytes: swap.usedBytes, totalBytes: swap.totalBytes, tint: accentColor)
.frame(height: 8)
} else {

View file

@ -28,7 +28,7 @@ struct NetworkStatsDetailView: View {
var body: some View {
ScrollView {
VStack(spacing: 16) {
StatsCard(title: "Network Overview", padding: 16, background: cardBackground, cornerRadius: 12) {
StatsCard(title: String(localized: "Network Overview"), padding: 16, background: cardBackground, cornerRadius: 12) {
NetworkOverview(
download: statsManager.networkDownload,
upload: statsManager.networkUpload,
@ -41,7 +41,7 @@ struct NetworkStatsDetailView: View {
)
}
StatsCard(title: "Interfaces", padding: 16, background: cardBackground, cornerRadius: 12) {
StatsCard(title: String(localized: "Interfaces"), padding: 16, background: cardBackground, cornerRadius: 12) {
NetworkInterfacesCard(
interfaces: statsManager.networkInterfaces,
downloadColor: downloadColor,
@ -49,7 +49,7 @@ struct NetworkStatsDetailView: View {
)
}
StatsCard(title: "Session Totals", padding: 16, background: cardBackground, cornerRadius: 12) {
StatsCard(title: String(localized: "Session Totals"), padding: 16, background: cardBackground, cornerRadius: 12) {
NetworkTotalsView(totals: statsManager.networkTotals, downloadColor: downloadColor, uploadColor: uploadColor)
}
}
@ -101,8 +101,8 @@ private struct NetworkOverview: View {
Text(StatsFormatting.throughput(upload))
.font(.system(size: 26, weight: .bold, design: .rounded))
.foregroundColor(.primary)
DetailRow(color: uploadColor.opacity(0.6), label: "Average", value: StatsFormatting.throughput(avgUpload))
DetailRow(color: uploadColor.opacity(0.45), label: "Peak", value: StatsFormatting.throughput(peakUpload))
DetailRow(color: uploadColor.opacity(0.6), label: String(localized: "Average"), value: StatsFormatting.throughput(avgUpload))
DetailRow(color: uploadColor.opacity(0.45), label: String(localized: "Peak"), value: StatsFormatting.throughput(peakUpload))
}
.frame(maxWidth: .infinity, alignment: .leading)
}
@ -116,8 +116,8 @@ private struct NetworkTotalsView: View {
var body: some View {
VStack(spacing: 10) {
DetailRow(color: downloadColor.opacity(0.75), label: "Downloaded", value: formattedBytes(totals.downloadedMB))
DetailRow(color: uploadColor.opacity(0.75), label: "Uploaded", value: formattedBytes(totals.uploadedMB))
DetailRow(color: downloadColor.opacity(0.75), label: String(localized: "Downloaded"), value: formattedBytes(totals.downloadedMB))
DetailRow(color: uploadColor.opacity(0.75), label: String(localized: "Uploaded"), value: formattedBytes(totals.uploadedMB))
}
}
@ -193,7 +193,7 @@ private struct NetworkInterfaceRow: View {
.font(.system(size: 13, weight: .semibold))
.foregroundColor(.primary)
if interface.isActive {
Text("Active")
Text(String(localized: "stats_resource_active", defaultValue: "Active"))
.font(.caption2)
.foregroundColor(downloadColor)
.padding(.horizontal, 6)
@ -222,8 +222,8 @@ private struct NetworkInterfaceRow: View {
Spacer()
VStack(alignment: .trailing, spacing: 4) {
metricRow(label: "Down", value: StatsFormatting.throughput(interface.currentDownload), color: downloadColor)
metricRow(label: "Up", value: StatsFormatting.throughput(interface.currentUpload), color: uploadColor)
metricRow(label: String(localized: "Down"), value: StatsFormatting.throughput(interface.currentDownload), color: downloadColor)
metricRow(label: String(localized: "Up"), value: StatsFormatting.throughput(interface.currentUpload), color: uploadColor)
}
}
}