Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
5 changes: 3 additions & 2 deletions Loop Widget Extension/Bootstrap/Localizable.xcstrings
Original file line number Diff line number Diff line change
Expand Up @@ -440,7 +440,8 @@
}
},
"%@U" : {

"comment" : "A label displaying the basal insulin rate in micro-units (U).",
"isCommentAutoGenerated" : true
},
"%1$@ v%2$@" : {
"comment" : "The format string for the app name and version number. (1: bundle name)(2: bundle version)",
Expand Down Expand Up @@ -1553,5 +1554,5 @@
}
}
},
"version" : "1.0"
"version" : "1.1"
}
4 changes: 4 additions & 0 deletions Loop Widget Extension/Live Activity/BasalViewActivity.swift
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,14 @@ struct BasalViewActivity: View {
if let rateString = decimalFormatter.string(from: NSNumber(value: rate)) {
Text("\(rateString)U")
.font(.subheadline)
.minimumScaleFactor(0.5)
.lineLimit(2)
}
else {
Text("-U")
.font(.subheadline)
.minimumScaleFactor(0.5)
.lineLimit(2)
}
}
}
Expand Down
28 changes: 26 additions & 2 deletions Loop Widget Extension/Live Activity/ChartView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ struct ChartView: View {
private let glucoseRanges: [GlucoseRangeValue]
private let preset: Preset?
private let yAxisMarks: [Double]
private let colorGradient: LinearGradient

init(glucoseSamples: [GlucoseSampleAttributes], predicatedGlucose: [Double], predicatedStartDate: Date?, predicatedInterval: TimeInterval?, useLimits: Bool, lowerLimit: Double, upperLimit: Double, glucoseRanges: [GlucoseRangeValue], preset: Preset?, yAxisMarks: [Double]) {
self.glucoseSampleData = ChartValues.convert(data: glucoseSamples, useLimits: useLimits, lowerLimit: lowerLimit, upperLimit: upperLimit)
Expand All @@ -28,6 +29,7 @@ struct ChartView: View {
lowerLimit: lowerLimit,
upperLimit: upperLimit
)
self.colorGradient = ChartView.getGradient(useLimits: useLimits, lowerLimit: lowerLimit, upperLimit: upperLimit, highestValue: yAxisMarks.max() ?? 1)
self.preset = preset
self.glucoseRanges = glucoseRanges
self.yAxisMarks = yAxisMarks
Expand All @@ -39,6 +41,28 @@ struct ChartView: View {
self.preset = preset
self.glucoseRanges = glucoseRanges
self.yAxisMarks = yAxisMarks
self.colorGradient = ChartView.getGradient(useLimits: useLimits, lowerLimit: lowerLimit, upperLimit: upperLimit, highestValue: yAxisMarks.max() ?? 1)
}

private static func getGradient(useLimits: Bool, lowerLimit: Double, upperLimit: Double, highestValue: Double) -> LinearGradient {
var stops: [Gradient.Stop] = [Gradient.Stop(color: Color("glucose"), location: 0)]
if useLimits {
let lowerStop = lowerLimit / highestValue
let upperStop = upperLimit / highestValue
stops = [
Gradient.Stop(color: .red, location: 0),
Gradient.Stop(color: .red, location: lowerStop - 0.01),
Gradient.Stop(color: .green, location: lowerStop),
Gradient.Stop(color: .green, location: upperStop),
Gradient.Stop(color: .orange, location: upperStop + 0.01),
Gradient.Stop(color: .orange, location: 600), // Just use the mg/dl limit for the most upper value
]
}
return LinearGradient(
gradient: Gradient(stops: stops),
startPoint: .bottom,
endPoint: .top
)
}

var body: some View {
Expand Down Expand Up @@ -79,7 +103,7 @@ struct ChartView: View {
y: .value("Glucose level", item.y)
)
.lineStyle(StrokeStyle(lineWidth: 2, dash: [6, 5]))
.foregroundStyle(by: .value("Color", item.color))
.foregroundStyle(colorGradient)
}
}
.chartForegroundStyleScale([
Expand Down Expand Up @@ -144,7 +168,7 @@ struct ChartValues: Identifiable {
return ChartValues(
x: startDate.addingTimeInterval(interval * Double(index)),
y: item,
color: !useLimits ? "Default" : item < lowerLimit ? "Low" : item > upperLimit ? "High" : "Good"
color: "Default" // Color is handled by the gradient
)
}
}
Expand Down
44 changes: 30 additions & 14 deletions Loop/Localizable.xcstrings
Original file line number Diff line number Diff line change
Expand Up @@ -5321,7 +5321,7 @@
}
}
},
"Add item to bottom row" : {
"Add item to Lock Screen / CarPlay display" : {
"comment" : "Title for Add item"
},
"Add Meal" : {
Expand Down Expand Up @@ -5449,9 +5449,6 @@
}
}
},
"Add predictive line" : {
"comment" : "Title for predictive line toggle"
},
"Add Pump" : {
"comment" : "Action sheet title selecting Pump\nThe title of the pump chooser in settings\nTitle text for button to add pump device\nTitle text for button to set up a Pump",
"localizations" : {
Expand Down Expand Up @@ -9837,12 +9834,6 @@
}
}
},
"Bottom row" : {
"comment" : "Live activity Bottom row configuration title"
},
"Bottom row configuration" : {
"comment" : "Title for Bottom row configuration"
},
"Cancel" : {
"comment" : "Button label for cancel\nButton text to cancel\nCancel button for reset loop alert\nCancel export button title\nThe title of the cancel action in an action sheet",
"localizations" : {
Expand Down Expand Up @@ -13108,6 +13099,13 @@
}
}
},
"Configure Display" : {
"comment" : "Title for the view to configure the lock screen display"
},
"Configure Lock Screen / Carplay Row" : {
"comment" : "A link in the live activity settings that takes the user to a view where they can configure the row displayed on their lock screen or carplay.",
"isCommentAutoGenerated" : true
},
"Continue" : {
"comment" : "Button label for continue\nDefault alert dismissal",
"localizations" : {
Expand Down Expand Up @@ -16128,6 +16126,19 @@
}
}
},
"Display colors for glucose" : {
"comment" : "Title for glucose coloring"
},
"Display Control Options" : {
"comment" : "A section header for controls related to the display of glucose levels in the live activity chart.",
"isCommentAutoGenerated" : true
},
"Display prediction in plot" : {
"comment" : "Title for prediction line toggle"
},
"Display up to 4 items. Display label is in parentheses." : {
"comment" : "Indicates the maximum number of items that can be displayed and how the label for each item is shortened."
},
"Done" : {
"localizations" : {
"cs" : {
Expand Down Expand Up @@ -23559,6 +23570,10 @@
}
}
},
"Lock Screen / Dynamic Island / CarPlay" : {
"comment" : "The title of a section in the live activity settings view, related to lock screen, dynamic island, and carplay.",
"isCommentAutoGenerated" : true
},
"Log Dose" : {
"comment" : "Button text to log a dose\nTitle for dose logging screen",
"localizations" : {
Expand Down Expand Up @@ -32945,6 +32960,10 @@
}
}
},
"Select Lock Screen Display Options" : {
"comment" : "A section header in the live activity settings screen, describing the options available for customizing the display on the lock screen.",
"isCommentAutoGenerated" : true
},
"Selecting a favorite food in the carb entry screen automatically fills in the carb quantity, food type, and absorption time fields! Tap the add button below to create your first favorite food!" : {
"localizations" : {
"da" : {
Expand Down Expand Up @@ -38430,9 +38449,6 @@
}
}
},
"Use BG coloring" : {
"comment" : "Title for BG coloring"
},
"Use Pre-Meal Preset" : {
"comment" : "The title of the alert controller used to select a duration for pre-meal targets",
"localizations" : {
Expand Down Expand Up @@ -40913,5 +40929,5 @@
}
}
},
"version" : "1.0"
"version" : "1.1"
}
31 changes: 16 additions & 15 deletions Loop/Views/LiveActivityBottomRowManagerView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -36,26 +36,27 @@ struct LiveActivityBottomRowManagerView: View {
}
buttons.append(.cancel(Text(NSLocalizedString("Cancel", comment: "Button text to cancel"))))

