added loading of pizza recipe yaml from url
This commit is contained in:
parent
24c2497b66
commit
a82ad9f375
5 changed files with 185 additions and 5 deletions
|
@ -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());
|
||||
}
|
||||
|
|
151
lib/pages/add_recipe_url.dart
Normal file
151
lib/pages/add_recipe_url.dart
Normal 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);
|
||||
});
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
|
|
|
@ -56,6 +56,8 @@ dependencies:
|
|||
|
||||
file_picker: ^4.0.2
|
||||
|
||||
http: ^0.13.3
|
||||
|
||||
dev_dependencies:
|
||||
flutter_test:
|
||||
sdk: flutter
|
||||
|
|
6
todo.md
6
todo.md
|
@ -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
|
||||
|
|
Loading…
Add table
Reference in a new issue