| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236 |
- //
- // InsertCannulaViewModel.swift
- // OmniKit
- //
- // Created by Pete Schwamb on 3/10/20.
- // Copyright © 2021 LoopKit Authors. All rights reserved.
- //
- import LoopKit
- import LoopKitUI
- import OmniKit
- public protocol CannulaInserter {
- func insertCannula(completion: @escaping (Result<TimeInterval,OmnipodPumpManagerError>) -> ())
- func checkCannulaInsertionFinished(completion: @escaping (OmnipodPumpManagerError?) -> Void)
- }
- extension OmnipodPumpManager: CannulaInserter {}
- class InsertCannulaViewModel: ObservableObject, Identifiable {
- enum InsertCannulaViewModelState {
- case ready
- case startingInsertion
- case inserting(finishTime: CFTimeInterval)
- case checkingInsertion
- case error(OmnipodPumpManagerError)
- case finished
-
- var actionButtonAccessibilityLabel: String {
- switch self {
- case .ready, .startingInsertion:
- return LocalizedString("Insert Cannula", comment: "Insert cannula action button accessibility label while ready to pair")
- case .inserting:
- return LocalizedString("Inserting. Please wait.", comment: "Insert cannula action button accessibility label while pairing")
- case .checkingInsertion:
- return LocalizedString("Checking Insertion", comment: "Insert cannula action button accessibility label checking insertion")
- case .error(let error):
- return String(format: "%@ %@", error.errorDescription ?? "", error.recoverySuggestion ?? "")
- case .finished:
- return LocalizedString("Cannula inserted successfully. Continue.", comment: "Insert cannula action button accessibility label when cannula insertion succeeded")
- }
- }
- var instructionsDisabled: Bool {
- switch self {
- case .ready, .error:
- return false
- default:
- return true
- }
- }
-
- var nextActionButtonDescription: String {
- switch self {
- case .ready:
- return LocalizedString("Insert Cannula", comment: "Cannula insertion button text while ready to insert")
- case .error:
- return LocalizedString("Retry", comment: "Cannula insertion button text while showing error")
- case .inserting, .startingInsertion:
- return LocalizedString("Inserting...", comment: "Cannula insertion button text while inserting")
- case .checkingInsertion:
- return LocalizedString("Checking...", comment: "Cannula insertion button text while checking insertion")
- case .finished:
- return LocalizedString("Continue", comment: "Cannula insertion button text when inserted")
- }
- }
-
- var nextActionButtonStyle: ActionButton.ButtonType {
- switch self {
- case .error(let error):
- if !error.recoverable {
- return .destructive
- }
- default:
- break
- }
- return .primary
- }
-
- var progressState: ProgressIndicatorState {
- switch self {
- case .ready, .error:
- return .hidden
- case .startingInsertion, .checkingInsertion:
- return .indeterminantProgress
- case .inserting(let finishTime):
- return .timedProgress(finishTime: finishTime)
- case .finished:
- return .completed
- }
- }
-
- var showProgressDetail: Bool {
- switch self {
- case .ready:
- return false
- default:
- return true
- }
- }
-
- var isProcessing: Bool {
- switch self {
- case .startingInsertion, .inserting:
- return true
- default:
- return false
- }
- }
-
- var isFinished: Bool {
- if case .finished = self {
- return true
- }
- return false
- }
- }
-
- var error: OmnipodPumpManagerError? {
- if case .error(let error) = self.state {
- return error
- }
- return nil
- }
- @Published var state: InsertCannulaViewModelState = .ready
-
- var didFinish: (() -> Void)?
-
- var didRequestDeactivation: (() -> Void)?
-
- var cannulaInserter: CannulaInserter
-
- init(cannulaInserter: CannulaInserter) {
- self.cannulaInserter = cannulaInserter
- }
-
- // private func handleEvent(_ event: ActivationStep2Event) {
- // switch event {
- // case .insertingCannula:
- // let finishTime = TimeInterval(Pod.estimatedCannulaInsertionDuration)
- // state = .inserting(finishTime: CACurrentMediaTime() + finishTime)
- // case .step2Completed:
- // state = .finished
- // default:
- // break
- // }
- // }
-
- private func checkCannulaInsertionFinished() {
- state = .startingInsertion
- cannulaInserter.checkCannulaInsertionFinished() { (error) in
- DispatchQueue.main.async {
- if let error = error {
- self.state = .error(error)
- } else {
- self.state = .finished
- }
- }
- }
- }
-
- private func insertCannula() {
- state = .startingInsertion
-
- cannulaInserter.insertCannula { (result) in
- DispatchQueue.main.async {
- switch(result) {
- case .success(let finishTime):
- self.state = .inserting(finishTime: CACurrentMediaTime() + finishTime)
- let delay = finishTime
- if delay > 0 {
- DispatchQueue.main.asyncAfter(deadline: .now() + delay) {
- self.checkCannulaInsertionFinished() // now check if actually ready
- }
- } else {
- self.state = .finished
- }
- case .failure(let error):
- self.state = .error(error)
- }
- }
-
- // switch status {
- // case .error(let error):
- // self.state = .error(error)
- // case .event(let event):
- // self.handleEvent(event)
- // }
- }
- }
-
- public func continueButtonTapped() {
- switch state {
- case .finished:
- didFinish?()
- case .error(let error):
- if error.recoverable {
- insertCannula()
- } else {
- didRequestDeactivation?()
- }
- default:
- insertCannula()
- }
- }
-
- }
- public extension OmnipodPumpManagerError {
- var recoverable: Bool {
- //TODO
- return true
- // switch self {
- // case .podIsInAlarm:
- // return false
- // case .activationError(let activationErrorCode):
- // switch activationErrorCode {
- // case .podIsLumpOfCoal1Hour, .podIsLumpOfCoal2Hours:
- // return false
- // default:
- // return true
- // }
- // case .internalError(.incompatibleProductId):
- // return false
- // case .systemError:
- // return false
- // default:
- // return true
- // }
- }
- }
|