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 86fd1e2..2ece18d 100644 Binary files a/Nextcloud Cookbook iOS Client.xcodeproj/project.xcworkspace/xcuserdata/vincie.xcuserdatad/UserInterfaceState.xcuserstate and b/Nextcloud Cookbook iOS Client.xcodeproj/project.xcworkspace/xcuserdata/vincie.xcuserdatad/UserInterfaceState.xcuserstate differ diff --git a/Nextcloud Cookbook iOS Client/AppState.swift b/Nextcloud Cookbook iOS Client/AppState.swift index 11da792..a31b2e1 100644 --- a/Nextcloud Cookbook iOS Client/AppState.swift +++ b/Nextcloud Cookbook iOS Client/AppState.swift @@ -170,6 +170,9 @@ import UIKit } var allRecipes: [Recipe] = [] for category in categories { + if self.recipes[category.name] == nil { + await getCategory(named: category.name, fetchMode: .preferLocal) + } if let recipeArray = self.recipes[category.name] { allRecipes.append(contentsOf: recipeArray) } diff --git a/Nextcloud Cookbook iOS Client/Localizable.xcstrings b/Nextcloud Cookbook iOS Client/Localizable.xcstrings index 9df0669..75d148e 100644 --- a/Nextcloud Cookbook iOS Client/Localizable.xcstrings +++ b/Nextcloud Cookbook iOS Client/Localizable.xcstrings @@ -485,7 +485,6 @@ } }, "Add" : { - "extractionState" : "stale", "localizations" : { "de" : { "stringUnit" : { @@ -3832,6 +3831,28 @@ } } }, + "To add grocieries manually, type them in the box below and press the button. To add multiple items at once, separate them by a new line." : { + "localizations" : { + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Durch das Feld unten können Einkäufe manuell hinzugefügt werden. Durch Zeilenumbrüche können mehrere Artikel auf einmal hinzugefügt werden." + } + }, + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Para añadir comestibles manualmente, escríbelos en el cuadro de abajo y pulsa el botón.\nPara añadir varios artículos a la vez, sepáralos con una nueva línea." + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Pour ajouter des courses manuellement, tape-les dans la case ci-dessous et appuie sur le bouton.\nPour ajouter plusieurs articles à la fois, sépare-les par un saut de ligne." + } + } + } + }, "Tool" : { "localizations" : { "de" : { diff --git a/Nextcloud Cookbook iOS Client/Views/Recipes/RecipeViewSections/RecipeGenericViews.swift b/Nextcloud Cookbook iOS Client/Views/Recipes/RecipeViewSections/RecipeGenericViews.swift index 5ada0c2..d64c840 100644 --- a/Nextcloud Cookbook iOS Client/Views/Recipes/RecipeViewSections/RecipeGenericViews.swift +++ b/Nextcloud Cookbook iOS Client/Views/Recipes/RecipeViewSections/RecipeGenericViews.swift @@ -53,7 +53,7 @@ struct EditableText: View { .textFieldStyle(.roundedBorder) .lineLimit(lineLimit) } else { - Text(text) + Text(ObservableRecipeDetail.applyMarkdownStyling(text)) } } } diff --git a/Nextcloud Cookbook iOS Client/Views/Tabs/GroceryListTabView.swift b/Nextcloud Cookbook iOS Client/Views/Tabs/GroceryListTabView.swift index b3ece9a..b78cea9 100644 --- a/Nextcloud Cookbook iOS Client/Views/Tabs/GroceryListTabView.swift +++ b/Nextcloud Cookbook iOS Client/Views/Tabs/GroceryListTabView.swift @@ -11,13 +11,34 @@ import SwiftUI struct GroceryListTabView: View { @EnvironmentObject var groceryList: GroceryList + @State var newGroceries: String = "" var body: some View { NavigationStack { if groceryList.groceryDict.isEmpty { - EmptyGroceryListView() + EmptyGroceryListView(newGroceries: $newGroceries) } else { List { + HStack(alignment: .top) { + TextEditor(text: $newGroceries) + .padding(4) + .overlay(RoundedRectangle(cornerRadius: 8) + .stroke(Color.secondary).opacity(0.5)) + Button { + if !newGroceries.isEmpty { + let items = newGroceries + .split(separator: "\n") + .compactMap { $0.trimmingCharacters(in: .whitespacesAndNewlines) } + .filter { !$0.isEmpty } + groceryList.addItems(items, toRecipe: "Other", recipeName: String(localized: "Other")) + } + newGroceries = "" + } label: { + Text("Add") + } + .buttonStyle(.borderedProminent) + } + ForEach(groceryList.groceryDict.keys.sorted(), id: \.self) { key in Section { ForEach(groceryList.groceryDict[key]!.items) { item in @@ -97,6 +118,9 @@ fileprivate struct GroceryListItemView: View { fileprivate struct EmptyGroceryListView: View { + @EnvironmentObject var groceryList: GroceryList + @Binding var newGroceries: String + var body: some View { List { Text("You're all set for cooking 🍓") @@ -105,6 +129,28 @@ fileprivate struct EmptyGroceryListView: View { .foregroundStyle(.secondary) Text("Your grocery list is stored locally and therefore not synchronized across your devices.") .foregroundStyle(.secondary) + Text("To add grocieries manually, type them in the box below and press the button. To add multiple items at once, separate them by a new line.") + .foregroundStyle(.secondary) + HStack(alignment: .top) { + TextEditor(text: $newGroceries) + .padding(4) + .overlay(RoundedRectangle(cornerRadius: 8) + .stroke(Color.secondary).opacity(0.5)) + Button { + if !newGroceries.isEmpty { + let items = newGroceries + .split(separator: "\n") + .compactMap { $0.trimmingCharacters(in: .whitespacesAndNewlines) } + .filter { !$0.isEmpty } + groceryList.addItems(items, toRecipe: "Other", recipeName: String(localized: "Other")) + } + newGroceries = "" + } label: { + Text("Add") + } + .buttonStyle(.borderedProminent) + } + .padding(.bottom, 4) } .navigationTitle("Grocery List") } @@ -169,7 +215,7 @@ class GroceryRecipeItem: Identifiable, Codable { for item in items { addItem(item, toRecipe: recipeId, recipeName: recipeName, saveGroceryDict: false) } - save() + self.save() objectWillChange.send() }