Repository navigation
Conversation
Trends reviews one period at a time (a day, 7, 14, 30 or 90 days) on one screen: summary tiles (average with SD and CV, GMI, insulin, carbs and boluses per day, Loop active), time in range, the daily pattern (AGP), basal and bolus, insulin per day and Loop status with its gaps. A one-day period leads with that day's timeline. Tapping a day opens a day page with the insulin timeline and active insulin and carbs, stepping a day at a time. The period exports as a PDF report or a CSV with one row per day. Inside Loop's 7 days the figures come from Loop's own stores, so manual and automatic boluses, temp basals, historical targets and presets are known. Older days come from Apple Health. Closed and open loop are recorded from launch, because Loop's automation history only covers 36 hours. Trends opens from Settings, beside Statistics, as a sheet with its own navigation and a Done button. Statistics and Current Setup are unchanged. This is part 1 of 6 splitting LoopKit#2621. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QHnVP7ynB62LNuuYMy3yvH
c0a0031 to
91a5ba0
Compare
Trends now carries everything Statistics shows that it lacked, so it can take Statistics' place: - Consensus goals: average under 8.6 mmol/L (154 mg/dL), GMI under 7% and CV 36% or less under the summary tiles; time in range over 70%, under 25% above and 4% below, under 5% very high and 1% very low, and CGM active over 70% on the Time in range card. - Scheduled basal under Basal in Basal and bolus: the schedule that applied over the same days (the stored profile with presets), or today's schedule where the profile history doesn't reach. - "Usually X U by HH:MM": today's insulin against the median by this time over the last 14 days, from InsulinDeliveryHistory as on Statistics. Under Total so far on today's Day view, and under the Insulin per day chart on longer periods ending today. - "CGM data covers 5 of 14 days." under Summary when readings start partway through the period. - Typed-in (fingerstick) readings are left out of every figure, as on Statistics. The day timeline still draws them. Each new line reuses a pattern already on the screen: the Aim footnote, the indented line under Bolus, and the muted footnote. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QHnVP7ynB62LNuuYMy3yvH
There was a problem hiding this comment.
Thanks for splitting this up. Trends reads well and the Statistics parity work is careful. Before this goes further I'd like to shrink it and remove the overlap with Statistics.
Replace Statistics. Trends should replace Statistics in this PR rather than sit beside it in Settings. Two screens answering the same question will confuse people, and the parity commit already covers what Statistics shows. Please remove the Statistics entry and the screen as part of this change.
Duplicated figures. Several numbers appear two or three times on one page:
- Insulin per day and the basal/bolus split are in the Summary tile, the Basal and bolus card, and the Insulin per day chart's average line and legend. Could Summary stay focused on glucose (plus carbs and boluses), and Basal and bolus fold into the Insulin per day card, with Scheduled and Manual/Automatic under the chart?
- Loop active in Summary repeats the Loop status card, and it covers a different window from the period's other figures. It's clearer only in Loop status, beside its coverage note.
- "Usually X U by HH:MM" appears twice. One place is enough.
Aim lines. The Aim sentences, especially the six-target one under Time in range, are hard to scan. Showing each band's target in its row, or marking a figure that misses its target, would say the same with less text.
Colors. The PR adds 17 named colors, and most could reuse what Loop already has. glucose-ink, accent-ink, insulin-ink, bolus and carbs-ink are variants of the existing glucose, accent, insulin and carbs colors. agp-inner, agp-outer, target-band, basal and basal-edge can be those colors at reduced opacity, with no new color sets. ink-muted can be .secondary. The five range-* colors duplicate GlucoseBand.agpColor in Statistics (TimeInRangeBar.swift). Since Trends replaces Statistics, keep one time-in-range palette; your dark-mode variants are an improvement, so move them there. control-thumb goes away with a system segmented Picker.
Scope. Could the day page, Gaps and Export come as follow-up parts? Export in particular produces a shareable, clinical-looking report that deserves its own review.
Open/closed loop history. Loop keeps 90 days of data (Bundle.main.localCacheDuration, LOOP_LOCAL_CACHE_DURATION_DAYS), and localHistoryStart already uses it. Rather than a new UserDefaults record (LoopModeHistory, 100 days), please read closed/open loop from data Loop already stores. StoredSettings carries dosingEnabled with a date, and SettingsStore keeps those records for the cache duration. The provider already uses getStoredSettings for target history. If that doesn't work out, a new record should follow the other stores' design (Core Data in the cache store, expiring with localCacheDuration) rather than live in UserDefaults.standard. It's also worth checking that every closed-loop toggle path saves settings, so the history isn't missing changes.
"Loop keeps 7 days". Two strings hard-code this: the Loop status footnote and the day page's Apple Health note. The provider's window is localHistoryStart, which is the cache duration, 90 days by default, so the text is wrong for most builds. It should follow the cache duration rather than hard-code a number.
Older periods. For days beyond Loop's local history, how does the screen show that the Manual/Automatic split and the scheduled basal are partial or estimated?
Part 1 of 6 splitting #2621. Review commits
91a5ba00(Trends) ande6136415(what came across from Statistics).Trends is a review of one period at a time: a day, 7, 14, 30 or 90 days.
Inside Loop's 7 days the figures come from Loop's own stores, so manual and automatic boluses, temp basals, historical targets and presets are known. Older days come from Apple Health. Closed and open loop are recorded from launch, because
LoopDataManager.automationHistorykeeps only 36 hours.Where it opens. Before the home screen changes, Trends opens from Settings → Trends, beside Statistics, as a sheet with its own navigation and a Done button. Statistics and Current Setup are unchanged. A pushed screen didn't work here:
navigationDestinationdoes nothing inside Settings'NavigationView, so the day page and Gaps wouldn't open.Screenshots are from #2621, where Trends is a tab. Here the same screen opens from Settings with a Done button.
What came across from Statistics
Trends and Statistics answer the same question, so the second commit (
e6136415) brings into Trends everything Statistics shows that Trends lacked. Trends already had the 7/14/30/90-day ranges, GMI, average, CV, CGM active, time in range, the daily pattern and daily insulin with its basal, bolus and automatic split.InsulinDeliveryHistory.typicalDelivery, so the same figure.Not carried over: "This device keeps N days of glucose. Increase the cache duration…" (Trends reads older days from Apple Health, so the local cache doesn't limit it), and the two helper lines "Each 5% increase in range is clinically beneficial" and "Each 1% time in range ≈ 15 minutes" (Trends shows each band's hours a day).
On the same 14 days of simulator data, GMI, average, CV, CGM active, "usually by now" and scheduled basal match Statistics exactly. Statistics is still in Settings in this part so the two can be compared side by side. Once you're happy Trends covers it, removing Statistics is a small follow-up.
Differences from #2621
algorithmSchedule()and.loopKit, asLoopDataManagerdoes.DayTimelineCard,DayTotalsTiles) live inDayDetailView.swift, notNowScreen.swift, because Trends needs them before Now exists.TrendsViewtakes an optionaldoneclosure for the Settings sheet.RangeBand.name/thresholdsandSummary.loopCoverageStart.Testing
On the
loopsimulator (iOS 27.0, Pump and CGM Simulators, 90 days of history), driven through XCUITest:LoopTests (448 run on this part, on
next-dev5ee95cc6): all pass exceptBolusEntryViewModelTests.testCarbEntryDateAndAbsorptionTimeStringand…String2, which fail the same way on plainnext-dev("12:00 PM" against "12:00"). Xcode's hosted test run stalls at test-host launch on this machine, so these ran in the app bundle under Xcode's simulator XCTest agent, with next-dev's test classes except the HealthKit-hostedDeviceDataManagerTests. Every part was built on its own, in order, on theloopsimulator.The series
#2621 is split into six PRs, in the order Pete suggested: statistics and Trends first, then the Logbook, then the home screen. Add carbs, the widget and Live Activity, and the appearance options follow as their own parts. Each part builds on the one before it and targets
next-dev(5ee95cc6, after #2635), so a PR shows the earlier parts' commits too. Review only the last commit of each PR (part 1 has two: Trends, then what came across from Statistics). #2621 stays open as the combined reference until the series lands.The six parts together match #2621 apart from the changes listed under "Differences from #2621" in each part.
Merging. Merged in order with merge commits, all six apply cleanly. With squash merges, each next PR needs a rebase onto
next-devonce the previous one lands, because it still carries the earlier part's original commit. I've checked that every one of those rebases applies cleanly and that the end result is identical to part 6. I'll rebase each PR as the one before it merges.Strings. Each part adds only its own catalogue entries, with their translations in Loop's languages, and fills in translations for the existing keys it starts using. GitHub's line diff of
Localizable.xcstringscan show deletions where Xcode's ordering interleaves new keys. Parsed as JSON, no part removes or rewrites any existing entry.🤖 Generated with Claude Code
https://claude.ai/code/session_01QHnVP7ynB62LNuuYMy3yvH