Sync upstream dev (0.8.4.106) into Build-Experiment - #91
Open
Sjoerd-Bo3 wants to merge 291 commits into
Open
Sjoerd-Bo3 wants to merge 291 commits into
Sjoerd-Bo3 wants to merge 291 commits into
Conversation
roundBasal floored every pump to a Medtronic x23/x54 band table, so Dana lost 240 of its 300 rates and a gen >= 23 Minimed lost the 0.025 U it delivers. It now floors against the paired driver's supportedBasalRates, injected per determination, exactly as roundToSupportedBasalRate does at enactment. Two parity determinations shift down by one increment.
performBasal and performBolus handed the determination straight to the driver unrounded, unlike their enactTempBasal and enactBolus twins.
BaseAPSManager registered itself as a PumpManagerStatusObserver only once, at init. When the live pump instance was replaced without an app relaunch (onboarding a pump, or the pumpManagerDidUpdateState fallback assignment) the observer stayed bound to the previous instance. The delegate is re-attached in DeviceDataManager's didSet, so reservoir/dose/status data kept flowing, but the observer-driven storeBatteryStatus never ran for the new pump -- no OpenAPS_Battery rows were written and the home battery icon stayed hidden until relaunch. Fix at the single funnel: DeviceDataManager emits pumpManagerDidChange from the pumpManager didSet (where the delegate is already re-attached), covering every assignment path. APSManager re-registers its status observer on that signal. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
A three-way [Decimal] concatenation type-checks on 26.6 but exceeds the budget on the 26.2 that CI pins. The five tables now live once in PumpRateTables, built with append(contentsOf:).
Decimal -> Double via Double(truncating:) can land a hair low, 0.07 becomes 0.06999999999999999, and every pump table floors, so 41 of Dana's 301 rates lost a full increment. Convert via the decimal string and drop the floor the algorithm already applied. Reported by mountrcg.
Glass panels and the small material affordances (rate capsule, chart-info button) fall back to an opaque, higher-contrast fill when Reduce Transparency or Increase Contrast is on. Also labels the icon-only chart-legend button.
Each value row reads as one element (label + value + button) with an accessibilityValue and an action to open the picker; the icon-only hint button gets a label. Covers ~20 settings modules that use this component.
Schedule editor entries read as one element with an accessible delete; numeric-field toolbar buttons (clear/prev/next/dismiss) get labels in both the SwiftUI and UIKit variants; custom Radio/Checkbox toggle styles expose on/off value and a toggle action to VoiceOver.
Slide-to-confirm gains a VoiceOver button action (was drag-only, blocking delivery); the + button exposes treatment + quick-bolus actions; quick-pick pills announce selection; the bobble reads value, range, trend, delta and age as one element instead of fragments.
Recommendation-math cards read as grouped phrases and the final dose reads with its unit; the recommendation apply/info buttons get labels and a hint; over-limit macro fields announce 'over the maximum' instead of a bare warning emoji.
Add VoiceOver labels to glucose and forecast charts, the version-copy button, and Max Carbs/Fat/Protein picker rows.
Give the progress bar a spoken chapter summary, mark the step header as a combined header with its icon hidden, announce selection state on the radio-card options, and make the delivery- limit and algorithm-setting picker rows operable with VoiceOver.
Announce selection/active state on override and temp-target cards and radio buttons, make target/value pickers operable with VoiceOver, label help buttons, group stat summaries into spoken values, hide decorative row dots, give history glucose rows a faithful spoken label, and name the twelve statistics charts.
Cap Dynamic Type at accessibility1 globally so large text still scales for low vision without shattering layouts, and cap the dense Statistics screen tighter at xxLarge like Home already does.
Speak the app version card's update status and hide its decorative icon, make the alarm-threshold and glucose-threshold tap-to-reveal picker rows operable with VoiceOver, and label the UI settings hint buttons.
Speak the loop pill, pump reservoir/battery/pod, IOB/COB, alarms, and eventual-glucose status in words instead of color and icon names; make the tappable header panels operable via VoiceOver actions; and label the icon-only help buttons across settings.
Announce selected state on the diagnostics, telemetry, and export choice rows, and give the icon-only and bracketed action buttons spoken labels (time nudge, serving add/remove, add/remove alarm and widget, dismiss).
Name the basal, carb-ratio, ISF, and target profile charts and the calibration chart for VoiceOver, and announce tone selection and play/stop state in the alarm sound picker.
Make the stop-adjustment, stop-temp-target, and stop-override cancels operable via VoiceOver, group the bolus-progress readout into a spoken value, label its cancel button, and expose the adjustment panel tap as an action.
Speak Nightscout and Tidepool connection state in words instead of icon glyphs, and fold the sensor warmup/expiry tag into the glucose bobble's spoken label.
Label the rendered contact-image previews and hide the row thumbnail, and give the app-icon grid readable names with a selected state instead of raw asset identifiers.
Speak elapsed/pod time as words so VoiceOver stops reading 'm' as meters, group the pump panel into one button that announces reservoir/battery/pod, and label the iOS 26 tab-bar items.
Hide the decorative welcome logo, mark the welcome heading as a header, collapse each bullet into one spoken element, and move VoiceOver focus to the top of each step on navigation.
Announce onboarding chapter rows as complete or not complete, and re-apply accessibility to the renamed quick-pick treatments: pills announce amount, unit and selected state, and the slide-to-confirm exposes a double-tap action for VoiceOver.
iOS resolves a UNNotificationSoundName against the main bundle root and Library/Sounds only. The tones shipped as an Xcode folder reference, so they landed in Trio.app/Sounds/ and every notification silently fell back to the default iOS sound — while the picker preview and the critical-audio player worked, being the only paths passing subdirectory: "Sounds". Register the 18 .caf files individually so they flatten to the bundle root, and drop the now-wrong subdirectory from both lookups. Vendor sounds move from Library/Sounds/<manager>/<file> to a flat <manager>-<file>, since iOS only reads the top level of that directory. Fixes nightscout#1371
The critical-audio fallback is what pierces the silent switch and Focus on builds without the Critical Alerts entitlement, but it rejected anything that wasn't .immediate. The not-looping watchdog is the only .delayed alert Trio creates, so the one alarm that fires unattended was the one alarm that never got audio. Start playback from the modal scheduler's timer instead, whose .insert decision already means live, not stale and not snoozed. Arming time is 20 minutes early, so .immediate keeps playing at issue time.
evaluateForecast bailed on the same CGM-ownership guard as the reading path, so on Dexcom, xDrip4iOS and Libre — where "Use CGM App Alerts" defaults on — Low Glucose Soon was never evaluated, silently and forever. A CGM app can alarm on the current reading but cannot compute Trio's oref forecast, so it can never cover this alarm. evaluateCarbsRequired already omits the guard for the same reason, and the settings screen only moves reading-driven types into the "Handled by CGM App" section, so the alarm was shown to the user as armed. Fixes nightscout#1428
Add a unit speller that expands compact abbreviations (mg/dL, mmol/L, U, g) and compound units (g/U, mg/dL/U, U/hr) into spoken words, and use it in the accessibility values across glucose, delivery-limit, therapy, and threshold controls.
Without the Critical Alerts entitlement the in-process audio player is the only thing that pierces the silent switch and Focus, and it can only sound while Trio is running. AlarmKit is system-rendered, needs no entitlement, and still fires when iOS has suspended the app. Ported from Loop's CriticalAlertAlarmScheduler. Alert-only presentation, so no Widget Extension is needed, scheduled two seconds out because a now/past fixed date schedules silently. The alarm plays the tone the user picked — AlertSound.named resolves like UNNotificationSoundName, from the bundle root, which is where the tones now live. Stop routes through a shared bridge so it acknowledges the Trio alert rather than only silencing it, queueing taps that land before the manager registers. The audible channel is now AlarmKit, then the audio player.
Anchor bolus and carb amount labels to a zero-size companion mark
Their trio branches carry Trio-only commits; the script manifest is fixed to match.
isDisplayOnly means the reading was shifted for visual consistency after calibration (LoopKit), not that it is unsafe to dose on: Loop keeps these samples and excludes them only from momentum and counteraction. The gate was LibreLoop-scoped, so Trio already dosed on Dexcom's display-only samples. It never held either way: LibreLoop's backfill paths forward the same sensor minute with isDisplayOnly false, so a dropped reading re-entered unflagged. On Libre 3 Plus the actionability bit is stuck clear, so every reading was discarded and those users could not loop at all. Readings the sensor reports as faulty are still withheld by the driver.
Backport of loopandlearn#159; addresses the -034 fault increase on Omnipod 5.
Refactor: Dependency Injection Hygiene
…y-gate Fix for Libre 3/3 Plus: Stop dropping display-only glucose readings
Resolves conflicts with the DI hygiene refactor (nightscout#1367), which moved TelemetryClient and TelemetryAttestor to container-scoped singletons with init(resolver:) and removed the lazy injectIfNeeded() pattern. Kept that structure and layered this branch's TelemetryRequestContext parameters on top of the new signatures. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
- Prefer appDevVersion over CFBundleShortVersionString for the X-Trio-Version header, falling back to "unknown". - Document the daily anonymous install heartbeat in PRIVACY_POLICY.md, including that it still runs when usage telemetry is opted out, and mirror a short version of it in the in-app privacy screen. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…-and-volume Various Alarm Adjustments / Fixes
…over Feat/chart selection popover
Significantly improve telemetry reliability
…modules Update submodules to current upstream
Merge the latest upstream dev (0.8.4.106) into the fork, preserving Build-Experiment customizations. Conflict resolution: - Adopted upstream's pump/CGM catalog refactor (setupPumpEntry / PumpCatalogEntry) since its callers are now wired throughout Home. - Adopted upstream's chart-selection readout (meal-slot ChartSelectionRow + ChartSelectionLookup) and removed the old in-chart detail card and the now-unused SelectionPopoverView, matching upstream. - Adopted upstream's device-alarm tier system (day/night windows, tone config, volume-handling fixes) and its accessibility labels across the header, meal panel, treatments and history. - Kept the fork's loop/reservoir spinning border animations, Quick-Pick Boluses, ProfilePresets activation flow, and settings-import work. - Kept Quick-Pick Treatments excised. - Superseded by upstream's contact-image work: took upstream's contact image views/rendering (they now include the background-mode picker). Note: the fork's per-alert severity screen is now superseded by upstream's Device Alarms and no longer affects delivery; slated for follow-up removal. Also absorbed: DI-hygiene refactor, telemetry updates, Libre3/OmnipodKit/ DanaKit/EversenseKit bumps, glucose display-only gating fixes, and many upstream fixes. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EpcDkYHNDwWH5Ub6kdVh5g
The 286-commit dev sync mis-balanced braces where fork and upstream diverged. Take upstream's full MealPanel/BottomControls/TreatmentsRootView (their Home rework, which keeps snooze, glass panels and remaining bars), and close the preset-activation glassActionSheet correctly in Adjustments while preserving the ProfilePresets activation/save-preset alerts. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EpcDkYHNDwWH5Ub6kdVh5g
The dev-sync resolution left upstream's Quick-Pick Treatments symbols in HomeRootView's accessibility action; point it at the fork's Quick-Pick Boluses flow (enableQuickBolus / quickBolusHistory / showQuickBolus*). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EpcDkYHNDwWH5Ub6kdVh5g
The switch includes the fork's .profiles (EmptyView) case, so the property needs @ViewBuilder for its heterogeneous branches; the merge resolution had dropped it. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EpcDkYHNDwWH5Ub6kdVh5g
Upstream removed the Medtronic Enlite CGM type; drop the obsolete import warning that referenced merged.cgm == .enlite. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EpcDkYHNDwWH5Ub6kdVh5g
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Brings Build-Experiment up to the latest upstream dev (0.8.4.106, 286 commits) so the build is current. This is a large sync with several upstream refactors; fork customizations are preserved.
Conflict resolution (18 files)
Adopted upstream (its callers are wired throughout, or it supersedes a fork bit):
setupPumpEntry/PumpCatalogEntry(Home + setup sheets now use it).ChartSelectionRow+ChartSelectionLookup); removed the old in-chart detail card and the now-unusedSelectionPopoverView.Kept ours (clean fork features):
The fork's per-alert severity screen (Settings → Notifications → Alert Severity) is now superseded by upstream's Device Alarms tier system and no longer affects alert delivery. It still compiles but would mislead — recommend removing that screen in a follow-up. (Left in place here to keep this sync focused on getting the build green.)
Verification
No conflict markers; pbxproj integrity clean (no duplicate GUIDs, no dangling build-file/file-reference entries); all new upstream files registered. Symbol checks pass for the adopted refactors (
PumpCatalogEntry,ChartSelectionLookup,applyDeviceSeverityConfig,minutesAgoAccessible) and the kept fork code (enactBolusAPI, QuickBolus wiring, catalog.concept). The Xcode-27 shift only added chart-label tweaks + a 26.2 type-check fix, socompile_check(Xcode 26.2) stays valid.Compiles only via the
compile_checkworkflow (branch added to its trigger list) — no local iOS build in this environment.🤖 Generated with Claude Code
https://claude.ai/code/session_01EpcDkYHNDwWH5Ub6kdVh5g
Generated by Claude Code