Skip to content

Commit 048ce8a

Browse files
author
Darin Krauss
authored
[LOOP-3323] Allow pause onboarding (#446)
- https://tidepool.atlassian.net/browse/LOOP-3323 - https://tidepool.atlassian.net/browse/LOOP-3538 - https://tidepool.atlassian.net/browse/LOOP-3539 - https://tidepool.atlassian.net/browse/LOOP-3540 - https://tidepool.atlassian.net/browse/LOOP-3541 - https://tidepool.atlassian.net/browse/LOOP-3770 - Allow suspending and resuming onboarding - Display resumed onboarding in modal dialog presentation - Display Complete Setup to pump pill if onboarding not complete and pump not onboarded - Display Complete Setup banner if onboarding not complete and pump onboarded - Only ensure current pump data if pump is onboarded - Refresh device data immediately after CGM or pump onboarded - Do not allow adding carbs via detail view if onboarding not complete - Do not allow changing closed loop state if onboarding not complete - Disable various toolbar items if onboarding not complete - Add ResumeOnboardingProvider - Add IconTitleSubtitleTableViewCell - Fix bug in LoopDataManager where settings were not persisted
1 parent cf728ab commit 048ce8a

File tree

13 files changed

+281
-48
lines changed

13 files changed

+281
-48
lines changed

Loop.xcodeproj/project.pbxproj

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -375,6 +375,7 @@
375375
89FE21AD24AC57E30033F501 /* Collection.swift in Sources */ = {isa = PBXBuildFile; fileRef = 89FE21AC24AC57E30033F501 /* Collection.swift */; };
376376
A90EF53C25DEF06200F32D61 /* PluginManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = C16DA84122E8E112008624C2 /* PluginManager.swift */; };
377377
A90EF54425DEF0A000F32D61 /* OSLog.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4374B5EE209D84BE00D17AA8 /* OSLog.swift */; };
378+
A91D2A3F26CF0FF80023B075 /* IconTitleSubtitleTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = A91D2A3E26CF0FF80023B075 /* IconTitleSubtitleTableViewCell.swift */; };
378379
A91E4C2124F867A700BE9213 /* StoredAlertTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = A91E4C2024F867A700BE9213 /* StoredAlertTests.swift */; };
379380
A91E4C2324F86F1000BE9213 /* CriticalEventLogExportManagerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = A91E4C2224F86F1000BE9213 /* CriticalEventLogExportManagerTests.swift */; };
380381
A92E557E2464DFFD00DB93BB /* DosingDecisionStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = A92E557D2464DFFD00DB93BB /* DosingDecisionStore.swift */; };
@@ -1288,6 +1289,7 @@
12881289
89F9119324358E4500ECCAF3 /* CarbAbsorptionTime.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CarbAbsorptionTime.swift; sourceTree = "<group>"; };
12891290
89F9119524358E6900ECCAF3 /* BolusPickerValues.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BolusPickerValues.swift; sourceTree = "<group>"; };
12901291
89FE21AC24AC57E30033F501 /* Collection.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Collection.swift; sourceTree = "<group>"; };
1292+
A91D2A3E26CF0FF80023B075 /* IconTitleSubtitleTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IconTitleSubtitleTableViewCell.swift; sourceTree = "<group>"; };
12911293
A91E4C2024F867A700BE9213 /* StoredAlertTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StoredAlertTests.swift; sourceTree = "<group>"; };
12921294
A91E4C2224F86F1000BE9213 /* CriticalEventLogExportManagerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CriticalEventLogExportManagerTests.swift; sourceTree = "<group>"; };
12931295
A92E557D2464DFFD00DB93BB /* DosingDecisionStore.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = DosingDecisionStore.swift; path = ../Stores/DosingDecisionStore.swift; sourceTree = "<group>"; };
@@ -2050,6 +2052,7 @@
20502052
A9A056B224B93C62007CF06D /* CriticalEventLogExportView.swift */,
20512053
43D381611EBD9759007F8C8F /* HeaderValuesTableViewCell.swift */,
20522054
430D85881F44037000AF2D4F /* HUDViewTableViewCell.swift */,
2055+
A91D2A3E26CF0FF80023B075 /* IconTitleSubtitleTableViewCell.swift */,
20532056
1DA46B5F2492E2E300D71A63 /* NotificationsCriticalAlertPermissionsView.swift */,
20542057
899433B723FE129700FA4BEA /* OverrideBadgeView.swift */,
20552058
89D6953D23B6DF8A002B3066 /* PotentialCarbEntryTableViewCell.swift */,
@@ -3486,6 +3489,7 @@
34863489
89CA2B32226C18B8004D9350 /* TestingScenariosTableViewController.swift in Sources */,
34873490
43E93FB71E469A5100EAB8DB /* HKUnit.swift in Sources */,
34883491
43C05CAF21EB2C24006FB252 /* NSBundle.swift in Sources */,
3492+
A91D2A3F26CF0FF80023B075 /* IconTitleSubtitleTableViewCell.swift in Sources */,
34893493
A967D94C24F99B9300CDDF8A /* OutputStream.swift in Sources */,
34903494
1DB1065124467E18005542BD /* AlertManager.swift in Sources */,
34913495
1D9650C82523FBA100A1370B /* DeviceDataManager+BolusEntryViewModelDelegate.swift in Sources */,

