From 48d3da19643ab822d6e18935478a1b153436eaad Mon Sep 17 00:00:00 2001 From: VincentMeilinger Date: Wed, 24 Jan 2024 19:23:59 +0100 Subject: [PATCH] Improved Grocery List --- .../UserInterfaceState.xcuserstate | Bin 68056 -> 65328 bytes .../Localizable.xcstrings | 3 + .../Views/MainView.swift | 11 +- .../Views/RecipeDetailView.swift | 31 ++- .../Views/Tabs/GroceryListTabView.swift | 211 +++++++++++++----- 5 files changed, 189 insertions(+), 67 deletions(-) diff --git a/Nextcloud Cookbook iOS Client.xcodeproj/project.xcworkspace/xcuserdata/vincie.xcuserdatad/UserInterfaceState.xcuserstate b/Nextcloud Cookbook iOS Client.xcodeproj/project.xcworkspace/xcuserdata/vincie.xcuserdatad/UserInterfaceState.xcuserstate index 432e8fb97725d96c2b51a4c489219df6c76375e7..6493ce8239807a086e54a5fa7656b260929c83be 100644 GIT binary patch delta 30678 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 delta 32577 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 Void @State var isSelected: Bool = false @State private var dragOffset: CGFloat = 0 let maxDragDistance = 30.0 var body: some View { HStack(alignment: .top) { - if dragOffset > 0 { - Image(systemName: "storefront") - .padding(2) - .background(Color.green) - .opacity((dragOffset - 10)/(maxDragDistance-10)) - } if isSelected { Image(systemName: "checkmark.circle") } else { @@ -432,11 +432,11 @@ fileprivate struct IngredientListItem: View { .onChanged { gesture in // Update drag offset as the user drags let dragAmount = gesture.translation.width - self.dragOffset = min(dragAmount, maxDragDistance + pow(dragAmount - maxDragDistance, 0.7)) + self.dragOffset = max(0, min(dragAmount, maxDragDistance + pow(dragAmount - maxDragDistance, 0.7))) } .onEnded { gesture in if gesture.translation.width > maxDragDistance * 0.8 { // Swipe right threshold - GroceryList.shared.addItem(ingredient) + addToGroceryListAction() } // Animate back to original position withAnimation { @@ -444,6 +444,17 @@ fileprivate struct IngredientListItem: View { } } ) + .background { + if dragOffset > 0 { + HStack { + Image(systemName: "storefront") + .foregroundStyle(Color.green) + .opacity((dragOffset - 10)/(maxDragDistance-10)) + + Spacer() + } + } + } } } diff --git a/Nextcloud Cookbook iOS Client/Views/Tabs/GroceryListTabView.swift b/Nextcloud Cookbook iOS Client/Views/Tabs/GroceryListTabView.swift index 0074325..6ab5302 100644 --- a/Nextcloud Cookbook iOS Client/Views/Tabs/GroceryListTabView.swift +++ b/Nextcloud Cookbook iOS Client/Views/Tabs/GroceryListTabView.swift @@ -10,58 +10,127 @@ import SwiftUI struct GroceryListTabView: View { + @EnvironmentObject var groceryList: GroceryList + var body: some View { NavigationStack { - if GroceryList.shared.listItems.isEmpty { - List { - Text("You're all set for cooking 🍓") - .font(.title2) - .foregroundStyle(.secondary) - Text("Add groceries to this list by either using the button next to an ingredient list in a recipe, or by swiping right on individual ingredients of a recipe.") - - .foregroundStyle(.secondary) - } - .padding() - .navigationTitle("Grocery List") + if groceryList.groceryDict.isEmpty { + EmptyGroceryListView() } else { - List(GroceryList.shared.listItems) { item in - HStack(alignment: .top) { - if item.isChecked { - Image(systemName: "checkmark.circle") - } else { - Image(systemName: "circle") + List { + ForEach(groceryList.groceryDict.keys.sorted(), id: \.self) { key in + Section { + ForEach(groceryList.groceryDict[key]!.items) { item in + GroceryListItemView(item: item, toggleAction: { + groceryList.toggleItemChecked(item) + groceryList.objectWillChange.send() + }, deleteAction: { + groceryList.deleteItem(item.name, fromRecipe: key) + withAnimation { + groceryList.objectWillChange.send() + } + }) + } + } header: { + HStack { + Text(groceryList.groceryDict[key]!.name) + .foregroundStyle(Color.nextcloudBlue) + Spacer() + Button { + groceryList.deleteGroceryRecipe(key) + } label: { + Image(systemName: "trash") + .foregroundStyle(Color.nextcloudBlue) + } + } } - - Text("\(item.name)") - .multilineTextAlignment(.leading) - .lineLimit(5) - } - .foregroundStyle(item.isChecked ? Color.secondary : Color.primary) - .onTapGesture { - item.isChecked.toggle() - } - .animation(.easeInOut, value: item.isChecked) - .swipeActions(edge: .trailing, allowsFullSwipe: true) { - Button { - GroceryList.shared.removeItem(item.name) - } label: { - Label("Delete", systemImage: "trash") - } - .tint(.red) } } - .padding() + + .listStyle(.plain) .navigationTitle("Grocery List") + .toolbar { + Button { + groceryList.deleteAll() + } label: { + Text("Delete") + .foregroundStyle(Color.nextcloudBlue) + } + } } - } } } -class GroceryListItem: ObservableObject, Identifiable, Codable { - var name: String +fileprivate struct GroceryListItemView: View { + let item: GroceryRecipeItem + let toggleAction: () -> Void + let deleteAction: () -> Void + + var body: some View { + HStack(alignment: .top) { + if item.isChecked { + Image(systemName: "checkmark.circle") + } else { + Image(systemName: "circle") + } + + Text("\(item.name)") + .multilineTextAlignment(.leading) + .lineLimit(5) + } + .padding(5) + .foregroundStyle(item.isChecked ? Color.secondary : Color.primary) + .onTapGesture(perform: toggleAction) + .animation(.easeInOut, value: item.isChecked) + .swipeActions(edge: .trailing, allowsFullSwipe: true) { + Button(action: deleteAction) { + Label("Delete", systemImage: "trash") + } + .tint(.red) + } + } +} + + + +fileprivate struct EmptyGroceryListView: View { + var body: some View { + List { + Text("You're all set for cooking 🍓") + .font(.headline) + Text("Add groceries to this list by either using the button next to an ingredient list in a recipe, or by swiping right on individual ingredients of a recipe.") + .foregroundStyle(.secondary) + Text("Your grocery list is stored locally and therefore not synchronized across different devices!") + .foregroundStyle(.secondary) + } + .navigationTitle("Grocery List") + } +} + + + +class GroceryRecipe: Identifiable, Codable { + let name: String + var items: [GroceryRecipeItem] + + init(name: String, items: [GroceryRecipeItem]) { + self.name = name + self.items = items + } + + init(name: String, item: GroceryRecipeItem) { + self.name = name + self.items = [item] + } +} + + + +class GroceryRecipeItem: Identifiable, Codable { + let name: String var isChecked: Bool init(_ name: String, isChecked: Bool = false) { @@ -73,46 +142,80 @@ class GroceryListItem: ObservableObject, Identifiable, Codable { class GroceryList: ObservableObject { - static let shared: GroceryList = GroceryList() - let dataStore: DataStore = DataStore() - @Published var listItems: [GroceryListItem] = [] + @Published var groceryDict: [String: GroceryRecipe] = [:] + @Published var sortBySimilarity: Bool = false - func addItem(_ name: String) { - listItems.append(GroceryListItem(name)) - save() + func addItem(_ itemName: String, toRecipe recipeId: String, recipeName: String? = nil, saveGroceryDict: Bool = true) { + print("Adding item of recipe \(String(describing: recipeName))") + DispatchQueue.main.async { + if self.groceryDict[recipeId] != nil { + self.groceryDict[recipeId]?.items.append(GroceryRecipeItem(itemName)) + } else { + let newRecipe = GroceryRecipe(name: recipeName ?? "-", items: [GroceryRecipeItem(itemName)]) + self.groceryDict[recipeId] = newRecipe + } + if saveGroceryDict { + self.save() + self.objectWillChange.send() + } + } } - func addItems(_ items: [String]) { + func addItems(_ items: [String], toRecipe recipeId: String, recipeName: String? = nil) { for item in items { - addItem(item) + addItem(item, toRecipe: recipeId, recipeName: recipeName, saveGroceryDict: false) + } + save() + objectWillChange.send() + } + + func deleteItem(_ itemName: String, fromRecipe recipeId: String) { + print("Deleting item \(itemName)") + guard let recipe = groceryDict[recipeId] else { return } + guard let itemIndex = groceryDict[recipeId]?.items.firstIndex(where: { $0.name == itemName }) else { return } + groceryDict[recipeId]?.items.remove(at: itemIndex) + if groceryDict[recipeId]!.items.isEmpty { + groceryDict.removeValue(forKey: recipeId) } save() } - func removeItem(_ name: String) { - guard let ix = listItems.firstIndex(where: { item in - item.name == name - }) else { return } - listItems.remove(at: ix) + func deleteGroceryRecipe(_ recipeId: String) { + print("Deleting grocery recipe with id \(recipeId)") + groceryDict.removeValue(forKey: recipeId) + save() + } + + func deleteAll() { + print("Deleting all grocery items") + groceryDict = [:] + save() + } + + func toggleItemChecked(_ groceryItem: GroceryRecipeItem) { + print("Item checked: \(groceryItem.name)") + groceryItem.isChecked.toggle() save() } func save() { Task { - await dataStore.save(data: listItems, toPath: "grocery_list.data") + await dataStore.save(data: groceryDict, toPath: "grocery_list.data") } } func load() async { do { - guard let listItems: [GroceryListItem] = try await dataStore.load( + guard let groceryDict: [String: GroceryRecipe] = try await dataStore.load( fromPath: "grocery_list.data" ) else { return } - self.listItems = listItems + self.groceryDict = groceryDict } catch { print("Unable to load grocery list") } } } + +