AdjustmentsStateModel+Helpers.swift 3.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. import SwiftUI
  2. extension Adjustments.StateModel {
  3. /// Returns a description of how insulin doses are adjusted based on percentage.
  4. func percentageDescription(_ percent: Double) -> Text? {
  5. if percent.isNaN || percent == 100 { return nil }
  6. var description: String = "Insulin doses will be "
  7. if percent < 100 {
  8. description += "decreased by "
  9. } else {
  10. description += "increased by "
  11. }
  12. let deviationFrom100 = abs(percent - 100)
  13. description += String(format: "%.0f% %.", deviationFrom100)
  14. return Text(description)
  15. }
  16. /// Checks if the device is using a 24-hour time format.
  17. func is24HourFormat() -> Bool {
  18. let formatter = DateFormatter()
  19. formatter.locale = Locale.current
  20. formatter.dateStyle = .none
  21. formatter.timeStyle = .short
  22. let dateString = formatter.string(from: Date())
  23. return !dateString.contains("AM") && !dateString.contains("PM")
  24. }
  25. /// Converts a given hour to a 12-hour AM/PM format string.
  26. func convertTo12HourFormat(_ hour: Int) -> String {
  27. let formatter = DateFormatter()
  28. formatter.dateFormat = "h a"
  29. let calendar = Calendar.current
  30. let components = DateComponents(hour: hour)
  31. let date = calendar.date(from: components) ?? Date()
  32. return formatter.string(from: date)
  33. }
  34. /// Formats a given 24-hour time number as a two-digit string.
  35. func format24Hour(_ hour: Int) -> String {
  36. String(format: "%02d", hour)
  37. }
  38. /// Converts a duration in minutes to a formatted string (e.g., "1 hr 30 min").
  39. func formatHrMin(_ durationInMinutes: Int) -> String {
  40. let hours = durationInMinutes / 60
  41. let minutes = durationInMinutes % 60
  42. switch (hours, minutes) {
  43. case let (0, m):
  44. return "\(m) min"
  45. case let (h, 0):
  46. return "\(h) hr"
  47. default:
  48. return "\(hours) hr \(minutes) min"
  49. }
  50. }
  51. /// Converts hours and minutes to total minutes as a `Decimal`.
  52. func convertToMinutes(_ hours: Int, _ minutes: Int) -> Decimal {
  53. let totalMinutes = (hours * 60) + minutes
  54. return Decimal(max(0, totalMinutes))
  55. }
  56. }
  57. extension PickerSettingsProvider {
  58. /// Generates picker values based on a setting, optionally rounding minimum to the nearest step.
  59. func generatePickerValues(from setting: PickerSetting, units: GlucoseUnits, roundMinToStep: Bool) -> [Decimal] {
  60. if !roundMinToStep {
  61. return generatePickerValues(from: setting, units: units)
  62. }
  63. // Adjust min to be divisible by step
  64. var newSetting = setting
  65. var min = Double(newSetting.min)
  66. let step = Double(newSetting.step)
  67. let remainder = min.truncatingRemainder(dividingBy: step)
  68. if remainder != 0 {
  69. // Move min up to the next value divisible by targetStep
  70. min += (step - remainder)
  71. }
  72. newSetting.min = Decimal(min)
  73. return generatePickerValues(from: newSetting, units: units)
  74. }
  75. }