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
8 changes: 6 additions & 2 deletions Loop/View Models/CarbEntryViewModel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,7 @@ final class CarbEntryViewModel: ObservableObject {
date: date,
quantity: LoopQuantity(unit: preferredCarbUnit, doubleValue: quantity),
startDate: time,
foodType: usesCustomFoodType ? foodType : selectedDefaultAbsorptionTimeEmoji,
foodType: effectiveFoodType,
absorptionTime: absorptionTime,
favoriteFoodID: favoriteFoodID
)
Expand All @@ -170,9 +170,13 @@ final class CarbEntryViewModel: ObservableObject {
}
}

var effectiveFoodType: String {
usesCustomFoodType ? foodType : selectedDefaultAbsorptionTimeEmoji
}

var saveFavoriteFoodButtonDisabled: Bool {
get {
if let carbsQuantity, 0...maxCarbEntryQuantity.doubleValue(for: preferredCarbUnit) ~= carbsQuantity, foodType != "", selectedFavoriteFoodIndex == -1 {
if let carbsQuantity, 0...maxCarbEntryQuantity.doubleValue(for: preferredCarbUnit) ~= carbsQuantity, effectiveFoodType != "", selectedFavoriteFoodIndex == -1 {
Comment thread
stachon marked this conversation as resolved.
return false
}
return true
Expand Down
54 changes: 20 additions & 34 deletions Loop/Views/BolusEntryView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -29,24 +29,23 @@ struct BolusEntryView: View {

@FocusState private var bolusFieldFocused: Bool

private var accessoryClearance: CGFloat {
dynamicTypeSize.isAccessibilitySize ? 72 : 52
}

var body: some View {
VStack(spacing: 0) {
ScrollViewReader { scrollProxy in
List {
self.chartSection
self.summarySection
}
.padding(.top, -28)
.contentMargins(.top, 16, for: .scrollContent)
.insetGroupedListStyle()
if !bolusFieldFocused {
actionArea
.actionAreaInset {
actionAreaContent
}
.keyboardEntryPage()
.onDisappear {
bolusFieldFocused = false
}

}
.navigationBarTitle(self.title)
.navigationBarTitle(self.title, displayMode: .inline)
.supportedInterfaceOrientations(.portrait)
.alert(item: self.$viewModel.activeAlert, content: self.alert(for:))
.onReceive(self.viewModel.$recommendedBolus) { recommendation in
Expand All @@ -65,7 +64,6 @@ struct BolusEntryView: View {
enteredBolusStringBinding.wrappedValue = "0"
}
}
.edgesIgnoringSafeArea(self.bolusFieldFocused ? [] : .bottom)
.task {
await self.viewModel.generateRecommendationAndStartObserving()
}
Expand Down Expand Up @@ -127,7 +125,7 @@ struct BolusEntryView: View {
} header: {
if let scheduleOverride = viewModel.scheduleOverride ?? viewModel.preMealOverride {
ActivePresetBanner(override: scheduleOverride)
.listRowInsets(EdgeInsets(top: 30, leading: 0, bottom: 12, trailing: 0))
.listRowInsets(EdgeInsets(top: 16, leading: 0, bottom: 12, trailing: 0))
.padding(.horizontal, -20)
.padding(.bottom, 8)
.textCase(nil)
Expand Down Expand Up @@ -297,12 +295,6 @@ struct BolusEntryView: View {
viewModel.updateEnteredBolus(enteredBolusString)
}
}
.toolbar {
ToolbarItemGroup(placement: .keyboard) {
Spacer()
Button("Done") { bolusFieldFocused = false }
}
}
bolusUnitsLabel
}
.accessibilityIdentifier("textField_Bolus")
Expand All @@ -324,22 +316,18 @@ struct BolusEntryView: View {
)
}

private var actionArea: some View {
VStack(spacing: 0) {
if viewModel.isNoticeVisible {
warning(for: viewModel.activeNotice!)
.padding([.top, .horizontal])
.transition(AnyTransition.opacity.combined(with: .move(edge: .bottom)))
}
@ViewBuilder
private var actionAreaContent: some View {
if viewModel.isNoticeVisible {
warning(for: viewModel.activeNotice!)
.transition(AnyTransition.opacity.combined(with: .move(edge: .bottom)))
}

if viewModel.isManualGlucosePromptVisible {
enterManualGlucoseButton
.transition(AnyTransition.opacity.combined(with: .move(edge: .bottom)))
}
actionButton
if viewModel.isManualGlucosePromptVisible {
enterManualGlucoseButton
.transition(AnyTransition.opacity.combined(with: .move(edge: .bottom)))
}
.padding(.bottom) // FIXME: unnecessary on iPhone 8 size devices
.background(Color(.secondarySystemGroupedBackground).shadow(radius: 5))
actionButton
}

private func warning(for notice: BolusEntryViewModel.Notice) -> some View {
Expand Down Expand Up @@ -384,7 +372,6 @@ struct BolusEntryView: View {
label: { Text("Enter Fingerstick Glucose", comment: "Button text prompting manual glucose entry on bolus screen") }
)
.buttonStyle(ActionButtonStyle(viewModel.primaryButton == .manualGlucoseEntry ? .primary : .secondary))
.padding([.top, .horizontal])
.accessibilityIdentifier("button_EnterFingerstickGlucose")
}

Expand Down Expand Up @@ -416,7 +403,6 @@ struct BolusEntryView: View {
)
.buttonStyle(ActionButtonStyle(viewModel.primaryButton == .actionButton ? .primary : .secondary))
.disabled(viewModel.enacting)
.padding()
.accessibilityIdentifier("button_bolusAction")
}

Expand Down
78 changes: 36 additions & 42 deletions Loop/Views/CarbEntryView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -43,23 +43,14 @@ struct CarbEntryView: View, HorizontalSizeClassOverride {
ToolbarItem(placement: .navigationBarLeading) {
dismissButton
}

ToolbarItem(placement: .navigationBarTrailing) {
continueButton
.accessibilityIdentifier("button_Continue")
}
}
}
.navigationViewStyle(.stack)
.keyboardEntryPage()
}
else {
content
.toolbar {
ToolbarItem(placement: .navigationBarTrailing) {
continueButton
.accessibilityIdentifier("button_Continue")
}
}
.keyboardEntryPage()
}
}

Expand All @@ -77,12 +68,11 @@ struct CarbEntryView: View, HorizontalSizeClassOverride {
warningsCard

mainCard
.padding(.top, 8)

continueActionButton

if isNewEntry, FeatureFlags.allowExperimentalFeatures {
.padding(.top, 16)

if isNewEntry, FeatureFlags.allowExperimentalFeatures, !viewModel.favoriteFoods.isEmpty {
favoriteFoodsCard
.padding(.top, 16)
}

if viewModel.selectedFavoriteFoodLastEaten != nil, FeatureFlags.allowExperimentalFeatures {
Expand All @@ -104,9 +94,18 @@ struct CarbEntryView: View, HorizontalSizeClassOverride {
.accessibility(hidden: true)
}
}
.actionAreaInset {
if isNewEntry, FeatureFlags.allowExperimentalFeatures, viewModel.selectedFavoriteFood == nil {
saveAsFavoriteFoodButton
}
continueActionButton
}
.onDisappear {
expandedRow = nil
}
.alert(item: $viewModel.alert, content: alert(for:))
.sheet(isPresented: $showAddFavoriteFood, onDismiss: clearExpandedRow) {
FavoriteFoodAddEditView(carbsQuantity: $viewModel.carbsQuantity.wrappedValue, foodType: $viewModel.foodType.wrappedValue, absorptionTime: $viewModel.absorptionTime.wrappedValue, onSave: onFavoriteFoodSave(_:))
FavoriteFoodAddEditView(carbsQuantity: $viewModel.carbsQuantity.wrappedValue, foodType: viewModel.effectiveFoodType, absorptionTime: $viewModel.absorptionTime.wrappedValue, onSave: onFavoriteFoodSave(_:))
}
.sheet(isPresented: $showHowAbsorptionTimeWorks) {
HowAbsorptionTimeWorksView()
Expand All @@ -119,7 +118,7 @@ struct CarbEntryView: View, HorizontalSizeClassOverride {
}

private var mainCard: some View {
VStack(spacing: 10) {
VStack(spacing: 16) {
let amountConsumedFocused: Binding<Bool> = Binding(get: { expandedRow == .amountConsumed }, set: { expandedRow = $0 ? .amountConsumed : nil })
let timeFocused: Binding<Bool> = Binding(get: { expandedRow == .time }, set: { expandedRow = $0 ? .time : nil })
let foodTypeFocused: Binding<Bool> = Binding(get: { expandedRow == .foodType }, set: { expandedRow = $0 ? .foodType : nil })
Expand All @@ -134,22 +133,25 @@ struct CarbEntryView: View, HorizontalSizeClassOverride {
)

CarbQuantityRow(quantity: $viewModel.carbsQuantity, isFocused: amountConsumedFocused, title: NSLocalizedString("Amount Consumed", comment: "Label for carb quantity entry row on carb entry screen"), preferredCarbUnit: viewModel.preferredCarbUnit)
.padding(.vertical, 4)

CardSectionDivider()

DatePickerRow(date: $viewModel.time, isFocused: timeFocused, minimumDate: viewModel.minimumDate, maximumDate: viewModel.maximumDate)

.padding(.vertical, 4)

CardSectionDivider()

FoodTypeRow(selectedFavoriteFood: selectedFavoriteFoodBinding, foodType: $viewModel.foodType, absorptionTime: $viewModel.absorptionTime, selectedDefaultAbsorptionTimeEmoji: $viewModel.selectedDefaultAbsorptionTimeEmoji, usesCustomFoodType: $viewModel.usesCustomFoodType, absorptionTimeWasEdited: $viewModel.absorptionTimeWasEdited, isFocused: foodTypeFocused, showClearFavoriteFoodButton: !isNewEntry, defaultAbsorptionTimes: viewModel.defaultAbsorptionTimes)

.padding(.vertical, 4)

CardSectionDivider()

AbsorptionTimePickerRow(absorptionTime: $viewModel.absorptionTime, isFocused: absorptionTimeFocused, validDurationRange: viewModel.absorptionRimesRange, showHowAbsorptionTimeWorks: $showHowAbsorptionTimeWorks)
.padding(.bottom, 2)
.padding(.vertical, 4)
}
.padding(.vertical, 12)
.padding(.horizontal)
.padding(.vertical, 16)
.padding(.horizontal, 20)
.background(CardBackground())
.padding(.horizontal)
}
Expand Down Expand Up @@ -259,6 +261,7 @@ extension CarbEntryView {
.minimumScaleFactor(0.8)
.frame(maxWidth: .infinity, alignment: .trailing)
}
.padding(.vertical, 8)

if expandedRow == .favoriteFoodSelection {
Picker("", selection: $viewModel.selectedFavoriteFoodIndex) {
Expand All @@ -280,18 +283,6 @@ extension CarbEntryView {
}
}
}

if viewModel.selectedFavoriteFood == nil {
CardSectionDivider()
}
}

if viewModel.selectedFavoriteFood == nil {
Button(action: saveAsFavoriteFood) {
Text("Save as favorite food")
.frame(maxWidth: .infinity)
}
.disabled(viewModel.saveFavoriteFoodButtonDisabled)
}
}
.padding(.vertical, 12)
Expand Down Expand Up @@ -339,20 +330,23 @@ extension CarbEntryView {
}
}

private var continueButton: some View {
Button(action: viewModel.continueToBolus) {
Text("Continue")
}
.disabled(viewModel.continueButtonDisabled)
private var saveAsFavoriteFoodButton: some View {
SecondaryActionButton(Text("Save as New Favorite Food", comment: "Button title to create a new favorite food from the current carb entry"), action: saveAsFavoriteFood)
.disabled(viewModel.saveFavoriteFoodButtonDisabled)
.accessibilityIdentifier("button_SaveAsFavoriteFood")
}

private var continueActionButton: some View {
Button(action: viewModel.continueToBolus) {
Button(action: {
expandedRow = nil
KeyboardDismissal.resignFirstResponder()
viewModel.continueToBolus()
}) {
Text("Continue")
}
.buttonStyle(ActionButtonStyle())
.padding()
.disabled(viewModel.continueButtonDisabled)
.accessibilityIdentifier("button_Continue")
}

}
Expand Down
Loading