Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
53 commits
Select commit Hold shift + click to select a range
a41eedb
Initial plan
Copilot Apr 6, 2026
bf905c8
feat: add Profile Presets system for switching between therapy settings
Copilot Apr 6, 2026
bf9014c
fix: add validation for preset save/activate and fix pluralization
Copilot Apr 6, 2026
1e822b7
refactor: move basal total calculation to ProfilePreset model
Copilot Apr 6, 2026
e97f3f8
feat: expand profile presets with SMB/Dynamic ISF settings and percen…
Copilot Apr 6, 2026
738969b
fix: address review feedback - default adjusted name suffix and singl…
Copilot Apr 6, 2026
8e55e7e
feat: add settings summary in save sheet, preset detail view, and pro…
Copilot Apr 6, 2026
bd18207
refactor: extract shared storage helpers and comparison state defaults
Copilot Apr 6, 2026
7ce26fe
fix: add ProfilePresetStorage.swift to Storage PBXGroup in Xcode project
Copilot Apr 6, 2026
e58ff6c
fix: add Hashable conformance to ProfilePreset and fix Text initializer
Copilot Apr 6, 2026
ead8948
Add icon picker and display to ProfilePresetsRootView
Copilot Apr 6, 2026
429b16c
feat: add icon to presets, homescreen indicator, profiles tab, charts…
Copilot Apr 6, 2026
fc47019
feat: tabbed save sheet, ISF/CR values in preset row with mmol suppor…
Copilot Apr 6, 2026
98f2fd0
fix: remove trailing spaces from placeholder text in preset row
Copilot Apr 6, 2026
1e0cb53
fix: add @ViewBuilder to resolve mismatching view types in Adjustment…
Copilot Apr 6, 2026
9e9c3c9
feat: redesign preset row with summary pills, context menu, and tap-t…
Copilot Apr 6, 2026
c9d8eb2
feat: remove activate buttons from Adjustments profiles tab, add summ…
Copilot Apr 6, 2026
bd3c09b
fix: store notification observer and remove in deinit to prevent memo…
Copilot Apr 6, 2026
e4889e2
fix: qualify NotificationCenter.default with Foundation prefix to res…
Copilot Apr 6, 2026
4a0f877
feat: add Activate option to preset context menu and swipe actions
Copilot Apr 6, 2026
ac84e42
feat: enhance preset UI - comparison highlighting, dynISF pill, renam…
Copilot Apr 6, 2026
6ec7003
refactor: address code review - better naming and extract duplicate c…
Copilot Apr 6, 2026
ad8456b
feat: add tap-to-activate, active banner, and deactivate button for p…
Copilot Apr 6, 2026
27aa64a
feat: improve compare UI with separate picker rows and current profil…
Copilot Apr 6, 2026
9339ae8
feat: add profile divergence detection - show modified indicator when…
Copilot Apr 6, 2026
c231f47
refactor: rename allOptions to comparisonOptions for clarity
Copilot Apr 6, 2026
1d89db1
feat: fix homescreen divergence detection, add update preset to curre…
Copilot Apr 6, 2026
22df56f
Implement profile preset run tracking with divergence support
Copilot Apr 7, 2026
4cad25d
Fix documentation comments for diverted/diverged run methods
Copilot Apr 7, 2026
33f4866
Add profile preset badge to Live Activity detailed chart view
Copilot Apr 7, 2026
393edfd
Add divergence save prompt when switching profile presets
Copilot Apr 7, 2026
07f02d7
Refactor: Extract shared preset switch logic into PresetSwitchCoordin…
Copilot Apr 7, 2026
b257318
Address review: accept String? in DivergenceSavePromptModifier to avo…
Copilot Apr 7, 2026
4b24cfe
feat: subtle chart bar, info panel, save-as-new, deactivate on delete
Copilot Apr 7, 2026
776d2cd
fix: add ISF/CR observer protocols and broadcast changes for divergen…
Copilot Apr 7, 2026
7ec5037
refactor: extract ProfilePreset.defaultIcon constant, address review …
Copilot Apr 7, 2026
4c0d2ea
docs: add comprehensive state machine, flow, sequence diagrams and us…
Copilot Apr 7, 2026
7836577
docs: add gap analysis section (§17) identifying missing states, edge…
Copilot Apr 7, 2026
91424c0
docs: fix typo DiveredAtBoot → DivergedAtBoot in gap analysis
Copilot Apr 7, 2026
9826331
feat: change the display area of profilepresets on homescreen
Sjoerd-Bo3 Apr 7, 2026
fc7bfb3
fix linting
Sjoerd-Bo3 Apr 7, 2026
c699899
Merge branch 'copilot/expand-profile-switcher-settings' of https://gi…
Sjoerd-Bo3 Apr 7, 2026
1debea0
fix: address diagram gaps — cold-start recovery, same-preset guard, r…
Copilot Apr 7, 2026
e25b59a
docs: update gap analysis with fix status, cold-start recovery diagra…
Copilot Apr 7, 2026
7fe4d0f
fix: use performAndWait in closeStaleRuns for synchronous cold-start …
Copilot Apr 7, 2026
2aa2be9
fix: improve closeStaleRuns error message for cold-start debugging, r…
Copilot Apr 7, 2026
30d28a0
feat: always include SMB/Dynamic settings in presets, add review tab,…
Copilot Apr 7, 2026
aa344ff
refactor: rename saveSMBSettingRow to settingRow for clarity
Copilot Apr 7, 2026
f5c5384
Rework profile preset save flow to onboarding-style pages and detail …
Copilot Apr 7, 2026
8da8b80
Address review feedback: consistent naming and accessibility labels f…
Copilot Apr 7, 2026
677f2c5
Add diff-only toggle to profile comparison and reordering to Settings…
Copilot Apr 7, 2026
b806e61
Fix code style: align multi-line boolean expressions consistently
Copilot Apr 7, 2026
2d80ad3
Improve profile comparison: show diff-only by default, format times a…
Copilot Apr 7, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions LiveActivity/LiveActivity.swift
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,9 @@ private extension LiveActivityAttributes.ContentState {
overrideDate: Date().addingTimeInterval(-3600),
overrideDuration: 120,
overrideTarget: 150,
isProfilePresetActive: false,
profilePresetName: "",
isProfilePresetDiverted: false,
widgetItems: LiveActivityAttributes.LiveActivityItem.defaultItems
)

