Skip to content

Commit

Permalink
[LOOP-453] Integrate InsulinSensitivityScheduleEditor (#87)
Browse files Browse the repository at this point in the history
* Implement suspend threshold guardrails

* Update project.pbxproj

* Tweak suspend threshold description

* Updates from design review

* Integrate InsulinSensitivityScheduleEditor

* Fix wonky suspend threshold animation
  • Loading branch information
mpangburn authored May 14, 2020
1 parent 7808e68 commit f7ee672
Show file tree
Hide file tree
Showing 6 changed files with 62 additions and 50 deletions.
14 changes: 7 additions & 7 deletions Loop.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -332,7 +332,6 @@
892D7C5123B54A15008A9656 /* CarbEntryViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 892D7C5023B54A14008A9656 /* CarbEntryViewController.swift */; };
892FB4CD22040104005293EC /* OverridePresetRow.swift in Sources */ = {isa = PBXBuildFile; fileRef = 892FB4CC22040104005293EC /* OverridePresetRow.swift */; };
892FB4CF220402C0005293EC /* OverrideSelectionController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 892FB4CE220402C0005293EC /* OverrideSelectionController.swift */; };
893C9F852446F54E00CD4185 /* Environment+Dismiss.swift in Sources */ = {isa = PBXBuildFile; fileRef = 893C9F842446F54E00CD4185 /* Environment+Dismiss.swift */; };
894F6DD3243BCBDB00CCE676 /* Environment+SizeClass.swift in Sources */ = {isa = PBXBuildFile; fileRef = 894F6DD2243BCBDB00CCE676 /* Environment+SizeClass.swift */; };
894F6DD7243C047300CCE676 /* View+Position.swift in Sources */ = {isa = PBXBuildFile; fileRef = 894F6DD6243C047300CCE676 /* View+Position.swift */; };
894F6DD9243C060600CCE676 /* ScalablePositionedText.swift in Sources */ = {isa = PBXBuildFile; fileRef = 894F6DD8243C060600CCE676 /* ScalablePositionedText.swift */; };
Expand Down Expand Up @@ -364,6 +363,7 @@
89AC9DB2244A41BB004A6B8A /* Guardrail.swift in Sources */ = {isa = PBXBuildFile; fileRef = 89AC9DB1244A41BB004A6B8A /* Guardrail.swift */; };
89AC9DB4244A423D004A6B8A /* SuspendThresholdPicker.swift in Sources */ = {isa = PBXBuildFile; fileRef = 89AC9DB3244A423D004A6B8A /* SuspendThresholdPicker.swift */; };
89ADE13B226BFA0F0067222B /* TestingScenariosManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 89ADE13A226BFA0F0067222B /* TestingScenariosManager.swift */; };
89BE75C92464B50600B145D9 /* DismissibleHostingController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 89BE75C82464B50600B145D9 /* DismissibleHostingController.swift */; };
89CA2B30226C0161004D9350 /* DirectoryObserver.swift in Sources */ = {isa = PBXBuildFile; fileRef = 89CA2B2F226C0161004D9350 /* DirectoryObserver.swift */; };
89CA2B32226C18B8004D9350 /* TestingScenariosTableViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 89CA2B31226C18B8004D9350 /* TestingScenariosTableViewController.swift */; };
89CA2B3D226E6B13004D9350 /* LocalTestingScenariosManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 89CA2B3C226E6B13004D9350 /* LocalTestingScenariosManager.swift */; };
Expand Down Expand Up @@ -1019,7 +1019,6 @@
892D7C5023B54A14008A9656 /* CarbEntryViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CarbEntryViewController.swift; sourceTree = "<group>"; };
892FB4CC22040104005293EC /* OverridePresetRow.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OverridePresetRow.swift; sourceTree = "<group>"; };
892FB4CE220402C0005293EC /* OverrideSelectionController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OverrideSelectionController.swift; sourceTree = "<group>"; };
893C9F842446F54E00CD4185 /* Environment+Dismiss.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Environment+Dismiss.swift"; sourceTree = "<group>"; };
894F6DD2243BCBDB00CCE676 /* Environment+SizeClass.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Environment+SizeClass.swift"; sourceTree = "<group>"; };
894F6DD6243C047300CCE676 /* View+Position.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = "View+Position.swift"; path = "WatchApp Extension/Views/View+Position.swift"; sourceTree = SOURCE_ROOT; };
894F6DD8243C060600CCE676 /* ScalablePositionedText.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ScalablePositionedText.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -1053,6 +1052,7 @@
89AC9DB1244A41BB004A6B8A /* Guardrail.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Guardrail.swift; sourceTree = "<group>"; };
89AC9DB3244A423D004A6B8A /* SuspendThresholdPicker.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SuspendThresholdPicker.swift; sourceTree = "<group>"; };
89ADE13A226BFA0F0067222B /* TestingScenariosManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TestingScenariosManager.swift; sourceTree = "<group>"; };
89BE75C82464B50600B145D9 /* DismissibleHostingController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DismissibleHostingController.swift; sourceTree = "<group>"; };
89CA2B2F226C0161004D9350 /* DirectoryObserver.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DirectoryObserver.swift; sourceTree = "<group>"; };
89CA2B31226C18B8004D9350 /* TestingScenariosTableViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TestingScenariosTableViewController.swift; sourceTree = "<group>"; };
89CA2B3C226E6B13004D9350 /* LocalTestingScenariosManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LocalTestingScenariosManager.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -1588,7 +1588,6 @@
892A5D58222F0A27008961AB /* Debug.swift */,
A9C62D832331700D00535612 /* DiagnosticLog+Subsystem.swift */,
89CA2B2F226C0161004D9350 /* DirectoryObserver.swift */,
893C9F842446F54E00CD4185 /* Environment+Dismiss.swift */,
89AC9DB1244A41BB004A6B8A /* Guardrail.swift */,
43D9003221EB258C00AF44BF /* InsulinModelSettings+Loop.swift */,
438172D81F4E9E37003C3328 /* NewPumpEvent.swift */,
Expand All @@ -1612,20 +1611,21 @@
children = (
43DBF04B1C93B8D700B3C386 /* BolusViewController.swift */,
43A51E1E1EB6D62A000736CC /* CarbAbsorptionViewController.swift */,
892D7C5023B54A14008A9656 /* CarbEntryViewController.swift */,
43DBF0581C93F73800B3C386 /* CarbEntryTableViewController.swift */,
892D7C5023B54A14008A9656 /* CarbEntryViewController.swift */,
43A51E201EB6DBDD000736CC /* ChartsTableViewController.swift */,
892ADE092446E9C3007CE08C /* ExplicitlyDismissibleModal.swift */,
433EA4C31D9F71C800CD78FB /* CommandResponseViewController.swift */,
89BE75C82464B50600B145D9 /* DismissibleHostingController.swift */,
892ADE092446E9C3007CE08C /* ExplicitlyDismissibleModal.swift */,
C178249F1E19CF9800D9D25C /* GlucoseThresholdTableViewController.swift */,
4302F4E21D4EA54200F0FCAF /* InsulinDeliveryTableViewController.swift */,
435CB6221F37967800C320C7 /* InsulinModelSettingsViewController.swift */,
437D9BA21D7BC977007245E8 /* PredictionTableViewController.swift */,
439A7941211F631C0041B75F /* RootNavigationController.swift */,
43F5C2DA1B92A5E1003EB13D /* SettingsTableViewController.swift */,
43E3449E1B9D68E900C85C07 /* StatusTableViewController.swift */,
4302F4E01D4E9C8900F0FCAF /* TextFieldTableViewController.swift */,
89CA2B31226C18B8004D9350 /* TestingScenariosTableViewController.swift */,
4302F4E01D4E9C8900F0FCAF /* TextFieldTableViewController.swift */,
);
path = "View Controllers";
sourceTree = "<group>";
Expand Down Expand Up @@ -2694,7 +2694,6 @@
4F70C2131DE90339006380B7 /* StatusExtensionContext.swift in Sources */,
43C05CC521EC29E3006FB252 /* TextFieldTableViewCell.swift in Sources */,
4FF4D1001E18374700846527 /* WatchContext.swift in Sources */,
893C9F852446F54E00CD4185 /* Environment+Dismiss.swift in Sources */,
C1D289B522F90A52003FFBD9 /* BasalDeliveryState.swift in Sources */,
4F2C15821E074FC600E160D4 /* NSTimeInterval.swift in Sources */,
4311FB9B1F37FE1B00D4C0A7 /* TitleSubtitleTextFieldTableViewCell.swift in Sources */,
Expand All @@ -2719,6 +2718,7 @@
43B260491ED248FB008CAA77 /* CarbEntryTableViewCell.swift in Sources */,
4302F4E11D4E9C8900F0FCAF /* TextFieldTableViewController.swift in Sources */,
43F64DD91D9C92C900D24DC6 /* TitleSubtitleTableViewCell.swift in Sources */,
89BE75C92464B50600B145D9 /* DismissibleHostingController.swift in Sources */,
43FCEEA9221A615B0013DD30 /* StatusChartsManager.swift in Sources */,
43511CE321FD80E400566C63 /* StandardRetrospectiveCorrection.swift in Sources */,
43E3449F1B9D68E900C85C07 /* StatusTableViewController.swift in Sources */,
Expand Down
22 changes: 0 additions & 22 deletions Loop/Extensions/Environment+Dismiss.swift

