diff --git a/MetaCocktailsSwiftData.xcodeproj/project.pbxproj b/MetaCocktailsSwiftData.xcodeproj/project.pbxproj index 655cb163..bfd2cdba 100644 --- a/MetaCocktailsSwiftData.xcodeproj/project.pbxproj +++ b/MetaCocktailsSwiftData.xcodeproj/project.pbxproj @@ -405,6 +405,7 @@ 4DBFF8572B60AAFB0011B5B1 /* CableCar.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4DBFF8562B60AAFB0011B5B1 /* CableCar.swift */; }; 4DBFF8592B60AD800011B5B1 /* CableCar(W&G).swift in Sources */ = {isa = PBXBuildFile; fileRef = 4DBFF8582B60AD800011B5B1 /* CableCar(W&G).swift */; }; 4DBFF85B2B60AFE60011B5B1 /* Carajillo.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4DBFF85A2B60AFE60011B5B1 /* Carajillo.swift */; }; + 4DC059132DC09D13006AAE5B /* BatchCellDryIngredientView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4DC059122DC09D13006AAE5B /* BatchCellDryIngredientView.swift */; }; 4DCAA7A52C35E77200FBC4FE /* CustomIngredientRecipeView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4DCAA7A42C35E77200FBC4FE /* CustomIngredientRecipeView.swift */; }; 4DCAA7A72C35E83F00FBC4FE /* AddRecipeStepDetailView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4DCAA7A62C35E83F00FBC4FE /* AddRecipeStepDetailView.swift */; }; 4DCAA7A92C373D1700FBC4FE /* AddIngredientDetailView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4DCAA7A82C373D1700FBC4FE /* AddIngredientDetailView.swift */; }; @@ -973,6 +974,7 @@ 4DBFF8562B60AAFB0011B5B1 /* CableCar.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CableCar.swift; sourceTree = ""; }; 4DBFF8582B60AD800011B5B1 /* CableCar(W&G).swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "CableCar(W&G).swift"; sourceTree = ""; }; 4DBFF85A2B60AFE60011B5B1 /* Carajillo.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Carajillo.swift; sourceTree = ""; }; + 4DC059122DC09D13006AAE5B /* BatchCellDryIngredientView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BatchCellDryIngredientView.swift; sourceTree = ""; }; 4DCAA7A42C35E77200FBC4FE /* CustomIngredientRecipeView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CustomIngredientRecipeView.swift; sourceTree = ""; }; 4DCAA7A62C35E83F00FBC4FE /* AddRecipeStepDetailView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AddRecipeStepDetailView.swift; sourceTree = ""; }; 4DCAA7A82C373D1700FBC4FE /* AddIngredientDetailView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AddIngredientDetailView.swift; sourceTree = ""; }; @@ -1772,6 +1774,7 @@ isa = PBXGroup; children = ( 4DED944D2C098DBF002305C2 /* BatchCellView.swift */, + 4DC059122DC09D13006AAE5B /* BatchCellDryIngredientView.swift */, ); path = SubViews; sourceTree = ""; @@ -2788,6 +2791,7 @@ 4D1E85D32B5CD8E700214BC6 /* RedWedding.swift in Sources */, 4D08602C2C60599E000AB17A /* IncludedIngredientSearchCell.swift in Sources */, 4DE33E212B91B82E00312EC3 /* Cosmonaut.swift in Sources */, + 4DC059132DC09D13006AAE5B /* BatchCellDryIngredientView.swift in Sources */, 4DA567782B6C8AAC003F6F04 /* PeaksOfReykjavik.swift in Sources */, 4D5DA0B82BA12B3E00C14F1F /* RegalAmburana.swift in Sources */, 4DA567742B6C827C003F6F04 /* LavandulaRosa.swift in Sources */, diff --git a/MetaCocktailsSwiftData/Views/CocktailBatchingCalculator/CBCMainView/CBCLoadedCocktailView.swift b/MetaCocktailsSwiftData/Views/CocktailBatchingCalculator/CBCMainView/CBCLoadedCocktailView.swift index ab68cf0d..5ab3323d 100644 --- a/MetaCocktailsSwiftData/Views/CocktailBatchingCalculator/CBCMainView/CBCLoadedCocktailView.swift +++ b/MetaCocktailsSwiftData/Views/CocktailBatchingCalculator/CBCMainView/CBCLoadedCocktailView.swift @@ -34,10 +34,6 @@ struct CBCLoadedCocktailView: View { .padding(.top, -20) } .background(ColorScheme.background) - .onChange(of: viewModel.quantifiedBatchedIngredients) { _, _ in - // Force view update when quantifiedBatchedIngredients change - viewModel.objectWillChange.send() - } .navigationBarBackButtonHidden() .navigationBarTitleDisplayMode(.inline) .jamesHeaderWithNavigation(title: "Batch Calculator", dismiss: dismiss) @@ -49,6 +45,9 @@ struct CBCLoadedCocktailView: View { }) }) + .onAppear { + viewModel.convertIngredientsToBatchCellData() + } } } @@ -152,14 +151,20 @@ struct QuantifiedIngredientsListView: View { .foregroundStyle(Color.secondary) } if isShowingOunceMeasurements { - let fluidOunces = viewModel.totalDilutionVolume / mlToOzConversionFactor - Text(String(format: "%.2f oz", fluidOunces)) + Text(String(format: "%.2f oz", viewModel.findDilutionInFluidOunces())) .font(FontFactory.formLabel18) .foregroundStyle(.secondary) .frame(maxWidth: .infinity, alignment: .trailing) } } } + if viewModel.quantifiedBatchedDryIngredients.count != 0 { + Section(header: CBCDryIngredientSectionHeader()) { + ForEach($viewModel.quantifiedBatchedDryIngredients, id: \.id) { $ingredient in + BatchCellDryIngredientView(quantifiedDryBatchedIngredient: $ingredient) + } + } + } Section { Text("Total Volume: \(viewModel.totalBatchVolume, specifier: "%.0f") ml") @@ -199,6 +204,13 @@ struct CBCIngredientSectionHeader: View { } } +struct CBCDryIngredientSectionHeader: View { + + var body: some View { + Text("Dry ingredient measurements") + } +} + struct CBCIngredientSectionFooter: View { @State var isShowingIngredientSwipeInfo = false diff --git a/MetaCocktailsSwiftData/Views/CocktailBatchingCalculator/CBCMainView/EditBatchModalView.swift b/MetaCocktailsSwiftData/Views/CocktailBatchingCalculator/CBCMainView/EditBatchModalView.swift index 75e927f8..512a48f3 100644 --- a/MetaCocktailsSwiftData/Views/CocktailBatchingCalculator/CBCMainView/EditBatchModalView.swift +++ b/MetaCocktailsSwiftData/Views/CocktailBatchingCalculator/CBCMainView/EditBatchModalView.swift @@ -20,6 +20,9 @@ struct EditBatchModalView: View { ForEach($viewModel.loadedCocktailData.ingredients, id: \.ingredient.ingredientBase.name) { ingredient in LoadedCocktailIngredientCell(ingredient: ingredient) } + ForEach($viewModel.loadedDryIngredients.ingredients, id: \.ingredient.ingredientBase.name) { ingredient in + LoadedCocktailIngredientCell(ingredient: ingredient) + } } .padding(.horizontal) Section(header: FontFactory.mediumText("Measurement Volume Options", size: 20)) { diff --git a/MetaCocktailsSwiftData/Views/CocktailBatchingCalculator/CBCMainView/SubViews/BatchCellDryIngredientView.swift b/MetaCocktailsSwiftData/Views/CocktailBatchingCalculator/CBCMainView/SubViews/BatchCellDryIngredientView.swift new file mode 100644 index 00000000..68fac81b --- /dev/null +++ b/MetaCocktailsSwiftData/Views/CocktailBatchingCalculator/CBCMainView/SubViews/BatchCellDryIngredientView.swift @@ -0,0 +1,38 @@ +// +// BatchCellDryIngredientView.swift +// MetaCocktailsSwiftData +// +// Created by James Menkal on 4/28/25. +// + + +import SwiftUI + +struct BatchCellDryIngredientView: View { + @EnvironmentObject var viewModel: CBCViewModel + @Binding var quantifiedDryBatchedIngredient: DryBatchedCellData + + var body: some View { + VStack { + HStack { + Text(quantifiedDryBatchedIngredient.dryIngredientName) + .font(FontFactory.formLabel18) + .foregroundStyle(.primary) + + Spacer() + + Text(viewModel.formattedDryIngredientAmount(for: quantifiedDryBatchedIngredient.dryIngredientName)) + .font(FontFactory.formLabel18) + .multilineTextAlignment(.trailing) + .background(.clear) + } + } + } +} + +#Preview { + @Previewable @State var quantifiedDryBatchedIngredient: DryBatchedCellData = DryBatchedCellData(dryIngredientName: "Test", dryIngredientAmount: 2.0, unitName: MeasurementUnit.grams.rawValue) + + BatchCellDryIngredientView(quantifiedDryBatchedIngredient: $quantifiedDryBatchedIngredient) + .environmentObject(CBCViewModel()) +} diff --git a/MetaCocktailsSwiftData/Views/CocktailBatchingCalculator/CBCMainView/SubViews/BatchCellView.swift b/MetaCocktailsSwiftData/Views/CocktailBatchingCalculator/CBCMainView/SubViews/BatchCellView.swift index a297e41f..2847f5bd 100644 --- a/MetaCocktailsSwiftData/Views/CocktailBatchingCalculator/CBCMainView/SubViews/BatchCellView.swift +++ b/MetaCocktailsSwiftData/Views/CocktailBatchingCalculator/CBCMainView/SubViews/BatchCellView.swift @@ -5,6 +5,7 @@ // Created by James Menkal on 5/30/24. // + import SwiftUI struct BatchCellView: View { @@ -17,18 +18,14 @@ struct BatchCellView: View { @State private var isShowingBottleMathModal: Bool = false var body: some View { - VStack { - HStack { - Text(quantifiedBatchedIngredient.ingredientName) .font(FontFactory.formLabel18) .foregroundStyle(.primary) Spacer() editableMlView(quantifiedBatchedIngredient: $quantifiedBatchedIngredient, isFocused: _isFocused) - } if isShowingOunceMeasurements { @@ -49,7 +46,6 @@ struct BatchCellView: View { .font(FontFactory.fontBody16) .foregroundStyle(.secondary) } - } .frame(maxWidth: .infinity, alignment: .trailing) } @@ -68,16 +64,17 @@ struct BatchCellView: View { isShowingBottleMathModal: $isShowingBottleMathModal, keyboardFocused: _isFocused) } + .id("\(quantifiedBatchedIngredient.id)-\(quantifiedBatchedIngredient.totalMls)") } } struct editableMlView: View { @EnvironmentObject var viewModel: CBCViewModel @Binding var quantifiedBatchedIngredient: BottleBatchedCellData - @FocusState var isFocused: Bool + @FocusState var isFocused: Bool + var body: some View { if viewModel.editingIngredient == quantifiedBatchedIngredient.ingredientName { - TextField("\(quantifiedBatchedIngredient.totalMls)", text: $quantifiedBatchedIngredient.editedTotalMls) .font(FontFactory.formLabel18) .tint(ColorScheme.interactionTint) @@ -85,18 +82,21 @@ struct editableMlView: View { .keyboardType(.numberPad) .background(.clear) .focused($isFocused) + .onAppear { + if quantifiedBatchedIngredient.editedTotalMls.isEmpty { + quantifiedBatchedIngredient.editedTotalMls = "\(quantifiedBatchedIngredient.totalMls)" + } + isFocused = true + } } else { - - Text("\(quantifiedBatchedIngredient.totalMls) ml") .font(FontFactory.mediumFont(size: 18)) .foregroundStyle(ColorScheme.interactionTint) .background(.clear) .onTapGesture { - quantifiedBatchedIngredient.editedTotalMls = String(quantifiedBatchedIngredient.totalMls) + quantifiedBatchedIngredient.editedTotalMls = "\(quantifiedBatchedIngredient.totalMls)" viewModel.updateEditingIngredient(name: quantifiedBatchedIngredient.ingredientName) isFocused = true - quantifiedBatchedIngredient.editedTotalMls = "" } } } diff --git a/MetaCocktailsSwiftData/Views/CocktailBatchingCalculator/CBCViewModel/CBCViewModel.swift b/MetaCocktailsSwiftData/Views/CocktailBatchingCalculator/CBCViewModel/CBCViewModel.swift index 06d761a8..a5509402 100644 --- a/MetaCocktailsSwiftData/Views/CocktailBatchingCalculator/CBCViewModel/CBCViewModel.swift +++ b/MetaCocktailsSwiftData/Views/CocktailBatchingCalculator/CBCViewModel/CBCViewModel.swift @@ -8,22 +8,24 @@ import SwiftUI import SwiftData import Combine +import Observation -final class CBCViewModel: ObservableObject { +@Observable final class CBCViewModel: ObservableObject { ///CBCMainView variables - @Published var dilutionPercentage = 25.0 - @Published var numberOfCocktailsText: Double = 100.0 - @Published var isShowingBottleMathMode: Bool = false + var dilutionPercentage = 25.0 + var numberOfCocktailsText: Double = 100.0 + var isShowingBottleMathMode: Bool = false - @Published var editingIngredient: String? - @Published var numberOfBottlesText: String? - @Published var sizeOfTheBottle: String? - @Published var editingBottleMathIngredient: BottleBatchedCellData? - //@Published var totalCocktailABVPercentage = 0.0 - @Published var loadedCocktailData: CBCLoadedCocktailData = CBCLoadedCocktailData(cocktailName: "Test", ingredients: []) - @Published var unitConversion: [MeasurementUnit: Double] = [ + var editingIngredient: String? + var numberOfBottlesText: String? + var sizeOfTheBottle: String? + var editingBottleMathIngredient: BottleBatchedCellData? + var totalCocktailABVPercentage = 0.0 + var loadedCocktailData: CBCLoadedCocktailData = CBCLoadedCocktailData(cocktailName: "Test", ingredients: []) + var loadedDryIngredients: CBCLoadedCocktailData = CBCLoadedCocktailData(cocktailName: "Test", ingredients: []) + var unitConversion: [MeasurementUnit: Double] = [ .barSpoon: 0.17, .teaspoon: 0.17, .splash: 0.17, @@ -37,18 +39,20 @@ final class CBCViewModel: ObservableObject { .fluidOunces: 1.0 ] ///Main batch view variables - @Published var totalDilutionVolume = 0.0 - @Published var totalBatchVolume = 0.0 - @Published var quantifiedBatchedIngredients: [BottleBatchedCellData] = [] - @Published var chosenCocktail: Cocktail = DummyCocktails.randomCocktail() + var totalDilutionVolume = 0.0 + var totalBatchVolume = 0.0 + var quantifiedBatchedIngredients: [BottleBatchedCellData] = [] + var quantifiedBatchedDryIngredients: [DryBatchedCellData] = [] + var chosenCocktail: Cocktail = DummyCocktails.randomCocktail() ///Split Batch View - @Published var containerSize = 4000 - @Published var numberOfContainers = 2 - @Published var splitBatchData: [SplitBatchCellData] = [] - @Published var containerSizeLabel = "4 Liter" - @Published var groupedContainerSizes: [(label: String, volume: Int)] = [] - @Published var containerSizes: [(label: String, volume: Int)] = [] + var containerSize = 4000 + var numberOfContainers = 2 + var splitBatchData: [SplitBatchCellData] = [] + var containerSizeLabel = "4 Liter" + var groupedContainerSizes: [(label: String, volume: Int)] = [] + var containerSizes: [(label: String, volume: Int)] = [] + var formatter: NumberFormatter = { let formatter = NumberFormatter() @@ -70,6 +74,22 @@ final class CBCViewModel: ObservableObject { containerSizes.append((label: lastLabel, volume: size)) } + func dynamicallyChangeDryIngredientBatchUnit(for unit: String) -> String { + var nameToReturn = unit + + if unit == MeasurementUnit.grams.rawValue { + nameToReturn = "grams" + } + if unit == MeasurementUnit.sliceOf.rawValue { + nameToReturn = "slices" + } + if unit == MeasurementUnit.whole.rawValue { + nameToReturn = "" + } + + return nameToReturn + } + func groupContainerSizes() { makeDynamicContainerSizes() @@ -123,6 +143,7 @@ final class CBCViewModel: ObservableObject { //Theoretically, this will never get returned. return (label: "Error", volume: 0) } + objectWillChange.send() } func findIndexForBottleMath() -> Int { @@ -153,7 +174,6 @@ final class CBCViewModel: ObservableObject { containerSizeLabel = label } convertIngredientsToBatchCellData() - doSplitBatchMath() } func getIngredientMeasurement(for batchCellData: BottleBatchedCellData) -> (value: Double, unit: MeasurementUnit)? { if let foundIngredient = chosenCocktail.spec.first(where: { $0.ingredientBase.name == batchCellData.ingredientName }) { @@ -187,6 +207,7 @@ final class CBCViewModel: ObservableObject { func convertIngredientsToBatchCellData() { var quantifiableIngredients = [BottleBatchedCellData]() + var quantifiableDryIngredients = [DryBatchedCellData]() var totalVolume = 0.0 @@ -212,10 +233,22 @@ final class CBCViewModel: ObservableObject { )) } } + for dryIngredient in loadedDryIngredients.ingredients { + if dryIngredient.isIncluded { + let existingDryIngredient = quantifiedBatchedDryIngredients.first { + $0.dryIngredientName == dryIngredient.ingredient.ingredientBase.name + } + + quantifiableDryIngredients.append(DryBatchedCellData(id: existingDryIngredient?.id ?? UUID(), + dryIngredientName: dryIngredient.ingredient.ingredientBase.name, + dryIngredientAmount: dryIngredient.ingredient.value * numberOfCocktailsText, + unitName: dynamicallyChangeDryIngredientBatchUnit(for: dryIngredient.ingredient.unit.rawValue))) + } + } totalDilutionVolume = totalVolume * (dilutionPercentage / 100.0) totalBatchVolume = totalVolume + totalDilutionVolume - numberOfContainers = Int(ceil(totalBatchVolume / (Double(containerSize) * 0.9))) + numberOfContainers = getContainerCount(for: containerSize) // recalculate bottle sizes and remaining mls for (index, ingredient) in quantifiableIngredients.enumerated() { @@ -226,7 +259,12 @@ final class CBCViewModel: ObservableObject { quantifiableIngredients[index].remainingMls = totalMls % existingIngredient.bottleSize } } + + quantifiedBatchedDryIngredients = quantifiableDryIngredients quantifiedBatchedIngredients = quantifiableIngredients + + doSplitBatchMath() + objectWillChange.send() } @@ -243,6 +281,41 @@ final class CBCViewModel: ObservableObject { convertIngredientsToBatchCellData() } } + func calculateDryIngredientAmount(for dryIngredientName: String) -> Double { + + if let originalIngredient = loadedDryIngredients.ingredients.first(where: { + $0.ingredient.ingredientBase.name == dryIngredientName + }) { + return originalIngredient.ingredient.value * numberOfCocktailsText + } + + if let calculatedIngredient = quantifiedBatchedDryIngredients.first(where: { + $0.dryIngredientName == dryIngredientName + }) { + return calculatedIngredient.dryIngredientAmount + } + return 0.0 + } + + func formattedDryIngredientAmount(for dryIngredientName: String, withUnit: Bool = true) -> String { + let amount = calculateDryIngredientAmount(for: dryIngredientName) + let roundedAmount = Int(amount.rounded()) + + if withUnit { + if let dryIngredient = quantifiedBatchedDryIngredients.first(where: { + $0.dryIngredientName == dryIngredientName + }) { + return "\(roundedAmount) \(dryIngredient.unitName)" + } + return "\(roundedAmount)" + } else { + return "\(roundedAmount)" + } + } + + func findDilutionInFluidOunces() -> Double { + return totalDilutionVolume / mlToOzConversionFactor + } func doMathForModified1LBottleCount(initialAmount: Double, newQuantityAmount: Double) { @@ -260,6 +333,8 @@ final class CBCViewModel: ObservableObject { func convertLoadedCocktail(for cocktail: Cocktail) { var newLoadedCocktailData = CBCLoadedCocktailData(cocktailName: cocktail.cocktailName, ingredients: []) + var newDryIngredients = CBCLoadedCocktailData(cocktailName: cocktail.cocktailName, ingredients: []) + for spec in cocktail.spec { if UmbrellaCategory(rawValue: spec.ingredientBase.umbrellaCategory) != .herbs && UmbrellaCategory(rawValue: spec.ingredientBase.umbrellaCategory) != .fruit @@ -268,22 +343,32 @@ final class CBCViewModel: ObservableObject { && spec.unit != .pinch { newLoadedCocktailData.ingredients.append(CBCLoadedIngredient(ingredient: spec, isIncluded: true)) } + if UmbrellaCategory(rawValue: spec.ingredientBase.umbrellaCategory) == .herbs + || UmbrellaCategory(rawValue: spec.ingredientBase.umbrellaCategory) == .fruit || UmbrellaCategory(rawValue: spec.ingredientBase.umbrellaCategory) == .otherNonAlc { if spec.unit == .whole || spec.unit == .grams || spec.unit == .sliceOf { + newDryIngredients.ingredients.append(CBCLoadedIngredient(ingredient: spec, isIncluded: true)) + } + } } - + loadedDryIngredients = newDryIngredients loadedCocktailData = newLoadedCocktailData + convertIngredientsToBatchCellData() } func doSplitBatchMath() { var splitData: [SplitBatchCellData] = [] for ingredient in quantifiedBatchedIngredients { - splitData.append(SplitBatchCellData(ingredientName: ingredient.ingredientName, splitIngredientAmount: Int(ingredient.totalMls / numberOfContainers))) + splitData.append(SplitBatchCellData(ingredientName: ingredient.ingredientName, + splitIngredientAmount: Int(ingredient.totalMls / numberOfContainers))) } - splitData.append(SplitBatchCellData(ingredientName: "Dilution", splitIngredientAmount: (Int(totalDilutionVolume) / numberOfContainers))) - splitBatchData = splitData + splitData.append(SplitBatchCellData(ingredientName: "Dilution", + splitIngredientAmount: (Int(totalDilutionVolume) / numberOfContainers))) + splitBatchData = splitData + objectWillChange.send() } func updateEditingIngredient(name: String) { editingIngredient = name + objectWillChange.send() } @@ -298,6 +383,7 @@ final class CBCViewModel: ObservableObject { } } editingIngredient = nil + objectWillChange.send() } } @@ -319,6 +405,31 @@ struct CBCLoadedIngredient { var isIncluded: Bool } +struct DryBatchedCellData: Hashable, Equatable, Identifiable { + + let id: UUID + var dryIngredientName: String + var dryIngredientAmount: Double + var unitName: String + + + init(id: UUID = UUID(), dryIngredientName: String, dryIngredientAmount: Double, unitName: String) { + self.id = id + self.dryIngredientName = dryIngredientName + self.dryIngredientAmount = dryIngredientAmount + self.unitName = unitName + + } + + static func == (lhs: DryBatchedCellData, rhs: DryBatchedCellData) -> Bool { + return lhs.dryIngredientName == rhs.dryIngredientName + } + + func hash(into hasher: inout Hasher) { + hasher.combine(dryIngredientName) + } +} + struct BottleBatchedCellData: Hashable, Equatable, Identifiable { let id: UUID var ingredientName: String diff --git a/MetaCocktailsSwiftData/Views/CreateACocktailView/AddCocktailViewModel.swift b/MetaCocktailsSwiftData/Views/CreateACocktailView/AddCocktailViewModel.swift index d38178aa..420c5cf2 100644 --- a/MetaCocktailsSwiftData/Views/CreateACocktailView/AddCocktailViewModel.swift +++ b/MetaCocktailsSwiftData/Views/CreateACocktailView/AddCocktailViewModel.swift @@ -202,41 +202,25 @@ import Combine } func addIngredientToCocktailBuild(ingredients: [IngredientBase]) { - if ingredientIsValid(allIngredients: ingredients) { - - if isEdit && didChooseExistingIngredient { - updateEditedIngredient(isCustom: false) - } - if isEdit && !didChooseExistingIngredient { - updateEditedIngredient(isCustom: true) - } - - if !isEdit && didChooseExistingIngredient { - if let ingredientValue = ingredientAmount{ - let ingredient = Ingredient(ingredientBase: IngredientBase(name: ingredientName, - category: category, - prep: prep), - value: ingredientValue, - unit: selectedMeasurementUnit) - - addedIngredients.append(ingredient) - } - } - if !isEdit && !didChooseExistingIngredient { - if !prepIngredientRecipe.isEmpty { - prep = Prep(prepIngredientName: ingredientName, prepRecipe: prepIngredientRecipe) - } - if let ingredientValue = ingredientAmount { - addedIngredients.append(Ingredient(ingredientBase: IngredientBase(name: ingredientName, - category: category, - prep: prep, - isCustom: true), - value: ingredientValue, - unit: selectedMeasurementUnit)) - } - } - clearIngredientData() + guard ingredientIsValid(allIngredients: ingredients) else { return } + + switch (isEdit, didChooseExistingIngredient) { + case (true, true): + updateEditedIngredient(isCustom: false) + case (true, false): + updateEditedIngredient(isCustom: true) + case (false, true): + guard let ingredientValue = ingredientAmount else { return } + let ingredientBase = IngredientBase(name: ingredientName, category: category, prep: prep) + addedIngredients.append(Ingredient(ingredientBase: ingredientBase, value: ingredientValue, unit: selectedMeasurementUnit)) + case (false, false): + guard let ingredientValue = ingredientAmount else { return } + let prep = prepIngredientRecipe.isEmpty ? nil : Prep(prepIngredientName: ingredientName, prepRecipe: prepIngredientRecipe) + let ingredientBase = IngredientBase(name: ingredientName, category: category, prep: prep, isCustom: true) + addedIngredients.append(Ingredient(ingredientBase: ingredientBase, value: ingredientValue, unit: selectedMeasurementUnit)) } + + clearIngredientData() } @MainActor @@ -509,7 +493,7 @@ import Combine case .seasoning: return [.pinch, .drops, .dashes, .barSpoon, .teaspoon, .tablespoon] case .otherNonAlc: - return standardMeasurements + return [.fluidOunces, .barSpoon, .dashes, .drops, .ml, .sprays, .teaspoon, .tablespoon, .bottles, .oneLiterBottle, .whole] default: return standardMeasurements } diff --git a/MetaCocktailsSwiftData/Views/CreateACocktailView/SubViews/AddIngredient/CustomIngredient/CategoryPickerView.swift b/MetaCocktailsSwiftData/Views/CreateACocktailView/SubViews/AddIngredient/CustomIngredient/CategoryPickerView.swift index 2f3c067b..74e683f1 100644 --- a/MetaCocktailsSwiftData/Views/CreateACocktailView/SubViews/AddIngredient/CustomIngredient/CategoryPickerView.swift +++ b/MetaCocktailsSwiftData/Views/CreateACocktailView/SubViews/AddIngredient/CustomIngredient/CategoryPickerView.swift @@ -11,27 +11,25 @@ struct CategoryPickerView: View { @Bindable var viewModel: AddCocktailViewModel var body: some View { Section(header: Text("Category").font(FontFactory.sectionHeader12)) { - HStack{ - Menu { - ForEach(UmbrellaCategory.allCases, id: \.self) { category in - - Button("\(category.rawValue)") { - viewModel.category = category - viewModel.dynamicallyChangeMeasurementUnit() - } - } - } label: { - HStack{ - Text(viewModel.category.rawValue) - .font(FontFactory.formLabel18) - Image(systemName: "chevron.down") - .foregroundStyle(.gray) - Spacer() - + Menu { + ForEach(UmbrellaCategory.allCases, id: \.self) { category in + + Button(category.rawValue) { + viewModel.category = category + viewModel.dynamicallyChangeMeasurementUnit() } } - .tint(.primary) + } label: { + HStack{ + Text(viewModel.category.rawValue) + .font(FontFactory.formLabel18) + Image(systemName: "chevron.down") + .foregroundStyle(.gray) + Spacer() + + } } + .tint(.primary) } } } diff --git a/MetaCocktailsSwiftData/Views/Recipe View/RecipeFrontView.swift b/MetaCocktailsSwiftData/Views/Recipe View/RecipeFrontView.swift index 8356dd72..b0e960a1 100644 --- a/MetaCocktailsSwiftData/Views/Recipe View/RecipeFrontView.swift +++ b/MetaCocktailsSwiftData/Views/Recipe View/RecipeFrontView.swift @@ -76,7 +76,7 @@ struct RecipeFlipCardView: View { .allowsHitTesting(!viewModel.isFlipped) .background(BlackGlassBackgroundView()) .task { - showSpecInMl = viewModel.findIntendedMeasurementUnit() + showSpecInMl = viewModel.shouldDisplayRecipeInMls() } GeometryReader { innerGeo in diff --git a/MetaCocktailsSwiftData/Views/Recipe View/RecipeViewModel.swift b/MetaCocktailsSwiftData/Views/Recipe View/RecipeViewModel.swift index 9fc21534..a3f8df09 100644 --- a/MetaCocktailsSwiftData/Views/Recipe View/RecipeViewModel.swift +++ b/MetaCocktailsSwiftData/Views/Recipe View/RecipeViewModel.swift @@ -48,16 +48,8 @@ import Observation } } - func findIntendedMeasurementUnit() -> Bool { - for ingredient in cocktail.spec { - if ingredient.unit == .fluidOunces { - return false - } - if ingredient.unit == .ml { - return true - } - } - return false + func shouldDisplayRecipeInMls() -> Bool { + cocktail.spec.contains(where: { $0.unit == .ml }) ? true : false } func getMethodText(cocktail: Cocktail) -> String? { diff --git a/MetaCocktailsSwiftData/Views/Subviews/Cells/LoadedCocktailIngredientCell.swift b/MetaCocktailsSwiftData/Views/Subviews/Cells/LoadedCocktailIngredientCell.swift index 47f1c4ba..db440288 100644 --- a/MetaCocktailsSwiftData/Views/Subviews/Cells/LoadedCocktailIngredientCell.swift +++ b/MetaCocktailsSwiftData/Views/Subviews/Cells/LoadedCocktailIngredientCell.swift @@ -29,6 +29,7 @@ struct LoadedCocktailIngredientCell: View { } } + #Preview { LoadedCocktailIngredientCell(ingredient: .constant(CBCLoadedIngredient(ingredient: Ingredient(ingredientBase: IngredientBase(name: "Lemon Juice", category: .juices, prep: nil), value: 0.75, unit: .fluidOunces), isIncluded: true))) }