1
0
Fork 0

Implement cart store

inheritedwidget
Jonas Franz 2 years ago
parent c56cdd1314
commit 1ddb63525f
  1. 5
      lib/app.dart
  2. 4
      lib/screens/product_list/cart_button.dart
  3. 8
      lib/screens/product_list/product_item.dart
  4. 82
      lib/stores/cart_store.dart
  5. 31
      lib/stores/product_selection_store.dart
  6. 6
      lib/stores/product_store.dart

@ -3,6 +3,7 @@ import 'package:thesis_shop/route_key.dart';
import 'package:thesis_shop/screens/cart/cart_screen.dart';
import 'package:thesis_shop/screens/product_list/product_list_screen.dart';
import 'package:thesis_shop/service/product_service.dart';
import 'package:thesis_shop/stores/cart_store.dart';
import 'package:thesis_shop/stores/product_store.dart';
import 'package:thesis_shop/stores/user_store.dart';
import 'package:thesis_shop/utils/map_keys_extension.dart';
@ -16,7 +17,9 @@ class ThesisShopApp extends StatelessWidget {
return UserStoreImplementation(
child: ProductStoreImplementation(
productService: productService,
child: child,
child: CartStoreImplementation(
child: child,
),
),
);
}

@ -1,17 +1,19 @@
import 'package:flutter/material.dart';
import 'package:thesis_shop/benchmark_counter.dart';
import 'package:thesis_shop/route_key.dart';
import 'package:thesis_shop/stores/cart_store.dart';
class CartButton extends StatelessWidget {
const CartButton() : super(key: const Key('cart_button'));
@override
Widget build(BuildContext context) {
final cartStore = CartStore.of(context);
BenchmarkCounters.cartButton++;
return ElevatedButton.icon(
onPressed: () => Navigator.of(context).pushRouteKey(RouteKey.cart),
icon: const Icon(Icons.shopping_basket),
label: const Text('Warenkorb (3 Produkte)'),
label: Text('Warenkorb (${cartStore.cartItems.length} Produkte)'),
);
}
}

@ -1,5 +1,6 @@
import 'package:flutter/material.dart';
import 'package:thesis_shop/models/product.dart';
import 'package:thesis_shop/stores/cart_store.dart';
import 'package:thesis_shop/widgets/number_picker.dart';
class ProductItem extends StatelessWidget {
@ -8,9 +9,14 @@ class ProductItem extends StatelessWidget {
@override
Widget build(BuildContext context) {
final cartStore = CartStore.of(context);
return ListTile(
title: Text('${product.title} (${product.priceAsString}€/Stück)'),
trailing: NumberPicker(value: 5, onUp: () {}, onDown: () {}),
trailing: NumberPicker(
value: cartStore.amountOfProduct(product),
onUp: () => cartStore.increaseAmount(product),
onDown: () => cartStore.decreaseAmount(product),
),
);
}
}

@ -0,0 +1,82 @@
import 'package:flutter/material.dart';
import 'package:thesis_shop/models/cart_item.dart';
import 'package:thesis_shop/models/product.dart';
import 'package:thesis_shop/stores/product_store.dart';
class CartStoreImplementation extends StatefulWidget {
final Widget child;
const CartStoreImplementation({Key? key, required this.child})
: super(key: key);
@override
_CartStoreImplementationState createState() =>
_CartStoreImplementationState();
}
class _CartStoreImplementationState extends State<CartStoreImplementation> {
Map<ProductTitle, int> productAmounts = {};
void increaseAmount(Product product) => setState(() {
final currentAmount =
productAmounts.putIfAbsent(product.title, () => 0);
productAmounts[product.title] = currentAmount + 1;
});
void decreaseAmount(Product product) => setState(() {
final currentAmount =
productAmounts.putIfAbsent(product.title, () => 0);
productAmounts[product.title] =
currentAmount <= 0 ? 0 : currentAmount - 1;
});
@override
Widget build(BuildContext context) {
final products = ProductStore.of(context).productsOrNull ?? const [];
final productsByTitle = {
for (var product in products) product.title: product
};
final cartItems = productAmounts
.map((key, value) => MapEntry(productsByTitle[key], value))
.entries
.where((entry) => entry.key != null && entry.value > 0)
.map((entry) => CartItem(product: entry.key!, amount: entry.value))
.toList();
return CartStore(
cartItems: cartItems,
increaseAmount: increaseAmount,
decreaseAmount: decreaseAmount,
child: widget.child,
);
}
}
class CartStore extends InheritedWidget {
const CartStore({
Key? key,
required this.cartItems,
required this.increaseAmount,
required this.decreaseAmount,
required Widget child,
}) : super(key: key, child: child);
final List<CartItem> cartItems;
final Function(Product) increaseAmount;
final Function(Product) decreaseAmount;
int amountOfProduct(Product product) {
final amounts = {
for (final item in cartItems) item.product: item.amount,
};
return amounts.putIfAbsent(product, () => 0);
}
static CartStore of(BuildContext context) {
final CartStore? result =
context.dependOnInheritedWidgetOfExactType<CartStore>();
assert(result != null, 'No CartStore found in context');
return result!;
}
@override
bool updateShouldNotify(CartStore oldWidget) {
return cartItems != oldWidget.cartItems;
}
}

@ -1,31 +0,0 @@
import 'package:flutter/material.dart';
import 'package:thesis_shop/models/product.dart';
class ProductSelectionStore extends InheritedWidget {
const ProductSelectionStore({
Key? key,
required this.products,
required this.productAmounts,
required this.increaseAmount,
required this.decreaseAmount,
required Widget child,
}) : super(key: key, child: child);
final List<Product> products;
final Map<ProductTitle, int> productAmounts;
final Function(Product) increaseAmount;
final Function(Product) decreaseAmount;
static ProductSelectionStore of(BuildContext context) {
final ProductSelectionStore? result =
context.dependOnInheritedWidgetOfExactType<ProductSelectionStore>();
assert(result != null, 'No ProductSelectionStore found in context');
return result!;
}
@override
bool updateShouldNotify(ProductSelectionStore oldWidget) {
return productAmounts != oldWidget.productAmounts;
}
}

@ -55,6 +55,12 @@ class ProductStore extends InheritedWidget {
final RemoteResource<List<Product>> products;
List<Product> get mustProducts => products.asFinished().value;
List<Product>? get productsOrNull {
if (products is FinishedRemoteResource) {
return mustProducts;
}
return null;
}
static ProductStore of(BuildContext context) {
final ProductStore? result =

Loading…
Cancel
Save