From 7bf48b0200e5f0cbc83045ae507ec357d95e33ed Mon Sep 17 00:00:00 2001 From: cli1005 <87010739+cli1005@users.noreply.github.com> Date: Thu, 7 Apr 2022 10:25:09 +0200 Subject: [PATCH] feat: #1034 - tap to open search card (#1502) --- .../data_models/continuous_scan_model.dart | 2 +- .../onboarding/onboarding_flow_navigator.dart | 3 +- .../smooth_app/lib/pages/page_manager.dart | 23 ++++++-- .../lib/pages/product/new_product_page.dart | 2 +- .../pages/scan/inherited_data_manager.dart | 58 +++++++++++++++++++ .../lib/pages/scan/scanner_overlay.dart | 2 +- .../lib/widgets/smooth_product_carousel.dart | 26 ++++++--- 7 files changed, 98 insertions(+), 18 deletions(-) create mode 100644 packages/smooth_app/lib/pages/scan/inherited_data_manager.dart diff --git a/packages/smooth_app/lib/data_models/continuous_scan_model.dart b/packages/smooth_app/lib/data_models/continuous_scan_model.dart index 4a0a0eb74a9..094a220cb61 100644 --- a/packages/smooth_app/lib/data_models/continuous_scan_model.dart +++ b/packages/smooth_app/lib/data_models/continuous_scan_model.dart @@ -60,7 +60,7 @@ class ContinuousScanModel with ChangeNotifier { _states.clear(); _latestScannedBarcode = null; await refreshProductList(); - for (final String barcode in _productList.barcodes.reversed) { + for (final String barcode in _productList.barcodes) { _barcodes.add(barcode); _states[barcode] = ScannedProductState.CACHED; _latestScannedBarcode = barcode; diff --git a/packages/smooth_app/lib/pages/onboarding/onboarding_flow_navigator.dart b/packages/smooth_app/lib/pages/onboarding/onboarding_flow_navigator.dart index dc606ab091e..620243be4fb 100644 --- a/packages/smooth_app/lib/pages/onboarding/onboarding_flow_navigator.dart +++ b/packages/smooth_app/lib/pages/onboarding/onboarding_flow_navigator.dart @@ -9,6 +9,7 @@ import 'package:smooth_app/pages/onboarding/sample_health_card_page.dart'; import 'package:smooth_app/pages/onboarding/scan_example.dart'; import 'package:smooth_app/pages/onboarding/welcome_page.dart'; import 'package:smooth_app/pages/page_manager.dart'; +import 'package:smooth_app/pages/scan/inherited_data_manager.dart'; import 'package:smooth_app/themes/constant_icons.dart'; enum OnboardingPage { @@ -109,7 +110,7 @@ class OnboardingFlowNavigator { return _wrapWidgetInCustomBackNavigator( context, page, const ConsentAnalytics()); case OnboardingPage.ONBOARDING_COMPLETE: - return PageManager(); + return InheritedDataManager(child: PageManager()); } } diff --git a/packages/smooth_app/lib/pages/page_manager.dart b/packages/smooth_app/lib/pages/page_manager.dart index 8057bcfff84..b1fbbff0003 100644 --- a/packages/smooth_app/lib/pages/page_manager.dart +++ b/packages/smooth_app/lib/pages/page_manager.dart @@ -1,5 +1,6 @@ import 'package:flutter/material.dart'; import 'package:flutter_gen/gen_l10n/app_localizations.dart'; +import 'package:smooth_app/pages/scan/inherited_data_manager.dart'; import 'package:smooth_app/widgets/tab_navigator.dart'; enum BottomNavigationTab { @@ -34,6 +35,7 @@ class PageManagerState extends State { }; BottomNavigationTab _currentPage = BottomNavigationTab.Scan; + List _tabs = []; void _selectTab(BottomNavigationTab tabItem, int index) { if (tabItem == _currentPage) { @@ -50,6 +52,12 @@ class PageManagerState extends State { @override Widget build(BuildContext context) { final AppLocalizations appLocalizations = AppLocalizations.of(context)!; + _tabs = [ + _buildOffstageNavigator(BottomNavigationTab.Profile), + _buildOffstageNavigator(BottomNavigationTab.Scan), + _buildOffstageNavigator(BottomNavigationTab.History), + ]; + final ThemeData themeData = Theme.of(context); final bool brightnessCheck = themeData.brightness == Brightness.light; return WillPopScope( @@ -66,11 +74,7 @@ class PageManagerState extends State { return isFirstRouteInCurrentTab; }, child: Scaffold( - body: Stack(children: [ - _buildOffstageNavigator(BottomNavigationTab.Profile), - _buildOffstageNavigator(BottomNavigationTab.Scan), - _buildOffstageNavigator(BottomNavigationTab.History), - ]), + body: Stack(children: _tabs), bottomNavigationBar: BottomNavigationBar( unselectedItemColor: brightnessCheck ? Colors.black : Colors.grey, showSelectedLabels: false, @@ -78,7 +82,14 @@ class PageManagerState extends State { selectedItemColor: Colors.white, backgroundColor: Theme.of(context).appBarTheme.backgroundColor, onTap: (int index) { - _selectTab(_pageKeys[index], index); + if (_currentPage == BottomNavigationTab.Scan && + _pageKeys[index] == BottomNavigationTab.Scan) { + InheritedDataManager.of(context).resetShowSearchCard(true); + _selectTab(_pageKeys[index], index); + } else { + InheritedDataManager.of(context).resetShowSearchCard(false); + _selectTab(_pageKeys[index], index); + } }, currentIndex: _currentPage.index, items: [ diff --git a/packages/smooth_app/lib/pages/product/new_product_page.dart b/packages/smooth_app/lib/pages/product/new_product_page.dart index 29fee31d3e8..0e372b8a6b8 100644 --- a/packages/smooth_app/lib/pages/product/new_product_page.dart +++ b/packages/smooth_app/lib/pages/product/new_product_page.dart @@ -70,7 +70,7 @@ class _ProductPageState extends State { ? FloatingActionButton( backgroundColor: colorScheme.primary, onPressed: () { - Navigator.pop(context); + Navigator.maybePop(context); }, child: Icon( ConstantIcons.instance.getBackIcon(), diff --git a/packages/smooth_app/lib/pages/scan/inherited_data_manager.dart b/packages/smooth_app/lib/pages/scan/inherited_data_manager.dart new file mode 100644 index 00000000000..becd3e84a15 --- /dev/null +++ b/packages/smooth_app/lib/pages/scan/inherited_data_manager.dart @@ -0,0 +1,58 @@ +import 'package:flutter/material.dart'; + +class InheritedDataManager extends StatefulWidget { + const InheritedDataManager({ + Key? key, + required this.child, + }) : super(key: key); + + final Widget child; + + static InheritedDataManagerState of(BuildContext context) { + return context + .dependOnInheritedWidgetOfExactType<_InheritedDataManagerProvider>()! + .data; + } + + @override + State createState() => InheritedDataManagerState(); +} + +class InheritedDataManagerState extends State { + late bool showSearchCard; + + @override + void initState() { + showSearchCard = false; + super.initState(); + } + + void resetShowSearchCard(bool newValue) { + setState(() { + showSearchCard = newValue; + }); + } + + @override + Widget build(BuildContext context) { + return _InheritedDataManagerProvider( + data: this, + child: widget.child, + ); + } +} + +class _InheritedDataManagerProvider extends InheritedWidget { + const _InheritedDataManagerProvider({ + Key? key, + required this.data, + required Widget child, + }) : super(key: key, child: child); + + final InheritedDataManagerState data; + + @override + bool updateShouldNotify(_InheritedDataManagerProvider oldWidget) { + return data.showSearchCard; + } +} diff --git a/packages/smooth_app/lib/pages/scan/scanner_overlay.dart b/packages/smooth_app/lib/pages/scan/scanner_overlay.dart index 3659858c566..20f636a4e49 100644 --- a/packages/smooth_app/lib/pages/scan/scanner_overlay.dart +++ b/packages/smooth_app/lib/pages/scan/scanner_overlay.dart @@ -89,7 +89,7 @@ class ScannerOverlay extends StatelessWidget { Padding( padding: const EdgeInsets.only(bottom: 10.0), child: SmoothProductCarousel( - showSearchCard: true, + containSearchCard: true, height: carouselHeight, ), ), diff --git a/packages/smooth_app/lib/widgets/smooth_product_carousel.dart b/packages/smooth_app/lib/widgets/smooth_product_carousel.dart index db872b56f93..670fb06215f 100644 --- a/packages/smooth_app/lib/widgets/smooth_product_carousel.dart +++ b/packages/smooth_app/lib/widgets/smooth_product_carousel.dart @@ -10,16 +10,17 @@ import 'package:smooth_app/cards/product_cards/smooth_product_card_not_found.dar import 'package:smooth_app/cards/product_cards/smooth_product_card_thanks.dart'; import 'package:smooth_app/data_models/continuous_scan_model.dart'; import 'package:smooth_app/generic_lib/widgets/smooth_card.dart'; +import 'package:smooth_app/pages/scan/inherited_data_manager.dart'; import 'package:smooth_app/pages/scan/scan_product_card.dart'; import 'package:smooth_app/pages/scan/search_page.dart'; class SmoothProductCarousel extends StatefulWidget { const SmoothProductCarousel({ - this.showSearchCard = false, + this.containSearchCard = false, required this.height, }); - final bool showSearchCard; + final bool containSearchCard; final double height; @override @@ -29,18 +30,22 @@ class SmoothProductCarousel extends StatefulWidget { class _SmoothProductCarouselState extends State { final CarouselController _controller = CarouselController(); List barcodes = []; + bool _returnToSearchCard = false; - int get _searchCardAdjustment => widget.showSearchCard ? 1 : 0; + int get _searchCardAdjustment => widget.containSearchCard ? 1 : 0; @override void didChangeDependencies() { super.didChangeDependencies(); final ContinuousScanModel model = context.watch(); - setState(() { - barcodes = model.getBarcodes(); - }); + barcodes = model.getBarcodes(); + _returnToSearchCard = InheritedDataManager.of(context).showSearchCard; if (_controller.ready) { - _controller.animateToPage(barcodes.length - 1 + _searchCardAdjustment); + if (_returnToSearchCard && widget.containSearchCard) { + _controller.animateToPage(0); + } else { + _controller.animateToPage(barcodes.length - 1 + _searchCardAdjustment); + } } } @@ -51,7 +56,7 @@ class _SmoothProductCarouselState extends State { itemBuilder: (BuildContext context, int itemIndex, int itemRealIndex) { return Padding( padding: const EdgeInsets.symmetric(horizontal: 2.0), - child: widget.showSearchCard && itemIndex == 0 + child: widget.containSearchCard && itemIndex == 0 ? SearchCard(height: widget.height) : _getWidget(itemIndex - _searchCardAdjustment), ); @@ -62,6 +67,11 @@ class _SmoothProductCarouselState extends State { viewportFraction: 0.91, height: widget.height, enableInfiniteScroll: false, + onPageChanged: (int index, CarouselPageChangedReason reason) { + if (index > 0 && InheritedDataManager.of(context).showSearchCard) { + InheritedDataManager.of(context).resetShowSearchCard(false); + } + }, ), ); }