From 00eb7808d8885f55b11f249f177c96c1180ce55d Mon Sep 17 00:00:00 2001 From: Jonas Franz Date: Sat, 19 Feb 2022 14:10:53 +0100 Subject: [PATCH] Add user store --- lib/app.dart | 30 ++++++---- lib/screens/cart/cart_screen.dart | 2 +- .../product_list/product_list_screen.dart | 2 +- lib/stores/user_store.dart | 56 +++++++++++++++++++ lib/widgets/user_switch.dart | 13 ++--- 5 files changed, 82 insertions(+), 21 deletions(-) create mode 100644 lib/stores/user_store.dart diff --git a/lib/app.dart b/lib/app.dart index c755039..6c097dd 100644 --- a/lib/app.dart +++ b/lib/app.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/user_store.dart'; import 'package:thesis_shop/utils/map_keys_extension.dart'; class ThesisShopApp extends StatelessWidget { @@ -10,20 +11,27 @@ class ThesisShopApp extends StatelessWidget { const ThesisShopApp({Key? key, required this.productService}) : super(key: key); + Widget injectStores(BuildContext context, {required Widget child}) { + return UserStoreImplementation(child: child); + } + @override Widget build(BuildContext context) { - return MaterialApp( - title: 'Thesis Shop', - theme: ThemeData(primarySwatch: Colors.red), - darkTheme: ThemeData( - primarySwatch: Colors.red, - brightness: Brightness.dark, + return injectStores( + context, + child: MaterialApp( + title: 'Thesis Shop', + theme: ThemeData(primarySwatch: Colors.red), + darkTheme: ThemeData( + primarySwatch: Colors.red, + brightness: Brightness.dark, + ), + routes: { + RouteKey.products: (context) => const ProductListScreen(), + RouteKey.cart: (context) => const CartScreen(), + }.mapKeys((key) => key.name), + initialRoute: 'products', ), - routes: { - RouteKey.products: (context) => const ProductListScreen(), - RouteKey.cart: (context) => const CartScreen(), - }.mapKeys((key) => key.name), - initialRoute: 'products', ); } } diff --git a/lib/screens/cart/cart_screen.dart b/lib/screens/cart/cart_screen.dart index 3e7ded1..2d389b0 100644 --- a/lib/screens/cart/cart_screen.dart +++ b/lib/screens/cart/cart_screen.dart @@ -12,7 +12,7 @@ class CartScreen extends StatelessWidget { return Scaffold( appBar: AppBar( title: const Text('Warenkorb'), - actions: [UserSwitch(isOn: true, onChanged: (_) {})], + actions: const [UserSwitch()], ), body: Column( mainAxisSize: MainAxisSize.max, diff --git a/lib/screens/product_list/product_list_screen.dart b/lib/screens/product_list/product_list_screen.dart index 30ce3a8..e623621 100644 --- a/lib/screens/product_list/product_list_screen.dart +++ b/lib/screens/product_list/product_list_screen.dart @@ -21,7 +21,7 @@ class ProductListScreen extends StatelessWidget { return Scaffold( appBar: AppBar( title: const Text('Thesis Shop'), - actions: [UserSwitch(isOn: true, onChanged: (_) {})], + actions: const [UserSwitch()], ), body: const CartButtonOverlay( child: ProductList(products: products), diff --git a/lib/stores/user_store.dart b/lib/stores/user_store.dart new file mode 100644 index 0000000..61d13d3 --- /dev/null +++ b/lib/stores/user_store.dart @@ -0,0 +1,56 @@ +import 'package:flutter/material.dart'; + +typedef BoolSetter = Function(bool isSignedIn); + +class UserStoreImplementation extends StatefulWidget { + final Widget child; + const UserStoreImplementation({Key? key, required this.child}) + : super(key: key); + + @override + _UserStoreImplementationState createState() => + _UserStoreImplementationState(); +} + +class _UserStoreImplementationState extends State { + bool _isSignedIn = false; + + void _updateSignedIn(bool newValue) => setState( + () { + _isSignedIn = newValue; + }, + ); + + @override + Widget build(BuildContext context) { + return UserStore( + isSignedIn: _isSignedIn, + setIsSignedIn: _updateSignedIn, + child: widget.child, + ); + } +} + +class UserStore extends InheritedWidget { + const UserStore({ + Key? key, + required this.isSignedIn, + required this.setIsSignedIn, + required Widget child, + }) : super(key: key, child: child); + + final bool isSignedIn; + final BoolSetter setIsSignedIn; + + static UserStore of(BuildContext context) { + final UserStore? result = + context.dependOnInheritedWidgetOfExactType(); + assert(result != null, 'No UserStore found in context'); + return result!; + } + + @override + bool updateShouldNotify(UserStore oldWidget) { + return oldWidget.isSignedIn != isSignedIn; + } +} diff --git a/lib/widgets/user_switch.dart b/lib/widgets/user_switch.dart index 63107e7..a0e04fe 100644 --- a/lib/widgets/user_switch.dart +++ b/lib/widgets/user_switch.dart @@ -1,24 +1,21 @@ import 'package:flutter/material.dart'; import 'package:thesis_shop/benchmark_counter.dart'; +import 'package:thesis_shop/stores/user_store.dart'; class UserSwitch extends StatelessWidget { - final bool isOn; - final ValueChanged onChanged; - const UserSwitch({ - required this.isOn, - required this.onChanged, - }) : super(key: const Key('user_switch')); + const UserSwitch() : super(key: const Key('user_switch')); @override Widget build(BuildContext context) { + final userStore = UserStore.of(context); BenchmarkCounters.userSwitch++; return Row( mainAxisSize: MainAxisSize.min, children: [ const Icon(Icons.account_circle), Switch( - value: isOn, - onChanged: onChanged, + value: userStore.isSignedIn, + onChanged: userStore.setIsSignedIn, activeColor: Colors.green, ) ],