@@ -50,6 +50,7 @@ final class CarbEntryViewModel: ObservableObject {
5050 @Published var selectedDefaultAbsorptionTimeEmoji : String = " "
5151 @Published var usesCustomFoodType = false
5252 @Published var absorptionTimeWasEdited = false // if true, selecting an emoji will not alter the absorption time
53+ private var absorptionEditIsProgrammatic = false // needed for when absorption time is changed due to favorite food selection, so that absorptionTimeWasEdited does not get set to true
5354
5455 @Published var absorptionTime : TimeInterval
5556 let defaultAbsorptionTimes : CarbStore . DefaultAbsorptionTimes
@@ -59,6 +60,9 @@ final class CarbEntryViewModel: ObservableObject {
5960 return minAbsorptionTime... maxAbsorptionTime
6061 }
6162
63+ @Published var favoriteFoods = UserDefaults . standard. favoriteFoods
64+ @Published var selectedFavoriteFoodIndex = - 1
65+
6266 weak var delegate : CarbEntryViewModelDelegate ?
6367
6468 private lazy var cancellables = Set < AnyCancellable > ( )
@@ -71,6 +75,8 @@ final class CarbEntryViewModel: ObservableObject {
7175 self . shouldBeginEditingQuantity = true
7276
7377 observeAbsorptionTimeChange ( )
78+ observeFavoriteFoodChange ( )
79+ observeFavoriteFoodIndexChange ( )
7480 }
7581
7682 /// Initalizer for when`CarbEntryView` has an entry to edit
@@ -89,6 +95,7 @@ final class CarbEntryViewModel: ObservableObject {
8995 }
9096
9197 var originalCarbEntry : StoredCarbEntry ? = nil
98+ private var favoriteFood : FavoriteFood ? = nil
9299
93100 private var updatedCarbEntry : NewCarbEntry ? {
94101 if let quantity = carbsQuantity, quantity != 0 {
@@ -111,7 +118,7 @@ final class CarbEntryViewModel: ObservableObject {
111118
112119 var saveFavoriteFoodButtonDisabled : Bool {
113120 get {
114- if let carbsQuantity, 0 ... maxCarbEntryQuantity. doubleValue ( for: preferredCarbUnit) ~= carbsQuantity, foodType != " " {
121+ if let carbsQuantity, 0 ... maxCarbEntryQuantity. doubleValue ( for: preferredCarbUnit) ~= carbsQuantity, foodType != " " , selectedFavoriteFoodIndex == - 1 {
115122 return false
116123 }
117124 return true
@@ -142,7 +149,7 @@ final class CarbEntryViewModel: ObservableObject {
142149 self . alert = . maxQuantityExceded
143150 return
144151 }
145- else if quantity. compare ( warningCarbEntryQuantity) == . orderedDescending {
152+ else if quantity. compare ( warningCarbEntryQuantity) == . orderedDescending, selectedFavoriteFoodIndex == - 1 {
146153 self . alert = . warningQuantityValidation
147154 return
148155 }
@@ -181,13 +188,64 @@ final class CarbEntryViewModel: ObservableObject {
181188 }
182189 }
183190
191+ // MARK: - Favorite Foods
192+ func onFavoriteFoodSave( _ food: NewFavoriteFood ) {
193+ let newStoredFood = StoredFavoriteFood ( name: food. name, carbsQuantity: food. carbsQuantity, foodType: food. foodType, absorptionTime: food. absorptionTime)
194+ favoriteFoods. append ( newStoredFood)
195+ selectedFavoriteFoodIndex = favoriteFoods. count - 1
196+ }
197+
198+ private func observeFavoriteFoodIndexChange( ) {
199+ $selectedFavoriteFoodIndex
200+ . receive ( on: RunLoop . main)
201+ . dropFirst ( )
202+ . sink { [ weak self] index in
203+ self ? . favoriteFoodSelected ( at: index)
204+ }
205+ . store ( in: & cancellables)
206+ }
207+
208+ private func observeFavoriteFoodChange( ) {
209+ $favoriteFoods
210+ . dropFirst ( )
211+ . removeDuplicates ( )
212+ . sink { newValue in
213+ UserDefaults . standard. favoriteFoods = newValue
214+ }
215+ . store ( in: & cancellables)
216+ }
217+
218+ private func favoriteFoodSelected( at index: Int ) {
219+ self . absorptionEditIsProgrammatic = true
220+ if index == - 1 {
221+ self . carbsQuantity = 0
222+ self . foodType = " "
223+ self . absorptionTime = defaultAbsorptionTimes. medium
224+ self . absorptionTimeWasEdited = false
225+ self . usesCustomFoodType = false
226+ }
227+ else {
228+ let food = favoriteFoods [ index]
229+ self . carbsQuantity = food. carbsQuantity. doubleValue ( for: preferredCarbUnit)
230+ self . foodType = food. foodType
231+ self . absorptionTime = food. absorptionTime
232+ self . absorptionTimeWasEdited = true
233+ self . usesCustomFoodType = true
234+ }
235+ }
236+
184237 // MARK: - Utility
185238 private func observeAbsorptionTimeChange( ) {
186239 $absorptionTime
187240 . receive ( on: RunLoop . main)
188241 . dropFirst ( )
189242 . sink { [ weak self] _ in
190- self ? . absorptionTimeWasEdited = true
243+ if self ? . absorptionEditIsProgrammatic == true {
244+ self ? . absorptionEditIsProgrammatic = false
245+ }
246+ else {
247+ self ? . absorptionTimeWasEdited = true
248+ }
191249 }
192250 . store ( in: & cancellables)
193251 }
0 commit comments