diff --git a/Nextcloud Cookbook iOS Client.xcodeproj/project.pbxproj b/Nextcloud Cookbook iOS Client.xcodeproj/project.pbxproj index c188138..d7948a5 100644 --- a/Nextcloud Cookbook iOS Client.xcodeproj/project.pbxproj +++ b/Nextcloud Cookbook iOS Client.xcodeproj/project.pbxproj @@ -44,7 +44,6 @@ A7FB0D7A2B25C66600A3469E /* OnboardingView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A7FB0D792B25C66600A3469E /* OnboardingView.swift */; }; A7FB0D7C2B25C68500A3469E /* TokenLoginView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A7FB0D7B2B25C68500A3469E /* TokenLoginView.swift */; }; A7FB0D7E2B25C6A200A3469E /* V2LoginView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A7FB0D7D2B25C6A200A3469E /* V2LoginView.swift */; }; - A90C45F42B9F4DB6005D62B6 /* Units.swift in Sources */ = {isa = PBXBuildFile; fileRef = A90C45F32B9F4DB6005D62B6 /* Units.swift */; }; A97506132B920D9F00E86029 /* RecipeDurationSection.swift in Sources */ = {isa = PBXBuildFile; fileRef = A97506122B920D9F00E86029 /* RecipeDurationSection.swift */; }; A97506152B920DF200E86029 /* RecipeGenericViews.swift in Sources */ = {isa = PBXBuildFile; fileRef = A97506142B920DF200E86029 /* RecipeGenericViews.swift */; }; A97506192B920EC200E86029 /* RecipeIngredientSection.swift in Sources */ = {isa = PBXBuildFile; fileRef = A97506182B920EC200E86029 /* RecipeIngredientSection.swift */; }; @@ -126,7 +125,6 @@ A7FB0D792B25C66600A3469E /* OnboardingView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OnboardingView.swift; sourceTree = ""; }; A7FB0D7B2B25C68500A3469E /* TokenLoginView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TokenLoginView.swift; sourceTree = ""; }; A7FB0D7D2B25C6A200A3469E /* V2LoginView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = V2LoginView.swift; sourceTree = ""; }; - A90C45F32B9F4DB6005D62B6 /* Units.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Units.swift; sourceTree = ""; }; A97506122B920D9F00E86029 /* RecipeDurationSection.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RecipeDurationSection.swift; sourceTree = ""; }; A97506142B920DF200E86029 /* RecipeGenericViews.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RecipeGenericViews.swift; sourceTree = ""; }; A97506182B920EC200E86029 /* RecipeIngredientSection.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RecipeIngredientSection.swift; sourceTree = ""; }; @@ -287,7 +285,6 @@ A70171C52AB4C43A00064C43 /* DataModels.swift */, A97B4D312B80B3E900EC1A88 /* RecipeModels.swift */, A9BBB38F2B91BE31002DA7FF /* ObservableRecipeDetail.swift */, - A90C45F32B9F4DB6005D62B6 /* Units.swift */, ); path = Data; sourceTree = ""; @@ -596,7 +593,6 @@ A7F3F8E82ACBFC760076C227 /* RecipeKeywordSection.swift in Sources */, A79AA8E02AFF80E3007D25F2 /* DurationComponents.swift in Sources */, A70171C02AB498A900064C43 /* RecipeView.swift in Sources */, - A90C45F42B9F4DB6005D62B6 /* Units.swift in Sources */, A79AA8E42B02A962007D25F2 /* CookbookApi.swift in Sources */, A975061B2B920F9F00E86029 /* RecipeNutritionSection.swift in Sources */, A70171CD2AB501B100064C43 /* SettingsView.swift in Sources */, 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 cd5584e..21581c2 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/Data/ObservableRecipeDetail.swift b/Nextcloud Cookbook iOS Client/Data/ObservableRecipeDetail.swift index 75a88c1..bf3ce30 100644 --- a/Nextcloud Cookbook iOS Client/Data/ObservableRecipeDetail.swift +++ b/Nextcloud Cookbook iOS Client/Data/ObservableRecipeDetail.swift @@ -126,13 +126,11 @@ class ObservableRecipeDetail: ObservableObject { var attributedString = AttributedString(ingredient) for (newSubstring, matchRange) in matches { - print(newSubstring, matchRange) guard let range = Range(matchRange, in: attributedString) else { continue } var attributedSubString = AttributedString(newSubstring) //attributedSubString.foregroundColor = .ncTextHighlight attributedSubString.font = .system(.body, weight: .bold) attributedString.replaceSubrange(range, with: attributedSubString) - print("\n", attributedString) } return attributedString diff --git a/Nextcloud Cookbook iOS Client/Data/Units.swift b/Nextcloud Cookbook iOS Client/Data/Units.swift deleted file mode 100644 index de112f5..0000000 --- a/Nextcloud Cookbook iOS Client/Data/Units.swift +++ /dev/null @@ -1,212 +0,0 @@ -// -// Units.swift -// Nextcloud Cookbook iOS Client -// -// Created by Vincent Meilinger on 11.03.24. -// - -import Foundation -import SwiftUI - - -// MARK: - Ingredient Units - -enum MeasurementUnit { - // Volume Metric - case milliLiter, centiLiter, deciLiter, liter - - // Volume Imperial - case teaspoon, tablespoon, cup, pint, quart, gallon, gill, fluidOunce // Please just use metric - - // Weight Metric - case milliGram, gram, kilogram - - // Weight Imperial - case ounce, pound - - // Other - case pinch, dash, smidgen - - - var localizedDescription: [LocalizedStringKey] { - switch self { - case .milliLiter: - return ["milliliter", "millilitre", "ml", "cc"] - case .centiLiter: - return ["centiliter", "centilitre", "cl"] - case .deciLiter: - return ["deciliter", "decilitre", "dl"] - case .liter: - return ["liter", "litre", "l"] - case .teaspoon: - return ["teaspoon", "tsp"] - case .tablespoon: - return ["tablespoon", "tbsp"] - case .cup: - return ["cup", "c"] - case .pint: - return ["pint", "pt"] - case .quart: - return ["quart", "qt"] - case .gallon: - return ["gallon", "gal"] - case .gill: - return ["gill", "gi"] - case .fluidOunce: - return ["fluid ounce", "fl oz"] - case .milliGram: - return ["milligram", "mg"] - case .gram: - return ["gram", "g"] - case .kilogram: - return ["kilogram", "kg"] - case .ounce: - return ["ounce", "oz"] - case .pound: - return ["pound", "lb"] - case .pinch: - return ["pinch"] - case .dash: - return ["dash"] - case .smidgen: - return ["smidgen"] - } - } - - static func convert(value: Double, from fromUnit: MeasurementUnit, to toUnit: MeasurementUnit) -> Double? { - let (baseValue, _) = MeasurementUnit.toBaseUnit(value: value, unit: fromUnit) - return MeasurementUnit.fromBaseUnit(value: baseValue, targetUnit: toUnit) - } - - private static func baseUnit(of unit: MeasurementUnit) -> MeasurementUnit { - switch unit { - // Volume Metric (all converted to liters) - case .milliLiter, .centiLiter, .deciLiter, .liter, .teaspoon, .tablespoon, .cup, .pint, .quart, .gallon, .gill, .fluidOunce, .dash: - return .liter - - // Weight (all converted to grams) - case .milliGram, .gram, .kilogram, .ounce, .pound, .pinch, .smidgen: - return .gram - } - } - - private static func toBaseUnit(value: Double, unit: MeasurementUnit) -> (Double, MeasurementUnit) { - guard abs(value) >= Double(1e-10) else { - return (0, unit) - } - switch unit { - case .milliLiter: - return (value/1000, .liter) - case .centiLiter: - return (value/100, .liter) - case .deciLiter: - return (value/10, .liter) - case .liter: - return (value, .liter) - case .teaspoon: - return (value * 0.005, .liter) - case .tablespoon: - return (value * 0.015, .liter) - case .cup: - return (value * 0.25, .liter) - case .pint: - return (value * 0.5, .liter) - case .quart: - return (value * 0.946, .liter) - case .gallon: - return (value * 3.8, .liter) - case .gill: - return (value * 0.17, .liter) - case .fluidOunce: - return (value * 0.03, .liter) - case .milliGram: - return (value * 0.001, .gram) - case .gram: - return (value, .gram) - case .kilogram: - return (value * 1000, .gram) - case .ounce: - return (value * 30, .gram) - case .pound: - return (value * 450, .gram) - case .pinch: - return (value * 0.3, .gram) - case .dash: - return (value * 0.000625, .liter) - case .smidgen: - return (value * 0.15, .gram) - } - } - - static private func fromBaseUnit(value: Double, targetUnit: MeasurementUnit) -> Double { - guard abs(value) >= Double(1e-10) else { - return 0 - } - - switch targetUnit { - case .milliLiter: - return value * 1000 - case .centiLiter: - return value * 100 - case .deciLiter: - return value * 10 - case .liter: - return value - case .teaspoon: - return value / 0.005 - case .tablespoon: - return value / 0.015 - case .cup: - return value / 0.25 - case .pint: - return value / 0.5 - case .quart: - return value / 0.946 - case .gallon: - return value / 3.8 - case .gill: - return value / 0.17 - case .fluidOunce: - return value / 0.03 - case .milliGram: - return value * 1000 - case .gram: - return value - case .kilogram: - return value / 1000 - case .ounce: - return value / 30 - case .pound: - return value / 450 - case .pinch: - return value / 0.3 - case .dash: - return value / 0.000625 - case .smidgen: - return value / 0.15 - } - } -} - - - -enum TemperatureUnit { - case fahrenheit, celsius - - var localizedDescription: [LocalizedStringKey] { - switch self { - case .fahrenheit: - ["fahrenheit", "f"] - case .celsius: - ["celsius", "c"] - } - } - - static func celsiusToFahrenheit(_ celsius: Double) -> Double { - return celsius * 9.0 / 5.0 + 32.0 - } - - static func fahrenheitToCelsius(_ fahrenheit: Double) -> Double { - return (fahrenheit - 32.0) * 5.0 / 9.0 - } -} diff --git a/Nextcloud Cookbook iOS Client/Localizable.xcstrings b/Nextcloud Cookbook iOS Client/Localizable.xcstrings index 8fc8f32..9df0669 100644 --- a/Nextcloud Cookbook iOS Client/Localizable.xcstrings +++ b/Nextcloud Cookbook iOS Client/Localizable.xcstrings @@ -91,7 +91,26 @@ } }, "%.2f" : { - + "localizations" : { + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "%.2f" + } + }, + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "%.2f" + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "" + } + } + } }, "%@" : { "localizations" : { @@ -664,9 +683,6 @@ } } } - }, - "c" : { - }, "Calories" : { "comment" : "Calories", @@ -780,18 +796,6 @@ } } } - }, - "cc" : { - - }, - "celsius" : { - - }, - "centiliter" : { - - }, - "centilitre" : { - }, "Cholesterol content" : { "comment" : "Cholesterol content", @@ -837,12 +841,28 @@ } } } - }, - "cl" : { - }, "Comma (e.g. 1,42)" : { - + "localizations" : { + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Komma (z.B. 1,42)" + } + }, + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Coma (por ejemplo, 1,42)" + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Virgule (par exemple, 1,42)" + } + } + } }, "Configure what is stored on your device." : { "localizations" : { @@ -1085,21 +1105,28 @@ } } } - }, - "cup" : { - - }, - "dash" : { - - }, - "deciliter" : { - - }, - "decilitre" : { - }, "Decimal number format" : { - + "localizations" : { + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Dezimalzahlenformat" + } + }, + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Formato de número decimal" + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Format de nombre décimal" + } + } + } }, "Delete" : { "localizations" : { @@ -1277,9 +1304,6 @@ } } } - }, - "dl" : { - }, "Done" : { "localizations" : { @@ -1523,12 +1547,6 @@ } } } - }, - "f" : { - - }, - "fahrenheit" : { - }, "Fat content" : { "comment" : "Fat content", @@ -1575,24 +1593,28 @@ } } } - }, - "fl oz" : { - - }, - "fluid ounce" : { - }, "Fraction" : { - - }, - "g" : { - - }, - "gal" : { - - }, - "gallon" : { - + "localizations" : { + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Bruch" + } + }, + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Fracción" + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Fraction" + } + } + } }, "General" : { "localizations" : { @@ -1637,15 +1659,6 @@ } } } - }, - "gi" : { - - }, - "gill" : { - - }, - "gram" : { - }, "Grocery List" : { "localizations" : { @@ -2000,15 +2013,6 @@ } } } - }, - "kg" : { - - }, - "kilogram" : { - - }, - "l" : { - }, "Language" : { "localizations" : { @@ -2075,9 +2079,6 @@ } } } - }, - "lb" : { - }, "List your tools here. 🍴" : { "localizations" : { @@ -2100,12 +2101,6 @@ } } } - }, - "liter" : { - - }, - "litre" : { - }, "Log out" : { "localizations" : { @@ -2218,19 +2213,26 @@ } }, "Marked ingredients could not be adjusted!" : { - - }, - "mg" : { - - }, - "milligram" : { - - }, - "milliliter" : { - - }, - "millilitre" : { - + "localizations" : { + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Markierte Zutaten können nicht angepasst werden." + } + }, + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "¡Los ingredientes marcados no pudieron ser ajustados!" + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Les ingrédients marqués n'ont pas pu être ajustés!" + } + } + } }, "Minutes" : { "localizations" : { @@ -2323,10 +2325,26 @@ } }, "Mixed fraction" : { - - }, - "ml" : { - + "localizations" : { + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Gemischter Bruch" + } + }, + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Fracción mixta" + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Fraction mixte" + } + } + } }, "More information" : { "localizations" : { @@ -2506,7 +2524,26 @@ } }, "Number" : { - + "localizations" : { + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Dezimalzahl" + } + }, + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Número" + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Nombre" + } + } + } }, "Nutrition" : { "localizations" : { @@ -2617,12 +2654,6 @@ } } } - }, - "ounce" : { - - }, - "oz" : { - }, "Parsing error" : { "localizations" : { @@ -2689,12 +2720,6 @@ } } } - }, - "pinch" : { - - }, - "pint" : { - }, "Please check the entered URL." : { "localizations" : { @@ -2763,10 +2788,26 @@ } }, "Point (e.g. 1.42)" : { - - }, - "pound" : { - + "localizations" : { + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Punkt (z.B. 1.42)" + } + }, + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Punto (por ejemplo, 1.42)" + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Point (par exemple, 1.42)" + } + } + } }, "Preparation" : { "localizations" : { @@ -2835,15 +2876,6 @@ } } } - }, - "pt" : { - - }, - "qt" : { - - }, - "quart" : { - }, "Recipe" : { "localizations" : { @@ -2933,6 +2965,28 @@ } } }, + "Refresh" : { + "localizations" : { + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Aktualisieren" + } + }, + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Refrescar" + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Actualiser" + } + } + } + }, "Refresh all" : { "localizations" : { "de" : { @@ -3332,9 +3386,6 @@ } } } - }, - "smidgen" : { - }, "Sodium content" : { "comment" : "Sodium content", @@ -3364,7 +3415,7 @@ "de" : { "stringUnit" : { "state" : "translated", - "value" : "Hier fehlen Zutaten! 🥬" + "value" : "Hier ist Platz für Zutaten! 🥬" } }, "es" : { @@ -3535,15 +3586,6 @@ } } } - }, - "tablespoon" : { - - }, - "tbsp" : { - - }, - "teaspoon" : { - }, "Thank you for downloading" : { "localizations" : { @@ -3634,6 +3676,28 @@ } } }, + "There are no recipes in this cookbook!" : { + "localizations" : { + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Hier gibt es momentan noch keine Rezepte zu sehen." + } + }, + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "No hay recetas en esta categoría." + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Il n'y a pas de recettes dans cette catégorie." + } + } + } + }, "There was no name in the request given for the recipe. Cannot save the recipe." : { "extractionState" : "stale", "localizations" : { @@ -3702,7 +3766,26 @@ } }, "This setting will take effect after the app is restarted. It affects the adjustment of ingredient quantities." : { - + "localizations" : { + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Diese Einstellung wird erst nach einem Neustart der App wirksam. Die Einstellung betrifft die Mengenberechnung der Rezeptzutaten." + } + }, + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Esta configuración surtirá efecto después de reiniciar la aplicación. Afecta el ajuste de las cantidades de ingredientes." + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Ce paramètre prendra effet après le redémarrage de l'application. Il affecte l'ajustement des quantités d'ingrédients." + } + } + } }, "This website might not be currently supported. If this appears incorrect, you can use the support options in the app settings to raise awareness about this issue." : { "localizations" : { @@ -3882,9 +3965,6 @@ } } } - }, - "tsp" : { - }, "Unable to complete action." : { "localizations" : { diff --git a/Nextcloud Cookbook iOS Client/Views/Recipes/RecipeListView.swift b/Nextcloud Cookbook iOS Client/Views/Recipes/RecipeListView.swift index 147914d..304d0a2 100644 --- a/Nextcloud Cookbook iOS Client/Views/Recipes/RecipeListView.swift +++ b/Nextcloud Cookbook iOS Client/Views/Recipes/RecipeListView.swift @@ -19,21 +19,40 @@ struct RecipeListView: View { @State var selectedRecipe: Recipe? = nil var body: some View { - List(recipesFiltered(), id: \.recipe_id) { recipe in - RecipeCardView(recipe: recipe) - .shadow(radius: 2) - .background( - NavigationLink(value: recipe) { - EmptyView() + Group { + let recipes = recipesFiltered() + if !recipes.isEmpty { + List(recipesFiltered(), id: \.recipe_id) { recipe in + RecipeCardView(recipe: recipe) + .shadow(radius: 2) + .background( + NavigationLink(value: recipe) { + EmptyView() + } + .buttonStyle(.plain) + .opacity(0) + ) + .frame(height: 85) + .listRowInsets(EdgeInsets(top: 5, leading: 15, bottom: 5, trailing: 15)) + .listRowSeparatorTint(.clear) + } + .listStyle(.plain) + } else { + VStack { + Text("There are no recipes in this cookbook!") + Button { + Task { + await appState.getCategories() + await appState.getCategory(named: categoryName, fetchMode: .preferServer) + } + } label: { + Text("Refresh") + .bold() } - .buttonStyle(.plain) - .opacity(0) - ) - .frame(height: 85) - .listRowInsets(EdgeInsets(top: 5, leading: 15, bottom: 5, trailing: 15)) - .listRowSeparatorTint(.clear) + .buttonStyle(.bordered) + }.padding() + } } - .listStyle(.plain) .searchable(text: $searchText, prompt: "Search recipes/keywords") .navigationTitle(categoryName == "*" ? String(localized: "Other") : categoryName) diff --git a/Nextcloud Cookbook iOS Client/Views/Tabs/RecipeTabView.swift b/Nextcloud Cookbook iOS Client/Views/Tabs/RecipeTabView.swift index d9c6199..c060116 100644 --- a/Nextcloud Cookbook iOS Client/Views/Tabs/RecipeTabView.swift +++ b/Nextcloud Cookbook iOS Client/Views/Tabs/RecipeTabView.swift @@ -19,28 +19,34 @@ struct RecipeTabView: View { List(selection: $viewModel.selectedCategory) { // Categories ForEach(appState.categories) { category in - if category.recipe_count != 0 { - NavigationLink(value: category) { - HStack(alignment: .center) { - if viewModel.selectedCategory != nil && category.name == viewModel.selectedCategory!.name { - Image(systemName: "book") - } else { - Image(systemName: "book.closed.fill") - } - Text(category.name == "*" ? String(localized: "Other") : category.name) + NavigationLink(value: category) { + HStack(alignment: .center) { + if viewModel.selectedCategory != nil && + category.name == viewModel.selectedCategory!.name { + Image(systemName: "book") + } else { + Image(systemName: "book.closed.fill") + } + + if category.name == "*" { + Text("Other") .font(.system(size: 20, weight: .medium, design: .default)) - Spacer() - Text("\(category.recipe_count)") - .font(.system(size: 15, weight: .bold, design: .default)) - .foregroundStyle(Color.background) - .frame(width: 25, height: 25, alignment: .center) - .minimumScaleFactor(0.5) - .background { - Circle() - .foregroundStyle(Color.secondary) - } - }.padding(7) - } + } else { + Text(category.name) + .font(.system(size: 20, weight: .medium, design: .default)) + } + + Spacer() + Text("\(category.recipe_count)") + .font(.system(size: 15, weight: .bold, design: .default)) + .foregroundStyle(Color.background) + .frame(width: 25, height: 25, alignment: .center) + .minimumScaleFactor(0.5) + .background { + Circle() + .foregroundStyle(Color.secondary) + } + }.padding(7) } } } @@ -100,7 +106,7 @@ struct RecipeTabView: View { fileprivate struct RecipeTabViewToolBar: ToolbarContent { - @EnvironmentObject var mainViewModel: AppState + @EnvironmentObject var appState: AppState @EnvironmentObject var viewModel: RecipeTabView.ViewModel var body: some ToolbarContent { @@ -111,11 +117,11 @@ fileprivate struct RecipeTabViewToolBar: ToolbarContent { Task { viewModel.presentLoadingIndicator = true UserSettings.shared.lastUpdate = Date.distantPast - await mainViewModel.getCategories() - for category in mainViewModel.categories { - await mainViewModel.getCategory(named: category.name, fetchMode: .preferServer) + await appState.getCategories() + for category in appState.categories { + await appState.getCategory(named: category.name, fetchMode: .preferServer) } - await mainViewModel.updateAllRecipeDetails() + await appState.updateAllRecipeDetails() viewModel.presentLoadingIndicator = false } } label: {