Skip to content

Commit

Permalink
make favorite food translatable
Browse files Browse the repository at this point in the history
  • Loading branch information
Joerg-Schoemer committed Jan 11, 2024
1 parent b6610a1 commit 6cfce86
Show file tree
Hide file tree
Showing 5 changed files with 98 additions and 28 deletions.
2 changes: 1 addition & 1 deletion Loop/Extensions/EditMode.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import SwiftUI

extension EditMode {
var title: String {
self == .active ? "Done" : "Edit"
self == .active ? NSLocalizedString("Done", comment: "") : NSLocalizedString("Edit", comment: "")
}

mutating func toggle() {
Expand Down
30 changes: 25 additions & 5 deletions Loop/Views/AddEditFavoriteFoodView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -93,20 +93,40 @@ struct AddEditFavoriteFoodView: View {
let foodTypeFocused: Binding<Bool> = Binding(get: { expandedRow == .foodType }, set: { expandedRow = $0 ? .foodType : nil })
let absorptionTimeFocused: Binding<Bool> = Binding(get: { expandedRow == .absorptionTime }, set: { expandedRow = $0 ? .absorptionTime : nil })

TextFieldRow(text: $viewModel.name, isFocused: nameFocused, title: "Name", placeholder: "Apple")
TextFieldRow(
text: $viewModel.name,
isFocused: nameFocused,
title: NSLocalizedString("Name", comment: "Label for name in favorite food entry screen"),
placeholder: NSLocalizedString("Apple", comment: "Placeholder for name in favorite food entry screen")
)

CardSectionDivider()

CarbQuantityRow(quantity: $viewModel.carbsQuantity, isFocused: carbQuantityFocused, title: "Carb Quantity", preferredCarbUnit: viewModel.preferredCarbUnit)
CarbQuantityRow(
quantity: $viewModel.carbsQuantity,
isFocused: carbQuantityFocused,
title: NSLocalizedString("Carb Quantity", comment: "Label for carb quantity in favorite food entry screen"),
preferredCarbUnit: viewModel.preferredCarbUnit
)

CardSectionDivider()

EmojiRow(text: $viewModel.foodType, isFocused: foodTypeFocused, emojiType: .food, title: "Food Type")
EmojiRow(
text: $viewModel.foodType,
isFocused: foodTypeFocused,
emojiType: .food,
title: NSLocalizedString("Food Type", comment: "Label for food type in favorite entry screen")
)

CardSectionDivider()

AbsorptionTimePickerRow(absorptionTime: $viewModel.absorptionTime, isFocused: absorptionTimeFocused, validDurationRange: viewModel.absorptionRimesRange, showHowAbsorptionTimeWorks: $showHowAbsorptionTimeWorks)
.padding(.bottom, 2)
AbsorptionTimePickerRow(
absorptionTime: $viewModel.absorptionTime,
isFocused: absorptionTimeFocused,
validDurationRange: viewModel.absorptionRimesRange,
showHowAbsorptionTimeWorks: $showHowAbsorptionTimeWorks
)
.padding(.bottom, 2)
}
.padding(.vertical, 12)
.padding(.horizontal)
Expand Down
8 changes: 4 additions & 4 deletions Loop/Views/FavoriteFoodDetailView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,10 @@ public struct FavoriteFoodDetailView: View {
Section("Information") {
VStack(spacing: 16) {
let rows: [(field: String, value: String)] = [
("Name", food.name),
("Carb Quantity", food.carbsString(formatter: carbFormatter)),
("Food Type", food.foodType),
("Absorption Time", food.absorptionTimeString(formatter: absorptionTimeFormatter))
(NSLocalizedString("Name", comment: "Label for name in favorite food entry"), food.name),
(NSLocalizedString("Carb Quantity", comment:"Label for carb quantity in favorite food entry"), food.carbsString(formatter: carbFormatter)),
(NSLocalizedString("Food Type", comment:"Label for food type in favorite food entry"), food.foodType),
(NSLocalizedString("Absorption Time", comment:"Label for absorption time in favorite food entry"), food.absorptionTimeString(formatter: absorptionTimeFormatter))
]
ForEach(rows, id: \.field) { row in
HStack {
Expand Down
28 changes: 14 additions & 14 deletions Loop/Views/SettingsView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -29,31 +29,31 @@ public struct SettingsView: View {
var id: String {
rawValue
}

case deleteCGMData
case deletePumpData
}

enum ActionSheet: String, Identifiable {
var id: String {
rawValue
}

case cgmPicker
case pumpPicker
case servicePicker
}

enum Sheet: String, Identifiable {
var id: String {
rawValue
}

case favoriteFoods
case therapySettings
}
}

@State private var actionSheet: Destination.ActionSheet?
@State private var alert: Destination.Alert?
@State private var sheet: Destination.Sheet?
Expand Down Expand Up @@ -254,7 +254,7 @@ extension SettingsView {
}
}
}

@ViewBuilder
private var alertWarning: some View {
if viewModel.alertPermissionsChecker.showWarning || viewModel.alertPermissionsChecker.notificationCenterSettings.scheduledDeliveryEnabled {
Expand Down Expand Up @@ -369,8 +369,8 @@ extension SettingsView {
LargeButton(action: { sheet = .favoriteFoods },
includeArrow: true,
imageView: Image("Favorite Foods Icon").renderingMode(.template).foregroundColor(carbTintColor),
label: "Favorite Foods",
descriptiveText: "Simplify Carb Entry")
label: NSLocalizedString("Favorite Foods", comment: "Label for favorite foods in settings view"),
descriptiveText: NSLocalizedString("Simplify Carb Entry", comment: "subheadline of favorite foods in settings view"))
}
}

Expand Down Expand Up @@ -493,7 +493,7 @@ extension SettingsView {
)
}
}

private func createAppExpirationSection(headerLabel: String, footerLabel: String, expirationLabel: String, updateURL: String, nearExpiration: Bool, expirationMessage: String) -> some View {
return Section(
header: SectionHeader(label: headerLabel),
Expand Down Expand Up @@ -557,7 +557,7 @@ fileprivate struct LargeButton<Content: View, SecondaryContent: View>: View {
let secondaryImageView: SecondaryContent
let label: String
let descriptiveText: String

init(
action: @escaping () -> Void,
includeArrow: Bool = true,
Expand Down Expand Up @@ -593,15 +593,15 @@ fileprivate struct LargeButton<Content: View, SecondaryContent: View>: View {
DescriptiveText(label: descriptiveText)
}
}

if !(secondaryImageView is EmptyView) || includeArrow {
Spacer()
}

if !(secondaryImageView is EmptyView) {
secondaryImageView.frame(width: secondaryImageWidth, height: secondaryImageHeight)
}

if includeArrow {
// TODO: Ick. I can't use a NavigationLink because we're not Navigating, but this seems worse somehow.
Image(systemName: "chevron.right").foregroundColor(.gray).font(.footnote)
Expand Down
58 changes: 54 additions & 4 deletions Loop/de.lproj/Localizable.strings
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,9 @@
/* Alert message for a missing pump error */
"A pump must be configured before a bolus can be delivered." = "Eine Pumpe muss konfiguriert werden, bevor ein Bolus abgegeben werden kann.";

/* Label for absorption time in favorite food entry */
"Absorption Time" = "Resorptionsdauer";

/* Action to copy the recommended Bolus value to the actual Bolus Field */
"AcceptRecommendedBolus" = "Akzeptiere empfohlenen Bolus";

Expand All @@ -143,6 +146,9 @@
/* The string format describing active insulin. (1: localized insulin value description) */
"Active Insulin: %@" = "Aktives Insulin: %@";

/* No comment provided by engineer. */
"Add a new favorite food" = "Erstelle einen neuen Favoriten";

/* Title of the user activity for adding carbs */
"Add Carb Entry" = "KH hinzufügen";

Expand Down Expand Up @@ -171,17 +177,24 @@
Notification & Critical Alert Permissions screen title */
"Alert Permissions" = "Benachrichtigungsberechtigungen";

/* Navigation title for algorithms experiments screen
The title of the Algorithm Experiments section in settings */
"Algorithm Experiments" = "Algorithmusexperimente";

/* Algorithm Experiments description. */
"Algorithm Experiments are optional modifications to the Loop Algorithm. These modifications are less tested than the standard Loop Algorithm, so please use carefully." = "Algorithmusexperimente sind optionale Modifikationen des Schleifenalgorithmus. Diese Modifikationen sind weniger getestet als der Standard-Loop-Algorithmus. Gehe daher bitte vorsichtig vor!";

/* The title of the section containing algorithm settings */
"Algorithm Settings" = "Algorithmus-Einstellungen";

/* Label for when mute alert will end */
"All alerts muted until" = "Alle Alarme stummgeschaltet bis";

/* No comment provided by engineer. */
"All Favorites" = "Alle Favoriten";

/* Label for carb quantity entry row on carb entry screen */
"Amount Consumed" = "KH-Menge gegessen";
"Amount Consumed" = "Menge gegessen";

/* Label for when mute alert will end */
"All alerts muted until" = "Alle Alarme stummgeschaltet bis";

/* The title of the Amplitude service */
"Amplitude" = "Amplitude";
Expand Down Expand Up @@ -210,6 +223,9 @@
/* Settings app profile section */
"App Profile" = "App-Profil";

/* Placeholder for name in favorite food entry screen */
"Apple" = "Apfel";

/* Action sheet confirmation message for pump history deletion */
"Are you sure you want to delete all history entries?" = "Möchtest Du wirklich alle Verlaufseinträge löschen?";

Expand Down Expand Up @@ -296,6 +312,10 @@
/* Label for carb entry row on bolus screen */
"Carb Entry" = "KH-Eintrag";

/* Label for carb quantity entry row on favorite food entry screen
Label for carb quantity in favorite food entry */
"Carb Quantity" = "KH-Menge";

/* Details for configuration error when carb ratio schedule is missing */
"Carb Ratio Schedule" = "Zeitplan für das Kohlenhydratverhältnis";

Expand Down Expand Up @@ -477,6 +497,9 @@
/* Override error description: duration exceed max (1: max duration in hours). */
"Duration exceeds: %1$.1f hours" = "Dauer überschritten: %1$.1f Stunden";

/* No comment provided by engineer. */
"Edit" = "Bearbeiten";

/* Message to the user to enable bluetooth */
"Enable\nBluetooth" = "Bluetooth einschalten";

Expand Down Expand Up @@ -540,6 +563,9 @@
/* No comment provided by engineer. */
"FAVORITE FOODS" = "Favorisiertes Essen";

/* No comment provided by engineer. */
"Favorite Foods" = "Favorisiertes Essen";

/* Title of insulin model preset */
"Fiasp" = "Fiasp";

Expand All @@ -549,6 +575,10 @@
/* Secondary text for alerts disabled warning, which appears on the main status screen. */
"Fix now by turning Notifications, Critical Alerts and Time Sensitive Notifications ON." = "Behebe dies jetzt, indem Du Benachrichtigungen, kritische Alarme und zeitkritische Benachrichtigungen einschaltest.";

/* label for food type in favorite entry screen
Label for food type in favorite food entry */
"Food Type" = "Essensart";

/* The format string used to describe a finite workout targets duration */
"For %1$@" = "Für %1$@";

Expand All @@ -567,6 +597,10 @@
/* The title of the glucose and prediction graph */
"Glucose" = "Blutzucker";

/* Title for glucose based partial application experiment description
Title of glucose based partial application experiment */
"Glucose Based Partial Application" = "Glucose Based Partial Application";

/* The error message when glucose data is too old to be used. (1: glucose data age in minutes) */
"Glucose data is %1$@ old" = "Blutzuckerdaten sind %1$@ alt";

Expand Down Expand Up @@ -760,6 +794,10 @@
/* Label for button to mute all alerts */
"Mute All Alerts" = "Alle Alarme stummschalten";

/* Label for name in favorite food entry
Label for name in favorite food entry screen */
"Name" = "Name";

/* Sensor state description for the non-valid state */
"Needs Attention" = "Erfordert Aufmerksamkeit";

Expand Down Expand Up @@ -938,15 +976,24 @@
/* The title of the notification action to retry a bolus command */
"Retry" = "Wiederholen";

/* No comment provided by engineer. */
"Save" = "Speichern";

/* Button text to save carbs and/or manual glucose entry and deliver a bolus */
"Save and Deliver" = "Speichern und Bolus abgeben";

/* No comment provided by engineer. */
"Save as favorite food" = "Als Favorit speichern";

/* Button text to save carbs and/or manual glucose entry without a bolus */
"Save without Bolusing" = "Speichern ohne Bolusgabe";

/* Scheduled Delivery status text */
"Scheduled" = "Geplant";

/* No comment provided by engineer. */
"Selecting a favorite food in the carb entry screen automatically fills in the carb quantity, food type, and absorption time fields! Tap the add button below to create your first favorite food!" = "Wenn Du auf dem Kohlenhydrat-Eingabebildschirm ein Lieblingslebensmittel auswählst, werden automatisch die Felder Kohlenhydratmenge, Lebensmittelart und Absorptionszeit ausgefüllt! Tippe unten auf die Schaltfläche „Hinzufügen“, um Dein erstes Lieblingsessen zu erstellen!";

/* The title of the services section in settings */
"Services" = "Dienste";

Expand All @@ -965,6 +1012,9 @@
/* Title of simple bolus view when displaying meal entry */
"Simple Meal Calculator" = "Einfacher Mahlzeitenrechner";

/* subheadline of Favorite Foods */
"Simplify Carb Entry" = "Vereinfachte KH Eingabe";

/* Format fragment for a start time */
"since %@" = "seit %@";

Expand Down

0 comments on commit 6cfce86

Please sign in to comment.