Expand Down
45 changes: 35 additions & 10 deletions LiveActivity/Views/LiveActivityView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -63,17 +63,42 @@ struct LiveActivityView: View {
.frame(maxWidth: UIScreen.main.bounds.width * 0.9)
.frame(height: 80)
.overlay(alignment: .topTrailing) {
if context.state.detailedViewState.isOverrideActive {
HStack {
Text("\(context.state.detailedViewState.overrideName)")
.font(.footnote)
.fontWeight(.bold)
.foregroundStyle(.white)
VStack(alignment: .trailing, spacing: 4) {
if context.state.detailedViewState.isOverrideActive {
HStack {
Text("\(context.state.detailedViewState.overrideName)")
.font(.footnote)
.fontWeight(.bold)
.foregroundStyle(.white)
}
.padding(6)
.background {
RoundedRectangle(cornerRadius: 10)
.fill(Color.purple.opacity(colorScheme == .dark ? 0.6 : 0.8))
}
}
.padding(6)
.background {
RoundedRectangle(cornerRadius: 10)
.fill(Color.purple.opacity(colorScheme == .dark ? 0.6 : 0.8))
if context.state.detailedViewState.isProfilePresetActive {
let presetName = context.state.detailedViewState.profilePresetName
let isDiverted = context.state.detailedViewState.isProfilePresetDiverted
HStack(spacing: 4) {
if isDiverted {
Image(systemName: "exclamationmark.triangle.fill")
.font(.caption2)
}
Text(presetName)
.font(.footnote)
.fontWeight(.bold)
.foregroundStyle(.white)
}
.padding(6)
.background {
RoundedRectangle(cornerRadius: 10)
.fill(
isDiverted
? Color.orange.opacity(colorScheme == .dark ? 0.7 : 0.85)
: Color.teal.opacity(colorScheme == .dark ? 0.7 : 0.85)
)
}
}
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import CoreData
import Foundation

@objc(ProfilePresetRunStored) public class ProfilePresetRunStored: NSManagedObject {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import CoreData
import Foundation

public extension ProfilePresetRunStored {
@nonobjc class func fetchRequest() -> NSFetchRequest<ProfilePresetRunStored> {
NSFetchRequest<ProfilePresetRunStored>(entityName: "ProfilePresetRunStored")
}

@NSManaged var endDate: Date?
@NSManaged var icon: String?
@NSManaged var id: UUID?
@NSManaged var isDiverted: Bool
@NSManaged var isUploadedToNS: Bool
@NSManaged var name: String?
@NSManaged var presetId: String?
@NSManaged var startDate: Date?
}

extension ProfilePresetRunStored: Identifiable {}
22 changes: 22 additions & 0 deletions Model/Helper/ProfilePresetRunStored+helper.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import CoreData
import Foundation

extension NSPredicate {
static var profilePresetRunStoredFromOneDayAgo: NSPredicate {
let date = Date.oneDayAgo
return NSPredicate(format: "startDate >= %@", date as NSDate)
}

static var activeProfilePresetRun: NSPredicate {
NSPredicate(format: "endDate == nil")
}

static var profilePresetRunsNotYetUploadedToNS: NSPredicate {
let date = Date.oneDayAgo
return NSPredicate(
format: "startDate >= %@ AND isUploadedToNS == %@ AND endDate != nil",
date as NSDate,
false as NSNumber
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -266,4 +266,17 @@
<fetchIndexElement property="isPreset" type="Binary" order="descending"/>
</fetchIndex>
</entity>
<entity name="ProfilePresetRunStored" representedClassName="ProfilePresetRunStored" syncable="YES">
<attribute name="endDate" optional="YES" attributeType="Date" usesScalarValueType="NO"/>
<attribute name="icon" optional="YES" attributeType="String"/>
<attribute name="id" optional="YES" attributeType="UUID" usesScalarValueType="NO"/>
<attribute name="isDiverted" optional="YES" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES"/>
<attribute name="isUploadedToNS" optional="YES" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES"/>
<attribute name="name" optional="YES" attributeType="String"/>
<attribute name="presetId" optional="YES" attributeType="String"/>
<attribute name="startDate" optional="YES" attributeType="Date" usesScalarValueType="NO"/>
<fetchIndex name="byStartDate">
<fetchIndexElement property="startDate" type="Binary" order="descending"/>
</fetchIndex>
</entity>
</model>
Loading