+Add quantity field to ingredients

+Clear list now requires confirmation
+Confirm / Cancel buttons are now coloured
This commit is contained in:
Alexander Laevens
2022-12-07 02:13:34 -07:00
parent 31c4505e49
commit 4d0388b262
20 changed files with 396 additions and 83 deletions

View File

@@ -6,8 +6,9 @@ import 'package:one_trip/api/models/list.dart';
import 'package:one_trip/api/models/listingredient.dart';
import 'package:one_trip/api/models/user.dart';
import 'package:one_trip/pages/list_page/widgets/listrow.dart';
import 'package:one_trip/pages/list_page/widgets/search_recipes.dart';
import 'package:one_trip/widgets/text_entry_dialog.dart';
import 'package:one_trip/pages/list_page/widgets/search_recipes_dialog.dart';
import 'package:one_trip/widgets/confirm_dialog.dart';
import 'package:one_trip/widgets/ingredient_dialog.dart';
import 'package:web_socket_channel/web_socket_channel.dart';
class ListPage extends StatefulWidget {
@@ -56,8 +57,8 @@ class _ListPageState extends State<ListPage> {
}
}
},
// ignore: avoid_print
onError: (error) => print("Websocket error: $error"),
onDone: () => print("Websocket Done"),
);
}
@@ -108,15 +109,18 @@ class _ListPageState extends State<ListPage> {
return ListArea(
list: _list!,
onAddOne: () async {
String? itemName =
await textEntryDialog(context, "Item Name", "Item");
IngredientDetails? details =
await ingredientDialog(context, "", "");
if (itemName == null || itemName == "") {
if (details == null || details.name == "") {
return;
}
ListIngredient? newIngredient =
await ListIngredient.create(itemName, _list!.homegroup);
ListIngredient? newIngredient = await ListIngredient.create(
_list!.homegroup,
details.name,
details.quantity != "" ? details.quantity : null);
if (newIngredient == null) {
return;
}
@@ -288,7 +292,12 @@ class ListArea extends StatelessWidget {
foregroundColor: MaterialStatePropertyAll(
Theme.of(context).colorScheme.onError),
),
onPressed: () => onClear(),
onPressed: () async {
bool doDelete = await confirmDialog(context, "Clear List");
if (doDelete) {
onClear();
}
},
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: const [Icon(Icons.delete), Text("Clear List")],

View File

@@ -67,7 +67,9 @@ class _ListRowState extends State<ListRow> {
Expanded(
child: Text(
// _ingredient.name,
widget.ingredient.name,
widget.ingredient.quantity == null
? widget.ingredient.name
: "${widget.ingredient.name} - ${widget.ingredient.quantity}",
style: Theme.of(context).textTheme.titleMedium!.copyWith(
decoration: widget.ingredient.inCart
? TextDecoration.lineThrough

View File

@@ -80,6 +80,7 @@ class _SearchRecipesDialogState extends State<SearchRecipesDialog> {
child: PaginationListView(
state: _listState,
shrinkWrap: true,
prefetchOne: true,
itemBuilder: (context, data) {
return GestureDetector(
behavior: HitTestBehavior.translucent,
@@ -98,7 +99,13 @@ class _SearchRecipesDialogState extends State<SearchRecipesDialog> {
color: selectedIDs.contains(data.id)
? Theme.of(context).colorScheme.secondary
: null,
child: Text(data.name),
child: Text(
data.name,
style: TextStyle(
color: selectedIDs.contains(data.id)
? Theme.of(context).colorScheme.onSecondary
: null),
),
),
);
},
@@ -106,16 +113,6 @@ class _SearchRecipesDialogState extends State<SearchRecipesDialog> {
return const Divider();
},
dataProvider: (int page) async {
// SearchResult<SimpleUser> result =
// await SimpleUser.search(_searchController.text, page);
// List<dynamic> users = List<dynamic>.from(result.results);
// if (result.next == null) {
// users.add(null);
// }
// return users;
SearchResult<Recipe> result =
await Recipe.search(_searchController.text, page);
List<dynamic> recipes =
@@ -137,12 +134,15 @@ class _SearchRecipesDialogState extends State<SearchRecipesDialog> {
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
ElevatedButton(
style: negativeButtonStyle(context),
onPressed: () => Navigator.pop(context),
child: const Text("Cancel"),
),
ElevatedButton(
onPressed: () => Navigator.pop(context, selectedIDs),
child: const Text("Done")),
style: positiveButtonStyle(context),
onPressed: () => Navigator.pop(context, selectedIDs),
child: const Text("Done"),
),
],
),
)

View File

@@ -139,12 +139,15 @@ class _InviteHomegroupDialogState extends State<InviteHomegroupDialog> {
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
ElevatedButton(
style: negativeButtonStyle(context),
onPressed: () => Navigator.pop(context),
child: const Text("Cancel"),
),
ElevatedButton(
onPressed: () => Navigator.pop(context, selectedIDs),
child: const Text("Done")),
style: positiveButtonStyle(context),
onPressed: () => Navigator.pop(context, selectedIDs),
child: const Text("Done"),
),
],
),
)

View File

@@ -4,7 +4,7 @@ import 'package:flutter/material.dart';
import 'package:one_trip/api/models/recipeingredient.dart';
import 'package:one_trip/api/models/recipe.dart';
import 'package:one_trip/theme.dart';
import 'package:one_trip/widgets/text_entry_dialog.dart';
import 'package:one_trip/widgets/ingredient_dialog.dart';
class RecipeCard extends StatefulWidget {
final Recipe recipe;
@@ -145,15 +145,18 @@ class _RecipeCardState extends State<RecipeCard> with TickerProviderStateMixin {
shape: const MaterialStatePropertyAll(
RoundedRectangleBorder())),
onPressed: () async {
String? name = await textEntryDialog(
context, "Ingredient Name", "Ingredient");
IngredientDetails? details =
await ingredientDialog(context, "", "");
if (name == null || name == "") {
if (details == null || details.name == "") {
return;
}
RecipeIngredient? ingredient =
await RecipeIngredient.create(name, widget.recipe.id);
await RecipeIngredient.create(
widget.recipe.id,
details.name,
details.quantity != "" ? details.quantity : null);
if (ingredient != null) {
widget.onChanged();
}
@@ -233,21 +236,29 @@ class _IngredientSectionState extends State<IngredientSection> {
children: [
Expanded(
child: Text(
widget.ingredients[index].name,
widget.ingredients[index].quantity == null
? widget.ingredients[index].name
: "${widget.ingredients[index].name} - ${widget.ingredients[index].quantity}",
style: Theme.of(context).textTheme.titleMedium,
)),
IconButton(
onPressed: () async {
String? name = await textEntryDialog(
context, "Change Ingredient Name", "Ingredient",
defaultValue: widget.ingredients[index].name);
IngredientDetails? details = await ingredientDialog(
context,
widget.ingredients[index].name,
widget.ingredients[index].quantity ?? "");
if (name == null || name == "") {
if (details == null || details.name == "") {
return;
}
RecipeIngredient? changed =
await widget.ingredients[index].patch(name);
await widget.ingredients[index].patch(
name: details.name,
quantity: details.quantity != ""
? details.quantity
: null);
if (changed != null) {
widget.onChanged();
}