Skip to content

Commit

Permalink
Rework how the carousel is managed (openfoodfacts#4403)
Browse files Browse the repository at this point in the history
  • Loading branch information
g123k authored Jul 31, 2023
1 parent e3b4768 commit a6cdcaf
Show file tree
Hide file tree
Showing 9 changed files with 114 additions and 123 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import 'package:smooth_app/generic_lib/design_constants.dart';
import 'package:smooth_app/generic_lib/widgets/smooth_card.dart';
import 'package:smooth_app/knowledge_panel/knowledge_panels/knowledge_panel_expanded_card.dart';
import 'package:smooth_app/knowledge_panel/knowledge_panels_builder.dart';
import 'package:smooth_app/pages/inherited_data_manager.dart';
import 'package:smooth_app/pages/carousel_manager.dart';
import 'package:smooth_app/pages/product/common/product_refresher.dart';
import 'package:smooth_app/widgets/smooth_app_bar.dart';
import 'package:smooth_app/widgets/smooth_scaffold.dart';
Expand Down Expand Up @@ -81,12 +81,13 @@ class _KnowledgePanelPageState extends State<KnowledgePanelPage>

Future<void> _refreshProduct(BuildContext context) async {
try {
final String barcode = InheritedDataManager.of(context).currentBarcode;
if (barcode.isEmpty) {
final String? barcode =
ExternalCarouselManager.read(context).currentBarcode;
if (barcode?.isEmpty == true) {
return;
}
await ProductRefresher().fetchAndRefresh(
barcode: barcode,
barcode: barcode ?? '',
widget: this,
);
} catch (e) {
Expand Down
86 changes: 86 additions & 0 deletions packages/smooth_app/lib/pages/carousel_manager.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
import 'package:carousel_slider/carousel_controller.dart';
import 'package:flutter/material.dart';
import 'package:smooth_app/helpers/haptic_feedback_helper.dart';

class ExternalCarouselManager extends StatefulWidget {
const ExternalCarouselManager({
super.key,
required this.child,
});

final Widget child;

static ExternalCarouselManagerState watch(BuildContext context) {
return context
.dependOnInheritedWidgetOfExactType<_InheritedCarouselManager>()!
.state;
}

static ExternalCarouselManagerState? find(BuildContext context) {
return context
.findAncestorWidgetOfExactType<_InheritedCarouselManager>()
?.state;
}

static ExternalCarouselManagerState read(BuildContext context) {
return find(context)!;
}

@override
State<ExternalCarouselManager> createState() =>
ExternalCarouselManagerState();
}

class ExternalCarouselManagerState extends State<ExternalCarouselManager> {
final CarouselController _controller = CarouselController();

String? _currentBarcode;

@override
Widget build(BuildContext context) {
return _InheritedCarouselManager(
state: this,
child: widget.child,
);
}

void showSearchCard({bool notify = false}) {
animatePageTo(0);

if (notify) {
SmoothHapticFeedback.lightNotification();
}
}

// With an animation
void animatePageTo(int page) => _controller.animateToPage(page);

// Without an animation
void moveToSearchCard() => _controller.jumpToPage(0);

CarouselController get controller => _controller;

String? get currentBarcode => _currentBarcode;

set currentBarcode(String? barcode) =>
setState(() => _currentBarcode = barcode);

bool updateShouldNotify(ExternalCarouselManagerState oldState) {
return oldState.currentBarcode != _currentBarcode;
}
}

class _InheritedCarouselManager extends InheritedWidget {
const _InheritedCarouselManager({
required Widget child,
required this.state,
Key? key,
}) : super(key: key, child: child);

final ExternalCarouselManagerState state;

@override
bool updateShouldNotify(_InheritedCarouselManager oldWidget) {
return state.updateShouldNotify(oldWidget.state);
}
}
69 changes: 0 additions & 69 deletions packages/smooth_app/lib/pages/inherited_data_manager.dart

This file was deleted.

6 changes: 3 additions & 3 deletions packages/smooth_app/lib/pages/navigator/app_navigator.dart
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import 'package:smooth_app/data_models/user_preferences.dart';
import 'package:smooth_app/helpers/analytics_helper.dart';
import 'package:smooth_app/helpers/data_importer/smooth_app_data_importer.dart';
import 'package:smooth_app/helpers/extension_on_text_helper.dart';
import 'package:smooth_app/pages/inherited_data_manager.dart';
import 'package:smooth_app/pages/carousel_manager.dart';
import 'package:smooth_app/pages/navigator/error_page.dart';
import 'package:smooth_app/pages/navigator/external_page.dart';
import 'package:smooth_app/pages/onboarding/onboarding_flow_navigator.dart';
Expand Down Expand Up @@ -136,8 +136,8 @@ class _SmoothGoRouter {
heroTag: state.queryParameters['heroTag'],
);

if (InheritedDataManager.find(context) == null) {
return InheritedDataManager(child: widget);
if (ExternalCarouselManager.find(context) == null) {
return ExternalCarouselManager(child: widget);
} else {
return widget;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:smooth_app/data_models/user_preferences.dart';
import 'package:smooth_app/database/local_database.dart';
import 'package:smooth_app/pages/inherited_data_manager.dart';
import 'package:smooth_app/pages/carousel_manager.dart';
import 'package:smooth_app/pages/navigator/app_navigator.dart';
import 'package:smooth_app/pages/onboarding/consent_analytics_page.dart';
import 'package:smooth_app/pages/onboarding/permissions_page.dart';
Expand Down Expand Up @@ -113,7 +113,7 @@ enum OnboardingPage {
ConsentAnalyticsPage(backgroundColor),
);
case OnboardingPage.ONBOARDING_COMPLETE:
return InheritedDataManager(child: PageManager());
return ExternalCarouselManager(child: PageManager());
}
}

Expand Down
30 changes: 6 additions & 24 deletions packages/smooth_app/lib/pages/page_manager.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import 'package:flutter/material.dart';
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
import 'package:provider/provider.dart';
import 'package:smooth_app/data_models/user_preferences.dart';
import 'package:smooth_app/pages/inherited_data_manager.dart';
import 'package:smooth_app/pages/carousel_manager.dart';
import 'package:smooth_app/pages/preferences/user_preferences_dev_mode.dart';
import 'package:smooth_app/widgets/tab_navigator.dart';

Expand Down Expand Up @@ -58,18 +58,6 @@ class PageManagerState extends State<PageManager> {
}
}

@override
void didChangeDependencies() {
super.didChangeDependencies();
final InheritedDataManagerState inheritedDataManager =
InheritedDataManager.of(context);
if (inheritedDataManager.showSearchCard &&
_currentPage != BottomNavigationTab.Scan) {
_currentPage = BottomNavigationTab.Scan;
_selectTab(_currentPage, 1);
}
}

@override
Widget build(BuildContext context) {
final AppLocalizations appLocalizations = AppLocalizations.of(context);
Expand All @@ -85,20 +73,14 @@ class PageManagerState extends State<PageManager> {
true;
final BottomNavigationBar bar = BottomNavigationBar(
onTap: (int index) {
final InheritedDataManagerState inheritedDataManager =
InheritedDataManager.of(context);
final ExternalCarouselManagerState carouselManager =
ExternalCarouselManager.read(context);
if (_currentPage == BottomNavigationTab.Scan &&
_pageKeys[index] == BottomNavigationTab.Scan) {
if (!inheritedDataManager.showSearchCard) {
inheritedDataManager.resetShowSearchCard(true);
}
_selectTab(_pageKeys[index], index);
} else {
if (inheritedDataManager.showSearchCard) {
inheritedDataManager.resetShowSearchCard(false);
}
_selectTab(_pageKeys[index], index);
carouselManager.showSearchCard();
}

_selectTab(_pageKeys[index], index);
},
currentIndex: _currentPage.index,
items: <BottomNavigationBarItem>[
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import 'package:smooth_app/generic_lib/widgets/smooth_responsive.dart';
import 'package:smooth_app/helpers/app_helper.dart';
import 'package:smooth_app/helpers/robotoff_insight_helper.dart';
import 'package:smooth_app/pages/all_product_list_page.dart';
import 'package:smooth_app/pages/inherited_data_manager.dart';
import 'package:smooth_app/pages/carousel_manager.dart';
import 'package:smooth_app/pages/personalized_ranking_page.dart';
import 'package:smooth_app/pages/product/common/product_list_item_simple.dart';
import 'package:smooth_app/pages/product/common/product_list_popup_items.dart';
Expand Down Expand Up @@ -128,7 +128,7 @@ class _ProductListPageState extends State<ProductListPage>
icon: const Icon(CupertinoIcons.barcode),
label: Text(appLocalizations.product_list_empty_title),
onPressed: () =>
InheritedDataManager.of(context).resetShowSearchCard(true),
ExternalCarouselManager.read(context).showSearchCard(),
)
: _selectionMode || products.length <= 1
? _CompareProductsButton(
Expand Down
8 changes: 4 additions & 4 deletions packages/smooth_app/lib/pages/product/new_product_page.dart
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ import 'package:smooth_app/helpers/launch_url_helper.dart';
import 'package:smooth_app/helpers/product_cards_helper.dart';
import 'package:smooth_app/knowledge_panel/knowledge_panels/knowledge_panel_product_cards.dart';
import 'package:smooth_app/knowledge_panel/knowledge_panels_builder.dart';
import 'package:smooth_app/pages/inherited_data_manager.dart';
import 'package:smooth_app/pages/carousel_manager.dart';
import 'package:smooth_app/pages/product/common/product_list_modal.dart';
import 'package:smooth_app/pages/product/common/product_refresher.dart';
import 'package:smooth_app/pages/product/edit_product_page.dart';
Expand Down Expand Up @@ -82,9 +82,9 @@ class _ProductPageState extends State<ProductPage>

@override
Widget build(BuildContext context) {
final InheritedDataManagerState inheritedDataManager =
InheritedDataManager.of(context);
inheritedDataManager.setCurrentBarcode(barcode);
final ExternalCarouselManagerState carouselManager =
ExternalCarouselManager.read(context);
carouselManager.currentBarcode = barcode;
final ThemeData themeData = Theme.of(context);
_productPreferences = context.watch<ProductPreferences>();
context.watch<LocalDatabase>();
Expand Down
21 changes: 6 additions & 15 deletions packages/smooth_app/lib/widgets/smooth_product_carousel.dart
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import 'package:smooth_app/data_models/tagline.dart';
import 'package:smooth_app/data_models/user_preferences.dart';
import 'package:smooth_app/generic_lib/design_constants.dart';
import 'package:smooth_app/helpers/app_helper.dart';
import 'package:smooth_app/pages/inherited_data_manager.dart';
import 'package:smooth_app/pages/carousel_manager.dart';
import 'package:smooth_app/pages/navigator/app_navigator.dart';
import 'package:smooth_app/pages/scan/scan_product_card_loader.dart';
import 'package:smooth_app/pages/scan/search_page.dart';
Expand All @@ -40,9 +40,7 @@ class SmoothProductCarousel extends StatefulWidget {
class _SmoothProductCarouselState extends State<SmoothProductCarousel> {
static const double HORIZONTAL_SPACE_BETWEEN_CARDS = 5.0;

final CarouselController _controller = CarouselController();
List<String> barcodes = <String>[];
bool _returnToSearchCard = false;
String? _lastConsultedBarcode;
int? _carrouselMovingTo;
int _lastIndex = 0;
Expand All @@ -55,7 +53,7 @@ class _SmoothProductCarouselState extends State<SmoothProductCarousel> {
super.didChangeDependencies();
_model = context.watch<ContinuousScanModel>();

if (!_controller.ready) {
if (!ExternalCarouselManager.read(context).controller.ready) {
return;
}

Expand All @@ -73,11 +71,9 @@ class _SmoothProductCarouselState extends State<SmoothProductCarousel> {
}

_lastConsultedBarcode = _model.latestConsultedBarcode;
_returnToSearchCard = InheritedDataManager.of(context).showSearchCard;
final int cardsCount = barcodes.length + _searchCardAdjustment;
if (_returnToSearchCard && widget.containSearchCard && _lastIndex > 0) {
_moveControllerTo(0);
} else if (_model.latestConsultedBarcode != null &&

if (_model.latestConsultedBarcode != null &&
_model.latestConsultedBarcode!.isNotEmpty) {
final int indexBarcode = barcodes.indexOf(_model.latestConsultedBarcode!);
if (indexBarcode >= 0) {
Expand Down Expand Up @@ -105,7 +101,7 @@ class _SmoothProductCarouselState extends State<SmoothProductCarousel> {
);

_carrouselMovingTo = page;
_controller.animateToPage(page);
ExternalCarouselManager.read(context).animatePageTo(page);
_carrouselMovingTo = null;
}
}
Expand All @@ -131,19 +127,14 @@ class _SmoothProductCarouselState extends State<SmoothProductCarousel> {
),
);
},
carouselController: _controller,
carouselController: ExternalCarouselManager.watch(context).controller,
options: CarouselOptions(
enlargeCenterPage: false,
viewportFraction: _computeViewPortFraction(),
height: constraints.maxHeight,
enableInfiniteScroll: false,
onPageChanged: (int index, CarouselPageChangedReason reason) {
_lastIndex = index;
final InheritedDataManagerState inheritedDataManager =
InheritedDataManager.of(context);
if (inheritedDataManager.showSearchCard) {
inheritedDataManager.resetShowSearchCard(false);
}

if (index > 0) {
if (reason == CarouselPageChangedReason.manual) {
Expand Down

0 comments on commit a6cdcaf

Please sign in to comment.