Skip to content

Commit

Permalink
feat: 4041 - now displaying user lists in "List" nav tab (#4298)
Browse files Browse the repository at this point in the history
  • Loading branch information
monsieurtanuki authored Jul 13, 2023
1 parent 296a0d2 commit aa73434
Show file tree
Hide file tree
Showing 8 changed files with 134 additions and 132 deletions.
45 changes: 27 additions & 18 deletions packages/smooth_app/lib/database/dao_product_list.dart
Original file line number Diff line number Diff line change
Expand Up @@ -287,33 +287,42 @@ class DaoProductList extends AbstractDao {
}

/// Returns the names of the user lists.
///
/// Possibly restricted to the user lists that contains ALL the given barcodes.
Future<List<String>> getUserLists({List<String>? withBarcodes}) async {
// TODO(m123): change return type to a set
List<String> getUserLists() {
final List<String> result = <String>[];
for (final dynamic key in _getBox().keys) {
final String tmp = key.toString();
final ProductListType productListType = getProductListType(tmp);
if (productListType != ProductListType.USER) {
continue;
}
result.add(getProductListParameters(tmp));
}
return result;
}

/// Returns the names of the user lists that contains ALL the given barcodes.
Future<List<String>> getUserListsWithBarcodes(
final List<String> withBarcodes,
) async {
final List<String> result = <String>[];
for (final dynamic key in _getBox().keys) {
final String tmp = key.toString();
final ProductListType productListType = getProductListType(tmp);
if (productListType != ProductListType.USER) {
continue;
}
if (withBarcodes != null) {
final _BarcodeList? barcodeList = await _getBox().get(key);
if (barcodeList == null) {
continue;
final _BarcodeList? barcodeList = await _getBox().get(key);
if (barcodeList == null) {
continue;
}
for (final String barcode in withBarcodes) {
if (!barcodeList.barcodes.contains(barcode)) {
break;
}
for (final String barcode in withBarcodes) {
if (!barcodeList.barcodes.contains(barcode)) {
break;
}
if (withBarcodes.last == barcode) {
result.add(getProductListParameters(tmp));
break;
}
if (withBarcodes.last == barcode) {
result.add(getProductListParameters(tmp));
break;
}
} else {
result.add(getProductListParameters(tmp));
}
}
return result;
Expand Down
4 changes: 4 additions & 0 deletions packages/smooth_app/lib/l10n/app_en.arb
Original file line number Diff line number Diff line change
Expand Up @@ -1773,6 +1773,10 @@
"@user_list_all_empty": {
"description": "Small message when there are no user lists"
},
"product_list_select": "Select a list",
"@product_list_select": {
"description": "Top title for the selection of a list"
},
"user_list_length": "{count,plural, =0{Empty list} =1{One product} other{{count} products}}",
"@user_list_length": {
"description": "Length of a user product list",
Expand Down
77 changes: 77 additions & 0 deletions packages/smooth_app/lib/pages/all_product_list_page.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
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/product_list.dart';
import 'package:smooth_app/database/dao_product_list.dart';
import 'package:smooth_app/database/local_database.dart';
import 'package:smooth_app/generic_lib/design_constants.dart';
import 'package:smooth_app/pages/preferences/user_preferences_list_tile.dart';
import 'package:smooth_app/pages/product/common/product_query_page_helper.dart';
import 'package:smooth_app/pages/product_list_user_dialog_helper.dart';
import 'package:smooth_app/widgets/smooth_app_bar.dart';
import 'package:smooth_app/widgets/smooth_scaffold.dart';

/// Page that lists all product lists.
class AllProductListPage extends StatelessWidget {
const AllProductListPage();

@override
Widget build(BuildContext context) {
final LocalDatabase localDatabase = context.watch<LocalDatabase>();
final DaoProductList daoProductList = DaoProductList(localDatabase);
final List<ProductList> productLists = <ProductList>[
ProductList.scanSession(),
ProductList.scanHistory(),
ProductList.history(),
];
final List<String> userLists = daoProductList.getUserLists();
for (final String userList in userLists) {
productLists.add(ProductList.user(userList));
}
final AppLocalizations appLocalizations = AppLocalizations.of(context);
return SmoothScaffold(
appBar: SmoothAppBar(title: Text(appLocalizations.product_list_select)),
body: ListView.builder(
itemCount: productLists.length,
itemBuilder: (final BuildContext context, final int index) {
final ProductList productList = productLists[index];
return UserPreferencesListTile(
title: Text(
ProductQueryPageHelper.getProductListLabel(
productList,
appLocalizations,
),
),
subtitle: FutureBuilder<int>(
future: daoProductList.getLength(productList),
builder: (
final BuildContext context,
final AsyncSnapshot<int> snapshot,
) {
if (snapshot.data != null) {
return Text(
appLocalizations.user_list_length(snapshot.data!),
);
}
return EMPTY_WIDGET;
},
),
onTap: () => Navigator.of(context).pop(productList),
onLongPress: () async => ProductListUserDialogHelper(daoProductList)
.showDeleteUserListDialog(context, productList),
);
},
),
floatingActionButton: FloatingActionButton.extended(
onPressed: () async => ProductListUserDialogHelper(daoProductList)
.showCreateUserListDialog(context),
label: Row(
children: <Widget>[
const Icon(Icons.add),
Text(appLocalizations.add_list_label),
],
),
),
);
}
}
35 changes: 5 additions & 30 deletions packages/smooth_app/lib/pages/all_user_product_list_page.dart
Original file line number Diff line number Diff line change
Expand Up @@ -15,48 +15,23 @@ import 'package:smooth_app/themes/constant_icons.dart';
import 'package:smooth_app/widgets/smooth_app_bar.dart';
import 'package:smooth_app/widgets/smooth_scaffold.dart';

// TODO(monsieurtanuki): confirm if still relevant with the new ProductListPage and AllProductListPage
/// Page that lists all user product lists.
class AllUserProductList extends StatelessWidget {
class AllUserProductList extends StatefulWidget {
const AllUserProductList();

@override
Widget build(BuildContext context) {
final LocalDatabase localDatabase = context.watch<LocalDatabase>();
final DaoProductList daoProductList = DaoProductList(localDatabase);
return FutureBuilder<List<String>>(
future: daoProductList.getUserLists(),
builder: (
final BuildContext context,
final AsyncSnapshot<List<String>> snapshot,
) {
if (snapshot.data != null) {
return _AllUserProductListLoaded(snapshot.data!);
}
return const Center(child: CircularProgressIndicator.adaptive());
},
);
}
}

/// Page that lists all user product lists, with already loaded data.
class _AllUserProductListLoaded extends StatefulWidget {
const _AllUserProductListLoaded(this.userLists);

final List<String> userLists;

@override
State<_AllUserProductListLoaded> createState() =>
_AllUserProductListLoadedState();
State<AllUserProductList> createState() => _AllUserProductListState();
}

class _AllUserProductListLoadedState extends State<_AllUserProductListLoaded> {
class _AllUserProductListState extends State<AllUserProductList> {
@override
Widget build(BuildContext context) {
final LocalDatabase localDatabase = context.watch<LocalDatabase>();
final DaoProductList daoProductList = DaoProductList(localDatabase);
final AppLocalizations appLocalizations = AppLocalizations.of(context);
final ThemeData themeData = Theme.of(context);
final List<String> userLists = widget.userLists;
final List<String> userLists = daoProductList.getUserLists();
return SmoothScaffold(
appBar: SmoothAppBar(title: Text(appLocalizations.user_list_all_title)),
body: userLists.isEmpty
Expand Down
65 changes: 13 additions & 52 deletions packages/smooth_app/lib/pages/product/common/product_list_page.dart
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,13 @@ 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/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/pages/all_product_list_page.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';
Expand All @@ -28,6 +27,7 @@ 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';

/// Displays the products of a product list, with access to other lists.
class ProductListPage extends StatefulWidget {
const ProductListPage(this.productList);

Expand Down Expand Up @@ -59,12 +59,6 @@ class _ProductListPageState extends State<ProductListPage>
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 {
Expand Down Expand Up @@ -137,55 +131,22 @@ class _ProductListPageState extends State<ProductListPage>
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),
),
);
}
}
return SmoothModalSheet(
closeButton: true,
title: appLocalizations.list_navbar_label,
body: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: children,
),
);
},
final ProductList? selected =
await Navigator.push<ProductList>(
context,
MaterialPageRoute<ProductList>(
builder: (BuildContext context) =>
const AllProductListPage(),
fullscreenDialog: true,
),
);
if (action == null) {
if (selected == null) {
return;
}
if (context.mounted) {
final ProductList? differentProductList =
await action.doSomething(
productList: productList,
localDatabase: localDatabase,
context: context,
);
await DaoProductList(localDatabase).get(selected);
if (context.mounted) {
if (differentProductList != null) {
setState(() => productList = differentProductList);
}
setState(() => productList = selected);
}
}
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import 'package:smooth_app/database/local_database.dart';
import 'package:smooth_app/generic_lib/dialogs/smooth_alert_dialog.dart';
import 'package:smooth_app/helpers/analytics_helper.dart';
import 'package:smooth_app/helpers/temp_product_list_share_helper.dart';
import 'package:smooth_app/pages/product/common/product_query_page_helper.dart';
import 'package:smooth_app/pages/product_list_user_dialog_helper.dart';
import 'package:url_launcher/url_launcher.dart';

Expand Down Expand Up @@ -40,7 +39,7 @@ abstract class ProductListPopupItem {
class ProductListPopupClear extends ProductListPopupItem {
@override
String getTitle(final AppLocalizations appLocalizations) =>
appLocalizations.user_list_popup_clear;
appLocalizations.clear;

@override
Future<ProductList?> doSomething({
Expand Down Expand Up @@ -137,27 +136,3 @@ class ProductListPopupOpenInWeb extends ProductListPopupItem {
return null;
}
}

/// Popup menu item for the product list page: switch to another list.
class ProductListPopupList extends ProductListPopupItem {
ProductListPopupList(this.newProductList);

final ProductList newProductList;

@override
String getTitle(final AppLocalizations appLocalizations) =>
ProductQueryPageHelper.getProductListLabel(
newProductList,
appLocalizations,
);

@override
Future<ProductList?> doSomething({
required final ProductList productList,
required final LocalDatabase localDatabase,
required final BuildContext context,
}) async {
await DaoProductList(localDatabase).get(newProductList);
return newProductList;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -399,7 +399,7 @@ class _ProductPageState extends State<ProductPage>
final DaoProductList daoProductList,
) =>
FutureBuilder<List<String>>(
future: daoProductList.getUserLists(withBarcodes: <String>[barcode]),
future: daoProductList.getUserListsWithBarcodes(<String>[barcode]),
builder: (
final BuildContext context,
final AsyncSnapshot<List<String>> snapshot,
Expand Down
Loading

0 comments on commit aa73434

Please sign in to comment.