From 193074b9c363166da053df06841950ff3803b4ce Mon Sep 17 00:00:00 2001 From: Nathan Racklyeft Date: Sun, 17 Jul 2016 18:45:46 -0700 Subject: [PATCH] Adding a duration selection action sheet for workout targets --- Loop.xcodeproj/project.pbxproj | 4 ++ Loop/Extensions/UIAlertController.swift | 46 +++++++++++++++++++ Loop/Managers/DeviceDataManager.swift | 5 +- .../StatusTableViewController.swift | 7 ++- 4 files changed, 57 insertions(+), 5 deletions(-) create mode 100644 Loop/Extensions/UIAlertController.swift diff --git a/Loop.xcodeproj/project.pbxproj b/Loop.xcodeproj/project.pbxproj index 0c2f9a8d52..691587ff02 100644 --- a/Loop.xcodeproj/project.pbxproj +++ b/Loop.xcodeproj/project.pbxproj @@ -127,6 +127,7 @@ 43EDDBF31C361C75007D89B5 /* xDripG5.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 43EDDBF11C361C75007D89B5 /* xDripG5.framework */; }; 43F41C331D3A17AA00C11ED6 /* ChartAxisValueDoubleUnit.swift in Sources */ = {isa = PBXBuildFile; fileRef = 43F41C321D3A17AA00C11ED6 /* ChartAxisValueDoubleUnit.swift */; }; 43F41C351D3B623800C11ED6 /* ChartPointsTouchHighlightLayerViewCache.swift in Sources */ = {isa = PBXBuildFile; fileRef = 43F41C341D3B623800C11ED6 /* ChartPointsTouchHighlightLayerViewCache.swift */; }; + 43F41C371D3BF32400C11ED6 /* UIAlertController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 43F41C361D3BF32400C11ED6 /* UIAlertController.swift */; }; 43F4EF1D1BA2A57600526CE1 /* DiagnosticLogger.swift in Sources */ = {isa = PBXBuildFile; fileRef = 43F4EF1C1BA2A57600526CE1 /* DiagnosticLogger.swift */; }; 43F5C2C91B929C09003EB13D /* HealthKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 43F5C2C81B929C09003EB13D /* HealthKit.framework */; }; 43F5C2DB1B92A5E1003EB13D /* SettingsTableViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 43F5C2DA1B92A5E1003EB13D /* SettingsTableViewController.swift */; }; @@ -339,6 +340,7 @@ 43EDEE6B1CF2E12A00393BE3 /* Loop.entitlements */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = Loop.entitlements; sourceTree = ""; }; 43F41C321D3A17AA00C11ED6 /* ChartAxisValueDoubleUnit.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ChartAxisValueDoubleUnit.swift; sourceTree = ""; }; 43F41C341D3B623800C11ED6 /* ChartPointsTouchHighlightLayerViewCache.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ChartPointsTouchHighlightLayerViewCache.swift; sourceTree = ""; }; + 43F41C361D3BF32400C11ED6 /* UIAlertController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UIAlertController.swift; sourceTree = ""; }; 43F4EF1C1BA2A57600526CE1 /* DiagnosticLogger.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DiagnosticLogger.swift; sourceTree = ""; }; 43F5C2C81B929C09003EB13D /* HealthKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = HealthKit.framework; path = System/Library/Frameworks/HealthKit.framework; sourceTree = SDKROOT; }; 43F5C2D41B92A4A6003EB13D /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; @@ -583,6 +585,7 @@ 4398973A1CD2FC2000223065 /* NSDateFormatter.swift */, 439897341CD2F7DE00223065 /* NSTimeInterval.swift */, 43E344A31B9E1B1C00C85C07 /* NSUserDefaults.swift */, + 43F41C361D3BF32400C11ED6 /* UIAlertController.swift */, 43DE92501C541832001FFDE1 /* UIColor.swift */, 437CEEE31CDE5C0A003C8C80 /* UIImage.swift */, 434FF1ED1CF27EEF000DB779 /* UITableViewCell.swift */, @@ -991,6 +994,7 @@ 438849EC1D29EC34003B3F23 /* AmplitudeService.swift in Sources */, 43DBF0571C93F6EB00B3C386 /* ReservoirTableViewController.swift in Sources */, 435400341C9F878D00D5819C /* SetBolusUserInfo.swift in Sources */, + 43F41C371D3BF32400C11ED6 /* UIAlertController.swift in Sources */, 437CEEBC1CD6DE6A003C8C80 /* HUDView.swift in Sources */, 434F545F1D288345002A9274 /* ShareService.swift in Sources */, 4354003A1C9FB81100D5819C /* UIColor.swift in Sources */, diff --git a/Loop/Extensions/UIAlertController.swift b/Loop/Extensions/UIAlertController.swift new file mode 100644 index 0000000000..8ff092f2a6 --- /dev/null +++ b/Loop/Extensions/UIAlertController.swift @@ -0,0 +1,46 @@ +// +// UIAlertController.swift +// Loop +// +// Created by Nate Racklyeft on 7/17/16. +// Copyright © 2016 Nathan Racklyeft. All rights reserved. +// + +import UIKit + + +extension UIAlertController { + /** + Initializes an ActionSheet-styled controller for selecting a workout duration + + - parameter handler: A closure to execute when the sheet is dismissed after selection. The closure has a single argument: + - endDate: The date at which the user selected the workout to end + */ + convenience init(workoutDurationSelectionHandler handler: (endDate: NSDate) -> Void) { + self.init( + title: NSLocalizedString("Use Workout Glucose Targets", comment: "The title of the alert controller used to select a duration for workout targets"), + message: nil, + preferredStyle: .ActionSheet + ) + + let formatter = NSDateComponentsFormatter() + formatter.allowsFractionalUnits = false + formatter.unitsStyle = .Full + + for interval in [1, 2].map({ NSTimeInterval(hours: $0) }) { + let duration = NSLocalizedString("For %1$@", comment: "The format string used to describe a finite workout targets duration") + + addAction(UIAlertAction(title: String(format: duration, formatter.stringFromTimeInterval(interval)!), style: .Default) { _ in + handler(endDate: NSDate(timeIntervalSinceNow: interval)) + }) + } + + let distantFuture = NSLocalizedString("Indefinitely", comment: "The title of a target alert action specifying an indefinitely long workout targets duration") + addAction(UIAlertAction(title: distantFuture, style: .Default) { _ in + handler(endDate: NSDate.distantFuture()) + }) + + let cancel = NSLocalizedString("Cancel", comment: "The title of the cancel action in an action sheet") + addAction(UIAlertAction(title: cancel, style: .Cancel, handler: nil)) + } +} diff --git a/Loop/Managers/DeviceDataManager.swift b/Loop/Managers/DeviceDataManager.swift index 282f427e20..9abc41699f 100644 --- a/Loop/Managers/DeviceDataManager.swift +++ b/Loop/Managers/DeviceDataManager.swift @@ -713,14 +713,13 @@ class DeviceDataManager: CarbStoreDelegate, TransmitterDelegate { return override.endDate.timeIntervalSinceNow > 0 } - /// Attempts to enable workout glucose targets for the given duration, and returns true if successful. + /// Attempts to enable workout glucose targets until the given date, and returns true if successful. /// TODO: This can live on the schedule itself once its a value type, since didSet would invoke when mutated. - func enableWorkoutMode(duration duration: NSTimeInterval) -> Bool { + func enableWorkoutMode(until endDate: NSDate) -> Bool { guard let glucoseTargetRangeSchedule = glucoseTargetRangeSchedule else { return false } - let endDate = NSDate(timeIntervalSinceNow: duration) glucoseTargetRangeSchedule.setWorkoutOverrideUntilDate(endDate) NSNotificationCenter.defaultCenter().postNotificationName(self.dynamicType.LoopSettingsUpdatedNotification, object: self) diff --git a/Loop/View Controllers/StatusTableViewController.swift b/Loop/View Controllers/StatusTableViewController.swift index 490ff9262e..04da2eb9f4 100644 --- a/Loop/View Controllers/StatusTableViewController.swift +++ b/Loop/View Controllers/StatusTableViewController.swift @@ -739,11 +739,14 @@ class StatusTableViewController: UITableViewController, UIGestureRecognizerDeleg } @IBAction func toggleWorkoutMode(sender: UIBarButtonItem) { - // TODO: Display an action sheet to select a duration if let workoutModeEnabled = workoutMode where workoutModeEnabled { dataManager.disableWorkoutMode() } else { - dataManager.enableWorkoutMode(duration: NSTimeInterval(hours: 1)) + let vc = UIAlertController(workoutDurationSelectionHandler: { (endDate) in + self.dataManager.enableWorkoutMode(until: endDate) + }) + + presentViewController(vc, animated: true, completion: nil) } }