added loading of pizza recipe yaml from url

This commit is contained in:
broodjeaap89 2021-09-12 17:35:44 +02:00
parent 24c2497b66
commit a82ad9f375
5 changed files with 185 additions and 5 deletions

View file

@ -7,6 +7,7 @@ import 'package:pizzaplanner/entities/PizzaRecipe/pizza_recipe.dart';
import 'package:pizzaplanner/entities/PizzaRecipe/recipe_step.dart';
import 'package:pizzaplanner/entities/PizzaRecipe/recipe_substep.dart';
import 'package:pizzaplanner/pages/add_pizza_event_page.dart';
import 'package:pizzaplanner/pages/add_recipe_url.dart';
import 'package:pizzaplanner/pages/edit_recipe_page.dart';
import 'package:pizzaplanner/pages/edit_recipe_step_page.dart';
import 'package:pizzaplanner/pages/edit_recipe_sub_step_page.dart';
@ -187,6 +188,9 @@ class RouteGenerator {
}
return MaterialPageRoute(builder: (context) => EditRecipeSubStepPage(subStep));
}
case "/recipes/add/url": {
return MaterialPageRoute(builder: (context) => AddRecipeURLPage(settings.arguments as String?));
}
default: {
return MaterialPageRoute(builder: (context) => PizzaEventsPage());
}

View file

@ -0,0 +1,151 @@
import 'package:flutter/material.dart';
import 'package:hive_flutter/hive_flutter.dart';
import 'package:pizzaplanner/entities/PizzaRecipe/pizza_recipe.dart';
import 'package:pizzaplanner/pages/scaffold.dart';
import 'package:http/http.dart' as http;
import 'package:pizzaplanner/widgets/pizza_recipe_widget.dart';
class AddRecipeURLPage extends StatefulWidget {
final String? url;
const AddRecipeURLPage(this.url);
@override
AddRecipeURLPageState createState() => AddRecipeURLPageState();
}
class AddRecipeURLPageState extends State<AddRecipeURLPage> {
String? url;
String tempUrl = "?";
List<Widget> itemList = <Widget>[];
@override
void initState() {
super.initState();
url = widget.url;
}
@override
Widget build(BuildContext context){
return PizzaPlannerScaffold(
title: const Text("Fetch Pizza Recipe"),
body: Column(
children: <Widget>[
Expanded(
flex: 5,
child: InkWell(
onTap: () async {
showDialog(context: context, builder: (BuildContext context) {
return AlertDialog(
title: const Text("URL"),
content: TextFormField(
decoration: const InputDecoration(
hintText: "Recipe URL",
),
initialValue: url ?? "",
onChanged: (String newUrl) {
setState(() {
tempUrl = newUrl;
});
},
),
actions: <Widget>[
TextButton(
onPressed: () {
Navigator.pop(context);
},
child: const Text("Cancel"),
),
TextButton(
onPressed: () {
Navigator.pop(context);
url = tempUrl;
setState(() {
fetchUrl();
});
},
child: const Text("Fetch"),
),
],
);
});
},
child: Text(url ?? "?"),
),
),
Expanded(
flex: 45,
child: ListView(
children: itemList,
)
)
]
)
);
}
Future<void> fetchUrl() async {
if (url == null){
return;
}
final uri = Uri.parse(url!);
if (!uri.isAbsolute){
return;
}
try {
final response = await http.get(uri);
if (response.statusCode != 200) {
return;
}
final yamlBody = response.body;
final pizzaRecipe = await PizzaRecipe.fromYaml(yamlBody);
itemList.clear();
itemList.add(
InkWell(
onTap: () {
showDialog(context: context, builder: (BuildContext context) {
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, "/recipe/view", arguments: pizzaRecipe);
},
child: const Text("View"),
),
TextButton(
onPressed: () {
Navigator.pop(context);
addPizzaRecipeToBox(pizzaRecipe);
},
child: const Text("Add"),
),
]
);
});
},
child: PizzaRecipeWidget(pizzaRecipe),
)
);
} catch (exception) {
print(exception);
return;
}
}
Future<void> addPizzaRecipeToBox(PizzaRecipe pizzaRecipe) async {
final pizzaRecipeBox = Hive.box<PizzaRecipe>("PizzaRecipes");
if (pizzaRecipeBox.containsKey(pizzaRecipe.key)) {
return; // this recipe is already in the box
}
setState(() {
pizzaRecipeBox.add(pizzaRecipe);
});
}
}

View file

@ -154,7 +154,30 @@ class RecipesPageState extends State<RecipesPage> {
width: double.infinity,
child: TextButton(
onPressed: () async {
loadRecipe();
FocusScope.of(context).unfocus();
showDialog(context: context, builder: (BuildContext context) {
return AlertDialog(
title: const Text("Source"),
content: const Text("Add from a local file or from an URL?"),
actions: <Widget>[
TextButton(
onPressed: () {
Navigator.pop(context);
loadLocalRecipe();
},
child: const Text("Local"),
),
TextButton(
onPressed: () {
Navigator.pop(context);
Navigator.pushNamed(context, "/recipes/add/url");
},
child: const Text("URL"),
)
]
);
});
},
child: const Text("Load Recipe", style: TextStyle(color: Colors.white)),
)
@ -185,7 +208,7 @@ class RecipesPageState extends State<RecipesPage> {
);
}
Future<void> loadRecipe() async {
Future<void> loadLocalRecipe() async {
final result = await FilePicker.platform.pickFiles();
if (result == null){
return;

View file

@ -56,6 +56,8 @@ dependencies:
file_picker: ^4.0.2
http: ^0.13.3
dev_dependencies:
flutter_test:
sdk: flutter

View file

@ -2,9 +2,7 @@
## Feature
- add 'capturing' sharing intent
- add import of recipes
- from raw url
- maybe allow a 'dir' yaml, that just points to other raw pizza yaml urls
- maybe allow a 'dir' yaml when importing from url, that just points to other raw pizza yaml urls
- add settings page
- option for type of notification, full screen or just in the appbar
- pick alarm sound
@ -15,6 +13,8 @@
- RecipeStep.waitUnit should probably be an enum?
- refactor to const page names instead of loose strings everywhere ('/path/page')
- also do this with hive box names
- make the url fetching less shit
- probably use a stream for adding to the listview ?
## Bug
- add option to start recipe step instruction after step datetime and not completed