WatchSettingsViewController.swift 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  1. //
  2. // WatchSettingsViewController.swift
  3. // LoopFollow
  4. //
  5. // Created by Jose Paredes on 7/16/20.
  6. // Copyright © 2020 Jon Fawcett. All rights reserved.
  7. //
  8. import Foundation
  9. import Eureka
  10. import EventKit
  11. import EventKitUI
  12. class WatchSettingsViewController: FormViewController {
  13. var appStateController: AppStateController?
  14. override func viewDidLoad() {
  15. super.viewDidLoad()
  16. if UserDefaultsRepository.forceDarkMode.value {
  17. overrideUserInterfaceStyle = .dark
  18. }
  19. let eventStore = EKEventStore()
  20. eventStore.requestCalendarAccess { [weak self] (granted, error) in
  21. guard let self = self else { return }
  22. DispatchQueue.main.async {
  23. // Update the form based on the calendar access status
  24. self.buildWatchSettings(hasCalendarAccess: granted)
  25. self.showHideNSDetails()
  26. }
  27. }
  28. }
  29. func showHideNSDetails() {
  30. var isHidden = false
  31. var isEnabled = true
  32. if !IsNightscoutEnabled() {
  33. isHidden = true
  34. isEnabled = false
  35. }
  36. let tmpArr = ["IOB", "COB", "BASAL", "LOOP", "OVERRIDE"]
  37. for i in 0..<tmpArr.count {
  38. if let row1 = form.rowBy(tag: tmpArr[i]) as? LabelRow {
  39. row1.hidden = .function(["hide"], {form in
  40. return isHidden
  41. })
  42. row1.evaluateHidden()
  43. }
  44. }
  45. }
  46. private func buildWatchSettings(hasCalendarAccess: Bool){
  47. struct cal {
  48. var title: String
  49. var identifier: String
  50. }
  51. //array of calendars
  52. let store = EKEventStore()
  53. let ekCalendars = store.calendars(for: EKEntityType.event)
  54. var calendars: [cal] = []
  55. for i in 0..<ekCalendars.count{
  56. let item = cal(title: ekCalendars[i].title, identifier: ekCalendars[i].calendarIdentifier)
  57. calendars.append(item)
  58. }
  59. form
  60. +++ Section(header: "Save BG to Calendar", footer: "Add the Apple calendar complication to your Apple Watch face or Carplay to see BG readings. Create a new calendar called 'Follow' and modify the calendar settings in the iPhone Watch/Carplay App to only display the Follow calendar on your watch or car. It is important to use a new calendar because this will delete other events on the same calendar. Edit Line 1 and Line 2 to be displayed using variables below that will be replaced by the values. Other text entered will not be replaced")
  61. <<< LabelRow() {
  62. $0.title = "Calendar Access Denied"
  63. $0.hidden = Condition.function(["hide"], { _ in hasCalendarAccess })
  64. }.cellUpdate { cell, _ in
  65. cell.textLabel?.textColor = .red
  66. }
  67. <<< SwitchRow("writeCalendarEvent"){ row in
  68. row.title = "Save BG to Calendar"
  69. row.value = UserDefaultsRepository.writeCalendarEvent.value
  70. }.onChange { [weak self] row in
  71. guard let value = row.value else { return }
  72. UserDefaultsRepository.writeCalendarEvent.value = value
  73. }
  74. <<< PickerInputRow<String>("calendarIdentifier") { row in
  75. row.title = "Calendar"
  76. row.options = calendars.map { $0.identifier }
  77. row.value = UserDefaultsRepository.calendarIdentifier.value
  78. row.displayValueFor = { value in
  79. guard let value = value else { return nil }
  80. let matching = calendars
  81. .flatMap { $0 }
  82. .filter { $0.identifier.range(of: value) != nil || $0.title.range(of: value) != nil }
  83. if matching.count > 0 {
  84. return "\(String(matching[0].title))"
  85. } else {
  86. return " - "
  87. }
  88. }
  89. }.onChange { [weak self] row in
  90. guard let value = row.value else { return }
  91. UserDefaultsRepository.calendarIdentifier.value = value
  92. }
  93. <<< TextRow("watchLine1"){ row in
  94. row.title = "Line 1"
  95. row.value = UserDefaultsRepository.watchLine1.value
  96. }.onChange { row in
  97. guard let value = row.value else { return }
  98. UserDefaultsRepository.watchLine1.value = value
  99. }
  100. <<< TextRow("watchLine2"){ row in
  101. row.title = "Line 2"
  102. row.value = UserDefaultsRepository.watchLine2.value
  103. }.onChange { row in
  104. guard let value = row.value else { return }
  105. UserDefaultsRepository.watchLine2.value = value
  106. }
  107. +++ Section(header: "Available Variables", footer: "")
  108. <<< LabelRow("BG"){ row in
  109. row.title = "%BG% : Blood Glucose Reading"
  110. }
  111. <<< LabelRow("DIRECTION"){ row in
  112. row.title = "%DIRECTION% : Dexcom Trend Arrow"
  113. }
  114. <<< LabelRow("DELTA"){ row in
  115. row.title = "%DELTA% : +/- From Last Reading"
  116. }
  117. <<< LabelRow("IOB"){ row in
  118. row.title = "%IOB% : Insulin on Board"
  119. }
  120. <<< LabelRow("COB"){ row in
  121. row.title = "%COB% : Carbs on Board"
  122. }
  123. <<< LabelRow("BASAL"){ row in
  124. row.title = "%BASAL% : Current Basal u/hr"
  125. }
  126. <<< LabelRow("LOOP"){ row in
  127. row.title = "%LOOP% : Loop Status Symbol"
  128. }
  129. <<< LabelRow("OVERRIDE"){ row in
  130. row.title = "%OVERRIDE% : Active Override %"
  131. }
  132. <<< LabelRow("MINAGO"){ row in
  133. row.title = "%MINAGO% : Only displays for old readings"
  134. }
  135. +++ ButtonRow() {
  136. $0.title = "DONE"
  137. }.onCellSelection { (row, arg) in
  138. self.dismiss(animated:true, completion: nil)
  139. }
  140. }
  141. }