Просмотр исходного кода

Improve shortcuts words and translation

Improve shortcuts words in particular to include #543 proposals.
Fix translation sentences in shortcuts without using LocalizedStringResource.
Pierre L 11 месяцев назад
Родитель
Сommit
3cb79bb6d5

+ 212 - 6
Trio/Sources/Localizations/Main/Localizable.xcstrings

@@ -6424,6 +6424,16 @@
         }
       }
     },
+    "%@  %@" : {
+      "localizations" : {
+        "en" : {
+          "stringUnit" : {
+            "state" : "new",
+            "value" : "%1$@  %2$@"
+          }
+        }
+      }
+    },
     "%@ - 0.5 × (%@ - %@) = %@" : {
       "localizations" : {
         "bg" : {
@@ -6978,6 +6988,54 @@
         }
       }
     },
+    "%@ and %@ g fat" : {
+      "localizations" : {
+        "en" : {
+          "stringUnit" : {
+            "state" : "new",
+            "value" : "%1$@ and %2$@ g fat"
+          }
+        },
+        "fr" : {
+          "stringUnit" : {
+            "state" : "translated",
+            "value" : "%1$@ et %2$@ g lipides"
+          }
+        }
+      }
+    },
+    "%@ and %@ g protein" : {
+      "localizations" : {
+        "en" : {
+          "stringUnit" : {
+            "state" : "new",
+            "value" : "%1$@ and %2$@ g protein"
+          }
+        },
+        "fr" : {
+          "stringUnit" : {
+            "state" : "translated",
+            "value" : "%1$@ et %2$@ g de protéines"
+          }
+        }
+      }
+    },
+    "%@ at %@" : {
+      "localizations" : {
+        "en" : {
+          "stringUnit" : {
+            "state" : "new",
+            "value" : "%1$@ at %2$@"
+          }
+        },
+        "fr" : {
+          "stringUnit" : {
+            "state" : "translated",
+            "value" : "%1$@ à %2$@"
+          }
+        }
+      }
+    },
     "%@ g" : {
       "localizations" : {
         "bg" : {
@@ -22128,6 +22186,16 @@
         }
       }
     },
+    "Add %@ grams of carbs?" : {
+      "localizations" : {
+        "fr" : {
+          "stringUnit" : {
+            "state" : "translated",
+            "value" : "Ajouter %@ grammes de glucose ?"
+          }
+        }
+      }
+    },
     "Add %@ without bolusing" : {
       "comment" : "Add insulin from source outside of pump",
       "extractionState" : "manual",
@@ -26871,6 +26939,16 @@
         }
       }
     },
+    "Added %@ g carbs" : {
+      "localizations" : {
+        "fr" : {
+          "stringUnit" : {
+            "state" : "translated",
+            "value" : "Ajout de %@ g de glucides"
+          }
+        }
+      }
+    },
     "Additional notification types" : {
       "extractionState" : "manual",
       "localizations" : {
@@ -39185,7 +39263,18 @@
         }
       }
     },