Loop/Base.lproj/Main.storyboard

Lines changed: 56 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -477,7 +477,7 @@
477477
<color key="backgroundColor" systemColor="systemBackgroundColor"/>
478478
<prototypes>
479479
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" selectionStyle="none" indentationWidth="10" reuseIdentifier="HUDViewTableViewCell" rowHeight="70" id="vCp-19-ZkW" customClass="HUDViewTableViewCell" customModule="Loop" customModuleProvider="target">
480-
<rect key="frame" x="0.0" y="28" width="375" height="70"/>
480+
<rect key="frame" x="0.0" y="24.5" width="375" height="70"/>
481481
<autoresizingMask key="autoresizingMask"/>
482482
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="vCp-19-ZkW" id="b8U-Fn-hSd">
483483
<rect key="frame" x="0.0" y="0.0" width="375" height="70"/>
@@ -499,7 +499,7 @@
499499
</connections>
500500
</tableViewCell>
501501
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" selectionStyle="none" indentationWidth="10" reuseIdentifier="TitleSubtitleTableViewCell" id="zTq-QB-XNu" customClass="TitleSubtitleTableViewCell" customModule="Loop" customModuleProvider="target">
502-
<rect key="frame" x="0.0" y="98" width="375" height="44"/>
502+
<rect key="frame" x="0.0" y="94.5" width="375" height="44"/>
503503
<autoresizingMask key="autoresizingMask"/>
504504
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="zTq-QB-XNu" id="vD6-31-qVz">
505505
<rect key="frame" x="0.0" y="0.0" width="375" height="44"/>
@@ -543,8 +543,60 @@
543543
<outlet property="titleLabel" destination="k3F-Na-7mn" id="Mrt-ZL-fKG"/>
544544
</connections>
545545
</tableViewCell>
546+
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" selectionStyle="none" indentationWidth="10" reuseIdentifier="IconTitleSubtitleTableViewCell" id="5av-st-q28" customClass="IconTitleSubtitleTableViewCell" customModule="Loop" customModuleProvider="target">
547+
<rect key="frame" x="0.0" y="138.5" width="375" height="44"/>
548+
<autoresizingMask key="autoresizingMask"/>
549+
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="5av-st-q28" id="lLV-fl-2Ke">
550+
<rect key="frame" x="0.0" y="0.0" width="375" height="44"/>
551+
<autoresizingMask key="autoresizingMask"/>
552+
<subviews>
553+
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="lZi-ar-9iV">
554+
<rect key="frame" x="0.0" y="0.0" width="375" height="44"/>
555+
</view>
556+
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" verticalHuggingPriority="251" horizontalCompressionResistancePriority="751" text="3.5 U/hour @ 12:12 PM" textAlignment="right" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="fWV-jg-ICt">
557+
<rect key="frame" x="196" y="16" width="163" height="12"/>
558+
<fontDescription key="fontDescription" type="boldSystem" pointSize="15"/>
559+
<nil key="textColor"/>
560+
<nil key="highlightedColor"/>
561+
</label>
562+
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" misplaced="YES" text="Recommended Basal" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="xhx-PI-bBI">
563+
<rect key="frame" x="58" y="16" width="130" height="12"/>
564+
<fontDescription key="fontDescription" type="boldSystem" pointSize="15"/>
565+
<nil key="textColor"/>
566+
<nil key="highlightedColor"/>
567+
</label>
568+
<imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="252" verticalHuggingPriority="251" misplaced="YES" translatesAutoresizingMaskIntoConstraints="NO" id="Uyb-ce-nXY">
569+
<rect key="frame" x="16" y="5" width="33" height="33"/>
570+
</imageView>
571+
</subviews>
572+
<constraints>
573+
<constraint firstAttribute="bottom" secondItem="Uyb-ce-nXY" secondAttribute="bottom" id="3Iv-mH-pcL"/>
574+
<constraint firstAttribute="bottomMargin" secondItem="fWV-jg-ICt" secondAttribute="bottom" constant="5" id="EjW-rd-jxl"/>
575+
<constraint firstAttribute="bottomMargin" secondItem="xhx-PI-bBI" secondAttribute="bottom" constant="5" id="X7F-rd-kEw"/>
576+
<constraint firstItem="xhx-PI-bBI" firstAttribute="top" secondItem="lLV-fl-2Ke" secondAttribute="topMargin" constant="5" id="YZ6-LQ-URg"/>
577+
<constraint firstItem="Uyb-ce-nXY" firstAttribute="top" secondItem="lLV-fl-2Ke" secondAttribute="top" id="cos-il-XLC"/>
578+
<constraint firstItem="fWV-jg-ICt" firstAttribute="leading" secondItem="xhx-PI-bBI" secondAttribute="trailing" constant="8" symbolic="YES" id="hvf-Rm-1et"/>
579+
<constraint firstItem="fWV-jg-ICt" firstAttribute="top" secondItem="lLV-fl-2Ke" secondAttribute="topMargin" constant="5" id="jd7-tP-g9w"/>
580+
<constraint firstAttribute="trailingMargin" secondItem="fWV-jg-ICt" secondAttribute="trailing" id="nnf-aY-RjG"/>
581+
<constraint firstItem="xhx-PI-bBI" firstAttribute="leading" secondItem="Uyb-ce-nXY" secondAttribute="trailing" constant="8" symbolic="YES" id="o04-Iy-95H"/>
582+
<constraint firstAttribute="leadingMargin" secondItem="Uyb-ce-nXY" secondAttribute="leading" id="qHL-Ga-aMN"/>
583+
</constraints>
584+
</tableViewCellContentView>
585+
<constraints>
586+
<constraint firstItem="lZi-ar-9iV" firstAttribute="top" secondItem="5av-st-q28" secondAttribute="top" id="9Tk-CA-OxJ"/>
587+
<constraint firstAttribute="trailing" secondItem="lZi-ar-9iV" secondAttribute="trailing" id="CgY-Gc-Tfq"/>
588+
<constraint firstItem="lZi-ar-9iV" firstAttribute="leading" secondItem="5av-st-q28" secondAttribute="leading" id="FjH-CR-cTZ"/>
589+
<constraint firstAttribute="bottom" secondItem="lZi-ar-9iV" secondAttribute="bottom" id="lyr-yc-tdb"/>
590+
</constraints>
591+
<connections>
592+
<outlet property="backgroundView" destination="lZi-ar-9iV" id="hxP-ji-frQ"/>
593+
<outlet property="iconImageView" destination="Uyb-ce-nXY" id="V6G-a3-3L1"/>
594+
<outlet property="subtitleLabel" destination="fWV-jg-ICt" id="x1Z-Pa-Nro"/>
595+
<outlet property="titleLabel" destination="xhx-PI-bBI" id="2Xd-Nu-GMe"/>
596+
</connections>
597+
</tableViewCell>
546598
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" selectionStyle="none" indentationWidth="10" reuseIdentifier="ChartTableViewCell" rowHeight="200" id="FEV-fX-i48" customClass="ChartTableViewCell" customModule="LoopKitUI">
547-
<rect key="frame" x="0.0" y="142" width="375" height="200"/>
599+
<rect key="frame" x="0.0" y="182.5" width="375" height="200"/>
548600
<autoresizingMask key="autoresizingMask"/>
549601
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="FEV-fX-i48" id="lS6-Qa-Lw7">
550602
<rect key="frame" x="0.0" y="0.0" width="375" height="200"/>
@@ -635,7 +687,7 @@
635687
</tableViewController>
636688
<placeholder placeholderIdentifier="IBFirstResponder" id="9Tc-kF-7yT" userLabel="First Responder" sceneMemberID="firstResponder"/>
637689
</objects>
638-
<point key="canvasLocation" x="838.125" y="-458.45070422535213"/>
690+
<point key="canvasLocation" x="837.60000000000002" y="-459.22038980509751"/>
639691
</scene>
640692
<!--Root Navigation Controller-->
641693
<scene sceneID="1UI-1d-xLb">

