Repository navigation
Conversation
…dling Build Now, Trends and Logbook around Loop's existing controllers and stores. Keep delivered quantities and history partitions accurate, preserve editing drafts across updates, propagate load failures and share chart averages. Per-day Trends figures leave out the day in progress and share insulin's days, the day chart names a day without readings, and the Logbook carb editor receives Loop updates on the main thread. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
77551d1 to
a982d59
Compare
Driving the error states in the simulator (pump fault, comms issue,
suspension, sensor warmup, signal loss, sensor failed) showed that a
device problem could be off-screen: the status pills scrolled sideways,
so during warmup the CGM pill was past the edge and nothing visible said
so.
- Status pills wrap instead of scrolling.
- A device highlight, or a loop that hasn't completed for 15 minutes,
gets a notice under the pills with the device's message and icon, what
it means for Loop, and a tap through to the device; most serious first.
- Two-line plugin highlights ("Signal\nLoss") are joined.
- When Loop pauses closed loop (no CGM session or data), the pill says
"Closed loop paused" instead of "Open loop".
- Loop's status rows (No Recent Glucose, Tap to Resume, bolus progress,
presets) take the card shape in the new interface; the non-critical
pump notice is left out while the Resume row shows.
LoopTests: 323 pass on the iPhone 17 Pro simulator (iOS 26.3).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QHnVPAQn8LyVAJrZEA3f2T
Settings gets an "Appearance and App Icon" screen: - Appearance: System, Day or Night. It sets the window's interface style, so it applies to the whole app (new and classic interface, sheets included) and takes effect without a relaunch. - App Icon: Classic (the primary icon, unchanged), Day, Night, and Day and Night, whose dark appearance variant follows the home screen's light or dark icons. Day, Night and Day and Night are alternate icon sets in DerivedAssetsBase, listed in the Loop target's ASSETCATALOG_COMPILER_ALTERNATE_APPICON_NAMES; small preview image sets show them in the picker because iOS doesn't expose alternate icons as images. The new icons keep Loop's ring and add the blue reading dot from the Now screen, on a light ground for Day and a midnight-blue one for Night. The artwork was generated with GPT image generation and chosen from two takes each. iOS can report an error from its "icon changed" alert even though the icon changed (the iOS 26.3 simulator does this every time), so the picker trusts the icon iOS reports afterwards. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QHnVPAQn8LyVAJrZEA3f2T
Every string the new interface shows or speaks now goes through
NSLocalizedString with a translator comment, and Localizable.xcstrings
gains 213 keys with translations in all 23 of Loop's other languages
(ar cs da de es fi fr he hu it ja nb nl pl pt-BR ro ru sk sv tr uk vi
zh-Hans). Fourteen existing keys the redesign reuses ("Bolus", "%1$@ U",
"Settings", ...) keep their translations and gain the languages they
were missing.
- Sentences with values are whole keys with positional placeholders,
and counts ("%lld days", "%lld shorter gaps", "Loop · %lld changes")
use plural variations, so no text is glued together in code.
- Numbers, dates, ranges and durations follow the user's locale:
LoopFormat.number replaces String(format:), date ranges use
DateIntervalFormatter and durations DateComponentsFormatter.
- The Trends one-day period has its own key, "Day (Trends period)",
because "Day" is also the light appearance and icon name and some
languages need different words for the two.
- The Now action buttons wrap to two lines and tile labels scale down,
so longer languages don't truncate.
- The CSV export stays English with '.' decimals on purpose; it is
data for spreadsheets, not display text.
Translations follow Loop's existing terms per language and were checked
for placeholder and plural-category integrity. Each language was run
through the simulator with NSShowNonLocalizedStrings. They have not
been reviewed by native speakers.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QHnVPAQn8LyVAJrZEA3f2T
|
love this +1 |
…esign The home screen widget and the Live Activity now follow the redesign's rules from the Now screen: a white SF Pro Rounded glucose number with a blue trend arrow, low and high said in words rather than by tinting the number, Loop's state as a dot with words, sunken tiles, and device problems written out. - Widget: the Now hero with COB and Forecast tiles; the medium size adds Add carbs, Bolus, Pre-meal and Presets in the Now screen's styles. - Lock Screen: hero, the Now chart's style (blue readings, dashed prediction, target band) and the configured bottom row as one-line tiles, within the 160 pt limit. - Dynamic Island: white number and blue arrow, the change or "Low"/"High" in words with a loop dot, a keyline tinted for low and high, and an expanded view with a full-width status line and the chart. They follow the New Interface setting: the app mirrors it into the app group, reloads widget timelines and redraws the Live Activity when it changes, so classic users keep the classic widget and Live Activity. LoopDesign.swift and the redesign's colour sets are shared with the widget target. The widget entry gains the CGM highlight and COB from the existing extension context. The widget catalogue gains the redesign's strings in all 24 languages, reusing Loop's translations, plus a short "Forecast" tile label. The Arabic "in 5 min" now uses an Arabic-Indic digit in both catalogues. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QHnVPAQn8LyVAJrZEA3f2T
Nutcasey
left a comment
There was a problem hiding this comment.
Codex reviewed PR #2615 against dev using the code-reviewer-cx skill. I fixed all outstanding high-confidence issues identified in this review and pushed commit 76bbecb4c03a02de3259d95d3d487f49dfc354f8.
Important findings, now fixed:
- CSV column corruption — confidence 89/100.
Loop/Redesign/TrendsScreen.swift:204: localised glucose such as7,3became two CSV fields. Export now uses POSIX numeric formatting. The actual share flow produced nine-column rows before the fix and eight-column rows afterwards inde_DE. - Lost mode-history coverage — confidence 88/100.
Loop/Redesign/LoopHistoryProvider.swift:425: pruning could remove the record establishing the state before a new switch after more than 100 days. Retaining the preceding boundary record preserves recent coverage. - Frozen Live Activity freshness — confidence 89/100.
Loop Widget Extension/Redesign/RedesignLiveActivity.swift:38: the saved glucose timestamp was used as “now”. Freshness now uses the current time when rendered, matching the classic implementation's clock. - Missing ageing warning — confidence 87/100.
Loop Widget Extension/Redesign/WidgetDesign.swift:90: the redesigned status stayed green through the ageing interval. It now becomes amber after the fresh interval.
Verification:
- Simulator build and navigation/share-flow checks passed.
- Both new regression tests failed against the original implementations for the expected reasons, then passed with the fixes under
en_DE. - Full LoopTests: 325 passed, zero failures, Glooko iPhone 14 Pro simulator, iOS 26.3.1,
en_US. - Focused status probe: fresh at 2 minutes, amber at 8 and 20 minutes.
- Changed localisation entries: zero format-placeholder mismatches;
git diff --checkpassed.
No further high-confidence blockers found. Codex has reviewed this PR and fixed the outstanding issues it identified; it is ready for human review. The PR was already open and non-draft; I have updated its description to reflect that. These fixes were not deployed to the physical phone.
|
Closing in favour of #2621, which carries this redesign onto 🤖 Generated with Claude Code |
This adds a new interface to Loop: a tab bar with Now, Trends, Logbook and Settings. It is on by default, and Settings → New Interface switches back to the classic status screen without a relaunch.
This is ready for review. Feedback on the interface and how best to split the change is welcome.
How it fits into Loop
StatusTableViewController. In the new interface, its HUD and charts are hidden and two SwiftUI cells take their place. Bolus, carb entry, presets, settings, device screens, alerts, deeplinks and user-activity restoration all stay Loop's own code. Tiles, cards and pills open the screens Loop already has: IOB opens Insulin Delivery, COB opens Carb Absorption, "Next 3 hours" opens Predicted Glucose, and the device pills open the pump and CGM settings.LOOP_LOCAL_CACHE_DURATION_DAYS). Older days come from Apple Health and respect the existing "observe other apps" flags. Basal totals use the units the pump reports as delivered, not the programmed rate, and gaps with no pump record count as no insulin. Read failures show an error state rather than zero.LoopAppManager: installs and swaps the root, and applies the chosen appearance to the window.DeeplinkManager: looks up the root on each link, because the root changes when the interface is switched.StatusTableViewController: hosts the Now cells and capturesselfweakly in two existing Combine subscriptions, so switching interface releases the old controller. In the new interface it also gives its status row (No Recent Glucose, Tap to Resume, bolus progress, presets) a card's shape.SettingsView: adds the toggle and the Appearance and App Icon row.SystemStatusWidgetandGlucoseLiveActivityConfigurationchoose the redesigned views when New Interface is on. The timeline entry gains two fields.LoopCore'sUserDefaultsgains the shared setting.Loop/Redesign/, with colour assets inDefaultAssetsandLoopTests/Models/LoopHistoryMathTests.swift.Screenshots (iOS simulator, Pump and CGM Simulators, generated history; the insulin figures aren't realistic)
Error states (added after review)
Pete asked what the error conditions look like, for example a faulted pod, a sensor in warmup, or signal loss from a device. I set each of these up in the simulator. Doing so found problems, which this update fixes:
"Signal\nLoss"). They are now joined into one line.Before this update, for comparison: the warmup message is off-screen, and the pump fault pushes the CGM pill out of view.
How these were made. These are iOS simulator screenshots with the Pump and CGM Simulators.
Appearance and app icons
Settings → Appearance and App Icon adds two choices:
Implementation:
DerivedAssetsBase, listed in the Loop target'sASSETCATALOG_COMPILER_ALTERNATE_APPICON_NAMES.DefaultAssetsshow them in the picker.Loop/Redesign/AppearanceSettings.swift.LoopAppManagerapplies the style;SettingsViewadds the row.Tested:
Home screen widget, Lock Screen and Dynamic Island
The widget and the Live Activity now follow the same rules as the Now screen:
How it fits in:
LoopDesign.swiftand the redesign's colour sets are shared with the widget target.GlucoseActivityAttributesis unchanged, so the Live Activity settings (chart, limits, bottom row) still apply.Loop Widget Extension/Redesign/.Tested:
Before (classic) and after, each showing the home screen widgets, the expanded Dynamic Island and the Lock Screen:
Localisation
The new interface is localised in all 24 of Loop's languages:
ar · cs · da · de · en · es · fi · fr · he · hu · it · ja · nb · nl · pl · pt-BR · ro · ru · sk · sv · tr · uk · vi · zh-Hans
It uses Loop's existing
Localizable.xcstrings, so Lokalise picks the new strings up like any others.Code
NSLocalizedStringwith a translator comment. That covers text, VoiceOver labels and hints, alerts, chart legends and the PDF report.Loop hasn't run for %1$@). No text is glued together in code.%lld days,%lld shorter gaps,Loop · %lld changes · tap to list). That gives Arabic six plural forms, Polish, Czech, Russian and Ukrainian four, and so on.LoopFormat.numberreplacesString(format:), so German shows "9,3".DateIntervalFormatter.DateComponentsFormatter.Day (Trends period). "Day" is also the light appearance and icon name, and Arabic and Turkish need different words for "a day" and "daytime"..decimals, because it's data for spreadsheets.Translations
%1$@ U, "Settings" and so on) keep their translations unchanged and gain any languages they were missing.%signs and the plural categories each language needs.Testing
-NSShowNonLocalizedStrings YES, which shows any string missing from the catalogue in capitals.Now in each language
Trends and Logbook in five languages, including right-to-left
All 11 screens for every language are in
screenshots/l10n/, one folder per language.Testing
en_US, because two existing bolus tests hard-code US clock strings. There are 17 newLoopHistoryMathTests, covering:Known limitations and open questions
🤖 Generated with Claude Code
https://claude.ai/code/session_01QHnVPAQn8LyVAJrZEA3f2T
Codex review — 27 October 2026
Codex reviewed this PR using the code-reviewer-cx skill and fixed all outstanding high-confidence issues identified in that review in commit
76bbecb4:Verification: simulator build and navigation/sharing checks passed; CSV exports changed from nine-column rows to eight-column rows under
de_DE. Both new regression tests failed against the original code and passed with the fixes underen_DE. Full LoopTests: 325 passed, zero failures, Glooko iPhone 14 Pro simulator, iOS 26.3.1,en_US. A status probe checked fresh, ageing and stale colours. Changed localisation entries have no format-placeholder mismatches.No further high-confidence blockers found. Ready for human review. The existing real-device and translation-review limitations still apply; these fixes were verified in the simulator.