refactored to allow for multiple recipes in a single yaml, mixed with urls to other recipes

This commit is contained in:
broodjeaap89 2021-09-25 20:44:31 +02:00
parent 6c4b0f4e05
commit a0c0e02035
2 changed files with 109 additions and 68 deletions

View file

@ -90,9 +90,10 @@ class PizzaRecipe extends HiveObject {
} }
static Future<PizzaRecipe> fromYaml(String yamlString) async{ static Future<PizzaRecipe> fromYaml(String yamlString) async{
final yaml = loadYaml(yamlString); return fromParsedYaml(loadYaml(yamlString) as YamlMap);
final YamlMap recipe = yaml["recipe"] as YamlMap; }
static Future<PizzaRecipe> fromParsedYaml(YamlMap recipe) async {
final String name = recipe["name"] as String; final String name = recipe["name"] as String;
final String? image = recipe.containsKey("image") ? recipe["image"] as String : null; final String? image = recipe.containsKey("image") ? recipe["image"] as String : null;
final String description = recipe["description"] as String; final String description = recipe["description"] as String;
@ -101,10 +102,10 @@ class PizzaRecipe extends HiveObject {
final List<Ingredient> newIngredients = ingredients.map( final List<Ingredient> newIngredients = ingredients.map(
(ingredient) => Ingredient( (ingredient) => Ingredient(
ingredient["name"] as String, ingredient["name"] as String,
ingredient["unit"] as String, ingredient["unit"] as String,
ingredient["value"] as double ingredient["value"] as double
)).toList(); )).toList();
final YamlList steps = recipe["steps"] as YamlList; final YamlList steps = recipe["steps"] as YamlList;
final newRecipeSteps = List.generate(steps.length, (i) { final newRecipeSteps = List.generate(steps.length, (i) {
@ -130,27 +131,27 @@ class PizzaRecipe extends HiveObject {
final newSubSteps = List.generate(subSteps.length, (j) { final newSubSteps = List.generate(subSteps.length, (j) {
final subStep = subSteps[j]; final subStep = subSteps[j];
return RecipeSubStep( return RecipeSubStep(
subStep["name"] as String, subStep["name"] as String,
subStep["description"] as String subStep["description"] as String
); );
}); });
return RecipeStep( return RecipeStep(
stepName, stepName,
stepDescription, stepDescription,
waitDescription, waitDescription,
waitUnit, waitUnit,
waitMin, waitMin,
waitMax, waitMax,
newSubSteps newSubSteps
); );
}); });
return PizzaRecipe( return PizzaRecipe(
name, name,
description, description,
newIngredients, newIngredients,
newRecipeSteps, newRecipeSteps,
image: image image: image
); );
} }

View file

@ -125,7 +125,15 @@ class AddRecipeURLPageState extends State<AddRecipeURLPage> {
return await singleRecipe(yamlBody); return await singleRecipe(yamlBody);
} }
if (yamlBody.startsWith("recipes:")){ if (yamlBody.startsWith("recipes:")){
return await recipeDir(yamlBody); try {
return await recipeDir(yamlBody);
} catch (exception){
return const <Widget>[
Text(
"Failed to load",
)
];
}
} }
} catch (exception) { } catch (exception) {
print(exception); print(exception);
@ -139,66 +147,75 @@ class AddRecipeURLPageState extends State<AddRecipeURLPage> {
final widgets = <Widget>[]; final widgets = <Widget>[];
for (final item in urls) { for (final item in urls) {
try { try {
final name = item["name"] as String; final itemMap = item as YamlMap;
final url = item["url"] as String; if (itemMap.containsKey("url")){ // Dir item
widgets.add( widgets.add(buildDirWidget(itemMap));
InkWell( } else { // recipe item
onTap: () { widgets.add(await buildRecipeWidget(itemMap));
Navigator.pushNamed(context, AddRecipeURLPage.route, arguments: url); }
},
child: Container(
height: 70,
width: double.infinity,
color: Colors.blue,
child: Column(
children: <Widget>[
Center(
child: Text(name, style: const TextStyle(color: Colors.white)),
),
const Divider(),
Center(
child: Text(url, style: const TextStyle(color: Colors.white)),
),
],
)
),
)
);
widgets.add(const Divider()); widgets.add(const Divider());
} catch (exception){ } catch (exception){
print(exception); widgets.add(
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
"Failed to load",
style: Theme.of(context).textTheme.subtitle2
)
],
)
);
} }
} }
return widgets; return widgets;
} }
Widget buildDirWidget(YamlMap itemMap){
final name = itemMap["name"] as String;
final url = itemMap["url"] as String;
return InkWell(
onTap: () {
Navigator.pushNamed(context, AddRecipeURLPage.route, arguments: url);
},
child: Container(
height: 70,
width: double.infinity,
color: Colors.blue,
child: Column(
children: <Widget>[
Center(
child: Text(name, style: const TextStyle(color: Colors.white)),
),
const Divider(),
Center(
child: Text(url, style: const TextStyle(color: Colors.white)),
),
],
)
),
);
}
Future<Widget> buildRecipeWidget(YamlMap itemMap) async {
final pizzaRecipe = await PizzaRecipe.fromParsedYaml(itemMap);
return InkWell(
onTap: () {
showDialog(context: context, builder: (BuildContext context) {
return buildRecipeDialog(pizzaRecipe);
});
},
child: PizzaRecipeWidget(pizzaRecipe),
);
}
Future<List<Widget>> singleRecipe(String yamlBody) async { Future<List<Widget>> singleRecipe(String yamlBody) async {
final pizzaRecipe = await PizzaRecipe.fromYaml(yamlBody); final pizzaRecipe = await PizzaRecipe.fromYaml(yamlBody);
return <Widget>[ return <Widget>[
InkWell( InkWell(
onTap: () { onTap: () {
showDialog(context: context, builder: (BuildContext context) { showDialog(context: context, builder: (BuildContext context) {
return AlertDialog( return buildRecipeDialog(pizzaRecipe);
title: Text(pizzaRecipe.name),
content: const Text("What do you want to do?"),
actions: <Widget>[
TextButton(
onPressed: () {
Navigator.pop(context);
Navigator.pushNamed(context, RecipePage.route, arguments: pizzaRecipe);
},
child: const Text("View"),
),
TextButton(
onPressed: () {
Navigator.pop(context);
addPizzaRecipeToBox(pizzaRecipe);
},
child: const Text("Add"),
),
]
);
}); });
}, },
child: PizzaRecipeWidget(pizzaRecipe), child: PizzaRecipeWidget(pizzaRecipe),
@ -206,6 +223,29 @@ class AddRecipeURLPageState extends State<AddRecipeURLPage> {
]; ];
} }
AlertDialog buildRecipeDialog(PizzaRecipe pizzaRecipe){
return AlertDialog(
title: Text(pizzaRecipe.name),
content: const Text("What do you want to do?"),
actions: <Widget>[
TextButton(
onPressed: () {
Navigator.pop(context);
Navigator.pushNamed(context, RecipePage.route, arguments: pizzaRecipe);
},
child: const Text("View"),
),
TextButton(
onPressed: () {
Navigator.pop(context);
addPizzaRecipeToBox(pizzaRecipe);
},
child: const Text("Add"),
),
]
);
}
Future<void> addPizzaRecipeToBox(PizzaRecipe pizzaRecipe) async { Future<void> addPizzaRecipeToBox(PizzaRecipe pizzaRecipe) async {
final pizzaRecipeBox = Hive.box<PizzaRecipe>(PizzaRecipe.hiveName); final pizzaRecipeBox = Hive.box<PizzaRecipe>(PizzaRecipe.hiveName);
if (pizzaRecipeBox.containsKey(pizzaRecipe.key)) { if (pizzaRecipeBox.containsKey(pizzaRecipe.key)) {