Skip to content

Commit

Permalink
feat: 4041 - renamed "history" bottom item as "lists", w/ access to o…
Browse files Browse the repository at this point in the history
…ther lists (#4277)
  • Loading branch information
monsieurtanuki committed Jul 12, 2023
1 parent a5fb0e1 commit cac58a2
Show file tree
Hide file tree
Showing 8 changed files with 274 additions and 107 deletions.
8 changes: 8 additions & 0 deletions packages/smooth_app/lib/l10n/app_en.arb
Original file line number Diff line number Diff line change
Expand Up @@ -424,6 +424,10 @@
"@history_navbar_label": {
"description": "BottomNavigationBarLabel: For the history and compare mode"
},
"list_navbar_label": "Lists",
"@list_navbar_label": {
"description": "BottomNavigationBarLabel: For the lists"
},
"category": "Filter by category",
"@category": {
"description": "From a product list, there's a category filter: this is its title"
Expand Down Expand Up @@ -744,6 +748,10 @@
"@product_removed_history": {
"description": "Product got removed from history"
},
"product_removed_list": "Product removed from list",
"@product_removed_list": {
"description": "Product got removed from list"
},
"product_could_not_remove": "Could not remove product",
"@product_could_not_remove": {
"description": "Could not remove product from a list"
Expand Down
12 changes: 6 additions & 6 deletions packages/smooth_app/lib/pages/page_manager.dart
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import 'package:smooth_app/widgets/tab_navigator.dart';
enum BottomNavigationTab {
Profile,
Scan,
History,
List,
}

/// Here the different tabs in the bottom navigation bar are taken care of,
Expand All @@ -27,14 +27,14 @@ class PageManagerState extends State<PageManager> {
static const List<BottomNavigationTab> _pageKeys = <BottomNavigationTab>[
BottomNavigationTab.Profile,
BottomNavigationTab.Scan,
BottomNavigationTab.History,
BottomNavigationTab.List,
];

final Map<BottomNavigationTab, GlobalKey<NavigatorState>> _navigatorKeys =
<BottomNavigationTab, GlobalKey<NavigatorState>>{
BottomNavigationTab.Profile: GlobalKey<NavigatorState>(),
BottomNavigationTab.Scan: GlobalKey<NavigatorState>(),
BottomNavigationTab.History: GlobalKey<NavigatorState>(),
BottomNavigationTab.List: GlobalKey<NavigatorState>(),
};

BottomNavigationTab _currentPage = BottomNavigationTab.Scan;
Expand Down Expand Up @@ -76,7 +76,7 @@ class PageManagerState extends State<PageManager> {
final List<Widget> tabs = <Widget>[
_buildOffstageNavigator(BottomNavigationTab.Profile),
_buildOffstageNavigator(BottomNavigationTab.Scan),
_buildOffstageNavigator(BottomNavigationTab.History),
_buildOffstageNavigator(BottomNavigationTab.List),
];

final UserPreferences userPreferences = context.watch<UserPreferences>();
Expand Down Expand Up @@ -111,8 +111,8 @@ class PageManagerState extends State<PageManager> {
label: appLocalizations.scan_navbar_label,
),
BottomNavigationBarItem(
icon: const Icon(Icons.history),
label: appLocalizations.history_navbar_label,
icon: const Icon(Icons.list),
label: appLocalizations.list_navbar_label,
),
],
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -435,7 +435,10 @@ class _UserPreferencesPageState extends State<UserPreferencesSection> {
required final LocalDatabase localDatabase,
}) =>
_getListTile(
ProductQueryPageHelper.getProductListLabel(productList, context),
ProductQueryPageHelper.getProductListLabel(
productList,
AppLocalizations.of(context),
),
() async {
await DaoProductList(localDatabase).get(productList);
if (!mounted) {
Expand Down
186 changes: 90 additions & 96 deletions packages/smooth_app/lib/pages/product/common/product_list_page.dart
Original file line number Diff line number Diff line change
@@ -1,35 +1,32 @@
import 'dart:math';

import 'package:auto_size_text/auto_size_text.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:matomo_tracker/matomo_tracker.dart';
import 'package:openfoodfacts/openfoodfacts.dart';
import 'package:provider/provider.dart';
import 'package:share_plus/share_plus.dart';
import 'package:smooth_app/data_models/product_list.dart';
import 'package:smooth_app/database/dao_product.dart';
import 'package:smooth_app/database/dao_product_list.dart';
import 'package:smooth_app/database/local_database.dart';
import 'package:smooth_app/generic_lib/buttons/smooth_simple_button.dart';
import 'package:smooth_app/generic_lib/design_constants.dart';
import 'package:smooth_app/generic_lib/dialogs/smooth_alert_dialog.dart';
import 'package:smooth_app/generic_lib/duration_constants.dart';
import 'package:smooth_app/generic_lib/loading_dialog.dart';
import 'package:smooth_app/helpers/analytics_helper.dart';
import 'package:smooth_app/generic_lib/widgets/smooth_bottom_sheet.dart';
import 'package:smooth_app/helpers/app_helper.dart';
import 'package:smooth_app/helpers/robotoff_insight_helper.dart';
import 'package:smooth_app/helpers/temp_product_list_share_helper.dart';
import 'package:smooth_app/pages/inherited_data_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';
import 'package:smooth_app/pages/product/common/product_query_page_helper.dart';
import 'package:smooth_app/pages/product/common/product_refresher.dart';
import 'package:smooth_app/pages/product_list_user_dialog_helper.dart';
import 'package:smooth_app/query/product_query.dart';
import 'package:smooth_app/widgets/smooth_app_bar.dart';
import 'package:smooth_app/widgets/smooth_scaffold.dart';
import 'package:url_launcher/url_launcher.dart';

class ProductListPage extends StatefulWidget {
const ProductListPage(this.productList);
Expand All @@ -46,11 +43,6 @@ class _ProductListPageState extends State<ProductListPage>
final Set<String> _selectedBarcodes = <String>{};
bool _selectionMode = false;

static const String _popupActionClear = 'clear';
static const String _popupActionRename = 'rename';
static const String _popupActionOpenInWeb = 'openInWeb';
static const String _popupActionShare = 'share';

@override
String get traceName => 'Opened list_page';

Expand All @@ -63,6 +55,17 @@ class _ProductListPageState extends State<ProductListPage>
productList = widget.productList;
}

final ProductListPopupItem _rename = ProductListPopupRename();
final ProductListPopupItem _clear = ProductListPopupClear();
final ProductListPopupItem _openInWeb = ProductListPopupOpenInWeb();
final ProductListPopupItem _share = ProductListPopupShare();
final ProductListPopupList _listScanSession =
ProductListPopupList(ProductList.scanSession());
final ProductListPopupList _listScanHistory =
ProductListPopupList(ProductList.scanHistory());
final ProductListPopupList _listHistory =
ProductListPopupList(ProductList.history());

//returns bool to handle WillPopScope
Future<bool> _handleUserBacktap() async {
if (_selectionMode) {
Expand Down Expand Up @@ -108,7 +111,6 @@ class _ProductListPageState extends State<ProductListPage>
return SmoothScaffold(
floatingActionButton: products.isEmpty
? FloatingActionButton.extended(
heroTag: 'compare_fab_${Random(100)}',
icon: const Icon(CupertinoIcons.barcode),
label: Text(appLocalizations.product_list_empty_title),
onPressed: () =>
Expand All @@ -132,97 +134,89 @@ class _ProductListPageState extends State<ProductListPage>
actions: !(enableClear || enableRename)
? null
: <Widget>[
PopupMenuButton<String>(
onSelected: (final String action) async {
switch (action) {
case _popupActionClear:
await showDialog<bool>(
context: context,
builder: (BuildContext context) {
return SmoothAlertDialog(
body: Text(
productList.listType == ProductListType.USER
? appLocalizations.confirm_clear_user_list(
productList.parameters)
: appLocalizations.confirm_clear,
),
positiveAction: SmoothActionButton(
onPressed: () async {
await daoProductList.clear(productList);
await daoProductList.get(productList);
setState(() {});
if (!mounted) {
return;
}
Navigator.of(context).pop();
},
text: appLocalizations.yes,
),
negativeAction: SmoothActionButton(
onPressed: () {
Navigator.of(context).pop();
},
text: appLocalizations.no,
IconButton(
icon: const Icon(CupertinoIcons.square_list),
onPressed: () async {
final ProductListPopupItem? action =
await showSmoothModalSheet<ProductListPopupItem>(
context: context,
builder: (final BuildContext context) {
final List<Widget> children = <Widget>[];
final List<ProductListPopupList> orderedItems =
<ProductListPopupList>[
_listScanSession,
_listScanHistory,
_listHistory,
];
// do not add the same type
for (final ProductListPopupList item in orderedItems) {
if (item.newProductList.listType !=
productList.listType) {
children.add(
SmoothSimpleButton(
child: Text(item.getTitle(appLocalizations)),
onPressed: () =>
Navigator.of(context).pop(item),
),
);
},
);
break;
case _popupActionRename:
final ProductList? renamedProductList =
await ProductListUserDialogHelper(daoProductList)
.showRenameUserListDialog(context, productList);
if (renamedProductList == null) {
return;
}
}
setState(() => productList = renamedProductList);
break;
case _popupActionShare:
final String url =
shareProductList(products).toString();

final RenderBox? box =
context.findRenderObject() as RenderBox?;
AnalyticsHelper.trackEvent(AnalyticsEvent.shareList);
Share.share(
appLocalizations.share_product_list_text(url),
sharePositionOrigin:
box!.localToGlobal(Offset.zero) & box.size,
return SmoothModalSheet(
closeButton: true,
title: appLocalizations.list_navbar_label,
body: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: children,
),
);

break;
case _popupActionOpenInWeb:
AnalyticsHelper.trackEvent(AnalyticsEvent.openListWeb);
launchUrl(shareProductList(products));
break;
},
);
if (action == null) {
return;
}
if (context.mounted) {
final ProductList? differentProductList =
await action.doSomething(
productList: productList,
localDatabase: localDatabase,
context: context,
);
if (context.mounted) {
if (differentProductList != null) {
setState(() => productList = differentProductList);
}
}
}
},
),
PopupMenuButton<ProductListPopupItem>(
onSelected: (final ProductListPopupItem action) async {
final ProductList? differentProductList =
await action.doSomething(
productList: productList,
localDatabase: localDatabase,
context: context,
);
if (differentProductList != null) {
setState(() => productList = differentProductList);
}
},
itemBuilder: (BuildContext context) =>
<PopupMenuEntry<String>>[
if (enableRename)
PopupMenuItem<String>(
value: _popupActionRename,
child: Text(appLocalizations.user_list_popup_rename),
),
PopupMenuItem<String>(
value: _popupActionShare,
child: Text(appLocalizations.share),
),
PopupMenuItem<String>(
value: _popupActionOpenInWeb,
child: Text(appLocalizations.label_web),
),
if (enableClear)
PopupMenuItem<String>(
value: _popupActionClear,
child: Text(appLocalizations.user_list_popup_clear),
),
<PopupMenuEntry<ProductListPopupItem>>[
if (enableRename) _rename.getMenuItem(appLocalizations),
_share.getMenuItem(appLocalizations),
_openInWeb.getMenuItem(appLocalizations),
if (enableClear) _clear.getMenuItem(appLocalizations),
],
)
),
],
title: Text(
ProductQueryPageHelper.getProductListLabel(productList, context),
overflow: TextOverflow.fade,
title: AutoSizeText(
ProductQueryPageHelper.getProductListLabel(
productList,
appLocalizations,
),
maxLines: 2,
),
actionMode: _selectionMode,
onLeaveActionMode: () {
Expand Down Expand Up @@ -428,7 +422,7 @@ class _ProductListPageState extends State<ProductListPage>
SnackBar(
content: Text(
removed
? appLocalizations.product_removed_history
? appLocalizations.product_removed_list
: appLocalizations.product_could_not_remove,
),
duration: SnackBarDuration.medium,
Expand Down

0 comments on commit cac58a2

Please sign in to comment.