return ActionSheet(title: Text(NSLocalizedString("Add item to bottom row", comment: "Title for Add item")), buttons: buttons)
return ActionSheet(title: Text(NSLocalizedString("Add item to Lock Screen / CarPlay display", comment: "Title for Add item")), buttons: buttons)
}

var body: some View {
List {
ForEach($configuration, id: \.self) { item in
HStack {
deleteButton
.onTapGesture {
onDelete(item.wrappedValue)
isDirty = configuration != previousConfiguration
}
Text(item.wrappedValue.description())

Spacer()
editBars
Section(header: Text("Display up to 4 items. Display label is in parentheses.", comment: "Indicates the maximum number of items that can be displayed and how the label for each item is shortened.")) {
ForEach($configuration, id: \.self) { item in
HStack {
deleteButton
.onTapGesture {
onDelete(item.wrappedValue)
isDirty = configuration != previousConfiguration
}
Text(item.wrappedValue.description())
Spacer()
editBars
}
}
.onMove(perform: onReorder)
.deleteDisabled(true)
}
.onMove(perform: onReorder)
.deleteDisabled(true)

Section {
Button(action: onSave) {
Expand All @@ -81,7 +82,7 @@ struct LiveActivityBottomRowManagerView: View {
}
.actionSheet(isPresented: $showAdd, content: { addItem })
.insetGroupedListStyle()
.navigationBarTitle(Text(NSLocalizedString("Bottom row", comment: "Live activity Bottom row configuration title")))
.navigationBarTitle(Text(NSLocalizedString("Configure Display", comment: "Title for the view to configure the lock screen display")))
}

@ViewBuilder
Expand Down
72 changes: 37 additions & 35 deletions Loop/Views/LiveActivityManagementView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,14 @@ struct LiveActivityManagementView: View {
var body: some View {
VStack {
List {
Section {
Section(header: Text("Lock Screen / Dynamic Island / CarPlay")) {
Toggle(NSLocalizedString("Enabled", comment: "Title for enable live activity toggle"), isOn: $viewModel.enabled)
.onChange(of: viewModel.enabled) { _ in
self.isDirty = previousViewModel.enabled != viewModel.enabled
}

}

Section(header: Text("Select Lock Screen Display Options")){
ExpandableSetting(
isEditing: $viewModel.isEditingMode,
leadingValueContent: {
Expand All @@ -48,50 +50,50 @@ struct LiveActivityManagementView: View {
}
}

Section {
if viewModel.mode == .large {
Toggle(NSLocalizedString("Add predictive line", comment: "Title for predictive line toggle"), isOn: $viewModel.addPredictiveLine)
.transition(.move(edge: viewModel.mode == .large ? .top : .bottom))
.onChange(of: viewModel.addPredictiveLine) { _ in
self.isDirty = previousViewModel.addPredictiveLine != viewModel.addPredictiveLine
}
}
Section(header: Text("Display Control Options")) {
Toggle(NSLocalizedString("Display prediction in plot", comment: "Title for prediction line toggle"), isOn: $viewModel.addPredictiveLine)
.transition(.move(edge: viewModel.mode == .large ? .top : .bottom))
.onChange(of: viewModel.addPredictiveLine) { _ in
self.isDirty = previousViewModel.addPredictiveLine != viewModel.addPredictiveLine
}

Toggle(NSLocalizedString("Use BG coloring", comment: "Title for BG coloring"), isOn: $viewModel.useLimits)
Toggle(NSLocalizedString("Display colors for glucose", comment: "Title for glucose coloring"), isOn: $viewModel.useLimits)
.transition(.move(edge: viewModel.mode == .large ? .top : .bottom))
.onChange(of: viewModel.useLimits) { _ in
self.isDirty = previousViewModel.useLimits != viewModel.useLimits
}

if self.displayGlucosePreference.unit == .millimolesPerLiter {
TextInput(label: "Upper limit", value: $viewModel.upperLimitChartMmol)
.transition(.move(edge: viewModel.useLimits ? .top : .bottom))
.onChange(of: viewModel.upperLimitChartMmol) { _ in
self.isDirty = previousViewModel.upperLimitChartMmol != viewModel.upperLimitChartMmol
}
TextInput(label: "Lower limit", value: $viewModel.lowerLimitChartMmol)
.transition(.move(edge: viewModel.useLimits ? .top : .bottom))
.onChange(of: viewModel.lowerLimitChartMmol) { _ in
self.isDirty = previousViewModel.lowerLimitChartMmol != viewModel.lowerLimitChartMmol
}
} else {
TextInput(label: "Upper limit", value: $viewModel.upperLimitChartMg)
.transition(.move(edge: viewModel.useLimits ? .top : .bottom))
.onChange(of: viewModel.upperLimitChartMg) { _ in
self.isDirty = previousViewModel.upperLimitChartMg != viewModel.upperLimitChartMg
}
TextInput(label: "Lower limit", value: $viewModel.lowerLimitChartMg)
.transition(.move(edge: viewModel.useLimits ? .top : .bottom))
.onChange(of: viewModel.lowerLimitChartMg) { _ in
self.isDirty = previousViewModel.lowerLimitChartMg != viewModel.lowerLimitChartMg
}
if self.viewModel.useLimits {
if self.displayGlucosePreference.unit == .millimolesPerLiter {
TextInput(label: "Upper limit", value: $viewModel.upperLimitChartMmol)
.transition(.move(edge: viewModel.useLimits ? .top : .bottom))
.onChange(of: viewModel.upperLimitChartMmol) { _ in
self.isDirty = previousViewModel.upperLimitChartMmol != viewModel.upperLimitChartMmol
}
TextInput(label: "Lower limit", value: $viewModel.lowerLimitChartMmol)
.transition(.move(edge: viewModel.useLimits ? .top : .bottom))
.onChange(of: viewModel.lowerLimitChartMmol) { _ in
self.isDirty = previousViewModel.lowerLimitChartMmol != viewModel.lowerLimitChartMmol
}
} else {
TextInput(label: "Upper limit", value: $viewModel.upperLimitChartMg)
.transition(.move(edge: viewModel.useLimits ? .top : .bottom))
.onChange(of: viewModel.upperLimitChartMg) { _ in
self.isDirty = previousViewModel.upperLimitChartMg != viewModel.upperLimitChartMg
}
TextInput(label: "Lower limit", value: $viewModel.lowerLimitChartMg)
.transition(.move(edge: viewModel.useLimits ? .top : .bottom))
.onChange(of: viewModel.lowerLimitChartMg) { _ in
self.isDirty = previousViewModel.lowerLimitChartMg != viewModel.lowerLimitChartMg
}
}
}
}

Section {
Section(header: Text("Configure Lock Screen / Carplay Row")) {
NavigationLink(
destination: LiveActivityBottomRowManagerView(),
label: { Text(NSLocalizedString("Bottom row configuration", comment: "Title for Bottom row configuration")) }
label: { Text(NSLocalizedString("Configure Display", comment: "")) }
)
}
}
Expand Down
Loading