+    "Are you sure to bolus %@ U of insulin?" : {
+      "localizations" : {
+        "fr" : {
+          "stringUnit" : {
+            "state" : "translated",
+            "value" : "Etes-vous certain d’appliquer un bonus de %@ U d’insuline ? "
+          }
+        }
+      }
+    },
     "Are you sure you want to bolus %@ U of insulin?" : {
+      "extractionState" : "stale",
       "localizations" : {
         "bg" : {
           "stringUnit" : {
@@ -82044,9 +82133,6 @@
         }
       }
     },
-    "Do you want to add %@ grams of carbs?" : {
-
-    },
     "Don’t Allow" : {
       "localizations" : {
         "bg" : {
@@ -113209,8 +113295,56 @@
         }
       }
     },
-    "How many carbs do you want to add?" : {
-
+    "How many grams of carbs did you eat?" : {
+      "localizations" : {
+        "fr" : {
+          "stringUnit" : {
+            "state" : "translated",
+            "value" : "Combien de grammes de glucides avez-vous mangé ?"
+          }
+        }
+      }
+    },
+    "How many grams of carbs?" : {
+      "localizations" : {
+        "fr" : {
+          "stringUnit" : {
+            "state" : "translated",
+            "value" : "Combien de grammes de glucides ?"
+          }
+        }
+      }
+    },
+    "How many grams of fat did you eat?" : {
+      "localizations" : {
+        "fr" : {
+          "stringUnit" : {
+            "state" : "translated",
+            "value" : "Combien de grammes de lipides avez-vous mangé ? "
+          }
+        }
+      }
+    },
+    "How many grams of fats did you eat?" : {
+      "extractionState" : "stale",
+      "localizations" : {
+        "fr" : {
+          "stringUnit" : {
+            "state" : "translated",
+            "value" : "Combien de grammes de lipides avez-vous mangé ?"
+          }
+        }
+      }
+    },
+    "How many grams of protein did you eat?" : {
+      "localizations" : {
+        "fr" : {
+          "stringUnit" : {
+            "state" : "translated",
+            "value" : "Combien de grammes de protéines avez-vous mangé ?"
+          }
+        }
+      }
     },
     "How Trio Manages Contact Images" : {
       "localizations" : {
@@ -150156,6 +150290,17 @@
         }
       }
     },
+    "not adding carbs in Trio" : {
+      "extractionState" : "stale",
+      "localizations" : {
+        "fr" : {
+          "stringUnit" : {
+            "state" : "translated",
+            "value" : "Pas d’ajout de glucides dans Trio"
+          }
+        }
+      }
+    },
     "Not allowed" : {
       "localizations" : {
         "bg" : {
@@ -204948,6 +205093,16 @@
         }
       }
     },
+    "the preset to apply" : {
+      "localizations" : {
+        "fr" : {
+          "stringUnit" : {
+            "state" : "translated",
+            "value" : "L"
+          }
+        }
+      }
+    },
     "The ratio of how sensitive or resistant to insulin you are in the current loop cycle. Baseline = 1.0, Sensitive < 1.0, Resistant > 1.0" : {
       "localizations" : {
         "bg" : {
@@ -218150,6 +218305,16 @@
         }
       }
     },
+    "Tomorrow" : {
+      "localizations" : {
+        "fr" : {
+          "stringUnit" : {
+            "state" : "translated",
+            "value" : "Demain"
+          }
+        }
+      }
+    },
     "Top target" : {
       "comment" : "Upper temp target limit",
       "extractionState" : "manual",
@@ -235895,6 +236060,7 @@
       }
     },
     "What is the numeric value of the carb to add" : {
+      "extractionState" : "stale",
       "localizations" : {
         "bg" : {
           "stringUnit" : {
@@ -236637,6 +236803,16 @@
         }
       }
     },
+    "When did you eat ?" : {
+      "localizations" : {
+        "fr" : {
+          "stringUnit" : {
+            "state" : "translated",
+            "value" : "Quand avez-vous mangé ?"
+          }
+        }
+      }
+    },
     "When enabled, Super Micro Boluses (SMBs) will always be allowed if dosing calculations determine insulin is needed via the SMB delivery method, except when a high Temp Target is set." : {
       "localizations" : {
         "bg" : {
@@ -238362,6 +238538,26 @@
         }
       }
     },
+    "Which override do you want to apply?" : {
+      "localizations" : {
+        "fr" : {
+          "stringUnit" : {
+            "state" : "translated",
+            "value" : "Quelle dérogations voulez-vous appliquer ? "
+          }
+        }
+      }
+    },
+    "Which preset to apply?" : {
+      "localizations" : {
+        "fr" : {
+          "stringUnit" : {
+            "state" : "translated",
+            "value" : "Quelle dérogation à appliquer ?"
+          }
+        }
+      }
+    },
     "While onboarding, Trio continues to operate with your prior settings." : {
       "localizations" : {
         "bg" : {
@@ -240302,6 +240498,16 @@
         }
       }
     },
+    "Yesterday" : {
+      "localizations" : {
+        "fr" : {
+          "stringUnit" : {
+            "state" : "translated",
+            "value" : "Hier"
+          }
+        }
+      }
+    },
     "You can change these permissions any time in the iOS Settings app." : {
       "localizations" : {
         "bg" : {
@@ -243195,4 +243401,4 @@
     }
   },
   "version" : "1.0"
-}
+}

+ 6 - 4
Trio/Sources/Shortcuts/Bolus/BolusIntent.swift

