From 5b69a227d6585d539992754b68fed685753bbf02 Mon Sep 17 00:00:00 2001 From: Oliver Story Date: Mon, 8 Jul 2024 20:31:04 +1000 Subject: [PATCH] Display the previous day's carb entries on the carb absorption screen. This involves several changes: 1) Change Loop to calculate insulin counteraction effects for the previous 48 hours (was 24 hours). This is necessary so that dynamic carb absorption can be calculated for the previous day's entries. 2) Fetch carb entries up to the previous midnight, plus any entries that might still be absorbing at that time - previous day's entries are not shown prior to any counteraction effects if these are missing 3) Filter these entries to only display up to the previous midnight 4) Add the (localised) phrase 'Yesterday' in front of the date for yesterday's entries --- Loop/Managers/LoopDataManager.swift | 2 +- .../CarbAbsorptionViewController.swift | 31 ++++++++++++++++--- 2 files changed, 28 insertions(+), 5 deletions(-) diff --git a/Loop/Managers/LoopDataManager.swift b/Loop/Managers/LoopDataManager.swift index 2319f4eceb..f5949c0f70 100644 --- a/Loop/Managers/LoopDataManager.swift +++ b/Loop/Managers/LoopDataManager.swift @@ -992,7 +992,7 @@ extension LoopDataManager { let retrospectiveStart = lastGlucoseDate.addingTimeInterval(-type(of: retrospectiveCorrection).retrospectionInterval) - let earliestEffectDate = Date(timeInterval: .hours(-24), since: now()) + let earliestEffectDate = Date(timeInterval: .hours(-48), since: now()) let nextCounteractionEffectDate = insulinCounteractionEffects.last?.endDate ?? earliestEffectDate let insulinEffectStartDate = nextCounteractionEffectDate.addingTimeInterval(.minutes(-5)) diff --git a/Loop/View Controllers/CarbAbsorptionViewController.swift b/Loop/View Controllers/CarbAbsorptionViewController.swift index fc770192e9..0a13c9b6ee 100644 --- a/Loop/View Controllers/CarbAbsorptionViewController.swift +++ b/Loop/View Controllers/CarbAbsorptionViewController.swift @@ -139,7 +139,7 @@ final class CarbAbsorptionViewController: LoopChartsTableViewController, Identif charts.updateEndDate(chartStartDate.addingTimeInterval(.hours(totalHours+1))) // When there is no data, this allows presenting current hour + 1 let midnight = Calendar.current.startOfDay(for: Date()) - let listStart = min(midnight, chartStartDate, Date(timeIntervalSinceNow: -deviceManager.carbStore.maximumAbsorptionTimeInterval)) + let previousMidnight = midnight - .hours(24) let reloadGroup = DispatchGroup() let shouldUpdateGlucose = currentContext.contains(.glucose) @@ -158,11 +158,19 @@ final class CarbAbsorptionViewController: LoopChartsTableViewController, Identif let allInsulinCounteractionEffects = state.insulinCounteractionEffects insulinCounteractionEffects = allInsulinCounteractionEffects.filterDateRange(chartStartDate, nil) + let earliestCounteractionEffect = allInsulinCounteractionEffects.first?.startDate ?? Date() + // Show carb entries as far back as previous midnight, or only as far back as counteraction effects are available + let boundOnCarbList = max(previousMidnight, earliestCounteractionEffect) + // If counteraction effects are missing, at least show all the entries for today and those on the chart + let displayListStart = min(boundOnCarbList, midnight, chartStartDate) + // To estimate dynamic carb absorption for the entry at the start of the list, we need to fetch samples that might still be absorbing + let fetchEntriesStart = displayListStart.addingTimeInterval(-self.deviceManager.carbStore.maximumAbsorptionTimeInterval) + reloadGroup.enter() - self.deviceManager.carbStore.getCarbStatus(start: listStart, end: nil, effectVelocities: allInsulinCounteractionEffects) { (result) in + self.deviceManager.carbStore.getCarbStatus(start: fetchEntriesStart, end: nil, effectVelocities: allInsulinCounteractionEffects) { (result) in switch result { case .success(let status): - carbStatuses = status + carbStatuses = status.filterDateRange(displayListStart, nil) carbsOnBoard = status.getClampedCarbsOnBoard() case .failure(let error): self.log.error("CarbStore failed to get carbStatus: %{public}@", String(describing: error)) @@ -287,6 +295,14 @@ final class CarbAbsorptionViewController: LoopChartsTableViewController, Identif return formatter }() + private lazy var relativeTimeFormatter: DateFormatter = { + let formatter = DateFormatter() + formatter.dateStyle = .medium + formatter.doesRelativeDateFormatting = true + formatter.timeStyle = .short + return formatter + }() + override func numberOfSections(in tableView: UITableView) -> Int { return Section.count } @@ -343,7 +359,14 @@ final class CarbAbsorptionViewController: LoopChartsTableViewController, Identif } // Entry time - let startTime = timeFormatter.string(from: status.entry.startDate) + let startTime: String + // Indicate if an entry is from the previous day to avoid potential confusion + let midnight = Calendar.current.startOfDay(for: Date()) + if status.entry.startDate < midnight { + startTime = relativeTimeFormatter.string(from: status.entry.startDate) + } else { + startTime = timeFormatter.string(from: status.entry.startDate) + } if let absorptionTime = status.entry.absorptionTime, let duration = absorptionFormatter.string(from: absorptionTime) {