NotificationSettingsView.swift 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145
  1. //
  2. // NotificationSettingsView.swift
  3. // OmniKit
  4. //
  5. // Created by Pete Schwamb on 2/3/21.
  6. // Copyright © 2021 LoopKit Authors. All rights reserved.
  7. //
  8. import SwiftUI
  9. import LoopKit
  10. import LoopKitUI
  11. import HealthKit
  12. struct NotificationSettingsView: View {
  13. var dateFormatter: DateFormatter
  14. @Binding var expirationReminderDefault: Int
  15. @State private var showingHourPicker: Bool = false
  16. var scheduledReminderDate: Date?
  17. var allowedScheduledReminderDates: [Date]?
  18. var lowReservoirReminderValue: Int
  19. var onSaveScheduledExpirationReminder: ((_ selectedDate: Date?, _ completion: @escaping (_ error: Error?) -> Void) -> Void)?
  20. var onSaveLowReservoirReminder: ((_ selectedValue: Int, _ completion: @escaping (_ error: Error?) -> Void) -> Void)?
  21. var insulinQuantityFormatter = QuantityFormatter(for: .internationalUnit())
  22. var body: some View {
  23. RoundedCardScrollView {
  24. RoundedCard(
  25. title: LocalizedString("Pod Reminders", comment: "Title for pod reminders section"),
  26. footer: LocalizedString("The app configures a reminder on the Pod to notify you in advance of Pod expiration. Set the number of hours advance notice you would like to configure by default when pairing a new Pod.", comment: "Footer text for pod reminders section")
  27. ) {
  28. ExpirationReminderPickerView(expirationReminderDefault: $expirationReminderDefault)
  29. }
  30. if let allowedDates = allowedScheduledReminderDates {
  31. RoundedCard(
  32. footer: LocalizedString("The expiration reminder time for the current Pod.", comment: "Footer text for scheduled reminder area"))
  33. {
  34. Text(LocalizedString("Scheduled Reminder", comment: "Title of scheduled reminder card on NotificationSettingsView"))
  35. Divider()
  36. scheduledReminderRow(scheduledDate: scheduledReminderDate, allowedDates: allowedDates)
  37. }
  38. }
  39. RoundedCard(footer: LocalizedString("The app notifies you when the amount of insulin in the Pod reaches this level.", comment: "Footer text for low reservoir value row")) {
  40. lowReservoirValueRow
  41. }
  42. RoundedCard<EmptyView>(
  43. title: LocalizedString("Critical Alerts", comment: "Title for critical alerts description"),
  44. footer: LocalizedString("The above reminders will not sound in the app if your device is in Silent or Do Not Disturb mode. There are other critical Pod alerts that will sound in the app even if your device is set to Silent or Do Not Disturb mode.\n\nThe Pod will also use audible beeps for all Pod reminders and alerts except when the Pod is Silenced.", comment: "Description text for critical alerts")
  45. )
  46. }
  47. .navigationBarTitle(LocalizedString("Notification Settings", comment: "navigation title for notification settings"))
  48. }
  49. @State private var scheduleReminderDateEditViewIsShown: Bool = false
  50. private func scheduledReminderRow(scheduledDate: Date?, allowedDates: [Date]) -> some View {
  51. Group {
  52. // Make the expiration reminder time read-only if there aren't any more available times.
  53. if allowedDates.isEmpty {
  54. scheduledReminderRowContents(disclosure: false)
  55. } else {
  56. NavigationLink(
  57. destination: ScheduledExpirationReminderEditView(
  58. scheduledExpirationReminderDate: scheduledDate,
  59. allowedDates: allowedDates,
  60. dateFormatter: dateFormatter,
  61. onSave: onSaveScheduledExpirationReminder,
  62. onFinish: { scheduleReminderDateEditViewIsShown = false }),
  63. isActive: $scheduleReminderDateEditViewIsShown)
  64. {
  65. scheduledReminderRowContents(disclosure: true)
  66. }
  67. }
  68. }
  69. }
  70. private func scheduledReminderRowContents(disclosure: Bool) -> some View {
  71. RoundedCardValueRow(
  72. label: LocalizedString("Time", comment: "Label for scheduled reminder value row"),
  73. value: scheduledReminderDateString(scheduledReminderDate),
  74. highlightValue: false,
  75. disclosure: disclosure
  76. )
  77. }
  78. private func scheduledReminderDateString(_ scheduledDate: Date?) -> String {
  79. if let scheduledDate = scheduledDate {
  80. return dateFormatter.string(from: scheduledDate)
  81. } else {
  82. return LocalizedString("No Reminder", comment: "Value text for no expiration reminder")
  83. }
  84. }
  85. @State private var lowReservoirReminderEditViewIsShown: Bool = false
  86. var lowReservoirValueRow: some View {
  87. NavigationLink(
  88. destination: LowReservoirReminderEditView(
  89. lowReservoirReminderValue: lowReservoirReminderValue,
  90. insulinQuantityFormatter: insulinQuantityFormatter,
  91. onSave: onSaveLowReservoirReminder,
  92. onFinish: { lowReservoirReminderEditViewIsShown = false }),
  93. isActive: $lowReservoirReminderEditViewIsShown)
  94. {
  95. RoundedCardValueRow(
  96. label: LocalizedString("Low Reservoir Reminder", comment: "Label for low reservoir reminder row"),
  97. value: insulinQuantityFormatter.string(from: HKQuantity(unit: .internationalUnit(), doubleValue: Double(lowReservoirReminderValue)), for: .internationalUnit()) ?? "",
  98. highlightValue: false,
  99. disclosure: true)
  100. }
  101. }
  102. }
  103. struct NotificationSettingsView_Previews: PreviewProvider {
  104. static var previews: some View {
  105. return Group {
  106. NavigationView {
  107. let now = Date()
  108. NotificationSettingsView(dateFormatter: DateFormatter(), expirationReminderDefault: .constant(2), scheduledReminderDate: now + TimeInterval(hours: 1), allowedScheduledReminderDates: [now, now - TimeInterval(hours: 2), now - TimeInterval(hours: 3)], lowReservoirReminderValue: 20)
  109. .previewDevice(PreviewDevice(rawValue:"iPod touch (7th generation)"))
  110. .previewDisplayName("iPod touch (7th generation)")
  111. }
  112. NavigationView {
  113. let now = Date()
  114. NotificationSettingsView(dateFormatter: DateFormatter(), expirationReminderDefault: .constant(2), scheduledReminderDate: now + TimeInterval(hours: 1), allowedScheduledReminderDates: [now, now - TimeInterval(hours: 2), now - TimeInterval(hours: 3)], lowReservoirReminderValue: 20)
  115. .colorScheme(.dark)
  116. .previewDevice(PreviewDevice(rawValue: "iPhone XS Max"))
  117. .previewDisplayName("iPhone XS Max - Dark")
  118. }
  119. }
  120. }
  121. }