MainViewController.swift 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236
  1. //
  2. // MainViewController.swift
  3. // RileyLink
  4. //
  5. // Created by Pete Schwamb on 5/11/16.
  6. // Copyright © 2016 Pete Schwamb. All rights reserved.
  7. //
  8. import UIKit
  9. import SwiftUI
  10. import MinimedKit
  11. import MinimedKitUI
  12. import RileyLinkBLEKit
  13. import RileyLinkKit
  14. import RileyLinkKitUI
  15. import LoopKit
  16. import LoopKitUI
  17. import OmniKitUI
  18. class MainViewController: RileyLinkSettingsViewController {
  19. let deviceDataManager: DeviceDataManager
  20. let insulinTintColor: Color
  21. let guidanceColors: GuidanceColors
  22. init(deviceDataManager: DeviceDataManager, insulinTintColor: Color, guidanceColors: GuidanceColors) {
  23. self.deviceDataManager = deviceDataManager
  24. self.insulinTintColor = insulinTintColor
  25. self.guidanceColors = guidanceColors
  26. let rileyLinkPumpManager = RileyLinkPumpManager(rileyLinkDeviceProvider: deviceDataManager.rileyLinkConnectionManager.deviceProvider, rileyLinkConnectionManager: deviceDataManager.rileyLinkConnectionManager)
  27. super.init(rileyLinkPumpManager: rileyLinkPumpManager, devicesSectionIndex: Section.rileyLinks.rawValue, style: .grouped)
  28. self.title = NSLocalizedString("RileyLink Testing", comment: "Title for RileyLink Testing main view controller")
  29. }
  30. required init?(coder aDecoder: NSCoder) {
  31. fatalError("init(coder:) has not been implemented")
  32. }
  33. override func viewDidLoad() {
  34. super.viewDidLoad()
  35. tableView.backgroundColor = UIColor.white
  36. tableView.separatorStyle = .none
  37. tableView.rowHeight = UITableView.automaticDimension
  38. tableView.estimatedRowHeight = 44
  39. tableView.sectionHeaderHeight = UITableView.automaticDimension
  40. tableView.estimatedSectionHeaderHeight = 55
  41. tableView.register(TextButtonTableViewCell.self, forCellReuseIdentifier: TextButtonTableViewCell.className)
  42. tableView.register(SettingsImageTableViewCell.self, forCellReuseIdentifier: SettingsImageTableViewCell.className)
  43. let rlImage = UIImage(named: "RileyLink", in: Bundle.main, compatibleWith: tableView.traitCollection)
  44. let imageView = UIImageView(image: rlImage)
  45. imageView.tintColor = UIColor.white
  46. imageView.contentMode = .center
  47. imageView.frame.size.height += 30 // feels right
  48. imageView.backgroundColor = UIColor(named: "RileyLink Tint", in: Bundle.main, compatibleWith: tableView.traitCollection)
  49. tableView.tableHeaderView = imageView
  50. tableView.register(RileyLinkDeviceTableViewCell.self, forCellReuseIdentifier: RileyLinkDeviceTableViewCell.className)
  51. NotificationCenter.default.addObserver(self, selector: #selector(deviceConnectionStateDidChange), name: .DeviceConnectionStateDidChange, object: nil)
  52. }
  53. override func viewWillAppear(_ animated: Bool) {
  54. // Manually invoke the delegate for rows deselecting on appear
  55. for indexPath in tableView.indexPathsForSelectedRows ?? [] {
  56. _ = tableView(tableView, willDeselectRowAt: indexPath)
  57. }
  58. super.viewWillAppear(animated)
  59. }
  60. fileprivate enum Section: Int, CaseCountable {
  61. case rileyLinks = 0
  62. case pump
  63. }
  64. fileprivate enum PumpActionRow: Int, CaseCountable {
  65. case addMinimedPump = 0
  66. case setupOmnipod
  67. }
  68. weak var rileyLinkManager: RileyLinkBluetoothDeviceProvider!
  69. @objc private func deviceConnectionStateDidChange() {
  70. DispatchQueue.main.async {
  71. self.tableView.reloadSections(IndexSet([Section.pump.rawValue]), with: .none)
  72. }
  73. }
  74. private var shouldAllowAddingPump: Bool {
  75. return rileyLinkManager.connectingCount > 0
  76. }
  77. // MARK: Data Source
  78. override func numberOfSections(in tableView: UITableView) -> Int {
  79. return Section.count
  80. }
  81. override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
  82. switch Section(rawValue: section)! {
  83. case .rileyLinks:
  84. return super.tableView(tableView, numberOfRowsInSection: section)
  85. case .pump:
  86. if let _ = deviceDataManager.pumpManager {
  87. return 1
  88. } else {
  89. return PumpActionRow.count
  90. }
  91. }
  92. }
  93. override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
  94. let cell: UITableViewCell
  95. switch(Section(rawValue: indexPath.section)!) {
  96. case .rileyLinks:
  97. return super.tableView(tableView, cellForRowAt: indexPath)
  98. case .pump:
  99. if let pumpManager = deviceDataManager.pumpManager {
  100. cell = tableView.dequeueReusableCell(withIdentifier: SettingsImageTableViewCell.className, for: indexPath)
  101. cell.imageView?.image = pumpManager.smallImage
  102. cell.textLabel?.text = pumpManager.localizedTitle
  103. cell.detailTextLabel?.text = nil
  104. cell.accessoryType = .disclosureIndicator
  105. } else {
  106. switch(PumpActionRow(rawValue: indexPath.row)!) {
  107. case .addMinimedPump:
  108. cell = tableView.dequeueReusableCell(withIdentifier: TextButtonTableViewCell.className, for: indexPath)
  109. let textButtonCell = cell as? TextButtonTableViewCell
  110. textButtonCell?.isEnabled = shouldAllowAddingPump
  111. textButtonCell?.isUserInteractionEnabled = shouldAllowAddingPump
  112. cell.textLabel?.text = NSLocalizedString("Add Minimed Pump", comment: "Title text for button to set up a new minimed pump")
  113. case .setupOmnipod:
  114. cell = tableView.dequeueReusableCell(withIdentifier: TextButtonTableViewCell.className, for: indexPath)
  115. let textButtonCell = cell as? TextButtonTableViewCell
  116. textButtonCell?.isEnabled = shouldAllowAddingPump
  117. textButtonCell?.isUserInteractionEnabled = shouldAllowAddingPump
  118. cell.textLabel?.text = NSLocalizedString("Setup Omnipod", comment: "Title text for button to set up omnipod")
  119. }
  120. }
  121. }
  122. return cell
  123. }
  124. public override func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
  125. switch Section(rawValue: section)! {
  126. case .rileyLinks:
  127. return super.tableView(tableView, titleForHeaderInSection: section)
  128. case .pump:
  129. return NSLocalizedString("Pumps", comment: "Title text for section listing configured pumps")
  130. }
  131. }
  132. public override func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
  133. switch Section(rawValue: section)! {
  134. case .rileyLinks:
  135. return super.tableView(tableView, viewForHeaderInSection: section)
  136. case .pump:
  137. return nil
  138. }
  139. }
  140. public override func tableView(_ tableView: UITableView, estimatedHeightForHeaderInSection section: Int) -> CGFloat {
  141. return devicesDataSource.tableView(tableView, estimatedHeightForHeaderInSection: section)
  142. }
  143. // MARK: - UITableViewDelegate
  144. override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
  145. switch Section(rawValue: indexPath.section)! {
  146. case .rileyLinks:
  147. let device = devicesDataSource.devices[indexPath.row]
  148. let vc = RileyLinkDeviceTableViewController(device: device, batteryAlertLevel: nil, batteryAlertLevelChanged: nil)
  149. show(vc, sender: indexPath)
  150. case .pump:
  151. if let pumpManager = deviceDataManager.pumpManager {
  152. var settings = pumpManager.settingsViewController(insulinTintColor: insulinTintColor, guidanceColors: guidanceColors)
  153. settings.completionDelegate = self
  154. present(settings, animated: true)
  155. } else {
  156. var setupViewController: UIViewController & PumpManagerOnboarding & CompletionNotifying
  157. switch PumpActionRow(rawValue: indexPath.row)! {
  158. case .addMinimedPump:
  159. setupViewController = UIStoryboard(name: "MinimedPumpManager", bundle: Bundle(for: MinimedPumpManagerSetupViewController.self)).instantiateViewController(withIdentifier: "DevelopmentPumpSetup") as! MinimedPumpManagerSetupViewController
  160. case .setupOmnipod:
  161. setupViewController = UIStoryboard(name: "OmnipodPumpManager", bundle: Bundle(for: OmnipodPumpManagerSetupViewController.self)).instantiateViewController(withIdentifier: "DevelopmentPumpSetup") as! OmnipodPumpManagerSetupViewController
  162. }
  163. if let rileyLinkManagerViewController = setupViewController as? RileyLinkManagerSetupViewController {
  164. rileyLinkManagerViewController.rileyLinkPumpManager = RileyLinkPumpManager(rileyLinkDeviceProvider: deviceDataManager.rileyLinkConnectionManager.deviceProvider)
  165. }
  166. setupViewController.setupDelegate = self
  167. setupViewController.completionDelegate = self
  168. present(setupViewController, animated: true, completion: nil)
  169. }
  170. }
  171. }
  172. override func tableView(_ tableView: UITableView, willDeselectRowAt indexPath: IndexPath) -> IndexPath? {
  173. switch Section(rawValue: indexPath.section)! {
  174. case .rileyLinks:
  175. break
  176. case .pump:
  177. tableView.reloadSections(IndexSet([Section.pump.rawValue]), with: .none)
  178. }
  179. return indexPath
  180. }
  181. }
  182. extension MainViewController: CompletionDelegate {
  183. func completionNotifyingDidComplete(_ object: CompletionNotifying) {
  184. if let vc = object as? UIViewController, presentedViewController === vc {
  185. dismiss(animated: true, completion: nil)
  186. }
  187. }
  188. }
  189. extension MainViewController: PumpManagerCreateDelegate {
  190. func pumpManagerOnboarding(_ notifying: PumpManagerCreateNotifying, didCreatePumpManager pumpManager: PumpManagerUI) {
  191. deviceDataManager.pumpManager = pumpManager
  192. }
  193. }
  194. extension MainViewController: PumpManagerOnboardingDelegate {
  195. func pumpManagerOnboarding(_ notifying: PumpManagerOnboarding, didOnboardPumpManager pumpManager: PumpManagerUI, withSettings settings: PumpManagerSetupSettings) {
  196. show(pumpManager.settingsViewController(insulinTintColor: insulinTintColor, guidanceColors: guidanceColors), sender: nil)
  197. tableView.reloadSections(IndexSet([Section.pump.rawValue]), with: .none)
  198. }
  199. }