@@ -19,7 +19,8 @@ import Swinject
         /// A preferred approach would be to just block negatives and not specify an upperBound here, since it is implemented elsewhere
         inclusiveRange: (lowerBound: 0, upperBound: 200),
         requestValueDialog: IntentDialog(
-            LocalizedStringResource(
+            stringLiteral: String(
+                localized:
                 "Bolus amount (units of insulin)?"
             )
         )
@@ -52,8 +53,9 @@ import Swinject
                 try await requestConfirmation(
                     result: .result(
                         dialog: IntentDialog(
-                            LocalizedStringResource(
-                                "Are you sure you want to bolus \(bolusFormatted) U of insulin?"
+                            stringLiteral: String(
+                                localized:
+                                "Are you sure to bolus \(bolusFormatted) U of insulin?"
                             )
                         )
                     )
@@ -62,7 +64,7 @@ import Swinject
 
             let finalBolusDisplay = try await BolusIntentRequest().bolus(amount)
             return .result(
-                dialog: IntentDialog(finalBolusDisplay)
+                dialog: IntentDialog(stringLiteral: finalBolusDisplay)
             )
 
         } catch {

+ 7 - 4
Trio/Sources/Shortcuts/Bolus/BolusIntentRequest.swift

@@ -3,26 +3,29 @@ import CoreData
 import Foundation
 
 @available(iOS 16.0,*) final class BolusIntentRequest: BaseIntentsRequest {
-    func bolus(_ bolusAmount: Double) async throws -> LocalizedStringResource {
+    func bolus(_ bolusAmount: Double) async throws -> String {
         var bolusQuantity: Decimal = 0
         switch settingsManager.settings.bolusShortcut {
         // Block boluses if they are disabled
         case .notAllowed:
-            return LocalizedStringResource(
+            return String(
+                localized:
                 "Bolusing via Shortcuts is disabled in Trio settings."
             )
 
         // Block any bolus attempted if it is larger than the max bolus in settings
         case .limitBolusMax:
             if Decimal(bolusAmount) > settingsManager.pumpSettings.maxBolus {
-                return LocalizedStringResource(
+                return String(
+                    localized:
                     "The bolus cannot be larger than the pump setting max bolus (\(settingsManager.pumpSettings.maxBolus.description))."
                 )
             } else {
                 bolusQuantity = apsManager.roundBolus(amount: Decimal(bolusAmount))
             }
             await apsManager.enactBolus(amount: Double(bolusQuantity), isSMB: false, callback: nil)
-            return LocalizedStringResource(
+            return String(
+                localized:
                 "A bolus command of \(bolusQuantity.formatted()) U of insulin was sent."
             )
         }

+ 27 - 11
Trio/Sources/Shortcuts/Carbs/AddCarbPresetIntent.swift

@@ -8,10 +8,10 @@ import Swinject
     static var title: LocalizedStringResource = "Add carbs"
 
     // Description of the action in the Shortcuts app
-    static var description = IntentDescription("Allow to add carbs in Trio.")
+    static var description = IntentDescription(LocalizedStringResource("Allow to add carbs in Trio."))
 
     init() {
-        dateAdded = Date()
+        // dateAdded = Date()
     }
 
     @Parameter(
@@ -19,27 +19,30 @@ import Swinject
         description: "Quantity of carbs in g",
         controlStyle: .field,
         inclusiveRange: (lowerBound: 0, upperBound: 200),
-        requestValueDialog: IntentDialog("What is the numeric value of the carb to add")
+        requestValueDialog: IntentDialog(stringLiteral: String(localized: "How many grams of carbs did you eat?")),
     ) var carbQuantity: Double?
 
     @Parameter(
         title: "Quantity fat",
         description: "Quantity of fat in g",
         default: 0.0,
-        inclusiveRange: (0, 200)
+        inclusiveRange: (0, 200),
+        requestValueDialog: IntentDialog(stringLiteral: String(localized: "How many grams of fat did you eat?"))
     ) var fatQuantity: Double
 
     @Parameter(
         title: "Quantity Protein",
         description: "Quantity of Protein in g",
         default: 0.0,
-        inclusiveRange: (0, 200)
+        inclusiveRange: (0, 200),
+        requestValueDialog: IntentDialog(stringLiteral: String(localized: "How many grams of protein did you eat?"))
     ) var proteinQuantity: Double
 
     @Parameter(
         title: "Date",
-        description: "Date of adding"
-    ) var dateAdded: Date
+        description: "Date of adding",
+        requestValueDialog: IntentDialog(stringLiteral: String(localized: "When did you eat ?"))
+    ) var dateAdded: Date?
 
     @Parameter(
         title: "Notes",
@@ -76,13 +79,25 @@ import Swinject
             if let cq = carbQuantity {
                 quantityCarbs = cq
             } else {
-                quantityCarbs = try await $carbQuantity.requestValue("How many carbs do you want to add?")
+                quantityCarbs = try await $carbQuantity.requestValue("How many grams of carbs?")
+            }
+
+            let dateCarbsAdded: Date
+            let dateDefinedByUser: Bool
+            if let da = dateAdded {
+                dateCarbsAdded = da
+                dateDefinedByUser = true
+            } else {
+                dateCarbsAdded = Date()
+                dateDefinedByUser = false
             }
 
             let quantityCarbsName = quantityCarbs.toString()
             if confirmBeforeApplying {
                 try await requestConfirmation(
-                    result: .result(dialog: "Do you want to add \(quantityCarbsName) grams of carbs?")
+                    result: .result(
+                        dialog: IntentDialog(stringLiteral: String(localized: "Add \(quantityCarbsName) grams of carbs?"))
+                    )
                 )
             }
 
@@ -90,8 +105,9 @@ import Swinject
                 quantityCarbs,
                 fatQuantity,
                 proteinQuantity,
-                dateAdded,
-                note
+                dateCarbsAdded,
+                note,
+                dateDefinedByUser
             )
             return .result(
                 dialog: IntentDialog(stringLiteral: finalQuantityCarbsDisplay)

+ 43 - 6
Trio/Sources/Shortcuts/Carbs/CarbPresetIntentRequest.swift

@@ -7,7 +7,8 @@ import Foundation
         _ quantityFat: Double,
         _ quantityProtein: Double,
         _ dateAdded: Date,
-        _ note: String?
+        _ note: String?,
+        _ dateDefinedByUser: Bool
     ) async throws -> String {
         guard quantityCarbs >= 0.0 || quantityFat >= 0.0 || quantityProtein >= 0.0 else {
             return "not adding carbs in Trio"
@@ -30,15 +31,51 @@ import Foundation
             areFetchedFromRemote: false
         )
         var resultDisplay: String
-        resultDisplay = "\(carbs) g carbs"
+        resultDisplay = String(localized: "Added \(String(format: "%.0f", Double(carbs))) g carbs")
         if quantityFat > 0.0 {
-            resultDisplay = "\(resultDisplay) and \(quantityFat) g fats"
+            resultDisplay = String(localized: "\(resultDisplay) and \(String(format: "%.0f", Double(quantityFat))) g fat")
         }
         if quantityProtein > 0.0 {
-            resultDisplay = "\(resultDisplay) and \(quantityProtein) g protein"
+            resultDisplay = String(localized: "\(resultDisplay) and \(String(format: "%.0f", Double(quantityProtein))) g protein")
         }
-        let dateName = dateAdded.formatted()
-        resultDisplay = "\(resultDisplay) added at \(dateName)"
+        if dateDefinedByUser {
+            let dateFormatter = DateFormatter()
+            dateFormatter.dateStyle = .none
+            dateFormatter.timeStyle = .short
+
+            let hourName = dateFormatter.string(from: dateAdded)
+            resultDisplay = String(localized: "\(resultDisplay) at \(hourName)")
+
+            let dayStatus = determineDateStatus(dateAdded)
+            if let dayStatus = dayStatus {
+                resultDisplay = String(localized: "\(resultDisplay)  \(dayStatus)")
+            }
+        }
+
         return resultDisplay
     }
+
+    func determineDateStatus(_ date: Date) -> LocalizedStringResource? {
+        let calendar = Calendar.current
+        let now = Date()
+
+        let dateStartOfDay = calendar.startOfDay(for: date)
+        let nowStartOfDay = calendar.startOfDay(for: now)
+
+        let components = calendar.dateComponents([.day], from: nowStartOfDay, to: dateStartOfDay)
+
+        if let dayDifference = components.day {
+            switch dayDifference {
+            case -1:
+                return LocalizedStringResource(stringLiteral: "Yesterday")
+            case 0:
+                return nil
+            case 1:
+                return LocalizedStringResource(stringLiteral: "Tomorrow")
+            default:
+                return nil
+            }
+        }
+        return nil
+    }
 }

+ 9 - 5
Trio/Sources/Shortcuts/Override/ApplyOverridePresetIntent.swift

@@ -12,7 +12,8 @@ struct ApplyOverridePresetIntent: AppIntent {
     /// The override preset to be applied.
     @Parameter(
         title: LocalizedStringResource("Override"),
-        description: LocalizedStringResource("Override choice")
+        description: LocalizedStringResource("Override choice"),
+        requestValueDialog: IntentDialog(stringLiteral: String(localized: "Which override do you want to apply?"))
     ) var preset: OverridePreset?
 
     /// A boolean parameter that determines whether confirmation is required before applying the override.
@@ -49,7 +50,7 @@ struct ApplyOverridePresetIntent: AppIntent {
                 // Request user selection if no preset is provided
                 presetToApply = try await $preset.requestDisambiguation(
                     among: await OverridePresetsIntentRequest().fetchAndProcessOverrides(),
-                    dialog: IntentDialog(LocalizedStringResource("Select override"))
+                    dialog: IntentDialog(stringLiteral: String(localized: "Select override"))
                 )
             }
 
@@ -60,7 +61,8 @@ struct ApplyOverridePresetIntent: AppIntent {
                 try await requestConfirmation(
                     result: .result(
                         dialog: IntentDialog(
-                            LocalizedStringResource(
+                            stringLiteral: String(
+                                localized:
                                 "Confirm to apply override '\(displayName)'"
                             )
                         )
@@ -72,7 +74,8 @@ struct ApplyOverridePresetIntent: AppIntent {
             if await OverridePresetsIntentRequest().enactOverride(presetToApply) {
                 return .result(
                     dialog: IntentDialog(
-                        LocalizedStringResource(
+                        stringLiteral: String(
+                            localized:
                             "Override '\(presetToApply.name)' applied"
                         )
                     )
@@ -80,7 +83,8 @@ struct ApplyOverridePresetIntent: AppIntent {
             } else {
                 return .result(
                     dialog: IntentDialog(
-                        LocalizedStringResource(
+                        stringLiteral: String(
+                            localized:
                             "Override '\(presetToApply.name)' failed"
                         )
                     )

+ 1 - 1
Trio/Sources/Shortcuts/Override/CancelOverrideIntent.swift

@@ -16,7 +16,7 @@ struct CancelOverrideIntent: AppIntent {
     @MainActor func perform() async throws -> some ProvidesDialog {
         await OverridePresetsIntentRequest().cancelOverride()
         return .result(
-            dialog: IntentDialog(LocalizedStringResource("Override canceled"))
+            dialog: IntentDialog(stringLiteral: String(localized: "Override canceled"))
         )
     }
 }

+ 14 - 4
Trio/Sources/Shortcuts/TempPresets/ApplyTempPresetIntent.swift

@@ -10,7 +10,11 @@ struct ApplyTempPresetIntent: AppIntent {
     static var description = IntentDescription("Enable a Temporary Target")
 
     /// The temporary target preset to be applied.
-    @Parameter(title: "Preset") var preset: TempPreset?
+    @Parameter(
+        title: "Preset",
+        description: "the preset to apply",
+        requestValueDialog: IntentDialog(stringLiteral: String(localized: "Which preset to apply?"))
+    ) var preset: TempPreset?
 
     /// A boolean parameter that determines whether confirmation is required before applying the temporary target.
     @Parameter(
@@ -71,7 +75,11 @@ struct ApplyTempPresetIntent: AppIntent {
             // Request confirmation before applying if required
             if confirmBeforeApplying {
                 try await requestConfirmation(
-                    result: .result(dialog: "Confirm to apply Temporary Target '\(displayName)'")
+                    result: .result(
+                        dialog: IntentDialog(
+                            stringLiteral: String(localized: "Confirm to apply Temporary Target '\(displayName)'")
+                        )
+                    )
                 )
             }
 
@@ -79,7 +87,8 @@ struct ApplyTempPresetIntent: AppIntent {
             if await intentRequest.enactTempTarget(presetToApply) {
                 return .result(
                     dialog: IntentDialog(
-                        LocalizedStringResource(
+                        stringLiteral: String(
+                            localized:
                             "Temporary Target '\(presetToApply.name)' applied"
                         )
                     )
@@ -87,7 +96,8 @@ struct ApplyTempPresetIntent: AppIntent {
             } else {
                 return .result(
                     dialog: IntentDialog(
-                        LocalizedStringResource(
+                        stringLiteral: String(
+                            localized:
                             "Temporary Target '\(presetToApply.name)' failed"
                         )
                     )

+ 1 - 1
Trio/Sources/Shortcuts/TempPresets/CancelTempPresetIntent.swift

@@ -16,7 +16,7 @@ struct CancelTempPresetIntent: AppIntent {
     @MainActor func perform() async throws -> some ProvidesDialog {
         await TempPresetsIntentRequest().cancelTempTarget()
         return .result(
-            dialog: IntentDialog(stringLiteral: "Temporary Target canceled")
+            dialog: IntentDialog(stringLiteral: String(localized: "Temporary Target canceled"))
         )
     }
 }