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 */; };
|
A7FB0D7A2B25C66600A3469E /* OnboardingView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A7FB0D792B25C66600A3469E /* OnboardingView.swift */; };
|
||||||
A7FB0D7C2B25C68500A3469E /* TokenLoginView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A7FB0D7B2B25C68500A3469E /* TokenLoginView.swift */; };
|
A7FB0D7C2B25C68500A3469E /* TokenLoginView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A7FB0D7B2B25C68500A3469E /* TokenLoginView.swift */; };
|
||||||
A7FB0D7E2B25C6A200A3469E /* V2LoginView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A7FB0D7D2B25C6A200A3469E /* V2LoginView.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 */; };
|
A97506132B920D9F00E86029 /* RecipeDurationSection.swift in Sources */ = {isa = PBXBuildFile; fileRef = A97506122B920D9F00E86029 /* RecipeDurationSection.swift */; };
|
||||||
A97506152B920DF200E86029 /* RecipeGenericViews.swift in Sources */ = {isa = PBXBuildFile; fileRef = A97506142B920DF200E86029 /* RecipeGenericViews.swift */; };
|
A97506152B920DF200E86029 /* RecipeGenericViews.swift in Sources */ = {isa = PBXBuildFile; fileRef = A97506142B920DF200E86029 /* RecipeGenericViews.swift */; };
|
||||||
A97506192B920EC200E86029 /* RecipeIngredientSection.swift in Sources */ = {isa = PBXBuildFile; fileRef = A97506182B920EC200E86029 /* RecipeIngredientSection.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>"; };
|
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>"; };
|
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>"; };
|
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>"; };
|
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>"; };
|
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>"; };
|
A97506182B920EC200E86029 /* RecipeIngredientSection.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RecipeIngredientSection.swift; sourceTree = "<group>"; };
|
||||||
@@ -287,7 +285,6 @@
|
|||||||
A70171C52AB4C43A00064C43 /* DataModels.swift */,
|
A70171C52AB4C43A00064C43 /* DataModels.swift */,
|
||||||
A97B4D312B80B3E900EC1A88 /* RecipeModels.swift */,
|
A97B4D312B80B3E900EC1A88 /* RecipeModels.swift */,
|
||||||
A9BBB38F2B91BE31002DA7FF /* ObservableRecipeDetail.swift */,
|
A9BBB38F2B91BE31002DA7FF /* ObservableRecipeDetail.swift */,
|
||||||
A90C45F32B9F4DB6005D62B6 /* Units.swift */,
|
|
||||||
);
|
);
|
||||||
path = Data;
|
path = Data;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
@@ -596,7 +593,6 @@
|
|||||||
A7F3F8E82ACBFC760076C227 /* RecipeKeywordSection.swift in Sources */,
|
A7F3F8E82ACBFC760076C227 /* RecipeKeywordSection.swift in Sources */,
|
||||||
A79AA8E02AFF80E3007D25F2 /* DurationComponents.swift in Sources */,
|
A79AA8E02AFF80E3007D25F2 /* DurationComponents.swift in Sources */,
|
||||||
A70171C02AB498A900064C43 /* RecipeView.swift in Sources */,
|
A70171C02AB498A900064C43 /* RecipeView.swift in Sources */,
|
||||||
A90C45F42B9F4DB6005D62B6 /* Units.swift in Sources */,
|
|
||||||
A79AA8E42B02A962007D25F2 /* CookbookApi.swift in Sources */,
|
A79AA8E42B02A962007D25F2 /* CookbookApi.swift in Sources */,
|
||||||
A975061B2B920F9F00E86029 /* RecipeNutritionSection.swift in Sources */,
|
A975061B2B920F9F00E86029 /* RecipeNutritionSection.swift in Sources */,
|
||||||
A70171CD2AB501B100064C43 /* SettingsView.swift in Sources */,
|
A70171CD2AB501B100064C43 /* SettingsView.swift in Sources */,
|
||||||
|
|||||||
Binary file not shown.
@@ -126,13 +126,11 @@ class ObservableRecipeDetail: ObservableObject {
|
|||||||
|
|
||||||
var attributedString = AttributedString(ingredient)
|
var attributedString = AttributedString(ingredient)
|
||||||
for (newSubstring, matchRange) in matches {
|
for (newSubstring, matchRange) in matches {
|
||||||
print(newSubstring, matchRange)
|
|
||||||
guard let range = Range(matchRange, in: attributedString) else { continue }
|
guard let range = Range(matchRange, in: attributedString) else { continue }
|
||||||
var attributedSubString = AttributedString(newSubstring)
|
var attributedSubString = AttributedString(newSubstring)
|
||||||
//attributedSubString.foregroundColor = .ncTextHighlight
|
//attributedSubString.foregroundColor = .ncTextHighlight
|
||||||
attributedSubString.font = .system(.body, weight: .bold)
|
attributedSubString.font = .system(.body, weight: .bold)
|
||||||
attributedString.replaceSubrange(range, with: attributedSubString)
|
attributedString.replaceSubrange(range, with: attributedSubString)
|
||||||
print("\n", attributedString)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return 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" : {
|
"%.2f" : {
|
||||||
|
"localizations" : {
|
||||||
|
"de" : {
|
||||||
|
"stringUnit" : {
|
||||||
|
"state" : "translated",
|
||||||
|
"value" : "%.2f"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"es" : {
|
||||||
|
"stringUnit" : {
|
||||||
|
"state" : "translated",
|
||||||
|
"value" : "%.2f"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"fr" : {
|
||||||
|
"stringUnit" : {
|
||||||
|
"state" : "translated",
|
||||||
|
"value" : ""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"%@" : {
|
"%@" : {
|
||||||
"localizations" : {
|
"localizations" : {
|
||||||
@@ -664,9 +683,6 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
|
||||||
"c" : {
|
|
||||||
|
|
||||||
},
|
},
|
||||||
"Calories" : {
|
"Calories" : {
|
||||||
"comment" : "Calories",
|
"comment" : "Calories",
|
||||||
@@ -780,18 +796,6 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
|
||||||
"cc" : {
|
|
||||||
|
|
||||||
},
|
|
||||||
"celsius" : {
|
|
||||||
|
|
||||||
},
|
|
||||||
"centiliter" : {
|
|
||||||
|
|
||||||
},
|
|
||||||
"centilitre" : {
|
|
||||||
|
|
||||||
},
|
},
|
||||||
"Cholesterol content" : {
|
"Cholesterol content" : {
|
||||||
"comment" : "Cholesterol content",
|
"comment" : "Cholesterol content",
|
||||||
@@ -837,12 +841,28 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
|
||||||
"cl" : {
|
|
||||||
|
|
||||||
},
|
},
|
||||||
"Comma (e.g. 1,42)" : {
|
"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." : {
|
"Configure what is stored on your device." : {
|
||||||
"localizations" : {
|
"localizations" : {
|
||||||
@@ -1085,21 +1105,28 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
|
||||||
"cup" : {
|
|
||||||
|
|
||||||
},
|
|
||||||
"dash" : {
|
|
||||||
|
|
||||||
},
|
|
||||||
"deciliter" : {
|
|
||||||
|
|
||||||
},
|
|
||||||
"decilitre" : {
|
|
||||||
|
|
||||||
},
|
},
|
||||||
"Decimal number format" : {
|
"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" : {
|
"Delete" : {
|
||||||
"localizations" : {
|
"localizations" : {
|
||||||
@@ -1277,9 +1304,6 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
|
||||||
"dl" : {
|
|
||||||
|
|
||||||
},
|
},
|
||||||
"Done" : {
|
"Done" : {
|
||||||
"localizations" : {
|
"localizations" : {
|
||||||
@@ -1523,12 +1547,6 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
|
||||||
"f" : {
|
|
||||||
|
|
||||||
},
|
|
||||||
"fahrenheit" : {
|
|
||||||
|
|
||||||
},
|
},
|
||||||
"Fat content" : {
|
"Fat content" : {
|
||||||
"comment" : "Fat content",
|
"comment" : "Fat content",
|
||||||
@@ -1575,24 +1593,28 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
|
||||||
"fl oz" : {
|
|
||||||
|
|
||||||
},
|
|
||||||
"fluid ounce" : {
|
|
||||||
|
|
||||||
},
|
},
|
||||||
"Fraction" : {
|
"Fraction" : {
|
||||||
|
"localizations" : {
|
||||||
|
"de" : {
|
||||||
|
"stringUnit" : {
|
||||||
|
"state" : "translated",
|
||||||
|
"value" : "Bruch"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"g" : {
|
"es" : {
|
||||||
|
"stringUnit" : {
|
||||||
|
"state" : "translated",
|
||||||
|
"value" : "Fracción"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"gal" : {
|
"fr" : {
|
||||||
|
"stringUnit" : {
|
||||||
},
|
"state" : "translated",
|
||||||
"gallon" : {
|
"value" : "Fraction"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"General" : {
|
"General" : {
|
||||||
"localizations" : {
|
"localizations" : {
|
||||||
@@ -1637,15 +1659,6 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
|
||||||
"gi" : {
|
|
||||||
|
|
||||||
},
|
|
||||||
"gill" : {
|
|
||||||
|
|
||||||
},
|
|
||||||
"gram" : {
|
|
||||||
|
|
||||||
},
|
},
|
||||||
"Grocery List" : {
|
"Grocery List" : {
|
||||||
"localizations" : {
|
"localizations" : {
|
||||||
@@ -2000,15 +2013,6 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
|
||||||
"kg" : {
|
|
||||||
|
|
||||||
},
|
|
||||||
"kilogram" : {
|
|
||||||
|
|
||||||
},
|
|
||||||
"l" : {
|
|
||||||
|
|
||||||
},
|
},
|
||||||
"Language" : {
|
"Language" : {
|
||||||
"localizations" : {
|
"localizations" : {
|
||||||
@@ -2075,9 +2079,6 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
|
||||||
"lb" : {
|
|
||||||
|
|
||||||
},
|
},
|
||||||
"List your tools here. 🍴" : {
|
"List your tools here. 🍴" : {
|
||||||
"localizations" : {
|
"localizations" : {
|
||||||
@@ -2100,12 +2101,6 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
|
||||||
"liter" : {
|
|
||||||
|
|
||||||
},
|
|
||||||
"litre" : {
|
|
||||||
|
|
||||||
},
|
},
|
||||||
"Log out" : {
|
"Log out" : {
|
||||||
"localizations" : {
|
"localizations" : {
|
||||||
@@ -2218,19 +2213,26 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"Marked ingredients could not be adjusted!" : {
|
"Marked ingredients could not be adjusted!" : {
|
||||||
|
"localizations" : {
|
||||||
|
"de" : {
|
||||||
|
"stringUnit" : {
|
||||||
|
"state" : "translated",
|
||||||
|
"value" : "Markierte Zutaten können nicht angepasst werden."
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"mg" : {
|
"es" : {
|
||||||
|
"stringUnit" : {
|
||||||
|
"state" : "translated",
|
||||||
|
"value" : "¡Los ingredientes marcados no pudieron ser ajustados!"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"milligram" : {
|
"fr" : {
|
||||||
|
"stringUnit" : {
|
||||||
},
|
"state" : "translated",
|
||||||
"milliliter" : {
|
"value" : "Les ingrédients marqués n'ont pas pu être ajustés!"
|
||||||
|
}
|
||||||
},
|
}
|
||||||
"millilitre" : {
|
}
|
||||||
|
|
||||||
},
|
},
|
||||||
"Minutes" : {
|
"Minutes" : {
|
||||||
"localizations" : {
|
"localizations" : {
|
||||||
@@ -2323,10 +2325,26 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"Mixed fraction" : {
|
"Mixed fraction" : {
|
||||||
|
"localizations" : {
|
||||||
|
"de" : {
|
||||||
|
"stringUnit" : {
|
||||||
|
"state" : "translated",
|
||||||
|
"value" : "Gemischter Bruch"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"ml" : {
|
"es" : {
|
||||||
|
"stringUnit" : {
|
||||||
|
"state" : "translated",
|
||||||
|
"value" : "Fracción mixta"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"fr" : {
|
||||||
|
"stringUnit" : {
|
||||||
|
"state" : "translated",
|
||||||
|
"value" : "Fraction mixte"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"More information" : {
|
"More information" : {
|
||||||
"localizations" : {
|
"localizations" : {
|
||||||
@@ -2506,7 +2524,26 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"Number" : {
|
"Number" : {
|
||||||
|
"localizations" : {
|
||||||
|
"de" : {
|
||||||
|
"stringUnit" : {
|
||||||
|
"state" : "translated",
|
||||||
|
"value" : "Dezimalzahl"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"es" : {
|
||||||
|
"stringUnit" : {
|
||||||
|
"state" : "translated",
|
||||||
|
"value" : "Número"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"fr" : {
|
||||||
|
"stringUnit" : {
|
||||||
|
"state" : "translated",
|
||||||
|
"value" : "Nombre"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"Nutrition" : {
|
"Nutrition" : {
|
||||||
"localizations" : {
|
"localizations" : {
|
||||||
@@ -2617,12 +2654,6 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
|
||||||
"ounce" : {
|
|
||||||
|
|
||||||
},
|
|
||||||
"oz" : {
|
|
||||||
|
|
||||||
},
|
},
|
||||||
"Parsing error" : {
|
"Parsing error" : {
|
||||||
"localizations" : {
|
"localizations" : {
|
||||||
@@ -2689,12 +2720,6 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
|
||||||
"pinch" : {
|
|
||||||
|
|
||||||
},
|
|
||||||
"pint" : {
|
|
||||||
|
|
||||||
},
|
},
|
||||||
"Please check the entered URL." : {
|
"Please check the entered URL." : {
|
||||||
"localizations" : {
|
"localizations" : {
|
||||||
@@ -2763,10 +2788,26 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"Point (e.g. 1.42)" : {
|
"Point (e.g. 1.42)" : {
|
||||||
|
"localizations" : {
|
||||||
|
"de" : {
|
||||||
|
"stringUnit" : {
|
||||||
|
"state" : "translated",
|
||||||
|
"value" : "Punkt (z.B. 1.42)"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"pound" : {
|
"es" : {
|
||||||
|
"stringUnit" : {
|
||||||
|
"state" : "translated",
|
||||||
|
"value" : "Punto (por ejemplo, 1.42)"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"fr" : {
|
||||||
|
"stringUnit" : {
|
||||||
|
"state" : "translated",
|
||||||
|
"value" : "Point (par exemple, 1.42)"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"Preparation" : {
|
"Preparation" : {
|
||||||
"localizations" : {
|
"localizations" : {
|
||||||
@@ -2835,15 +2876,6 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
|
||||||
"pt" : {
|
|
||||||
|
|
||||||
},
|
|
||||||
"qt" : {
|
|
||||||
|
|
||||||
},
|
|
||||||
"quart" : {
|
|
||||||
|
|
||||||
},
|
},
|
||||||
"Recipe" : {
|
"Recipe" : {
|
||||||
"localizations" : {
|
"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" : {
|
"Refresh all" : {
|
||||||
"localizations" : {
|
"localizations" : {
|
||||||
"de" : {
|
"de" : {
|
||||||
@@ -3332,9 +3386,6 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
|
||||||
"smidgen" : {
|
|
||||||
|
|
||||||
},
|
},
|
||||||
"Sodium content" : {
|
"Sodium content" : {
|
||||||
"comment" : "Sodium content",
|
"comment" : "Sodium content",
|
||||||
@@ -3364,7 +3415,7 @@
|
|||||||
"de" : {
|
"de" : {
|
||||||
"stringUnit" : {
|
"stringUnit" : {
|
||||||
"state" : "translated",
|
"state" : "translated",
|
||||||
"value" : "Hier fehlen Zutaten! 🥬"
|
"value" : "Hier ist Platz für Zutaten! 🥬"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"es" : {
|
"es" : {
|
||||||
@@ -3535,15 +3586,6 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
|
||||||
"tablespoon" : {
|
|
||||||
|
|
||||||
},
|
|
||||||
"tbsp" : {
|
|
||||||
|
|
||||||
},
|
|
||||||
"teaspoon" : {
|
|
||||||
|
|
||||||
},
|
},
|
||||||
"Thank you for downloading" : {
|
"Thank you for downloading" : {
|
||||||
"localizations" : {
|
"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." : {
|
"There was no name in the request given for the recipe. Cannot save the recipe." : {
|
||||||
"extractionState" : "stale",
|
"extractionState" : "stale",
|
||||||
"localizations" : {
|
"localizations" : {
|
||||||
@@ -3702,7 +3766,26 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"This setting will take effect after the app is restarted. It affects the adjustment of ingredient quantities." : {
|
"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." : {
|
"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" : {
|
"localizations" : {
|
||||||
@@ -3882,9 +3965,6 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
|
||||||
"tsp" : {
|
|
||||||
|
|
||||||
},
|
},
|
||||||
"Unable to complete action." : {
|
"Unable to complete action." : {
|
||||||
"localizations" : {
|
"localizations" : {
|
||||||
|
|||||||
@@ -19,6 +19,9 @@ struct RecipeListView: View {
|
|||||||
@State var selectedRecipe: Recipe? = nil
|
@State var selectedRecipe: Recipe? = nil
|
||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
|
Group {
|
||||||
|
let recipes = recipesFiltered()
|
||||||
|
if !recipes.isEmpty {
|
||||||
List(recipesFiltered(), id: \.recipe_id) { recipe in
|
List(recipesFiltered(), id: \.recipe_id) { recipe in
|
||||||
RecipeCardView(recipe: recipe)
|
RecipeCardView(recipe: recipe)
|
||||||
.shadow(radius: 2)
|
.shadow(radius: 2)
|
||||||
@@ -34,6 +37,22 @@ struct RecipeListView: View {
|
|||||||
.listRowSeparatorTint(.clear)
|
.listRowSeparatorTint(.clear)
|
||||||
}
|
}
|
||||||
.listStyle(.plain)
|
.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(.bordered)
|
||||||
|
}.padding()
|
||||||
|
}
|
||||||
|
}
|
||||||
.searchable(text: $searchText, prompt: "Search recipes/keywords")
|
.searchable(text: $searchText, prompt: "Search recipes/keywords")
|
||||||
.navigationTitle(categoryName == "*" ? String(localized: "Other") : categoryName)
|
.navigationTitle(categoryName == "*" ? String(localized: "Other") : categoryName)
|
||||||
|
|
||||||
|
|||||||
@@ -19,16 +19,23 @@ struct RecipeTabView: View {
|
|||||||
List(selection: $viewModel.selectedCategory) {
|
List(selection: $viewModel.selectedCategory) {
|
||||||
// Categories
|
// Categories
|
||||||
ForEach(appState.categories) { category in
|
ForEach(appState.categories) { category in
|
||||||
if category.recipe_count != 0 {
|
|
||||||
NavigationLink(value: category) {
|
NavigationLink(value: category) {
|
||||||
HStack(alignment: .center) {
|
HStack(alignment: .center) {
|
||||||
if viewModel.selectedCategory != nil && category.name == viewModel.selectedCategory!.name {
|
if viewModel.selectedCategory != nil &&
|
||||||
|
category.name == viewModel.selectedCategory!.name {
|
||||||
Image(systemName: "book")
|
Image(systemName: "book")
|
||||||
} else {
|
} else {
|
||||||
Image(systemName: "book.closed.fill")
|
Image(systemName: "book.closed.fill")
|
||||||
}
|
}
|
||||||
Text(category.name == "*" ? String(localized: "Other") : category.name)
|
|
||||||
|
if category.name == "*" {
|
||||||
|
Text("Other")
|
||||||
.font(.system(size: 20, weight: .medium, design: .default))
|
.font(.system(size: 20, weight: .medium, design: .default))
|
||||||
|
} else {
|
||||||
|
Text(category.name)
|
||||||
|
.font(.system(size: 20, weight: .medium, design: .default))
|
||||||
|
}
|
||||||
|
|
||||||
Spacer()
|
Spacer()
|
||||||
Text("\(category.recipe_count)")
|
Text("\(category.recipe_count)")
|
||||||
.font(.system(size: 15, weight: .bold, design: .default))
|
.font(.system(size: 15, weight: .bold, design: .default))
|
||||||
@@ -43,7 +50,6 @@ struct RecipeTabView: View {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
.navigationTitle("Cookbooks")
|
.navigationTitle("Cookbooks")
|
||||||
.toolbar {
|
.toolbar {
|
||||||
RecipeTabViewToolBar()
|
RecipeTabViewToolBar()
|
||||||
@@ -100,7 +106,7 @@ struct RecipeTabView: View {
|
|||||||
|
|
||||||
|
|
||||||
fileprivate struct RecipeTabViewToolBar: ToolbarContent {
|
fileprivate struct RecipeTabViewToolBar: ToolbarContent {
|
||||||
@EnvironmentObject var mainViewModel: AppState
|
@EnvironmentObject var appState: AppState
|
||||||
@EnvironmentObject var viewModel: RecipeTabView.ViewModel
|
@EnvironmentObject var viewModel: RecipeTabView.ViewModel
|
||||||
|
|
||||||
var body: some ToolbarContent {
|
var body: some ToolbarContent {
|
||||||
@@ -111,11 +117,11 @@ fileprivate struct RecipeTabViewToolBar: ToolbarContent {
|
|||||||
Task {
|
Task {
|
||||||
viewModel.presentLoadingIndicator = true
|
viewModel.presentLoadingIndicator = true
|
||||||
UserSettings.shared.lastUpdate = Date.distantPast
|
UserSettings.shared.lastUpdate = Date.distantPast
|
||||||
await mainViewModel.getCategories()
|
await appState.getCategories()
|
||||||
for category in mainViewModel.categories {
|
for category in appState.categories {
|
||||||
await mainViewModel.getCategory(named: category.name, fetchMode: .preferServer)
|
await appState.getCategory(named: category.name, fetchMode: .preferServer)
|
||||||
}
|
}
|
||||||
await mainViewModel.updateAllRecipeDetails()
|
await appState.updateAllRecipeDetails()
|
||||||
viewModel.presentLoadingIndicator = false
|
viewModel.presentLoadingIndicator = false
|
||||||
}
|
}
|
||||||
} label: {
|
} label: {
|
||||||
|
|||||||
Reference in New Issue
Block a user