SettingsViewController.swift 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222
  1. //
  2. // SettingsViewController.swift
  3. // LoopFollow
  4. //
  5. // Created by Jon Fawcett on 6/3/20.
  6. // Copyright © 2020 Jon Fawcett. All rights reserved.
  7. //
  8. import UIKit
  9. import Eureka
  10. import EventKit
  11. import EventKitUI
  12. class SettingsViewController: FormViewController {
  13. var appStateController: AppStateController?
  14. func showHideNSDetails() {
  15. var isHidden = false
  16. var isEnabled = true
  17. if UserDefaultsRepository.url.value == "" {
  18. isHidden = true
  19. isEnabled = false
  20. }
  21. if let row1 = form.rowBy(tag: "informationDisplaySettings") as? ButtonRow {
  22. row1.hidden = .function(["hide"], {form in
  23. return isHidden
  24. })
  25. row1.evaluateHidden()
  26. }
  27. guard let nightscoutTab = self.tabBarController?.tabBar.items![3] else { return }
  28. nightscoutTab.isEnabled = isEnabled
  29. }
  30. override func viewDidLoad() {
  31. super.viewDidLoad()
  32. if UserDefaultsRepository.forceDarkMode.value {
  33. overrideUserInterfaceStyle = .dark
  34. }
  35. var expiration: Date = Date()
  36. if let provision = MobileProvision.read() {
  37. expiration = provision.expirationDate
  38. }
  39. form
  40. +++ Section(header: "Nightscout Settings", footer: "Changing Nightscout settings requires an app restart.")
  41. <<< TextRow(){ row in
  42. row.title = "URL"
  43. row.placeholder = "https://mycgm.herokuapp.com"
  44. row.value = UserDefaultsRepository.url.value
  45. }.cellSetup { (cell, row) in
  46. cell.textField.autocorrectionType = .no
  47. }.onChange { row in
  48. guard let value = row.value else {
  49. UserDefaultsRepository.url.value = ""
  50. self.showHideNSDetails()
  51. return }
  52. // check the format of the URL entered by the user and trim away any spaces or "/" at the end
  53. var urlNSInput = value.replacingOccurrences(of: "\\s+$", with: "", options: .regularExpression)
  54. if urlNSInput.last == "/" {
  55. urlNSInput = String(urlNSInput.dropLast())
  56. }
  57. UserDefaultsRepository.url.value = urlNSInput.lowercased()
  58. // set the row value back to the correctly formatted URL so that the user immediately sees how it should have been written
  59. row.value = UserDefaultsRepository.url.value
  60. self.showHideNSDetails()
  61. globalVariables.nsVerifiedAlert = 0
  62. }
  63. <<< TextRow(){ row in
  64. row.title = "NS Token"
  65. row.placeholder = "Leave blank if not using tokens"
  66. row.value = UserDefaultsRepository.token.value
  67. }.cellSetup { (cell, row) in
  68. cell.textField.autocorrectionType = .no
  69. }.onChange { row in
  70. if row.value == nil {
  71. UserDefaultsRepository.token.value = ""
  72. }
  73. guard let value = row.value else { return }
  74. UserDefaultsRepository.token.value = value
  75. globalVariables.nsVerifiedAlert = 0
  76. }
  77. <<< SegmentedRow<String>("units") { row in
  78. row.title = "Units"
  79. row.options = ["mg/dL", "mmol/L"]
  80. row.value = UserDefaultsRepository.units.value
  81. }.onChange { row in
  82. guard let value = row.value else { return }
  83. UserDefaultsRepository.units.value = value
  84. }
  85. +++ Section("Dexcom Settings")
  86. <<< TextRow(){ row in
  87. row.title = "User Name"
  88. row.value = UserDefaultsRepository.shareUserName.value
  89. }.cellSetup { (cell, row) in
  90. cell.textField.autocorrectionType = .no
  91. }.onChange { row in
  92. if row.value == nil {
  93. UserDefaultsRepository.shareUserName.value = ""
  94. }
  95. guard let value = row.value else { return }
  96. UserDefaultsRepository.shareUserName.value = value
  97. globalVariables.dexVerifiedAlert = 0
  98. }
  99. <<< TextRow(){ row in
  100. row.title = "Password"
  101. row.value = UserDefaultsRepository.sharePassword.value
  102. }.cellSetup { (cell, row) in
  103. cell.textField.autocorrectionType = .no
  104. cell.textField.isSecureTextEntry = true
  105. }.onChange { row in
  106. if row.value == nil {
  107. UserDefaultsRepository.sharePassword.value = ""
  108. }
  109. guard let value = row.value else { return }
  110. UserDefaultsRepository.sharePassword.value = value
  111. globalVariables.dexVerifiedAlert = 0
  112. }
  113. <<< SegmentedRow<String>("shareServer") { row in
  114. row.title = "Server"
  115. row.options = ["US", "NON-US"]
  116. row.value = UserDefaultsRepository.shareServer.value
  117. }.onChange { row in
  118. guard let value = row.value else { return }
  119. UserDefaultsRepository.shareServer.value = value
  120. }
  121. +++ Section("App Settings")
  122. <<< ButtonRow() {
  123. $0.title = "General Settings"
  124. $0.presentationMode = .show(
  125. controllerProvider: .callback(builder: {
  126. let controller = GeneralSettingsViewController()
  127. controller.appStateController = self.appStateController
  128. return controller
  129. }
  130. ), onDismiss: nil)
  131. }
  132. <<< ButtonRow("graphSettings") {
  133. $0.title = "Graph Settings"
  134. $0.presentationMode = .show(
  135. controllerProvider: .callback(builder: {
  136. let controller = GraphSettingsViewController()
  137. controller.appStateController = self.appStateController
  138. return controller
  139. }
  140. ), onDismiss: nil)
  141. }
  142. <<< ButtonRow("informationDisplaySettings") {
  143. $0.title = "Information Display Settings"
  144. $0.presentationMode = .show(
  145. controllerProvider: .callback(builder: {
  146. let controller = InfoDisplaySettingsViewController()
  147. controller.appStateController = self.appStateController
  148. return controller
  149. }
  150. ), onDismiss: nil)
  151. }
  152. +++ Section("Integrations")
  153. <<< ButtonRow() {
  154. $0.title = "Apple Watch and Carplay"
  155. $0.presentationMode = .show(
  156. controllerProvider: .callback(builder: {
  157. let controller = WatchSettingsViewController()
  158. controller.appStateController = self.appStateController
  159. return controller
  160. }
  161. ), onDismiss: nil)
  162. }
  163. <<< LabelRow("Clear Images"){ row in
  164. row.title = "Delete Watch Face Images"
  165. }.onCellSelection{ cell,row in
  166. if UserDefaultsRepository.saveImage.value {
  167. guard let mainScreen = self.tabBarController!.viewControllers?[0] as? MainViewController else { return }
  168. mainScreen.deleteOldImages()
  169. mainScreen.saveChartImage()
  170. }
  171. }
  172. +++ Section("Advanced Settings")
  173. <<< ButtonRow() {
  174. $0.title = "Advanced Settings"
  175. $0.presentationMode = .show(
  176. controllerProvider: .callback(builder: {
  177. let controller = AdvancedSettingsViewController()
  178. controller.appStateController = self.appStateController
  179. return controller
  180. }
  181. ), onDismiss: nil)
  182. }
  183. <<< LabelRow("Refresh Graph"){ row in
  184. row.title = "Refresh Graph"
  185. }.onCellSelection{ cell,row in
  186. if UserDefaultsRepository.saveImage.value {
  187. guard let mainScreen = self.tabBarController!.viewControllers?[0] as? MainViewController else { return }
  188. mainScreen.updateBGGraphSettings()
  189. self.tabBarController?.selectedIndex = 0
  190. }
  191. }
  192. +++ Section(header: "App Expiration", footer: String(expiration.description))
  193. showHideNSDetails()
  194. }
  195. }