diff --git a/Platform/Shared/BusyOverlay.swift b/Platform/Shared/BusyOverlay.swift index 5c6cdb9d94..1ef2bc9a2a 100644 --- a/Platform/Shared/BusyOverlay.swift +++ b/Platform/Shared/BusyOverlay.swift @@ -30,7 +30,7 @@ struct BusyOverlay: View { .alert(item: $data.alertItem) { item in switch item { case .downloadUrl(let url): - return Alert(title: Text("Download VM"), message: Text("Do you want to download '\(url)'?"), primaryButton: .cancel(), secondaryButton: .default(Text("Download")) { + return Alert(title: Text(NSLocalizedString("Download VM", comment: "BusyOverlay")), message: Text(String.localizedStringWithFormat(NSLocalizedString("Do you want to download '%@'?", comment: "BusyOverlay"), url.absoluteString)), primaryButton: .cancel(), secondaryButton: .default(Text(NSLocalizedString("Download", comment: "BusyOverlay"))) { data.downloadUTMZip(from: url) }) case .message(let message): diff --git a/Platform/Shared/UTMTips.swift b/Platform/Shared/UTMTips.swift index c125a806c9..e6b771b6f5 100644 --- a/Platform/Shared/UTMTips.swift +++ b/Platform/Shared/UTMTips.swift @@ -30,8 +30,8 @@ struct UTMTipDonate: Tip { } var actions: [Action] { - Action(id: "donate", title: "Donate") - Action(id: "no-thanks", title: "No Thanks") + Action(id: "donate", title: NSLocalizedString("Donate", comment: "UTMTips")) + Action(id: "no-thanks", title: NSLocalizedString("No Thanks", comment: "UTMTips")) } var rules: [Rule] { diff --git a/Platform/Shared/VMConfigDriveDetailsView.swift b/Platform/Shared/VMConfigDriveDetailsView.swift index efe9488b07..8128e209d0 100644 --- a/Platform/Shared/VMConfigDriveDetailsView.swift +++ b/Platform/Shared/VMConfigDriveDetailsView.swift @@ -143,11 +143,11 @@ struct VMConfigDriveDetailsView: View { }.alert(item: $confirmAlert) { item in switch item { case .reclaim(let imageURL): - return Alert(title: Text("Would you like to re-convert this disk image to reclaim unused space? Note this will require enough temporary space to perform the conversion. You are strongly encouraged to back-up this VM before proceeding."), primaryButton: .destructive(Text("Reclaim")) { reclaimSpace(for: imageURL, withCompression: false) }, secondaryButton: .cancel()) + return Alert(title: Text(NSLocalizedString("Would you like to re-convert this disk image to reclaim unused space? Note this will require enough temporary space to perform the conversion. You are strongly encouraged to back-up this VM before proceeding.", comment: "VMConfigDriveDetailsView")), primaryButton: .destructive(Text("Reclaim")) { reclaimSpace(for: imageURL, withCompression: false) }, secondaryButton: .cancel()) case .compress(let imageURL): - return Alert(title: Text("Would you like to re-convert this disk image to reclaim unused space and apply compression? Note this will require enough temporary space to perform the conversion. Compression only applies to existing data and new data will still be written uncompressed. You are strongly encouraged to back-up this VM before proceeding."), primaryButton: .destructive(Text("Reclaim")) { reclaimSpace(for: imageURL, withCompression: true) }, secondaryButton: .cancel()) + return Alert(title: Text(NSLocalizedString("Would you like to re-convert this disk image to reclaim unused space and apply compression? Note this will require enough temporary space to perform the conversion. Compression only applies to existing data and new data will still be written uncompressed. You are strongly encouraged to back-up this VM before proceeding.", comment: "VMConfigDriveDetailsView")), primaryButton: .destructive(Text("Reclaim")) { reclaimSpace(for: imageURL, withCompression: true) }, secondaryButton: .cancel()) case .resize(let imageURL): - return Alert(title: Text("Resizing is experimental and could result in data loss. You are strongly encouraged to back-up this VM before proceeding. Would you like to resize to \(proposedSizeMib / mibInGib) GiB?"), primaryButton: .destructive(Text("Resize")) { + return Alert(title: Text(String.localizedStringWithFormat(NSLocalizedString("Resizing is experimental and could result in data loss. You are strongly encouraged to back-up this VM before proceeding. Would you like to resize to %lld GiB?", comment: "VMConfigDriveDetailsView"), proposedSizeMib / mibInGib)), primaryButton: .destructive(Text("Resize")) { resizeDrive(for: imageURL, sizeInMib: proposedSizeMib) }, secondaryButton: .cancel()) } diff --git a/Platform/Shared/VMConfigNetworkView.swift b/Platform/Shared/VMConfigNetworkView.swift index cbd9ea3b0d..35f65c928e 100644 --- a/Platform/Shared/VMConfigNetworkView.swift +++ b/Platform/Shared/VMConfigNetworkView.swift @@ -47,7 +47,7 @@ struct VMConfigNetworkView: View { } } if config.mode == .host { - Picker("Host Network", selection: $config.hostNetUuid) { + Picker(NSLocalizedString("Host Network", comment: "VMConfigNetworkView"), selection: $config.hostNetUuid) { Text("Default (private)") .tag(nil as String?) ForEach(hostNetworks) { interface in diff --git a/Platform/Shared/VMDetailsView.swift b/Platform/Shared/VMDetailsView.swift index 4ff632a98a..1bc049586a 100644 --- a/Platform/Shared/VMDetailsView.swift +++ b/Platform/Shared/VMDetailsView.swift @@ -375,14 +375,14 @@ struct Details: View { } ForEach(network.currentIpAddresses) { guestIP in HStack { - plainLabel("Guest IP", systemImage: "network.badge.shield.half.filled") + plainLabel(LocalizedStringKey(NSLocalizedString("Guest IP", comment: "VMDetailsView")), systemImage: "network.badge.shield.half.filled") Spacer() OptionalSelectableText(guestIP) } } if network.mode == .bridged, let interface = network.bridgeInterface { HStack { - plainLabel("Bridge Interface", systemImage: "arrow.triangle.branch") + plainLabel(LocalizedStringKey(NSLocalizedString("Bridge Interface", comment: "VMDetailsView")), systemImage: "arrow.triangle.branch") Spacer() Text(interface) .foregroundColor(.secondary) @@ -405,7 +405,7 @@ struct Details: View { ForEach(appleConfig.serials) { serial in if serial.mode == .ptty { HStack { - plainLabel("Serial (TTY)", systemImage: "phone.connection") + plainLabel(LocalizedStringKey(NSLocalizedString("Serial (TTY)", comment: "VMDetailsView")), systemImage: "phone.connection") Spacer() OptionalSelectableText(serial.interface?.name) } @@ -417,14 +417,14 @@ struct Details: View { ForEach(qemuConfig.serials) { serial in if serial.mode == .tcpClient { HStack { - plainLabel("Serial (Client)", systemImage: "network") + plainLabel(LocalizedStringKey(NSLocalizedString("Serial (Client)", comment: "VMDetailsView")), systemImage: "network") Spacer() let address = "\(serial.tcpHostAddress ?? "example.com"):\(serial.tcpPort ?? 1234)" OptionalSelectableText(vm.state == .started ? address : nil) } } else if serial.mode == .tcpServer { HStack { - plainLabel("Serial (Server)", systemImage: "network") + plainLabel(LocalizedStringKey(NSLocalizedString("Serial (Server)", comment: "VMDetailsView")), systemImage: "network") Spacer() let address = "\(serial.tcpPort ?? 1234)" OptionalSelectableText(vm.state == .started ? address : nil) @@ -433,7 +433,7 @@ struct Details: View { #if os(macOS) if serial.mode == .ptty { HStack { - plainLabel("Serial (TTY)", systemImage: "phone.connection") + plainLabel(LocalizedStringKey(NSLocalizedString("Serial (TTY)", comment: "VMDetailsView")), systemImage: "phone.connection") Spacer() OptionalSelectableText(serial.pttyDevice?.path) } diff --git a/Platform/iOS/UTMDonateView.swift b/Platform/iOS/UTMDonateView.swift index db922d9910..473dd908aa 100644 --- a/Platform/iOS/UTMDonateView.swift +++ b/Platform/iOS/UTMDonateView.swift @@ -92,7 +92,7 @@ private struct StoreView: View { if store.consumables.isEmpty && store.subscriptions.isEmpty { Link("GitHub Sponsors", destination: URL(string: "https://github.com/sponsors/utmapp")!) } else if !store.subscriptions.isEmpty { - Button("Restore Purchases") { + Button(NSLocalizedString("Restore Purchases", comment: "UTMDonateView")) { Task { try? await AppStore.sync() }