This file was deleted.

29 changes: 29 additions & 0 deletions Loop/View Controllers/DismissibleHostingController.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
//
// DismissibleHostingController.swift
// Loop
//
// Created by Michael Pangburn on 5/7/20.
// Copyright © 2020 LoopKit Authors. All rights reserved.
//

import SwiftUI


class DismissibleHostingController: UIHostingController<AnyView> {
private var onDisappear: () -> Void = {}

convenience init<Content: View>(rootView: Content, onDisappear: @escaping () -> Void = {}) {
// Delay initialization of dismissal closure pushed into SwiftUI Environment until after calling the designated initializer
var dismiss = {}
self.init(rootView: AnyView(rootView.environment(\.dismiss, { dismiss() })))
dismiss = { [weak self] in self?.dismiss(animated: true) }
self.onDisappear = onDisappear

isModalInPresentation = true
}

override func viewWillDisappear(_ animated: Bool) {
super.viewWillAppear(animated)
onDisappear()
}
}
1 change: 1 addition & 0 deletions Loop/View Controllers/ExplicitlyDismissibleModal.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

import UIKit
import SwiftUI
import LoopKitUI


class ExplicitlyDismissibleModal: UINavigationController {
Expand Down
35 changes: 16 additions & 19 deletions Loop/View Controllers/SettingsTableViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -445,17 +445,23 @@ final class SettingsTableViewController: UITableViewController {

show(scheduleVC, sender: sender)
case .insulinSensitivity:
let unit = dataManager.loopManager.insulinSensitivitySchedule?.unit ?? dataManager.loopManager.glucoseStore.preferredUnit ?? HKUnit.milligramsPerDeciliter
let allowedSensitivityValues = dataManager.loopManager.settings.allowedSensitivityValues(for: unit)
let scheduleVC = InsulinSensitivityScheduleViewController(allowedValues: allowedSensitivityValues, unit: unit)

scheduleVC.delegate = self
scheduleVC.insulinSensitivityScheduleStorageDelegate = self
scheduleVC.title = NSLocalizedString("Insulin Sensitivities", comment: "The title of the insulin sensitivities schedule screen")

scheduleVC.schedule = dataManager.loopManager.insulinSensitivitySchedule
let glucoseUnit = dataManager.loopManager.insulinSensitivitySchedule?.unit ?? dataManager.loopManager.glucoseStore.preferredUnit ?? HKUnit.milligramsPerDeciliter

let editor = InsulinSensitivityScheduleEditor(
schedule: dataManager.loopManager.insulinSensitivitySchedule,
glucoseUnit: glucoseUnit,
onSave: { [dataManager] newSchedule in
dataManager?.loopManager.insulinSensitivitySchedule = newSchedule
dataManager?.analyticsServicesManager.didChangeInsulinSensitivitySchedule()
tableView.reloadRows(at: [indexPath], with: .automatic)
}
)

show(scheduleVC, sender: sender)
let hostingController = DismissibleHostingController(rootView: editor, onDisappear: {
tableView.deselectRow(at: indexPath, animated: true)
})

present(hostingController, animated: true)
case .glucoseTargetRange:
let unit = dataManager.loopManager.settings.glucoseTargetRangeSchedule?.unit ?? dataManager.loopManager.glucoseStore.preferredUnit ?? HKUnit.milligramsPerDeciliter
let allowedCorrectionRangeValues = dataManager.loopManager.settings.allowedCorrectionRangeValues(for: unit)
Expand Down Expand Up @@ -788,15 +794,6 @@ extension SettingsTableViewController: GlucoseRangeScheduleStorageDelegate {
}
}

extension SettingsTableViewController: InsulinSensitivityScheduleStorageDelegate {
func saveSchedule(_ schedule: InsulinSensitivitySchedule, for viewController: InsulinSensitivityScheduleViewController, completion: @escaping (SaveInsulinSensitivityScheduleResult) -> Void) {
dataManager.loopManager.insulinSensitivitySchedule = schedule
dataManager.analyticsServicesManager.didChangeInsulinSensitivitySchedule()
completion(.success)
tableView.reloadRows(at: [IndexPath(row: ConfigurationRow.insulinSensitivity.rawValue, section: Section.configuration.rawValue)], with: .none)
}
}

extension SettingsTableViewController: InsulinModelSettingsViewControllerDelegate {
func insulinModelSettingsViewControllerDidChangeValue(_ controller: InsulinModelSettingsViewController) {
guard let indexPath = self.tableView.indexPathForSelectedRow else {
Expand Down
11 changes: 9 additions & 2 deletions Loop/Views/SuspendThresholdPicker.swift
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,17 @@ struct SuspendThresholdPicker: View {
@Binding var isEditing: Bool

var body: some View {
VStack {
VStack(spacing: 0) {
HStack {
Spacer()
GuardrailConstrainedQuantityView(value: value, unit: unit, guardrail: .suspendThreshold, isEditing: isEditing)
GuardrailConstrainedQuantityView(
value: value,
unit: unit,
guardrail: .suspendThreshold,
isEditing: isEditing,
// Workaround for strange animation behavior on appearance
forceDisableAnimations: true
)
}
.contentShape(Rectangle())
.onTapGesture {
Expand Down

0 comments on commit f7ee672

Please sign in to comment.