Fix string detection issues and complete pt-BR localization (100% done, as far as I can tell)

This commit is contained in:
Felipe Giacomini Cocco 2026-02-05 22:55:25 -03:00
commit f6f6321def
14 changed files with 402 additions and 77 deletions

View file

@ -888,11 +888,59 @@
}
}
},
"%lld day%@ ago" : {
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "%1$lld day%2$@ ago"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "%1$lld dias %2$@ atrás"
}
}
}
},
"%lld hour%@ ago" : {
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "%1$lld hour%2$@ ago"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "%1$lld horas %2$@ atrás"
}
}
}
},
"%lld min" : {
"comment" : "A text label displaying the current value of the \"Notify before\" slider. The argument is the current value of the slider, expressed in minutes.",
"isCommentAutoGenerated" : true,
"shouldTranslate" : false
},
"%lld minute%@ ago" : {
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "%1$lld minute%2$@ ago"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "%1$lld minutos %2$@ atrás"
}
}
}
},
"%lld px" : {
"comment" : "A label displaying the current expanded notch width value. The value is shown in pixels.",
"isCommentAutoGenerated" : true,
@ -1014,6 +1062,9 @@
}
}
},
"%lldh" : {
"shouldTranslate" : false
},
"%lldh ago" : {
"localizations" : {
"pt-BR" : {
@ -1024,6 +1075,9 @@
}
}
},
"%lldm" : {
"shouldTranslate" : false
},
"%lldm ago" : {
"localizations" : {
"pt-BR" : {
@ -3546,6 +3600,9 @@
}
}
},
"Apple Music" : {
"shouldTranslate" : false
},
"Applies the notch-style parallax effect to the lock screen media widget album art." : {
"localizations" : {
"pt-BR" : {
@ -5349,6 +5406,16 @@
}
}
},
"Charging battery" : {
"localizations" : {
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Carregando Bateria"
}
}
}
},
"charging icon" : {
"localizations" : {
"pt-BR" : {
@ -7227,6 +7294,9 @@
"cpu" : {
"shouldTranslate" : false
},
"CPU" : {
"shouldTranslate" : false
},
"CPU Usage" : {
"localizations" : {
"fr" : {
@ -7749,7 +7819,7 @@
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Temporizador Personalizado"
"value" : "Temporizador Customizado"
}
}
}
@ -8127,7 +8197,7 @@
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Temporizador Personalizado Padrão"
"value" : "Temporizador Customizado Padrão"
}
}
}
@ -8449,6 +8519,16 @@
}
}
},
"Disk" : {
"localizations" : {
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Disco"
}
}
}
},
"Disk I/O" : {
"localizations" : {
"pt-BR" : {
@ -9017,7 +9097,7 @@
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Visibilidade da Dynamic Islan"
"value" : "Visibilidade da Dynamic Island"
}
}
}
@ -10699,6 +10779,16 @@
"fahrenheit" : {
"shouldTranslate" : false
},
"Favorites" : {
"localizations" : {
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Favoritos"
}
}
}
},
"feedback" : {
"shouldTranslate" : false
},
@ -10932,6 +11022,16 @@
}
}
},
"Full charge" : {
"localizations" : {
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Bateria Completa"
}
}
}
},
"Full Disk Access required" : {
"localizations" : {
"pt-BR" : {
@ -11703,6 +11803,9 @@
"gpu" : {
"shouldTranslate" : false
},
"GPU" : {
"shouldTranslate" : false
},
"GPU Usage" : {
"localizations" : {
"fr" : {
@ -12315,6 +12418,16 @@
}
}
},
"History" : {
"localizations" : {
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Histórico"
}
}
}
},
"History Size" : {
"localizations" : {
"fr" : {
@ -13123,6 +13236,16 @@
}
}
},
"just now" : {
"localizations" : {
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "agora mesmo"
}
}
}
},
"Just now" : {
"localizations" : {
"pt-BR" : {
@ -13945,6 +14068,16 @@
}
}
},
"Low battery" : {
"localizations" : {
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Bateria baixa"
}
}
}
},
"Low Power Mode" : {
"localizations" : {
"ar" : {
@ -14045,6 +14178,16 @@
}
}
},
"Low Power: %@" : {
"localizations" : {
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Pouca Energia: %@"
}
}
}
},
"lyrics" : {
"localizations" : {
"pt-BR" : {
@ -15285,6 +15428,16 @@
}
}
},
"Memory" : {
"localizations" : {
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Memória"
}
}
}
},
"Memory Usage" : {
"localizations" : {
"fr" : {
@ -15421,6 +15574,16 @@
}
}
},
"Mic" : {
"localizations" : {
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Microfone"
}
}
}
},
"Mic muted" : {
"comment" : "A description of the state when the microphone is muted.",
"isCommentAutoGenerated" : true,
@ -16545,6 +16708,16 @@
}
}
},
"Network" : {
"localizations" : {
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Rede"
}
}
}
},
"Network Activity" : {
"localizations" : {
"pt-BR" : {
@ -17335,6 +17508,16 @@
}
}
},
"Not charging" : {
"localizations" : {
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Carregamento Parado"
}
}
}
},
"Not Determined" : {
"localizations" : {
"pt-BR" : {
@ -17809,6 +17992,26 @@
}
}
},
"Now Playing" : {
"localizations" : {
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Tocando Agora"
}
}
}
},
"Off" : {
"localizations" : {
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Desligado"
}
}
}
},
"OK" : {
"localizations" : {
"ar" : {
@ -17910,6 +18113,16 @@
},
"shouldTranslate" : false
},
"On" : {
"localizations" : {
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Ligado"
}
}
}
},
"on-screen display" : {
"localizations" : {
"pt-BR" : {
@ -18216,6 +18429,16 @@
}
}
},
"Panel" : {
"localizations" : {
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Painel"
}
}
}
},
"panel border" : {
"localizations" : {
"pt-BR" : {
@ -19177,6 +19400,17 @@
}
}
},
"R " : {
"comment" : "Abbreviation for “Disk Read”",
"localizations" : {
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "L"
}
}
}
},
"ram" : {
"shouldTranslate" : false
},
@ -20431,7 +20665,7 @@
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Selecione um som personalizado para reproduzir quando um cronômetro terminar. Os formatos suportados incluem MP3, M4A, WAV e AIFF."
"value" : "Selecione um som Customizado para reproduzir quando um cronômetro terminar. Os formatos suportados incluem MP3, M4A, WAV e AIFF."
}
}
}
@ -21226,6 +21460,16 @@
}
}
},
"Show \"Change Media Output\" control" : {
"localizations" : {
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Mostrar controle \"Alterar Saída de Mídia\""
}
}
}
},
"Show All Color Formats" : {
"localizations" : {
"pt-BR" : {
@ -21442,6 +21686,16 @@
}
}
},
"Show floating media controls" : {
"localizations" : {
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Mostrar controles de mídia flutuantes"
}
}
}
},
"Show floating pause/stop controls" : {
"localizations" : {
"pt-BR" : {
@ -21574,6 +21828,16 @@
}
}
},
"Show media controls in Dynamic Island" : {
"localizations" : {
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Mostrar controles de mídia na Ilha Dinâmica"
}
}
}
},
"Show on a specific display" : {
"localizations" : {
"ar" : {
@ -21910,6 +22174,26 @@
}
}
},
"Shows screen assistant as a dropdown attached to the AI button" : {
"localizations" : {
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Mostra o assistente de tela como um menu suspenso anexado ao botão de IA"
}
}
}
},
"Shows screen assistant in a floating panel near the notch" : {
"localizations" : {
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Mostra o assistente de tela em um painel flutuante próximo ao notch"
}
}
}
},
"Shows the model's reasoning process before the final answer" : {
"localizations" : {
"fr" : {
@ -22624,6 +22908,9 @@
}
}
},
"Spotify" : {
"shouldTranslate" : false
},
"Square" : {
"localizations" : {
"ar" : {
@ -22899,7 +23186,7 @@
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Comece a digital…"
"value" : "Comece a digitar…"
}
}
}
@ -24529,6 +24816,16 @@
}
}
},
"Unplugged" : {
"localizations" : {
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Desconectado"
}
}
}
},
"Update interval" : {
"localizations" : {
"pt-BR" : {
@ -25337,6 +25634,17 @@
}
}
},
"W " : {
"comment" : "Abbreviation for “Disk Write”",
"localizations" : {
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "G"
}
}
}
},
"weather" : {
"localizations" : {
"pt-BR" : {
@ -26011,6 +26319,9 @@
}
}
},
"Youtube Music" : {
"shouldTranslate" : false
},
"YouTube Music requires this third-party app to be installed: " : {
"localizations" : {
"ar" : {

View file

@ -456,16 +456,16 @@ struct ClipboardPanelItemRow: View {
let interval = Date().timeIntervalSince(date)
if interval < 60 {
return "Just now"
return String(localized: "Just now")
} else if interval < 3600 {
let minutes = Int(interval / 60)
return "\(minutes)m ago"
return String(localized: "\(minutes)m ago")
} else if interval < 86400 {
let hours = Int(interval / 3600)
return "\(hours)h ago"
return String(localized: "\(hours)h ago")
} else {
let days = Int(interval / 86400)
return "\(days)d ago"
return String(localized: "\(days)d ago")
}
}
}

View file

@ -28,6 +28,13 @@ enum ClipboardTab: String, CaseIterable {
case .favorites: return "heart.fill"
}
}
var localizedName: String {
switch self {
case .history: return String(localized: "History")
case .favorites: return String(localized: "Favorites")
}
}
}
struct ClipboardTabButton: View {
@ -51,7 +58,7 @@ struct ClipboardTabButton: View {
Image(systemName: tab.icon)
.font(.system(size: 11))
Text(tab.rawValue)
Text(tab.localizedName)
.font(.system(size: 11, weight: .medium))
if itemCount > 0 {

View file

@ -530,16 +530,16 @@ struct ColorListRow: View {
let interval = Date().timeIntervalSince(date)
if interval < 60 {
return "Just now"
return String(localized: "Just now")
} else if interval < 3600 {
let minutes = Int(interval / 60)
return "\(minutes)m ago"
return String(localized: "\(minutes)m ago")
} else if interval < 86400 {
let hours = Int(interval / 3600)
return "\(hours)h ago"
return String(localized: "\(hours)h ago")
} else {
let days = Int(interval / 86400)
return "\(days)d ago"
return String(localized: "\(days)d ago")
}
}
}
@ -589,16 +589,16 @@ struct ColorDetailsView: View {
let interval = Date().timeIntervalSince(date)
if interval < 60 {
return "just now"
return String(localized: "just now")
} else if interval < 3600 {
let minutes = Int(interval / 60)
return "\(minutes) minute\(minutes == 1 ? "" : "s") ago"
return String(localized: "\(minutes) minute\(minutes == 1 ? "" : "s") ago")
} else if interval < 86400 {
let hours = Int(interval / 3600)
return "\(hours) hour\(hours == 1 ? "" : "s") ago"
return String(localized: "\(hours) hour\(hours == 1 ? "" : "s") ago")
} else {
let days = Int(interval / 86400)
return "\(days) day\(days == 1 ? "" : "s") ago"
return String(localized: "\(days) day\(days == 1 ? "" : "s") ago")
}
}
}

View file

@ -432,17 +432,17 @@ struct InlineHUD: View {
func Type2Name(_ type: SneakContentType) -> String {
switch(type) {
case .volume:
return "Volume"
return String(localized: "Volume")
case .brightness:
return "Brightness"
return String(localized: "Brightness")
case .backlight:
return "Backlight"
return String(localized: "Backlight")
case .mic:
return "Mic"
return String(localized: "Mic")
case .bluetoothAudio:
return BluetoothAudioManager.shared.lastConnectedDevice?.name ?? "Bluetooth"
case .capsLock:
return "Caps Lock"
return String(localized: "Caps Lock")
default:
return ""
}

View file

@ -193,16 +193,16 @@ struct ClipboardItemRow: View {
let interval = Date().timeIntervalSince(date)
if interval < 60 {
return "Just now"
return String(localized: "Just now")
} else if interval < 3600 {
let minutes = Int(interval / 60)
return "\(minutes)m ago"
return String(localized: "\(minutes)m ago")
} else if interval < 86400 {
let hours = Int(interval / 3600)
return "\(hours)h ago"
return String(localized: "\(hours)h ago")
} else {
let days = Int(interval / 86400)
return "\(days)d ago"
return String(localized: "\(days)d ago")
}
}
}

View file

@ -288,16 +288,16 @@ struct ColorInfoPopup: View {
let interval = Date().timeIntervalSince(date)
if interval < 60 {
return "Just now"
return String(localized: "Just now")
} else if interval < 3600 {
let minutes = Int(interval / 60)
return "\(minutes)m ago"
return String(localized: "\(minutes)m ago")
} else if interval < 86400 {
let hours = Int(interval / 3600)
return "\(hours)h ago"
return String(localized: "\(hours)h ago")
} else {
let days = Int(interval / 86400)
return "\(days)d ago"
return String(localized: "\(days)d ago")
}
}
}

View file

@ -527,9 +527,9 @@ struct NotchClipboardItemRow: View {
private func timeAgoString(from date: Date) -> String {
let interval = Date().timeIntervalSince(date)
if interval < 60 { return "Just now" }
if interval < 3600 { return "\(Int(interval/60))m" }
return "\(Int(interval/3600))h"
if interval < 60 { return String(localized: "Just now") }
if interval < 3600 { return String(localized: "\(Int(interval/60))m") }
return String(localized: "\(Int(interval/3600))h")
}
}
@ -936,9 +936,9 @@ struct NoteRow: View {
private func timeAgoString(from date: Date) -> String {
let interval = Date().timeIntervalSince(date)
if interval < 60 { return "Just now" }
if interval < 3600 { return "\(Int(interval/60))m" }
if interval < 86400 { return "\(Int(interval/3600))h" }
if interval < 60 { return String(localized: "Just now") }
if interval < 3600 { return String(localized: "\(Int(interval/60))m") }
if interval < 86400 { return String(localized: "\(Int(interval/3600))h") }
return date.formatted(.dateTime.day().month())
}
}

View file

@ -82,7 +82,7 @@ struct NotchStatsView: View {
if showCpuGraph {
graphs.append(SingleGraphData(
title: "CPU",
title: String(localized: "CPU"),
value: statsManager.cpuUsageString,
data: statsManager.cpuHistory,
color: .blue,
@ -92,7 +92,7 @@ struct NotchStatsView: View {
if showMemoryGraph {
graphs.append(SingleGraphData(
title: "Memory",
title: String(localized: "Memory"),
value: statsManager.memoryUsageString,
data: statsManager.memoryHistory,
color: .green,
@ -102,7 +102,7 @@ struct NotchStatsView: View {
if showGpuGraph {
graphs.append(SingleGraphData(
title: "GPU",
title: String(localized: "GPU"),
value: statsManager.gpuUsageString,
data: statsManager.gpuHistory,
color: .purple,
@ -112,7 +112,7 @@ struct NotchStatsView: View {
if showNetworkGraph {
graphs.append(DualGraphData(
title: "Network",
title: String(localized: "Network"),
positiveValue: "↓" + statsManager.networkDownloadString,
negativeValue: "↑" + statsManager.networkUploadString,
positiveData: statsManager.networkDownloadHistory,
@ -126,9 +126,9 @@ struct NotchStatsView: View {
if showDiskGraph {
graphs.append(DualGraphData(
title: "Disk",
positiveValue: "R " + statsManager.diskReadString,
negativeValue: "W " + statsManager.diskWriteString,
title: String(localized: "Disk"),
positiveValue: String(localized: "R ") + statsManager.diskReadString,
negativeValue: String(localized: "W ") + statsManager.diskWriteString,
positiveData: statsManager.diskReadHistory,
negativeData: statsManager.diskWriteHistory,
positiveColor: .cyan,

View file

@ -461,7 +461,7 @@ struct NotchTimerView: View {
private var startButton: some View {
Button {
withAnimation(.smooth) {
timerManager.startTimer(duration: customDurationInSeconds, name: "Custom Timer")
timerManager.startTimer(duration: customDurationInSeconds, name: String(localized: "Custom Timer"))
if !enableMinimalisticUI {
coordinator.currentView = .timer
}

View file

@ -2427,13 +2427,13 @@ private struct DevicesSettingsView: View {
var body: some View {
Form {
Section {
Defaults.Toggle("Show Bluetooth device connections", key: .showBluetoothDeviceConnections)
Defaults.Toggle(String(localized: "Show Bluetooth device connections"), key: .showBluetoothDeviceConnections)
.settingsHighlight(id: highlightID("Show Bluetooth device connections"))
Defaults.Toggle("Use circular battery indicator", key: .useCircularBluetoothBatteryIndicator)
Defaults.Toggle(String(localized: "Use circular battery indicator"), key: .useCircularBluetoothBatteryIndicator)
.settingsHighlight(id: highlightID("Use circular battery indicator"))
Defaults.Toggle("Show battery percentage text in HUD", key: .showBluetoothBatteryPercentageText)
Defaults.Toggle(String(localized: "Show battery percentage text in HUD"), key: .showBluetoothBatteryPercentageText)
.settingsHighlight(id: highlightID("Show battery percentage text in HUD"))
Defaults.Toggle("Scroll device name in HUD", key: .showBluetoothDeviceNameMarquee)
Defaults.Toggle(String(localized: "Scroll device name in HUD"), key: .showBluetoothDeviceNameMarquee)
.settingsHighlight(id: highlightID("Scroll device name in HUD"))
} header: {
Text("Bluetooth Audio Devices")
@ -2444,7 +2444,7 @@ private struct DevicesSettingsView: View {
}
Section {
Defaults.Toggle("Color-coded battery display", key: .useColorCodedBatteryDisplay)
Defaults.Toggle(String(localized: "Color-coded battery display"), key: .useColorCodedBatteryDisplay)
.disabled(colorCodingDisabled)
.settingsHighlight(id: highlightID("Color-coded battery display"))
} header: {
@ -2643,7 +2643,7 @@ struct Media: View {
Section {
Picker("Music Source", selection: $mediaController) {
ForEach(availableMediaControllers) { controller in
Text(controller.rawValue).tag(controller)
Text(controller.localizedName).tag(controller)
}
}
.onChange(of: mediaController) { _, _ in
@ -2672,7 +2672,7 @@ struct Media: View {
}
}
Section {
Defaults.Toggle("Show media controls in Dynamic Island", key: .showStandardMediaControls)
Defaults.Toggle(String(localized: "Show media controls in Dynamic Island"), key: .showStandardMediaControls)
.disabled(enableMinimalisticUI)
.settingsHighlight(id: highlightID("Show media controls in Dynamic Island"))
@ -2696,7 +2696,7 @@ struct Media: View {
}
}
if showShuffleAndRepeat {
Defaults.Toggle("Show \"Change Media Output\" control", key: .showMediaOutputControl)
Defaults.Toggle(String(localized: "Show \"Change Media Output\" control"), key: .showMediaOutputControl)
.settingsHighlight(id: highlightID("Show Change Media Output control"))
.help("Adds the AirPlay/route picker button back to the customizable controls palette.")
MusicSlotConfigurationView()
@ -2711,7 +2711,7 @@ struct Media: View {
}
Section(header: Text("Lock Screen Media")) {
Defaults.Toggle("Enable album art parallax", key: .lockScreenMusicAlbumParallaxEnabled)
Defaults.Toggle(String(localized: "Enable album art parallax"), key: .lockScreenMusicAlbumParallaxEnabled)
.settingsHighlight(id: highlightID("Enable album art parallax"))
Text("Applies the notch-style parallax effect to the lock screen media widget album art.")
.font(.caption)
@ -2741,18 +2741,16 @@ struct Media: View {
)
.disabled(standardControlsSuppressed)
.help(standardControlsSuppressed ? "Standard notch media controls are hidden while this toggle is off." : "")
Defaults.Toggle(
"Show floating media controls",
key: .musicControlWindowEnabled
)
Defaults.Toggle(String(localized: "Show floating media controls"),
key: .musicControlWindowEnabled)
.disabled(!coordinator.musicLiveActivityEnabled || standardControlsSuppressed)
.help("Displays play/pause and skip buttons beside the notch while music is active. Disabled by default.")
Toggle("Enable sneak peek", isOn: $enableSneakPeek)
Toggle("Show sneak peek on playback changes", isOn: $showSneakPeekOnTrackChange)
.disabled(!enableSneakPeek)
Defaults.Toggle("Enable lyrics", key: .enableLyrics)
Defaults.Toggle(String(localized: "Enable lyrics"), key: .enableLyrics)
.settingsHighlight(id: highlightID("Enable lyrics"))
Defaults.Toggle("Enable album art parallax effect", key: .enableParallaxEffect)
Defaults.Toggle(String(localized: "Enable album art parallax effect"), key: .enableParallaxEffect)
.settingsHighlight(id: highlightID("Enable album art parallax effect"))
Picker("Sneak Peek Style", selection: $sneakPeekStyles){
ForEach(SneakPeekStyle.allCases) { style in
@ -2789,10 +2787,10 @@ struct Media: View {
}
Section {
Defaults.Toggle("Show lock screen media panel", key: .enableLockScreenMediaWidget)
Defaults.Toggle("Show media app icon", key: .lockScreenShowAppIcon)
Defaults.Toggle(String(localized: "Show lock screen media panel"), key: .enableLockScreenMediaWidget)
Defaults.Toggle(String(localized: "Show media app icon"), key: .lockScreenShowAppIcon)
.disabled(!enableLockScreenMediaWidget)
Defaults.Toggle("Show panel border", key: .lockScreenPanelShowsBorder)
Defaults.Toggle(String(localized: "Show panel border"), key: .lockScreenPanelShowsBorder)
.disabled(!enableLockScreenMediaWidget)
if lockScreenGlassCustomizationMode == .customLiquid {
customLiquidBlurRow
@ -6346,7 +6344,7 @@ struct ScreenAssistantSettings: View {
}
}
.pickerStyle(.menu)
.frame(width: 100)
.frame(width: 150)
}
.settingsHighlight(id: highlightID("Display Mode"))
@ -6473,7 +6471,7 @@ struct ColorPickerSettings: View {
}
}
.pickerStyle(.menu)
.frame(width: 100)
.frame(width: 150)
}
.settingsHighlight(id: highlightID("Display Mode"))
@ -6487,7 +6485,7 @@ struct ColorPickerSettings: View {
Text("20 colors").tag(20)
}
.pickerStyle(.menu)
.frame(width: 100)
.frame(width: 150)
}
.settingsHighlight(id: highlightID("History Size"))

View file

@ -100,7 +100,7 @@ struct TimerPopover: View {
let duration = customDurationInSeconds
guard duration > 0 else { return }
withAnimation(.smooth) {
timerManager.startTimer(duration: duration, name: "Custom Timer")
timerManager.startTimer(duration: duration, name: String(localized: "Custom Timer"))
}
dismiss()
}

View file

@ -81,7 +81,7 @@ class BatteryStatusViewModel: ObservableObject {
print("🔌 Power source: \(isPluggedIn ? "Connected" : "Disconnected")")
withAnimation {
self.isPluggedIn = isPluggedIn
self.statusText = isPluggedIn ? "Plugged In" : "Unplugged"
self.statusText = isPluggedIn ? String(localized: "Plugged In") : String(localized: "Unplugged")
self.notifyImportanChangeStatus()
}
@ -98,7 +98,7 @@ class BatteryStatusViewModel: ObservableObject {
self.notifyImportanChangeStatus()
withAnimation {
self.isInLowPowerMode = isEnabled
self.statusText = "Low Power: \(self.isInLowPowerMode ? "On" : "Off")"
self.statusText = String(localized: "Low Power: \(self.isInLowPowerMode ? String(localized: "On") : String(localized: "Off"))")
}
case .isChargingChanged(let isCharging):
@ -110,8 +110,8 @@ class BatteryStatusViewModel: ObservableObject {
self.isCharging = isCharging
self.statusText =
isCharging
? "Charging battery"
: (self.levelBattery < self.maxCapacity ? "Not charging" : "Full charge")
? String(localized: "Charging battery")
: (self.levelBattery < self.maxCapacity ? String(localized: "Not charging") : String(localized: "Full charge"))
}
case .timeToFullChargeChanged(let time):
@ -141,7 +141,7 @@ class BatteryStatusViewModel: ObservableObject {
self.isInLowPowerMode = batteryInfo.isInLowPowerMode
self.timeToFullCharge = batteryInfo.timeToFullCharge
self.maxCapacity = batteryInfo.maxCapacity
self.statusText = batteryInfo.isPluggedIn ? "Plugged In" : "Unplugged"
self.statusText = batteryInfo.isPluggedIn ? String(localized: "Plugged In") : String(localized: "Unplugged")
}
}
@ -161,7 +161,7 @@ class BatteryStatusViewModel: ObservableObject {
for threshold in lowBatteryAlertThresholds {
if previousLevel >= threshold && newLevel < threshold {
self.statusText = "Low battery"
self.statusText = String(localized: "Low battery")
notifyImportanChangeStatus()
playLowBatteryAlertSound()
break

View file

@ -284,15 +284,15 @@ enum ScreenAssistantDisplayMode: String, CaseIterable, Codable, Defaults.Seriali
var displayName: String {
switch self {
case .popover: return "Popover"
case .panel: return "Panel"
case .popover: return String(localized: "Popover")
case .panel: return String(localized: "Panel")
}
}
var description: String {
switch self {
case .popover: return "Shows screen assistant as a dropdown attached to the AI button"
case .panel: return "Shows screen assistant in a floating panel near the notch"
case .popover: return String(localized: "Shows screen assistant as a dropdown attached to the AI button")
case .panel: return String(localized: "Shows screen assistant in a floating panel near the notch")
}
}
}
@ -335,6 +335,15 @@ enum MediaControllerType: String, CaseIterable, Identifiable, Defaults.Serializa
case youtubeMusic = "Youtube Music"
var id: String { self.rawValue }
var localizedName: String {
switch self {
case .nowPlaying: return String(localized: "Now Playing")
case .appleMusic: return String(localized: "Apple Music")
case .spotify: return String(localized: "Spotify")
case .youtubeMusic: return String(localized: "Youtube Music")
}
}
}
// Sneak peek styles for selection in settings