Code cleanup, translations, show empty categories
This commit is contained in:
@@ -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 = "<group>"; };
|
||||
A7FB0D7B2B25C68500A3469E /* TokenLoginView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TokenLoginView.swift; sourceTree = "<group>"; };
|
||||
A7FB0D7D2B25C6A200A3469E /* V2LoginView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = V2LoginView.swift; sourceTree = "<group>"; };
|
||||
A90C45F32B9F4DB6005D62B6 /* Units.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Units.swift; sourceTree = "<group>"; };
|
||||
A97506122B920D9F00E86029 /* RecipeDurationSection.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RecipeDurationSection.swift; sourceTree = "<group>"; };
|
||||
A97506142B920DF200E86029 /* RecipeGenericViews.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RecipeGenericViews.swift; sourceTree = "<group>"; };
|
||||
A97506182B920EC200E86029 /* RecipeIngredientSection.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RecipeIngredientSection.swift; sourceTree = "<group>"; };
|
||||
@@ -287,7 +285,6 @@
|
||||
A70171C52AB4C43A00064C43 /* DataModels.swift */,
|
||||
A97B4D312B80B3E900EC1A88 /* RecipeModels.swift */,
|
||||
A9BBB38F2B91BE31002DA7FF /* ObservableRecipeDetail.swift */,
|
||||
A90C45F32B9F4DB6005D62B6 /* Units.swift */,
|
||||
);
|
||||
path = Data;
|
||||
sourceTree = "<group>";
|
||||
@@ -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 */,
|
||||
|
||||
Binary file not shown.
@@ -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
|
||||
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
@@ -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" : {
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -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: {
|
||||
|
||||
Reference in New Issue
Block a user