Loop/Extensions/DeviceDataManager+DeviceStatus.swift

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,8 @@ extension DeviceDataManager {
3636
let bluetoothState = bluetoothProvider.bluetoothState
3737
if bluetoothState == .unsupported || bluetoothState == .unauthorized || bluetoothState == .poweredOff {
3838
return BluetoothState.enableHighlight
39+
} else if let onboardingManager = onboardingManager, !onboardingManager.isComplete, pumpManager?.isOnboarded != true {
40+
return DeviceDataManager.resumeOnboardingStatusHighlight
3941
} else if pumpManager == nil {
4042
return DeviceDataManager.addPumpStatusHighlight
4143
} else {
@@ -51,6 +53,16 @@ extension DeviceDataManager {
5153
return pumpManager?.pumpLifecycleProgress
5254
}
5355

56+
static var resumeOnboardingStatusHighlight: ResumeOnboardingStatusHighlight {
57+
return ResumeOnboardingStatusHighlight()
58+
}
59+
60+
struct ResumeOnboardingStatusHighlight: DeviceStatusHighlight {
61+
var localizedMessage: String = NSLocalizedString("Complete Setup", comment: "Title text for button to complete setup")
62+
var imageName: String = "exclamationmark.circle.fill"
63+
var state: DeviceStatusHighlightState = .warning
64+
}
65+
5466
static var addCGMStatusHighlight: AddDeviceStatusHighlight {
5567
return AddDeviceStatusHighlight(localizedMessage: NSLocalizedString("Add CGM", comment: "Title text for button to set up a CGM"),
5668
state: .critical)
@@ -84,6 +96,9 @@ extension DeviceDataManager {
8496
func didTapOnPumpStatus(_ view: BaseHUDView? = nil) -> HUDTapAction? {
8597
if let action = bluetoothProvider.bluetoothState.action {
8698
return action
99+
} else if let onboardingManager = onboardingManager, !onboardingManager.isComplete, pumpManager?.isOnboarded != true {
100+
onboardingManager.resume()
101+
return .takeNoAction
87102
} else if let pumpManagerHUDProvider = pumpManagerHUDProvider,
88103
let view = view,
89104
let action = pumpManagerHUDProvider.didTapOnHUDView(view, allowDebugFeatures: FeatureFlags.mockTherapySettingsEnabled)

Loop/Managers/DeviceDataManager.swift

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ final class DeviceDataManager {
2424
let pluginManager: PluginManager
2525
weak var alertManager: AlertManager!
2626
let bluetoothProvider: BluetoothProvider
27+
weak var onboardingManager: OnboardingManager?
2728

2829
/// Remember the launch date of the app for diagnostic reporting
2930
private let launchDate = Date()
@@ -836,6 +837,10 @@ extension DeviceDataManager: CGMManagerOnboardingDelegate {
836837
func cgmManagerOnboarding(didOnboardCGMManager cgmManager: CGMManagerUI) {
837838
precondition(cgmManager.isOnboarded)
838839
log.default("CGM manager with identifier '%{public}@' onboarded", cgmManager.managerIdentifier)
840+
841+
DispatchQueue.main.async {
842+
self.refreshDeviceData()
843+
}
839844
}
840845
}
841846

@@ -906,7 +911,10 @@ extension DeviceDataManager: PumpManagerDelegate {
906911
func refreshDeviceData() {
907912
refreshCGM() {
908913
self.queue.async {
909-
self.pumpManager?.ensureCurrentPumpData(completion: nil)
914+
guard let pumpManager = self.pumpManager, pumpManager.isOnboarded else {
915+
return
916+
}
917+
pumpManager.ensureCurrentPumpData(completion: nil)
910918
}
911919
}
912920
}
@@ -1043,12 +1051,15 @@ extension DeviceDataManager: PumpManagerOnboardingDelegate {
10431051
func pumpManagerOnboarding(didCreatePumpManager pumpManager: PumpManagerUI) {
10441052
log.default("Pump manager with identifier '%{public}@' created", pumpManager.managerIdentifier)
10451053
self.pumpManager = pumpManager
1046-
self.deliveryUncertaintyAlertManager = DeliveryUncertaintyAlertManager(pumpManager: pumpManager, alertPresenter: alertPresenter)
10471054
}
10481055

10491056
func pumpManagerOnboarding(didOnboardPumpManager pumpManager: PumpManagerUI) {
10501057
precondition(pumpManager.isOnboarded)
10511058
log.default("Pump manager with identifier '%{public}@' onboarded", pumpManager.managerIdentifier)
1059+
1060+
DispatchQueue.main.async {
1061+
self.refreshDeviceData()
1062+
}
10521063
}
10531064
}
10541065

Loop/Managers/LoopAppManager.swift

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -148,22 +148,23 @@ class LoopAppManager: NSObject {
148148
windowProvider: windowProvider,
149149
userDefaults: UserDefaults.appGroup!)
150150

151+
deviceDataManager.onboardingManager = onboardingManager
151152
deviceDataManager.analyticsServicesManager.application(didFinishLaunchingWithOptions: launchOptions)
152153

153-
self.state = state.next
154-
155154
closedLoopStatus.$isClosedLoopAllowed
156155
.combineLatest(deviceDataManager.loopManager.$dosingEnabled)
157156
.map { $0 && $1 }
158157
.assign(to: \.closedLoopStatus.isClosedLoop, on: self)
159158
.store(in: &cancellables)
159+
160+
self.state = state.next
160161
}
161162

162163
private func launchOnboarding() {
163164
dispatchPrecondition(condition: .onQueue(.main))
164165
precondition(state == .launchOnboarding)
165166

166-
onboardingManager.onboard {
167+
onboardingManager.launch {
167168
DispatchQueue.main.async {
168169
self.state = self.state.next
169170
self.resumeLaunch()
@@ -179,6 +180,7 @@ class LoopAppManager: NSObject {
179180
let statusTableViewController = storyboard.instantiateViewController(withIdentifier: "MainStatusViewController") as! StatusTableViewController
180181
statusTableViewController.closedLoopStatus = closedLoopStatus
181182
statusTableViewController.deviceManager = deviceDataManager
183+
statusTableViewController.onboardingManager = onboardingManager
182184
bluetoothStateManager.addBluetoothObserver(statusTableViewController)
183185

184186
var rootNavigationController = rootViewController as? RootNavigationController

0 commit comments

Comments
 (0)