Skip to content

Commit

Permalink
feat: 5986 - "top price locations" page
Browse files Browse the repository at this point in the history
New files:
* `price_location_widget.dart`: Price Location display (no price data here).
* `prices_locations_page.dart`: Page that displays the top prices locations.

Impacted files:
* `app_en.arb`: added labels for locations pages; added tooltips for tiny prices count buttons (proofs, prices, products, users)
* `get_prices_model.dart`: minor refactoring
* `labeler.yml`: wtf
* `price_button.dart`: minor refactoring
* `price_count_widget.dart`: refactored with "onPressed" as this button is now used somewhere else
* `price_data_widget.dart`: now links to new page "PricesLocationsPage"; refactored because of new class "PriceLocationWidget"
* `price_location_card.dart`: minor refactoring
* `price_product_widget.dart`: refactored according to "PriceCountWidget" evolutions
* `price_user_button.dart`: minor refactoring
* `prices_users_page.dart`: minor refactoring
* `product_prices_list.dart`: now displays the location once and on top, if relevant (e.g. "prices in that location")
* `user_preferences_prices.dart`: now links to new page "PricesLocationsPage"; minor refactoring
  • Loading branch information
monsieurtanuki committed Dec 4, 2024
1 parent 2038f32 commit d14f49c
Show file tree
Hide file tree
Showing 14 changed files with 446 additions and 158 deletions.
1 change: 0 additions & 1 deletion .github/labeler.yml
Original file line number Diff line number Diff line change
Expand Up @@ -279,7 +279,6 @@ Prices:
- any-glob-to-any-file: 'packages/smooth_app/lib/pages/prices/price_amount_card.dart'
- any-glob-to-any-file: 'packages/smooth_app/lib/pages/prices/price_amount_field.dart'
- any-glob-to-any-file: 'packages/smooth_app/lib/pages/prices/price_button.dart'
- any-glob-to-any-file: 'packages/smooth_app/lib/pages/prices/price_count_widget.dart'
- any-glob-to-any-file: 'packages/smooth_app/lib/pages/prices/price_currency_card.dart'
- any-glob-to-any-file: 'packages/smooth_app/lib/pages/prices/price_currency_selector.dart'
- any-glob-to-any-file: 'packages/smooth_app/lib/pages/prices/price_data_widget.dart'
Expand Down
52 changes: 52 additions & 0 deletions packages/smooth_app/lib/l10n/app_en.arb
Original file line number Diff line number Diff line change
Expand Up @@ -2011,6 +2011,54 @@
}
}
},
"prices_locations_list_length_many_pages": "Top {pageSize} locations (total: {total})",
"@prices_locations_list_length_many_pages": {
"description": "Number of locations for one-page result",
"placeholders": {
"pageSize": {
"type": "int"
},
"total": {
"type": "int"
}
}
},
"prices_button_count_proof": "{count,plural, =0{No proof} =1{One proof} other{{count} proofs}}",
"@prices_button_count_proof": {
"description": "Number of proofs, for a button",
"placeholders": {
"count": {
"type": "int"
}
}
},
"prices_button_count_product": "{count,plural, =0{No product} =1{One product} other{{count} products}}",
"@prices_button_count_product": {
"description": "Number of products, for a button",
"placeholders": {
"count": {
"type": "int"
}
}
},
"prices_button_count_user": "{count,plural, =0{No user} =1{One user} other{{count} users}}",
"@prices_button_count_user": {
"description": "Number of users, for a button",
"placeholders": {
"count": {
"type": "int"
}
}
},
"prices_button_count_price": "{count,plural, =0{No price} =1{One price} other{{count} prices}}",
"@prices_button_count_price": {
"description": "Number of prices, for a button",
"placeholders": {
"count": {
"type": "int"
}
}
},
"prices_amount_subtitle": "Amount",
"prices_amount_is_discounted": "Is discounted?",
"prices_amount_price_normal": "Price",
Expand Down Expand Up @@ -2142,6 +2190,10 @@
"@all_search_prices_top_location_title": {
"description": "Top price locations: list tile title"
},
"all_search_prices_top_location_single_title": "Prices in a store",
"@all_search_prices_top_location_single_title": {
"description": "Top price locations: list tile title"
},
"all_search_prices_top_product_title": "Products with the most prices",
"@all_search_prices_top_product_title": {
"description": "Top price products: list tile title"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,9 @@ import 'package:smooth_app/pages/preferences/user_preferences_item.dart';
import 'package:smooth_app/pages/preferences/user_preferences_list_tile.dart';
import 'package:smooth_app/pages/preferences/user_preferences_page.dart';
import 'package:smooth_app/pages/prices/get_prices_model.dart';
import 'package:smooth_app/pages/prices/price_button.dart';
import 'package:smooth_app/pages/prices/price_user_button.dart';
import 'package:smooth_app/pages/prices/prices_locations_page.dart';
import 'package:smooth_app/pages/prices/prices_page.dart';
import 'package:smooth_app/pages/prices/prices_proofs_page.dart';
import 'package:smooth_app/pages/prices/prices_users_page.dart';
Expand Down Expand Up @@ -87,17 +89,7 @@ class UserPreferencesPrices extends AbstractUserPreferences {
MaterialPageRoute<void>(
builder: (BuildContext context) => PricesPage(
GetPricesModel(
parameters: GetPricesParameters()
..orderBy = <OrderBy<GetPricesOrderField>>[
const OrderBy<GetPricesOrderField>(
field: GetPricesOrderField.created,
ascending: false,
),
]
..pageSize = GetPricesModel.pageSize
..pageNumber = 1,
displayOwner: true,
displayProduct: true,
parameters: GetPricesModel.getStandardPricesParameters(),
uri: OpenPricesAPIClient.getUri(
path: 'prices',
uriHelper: ProductQuery.uriPricesHelper,
Expand All @@ -118,11 +110,16 @@ class UserPreferencesPrices extends AbstractUserPreferences {
builder: (BuildContext context) => const PricesUsersPage(),
),
),
Icons.account_box,
PriceButton.userIconData,
),
_getPriceListTile(
_getListTile(
appLocalizations.all_search_prices_top_location_title,
'locations',
() async => Navigator.of(context).push(
MaterialPageRoute<void>(
builder: (BuildContext context) => const PricesLocationsPage(),
),
),
PriceButton.locationIconData,
),
_getPriceListTile(
appLocalizations.all_search_prices_top_product_title,
Expand Down
48 changes: 23 additions & 25 deletions packages/smooth_app/lib/pages/prices/get_prices_model.dart
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,9 @@ import 'package:smooth_app/query/product_query.dart';
class GetPricesModel {
const GetPricesModel({
required this.parameters,
required this.displayOwner,
required this.displayProduct,
this.displayEachOwner = true,
this.displayEachProduct = true,
this.displayEachLocation = true,
required this.uri,
required this.title,
this.lazyCounterPrices,
Expand All @@ -26,10 +27,13 @@ class GetPricesModel {
required final BuildContext context,
}) =>
GetPricesModel(
parameters: _getProductPricesParameters(product.barcode),
displayOwner: true,
displayProduct: false,
uri: _getProductPricesUri(product.barcode),
parameters: getStandardPricesParameters()
..productCode = product.barcode,
displayEachProduct: false,
uri: OpenPricesAPIClient.getUri(
path: 'products/${product.barcode}',
uriHelper: ProductQuery.uriPricesHelper,
),
title: product.getName(AppLocalizations.of(context)),
subtitle: product.barcode,
addButton: () async => ProductPriceAddPage.showProductPage(
Expand All @@ -40,36 +44,32 @@ class GetPricesModel {
enableCountButton: false,
);

static GetPricesParameters _getProductPricesParameters(
final String barcode,
) =>
static GetPricesParameters getStandardPricesParameters() =>
GetPricesParameters()
..productCode = barcode
..orderBy = <OrderBy<GetPricesOrderField>>[
const OrderBy<GetPricesOrderField>(
..orderBy = const <OrderBy<GetPricesOrderField>>[
OrderBy<GetPricesOrderField>(
field: GetPricesOrderField.created,
ascending: false,
),
OrderBy<GetPricesOrderField>(
field: GetPricesOrderField.date,
ascending: false,
),
]
..pageSize = pageSize
..pageSize = 10
..pageNumber = 1;

static Uri _getProductPricesUri(
final String barcode,
) =>
OpenPricesAPIClient.getUri(
path: 'products/$barcode',
uriHelper: ProductQuery.uriPricesHelper,
);

/// Query parameters.
final GetPricesParameters parameters;

/// Should we display the owner for each price? No if it's an owner query.
final bool displayOwner;
final bool displayEachOwner;

/// Should we display the product for each price? No if it's a product query.
final bool displayProduct;
final bool displayEachProduct;

/// Should we display the location for each price? No if it's a location query.
final bool displayEachLocation;

/// Related web app URI.
final Uri uri;
Expand All @@ -88,6 +88,4 @@ class GetPricesModel {

/// Lazy Counter to refresh.
final LazyCounterPrices? lazyCounterPrices;

static const int pageSize = 10;
}
8 changes: 8 additions & 0 deletions packages/smooth_app/lib/pages/prices/price_button.dart
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,14 @@ class PriceButton extends StatelessWidget {
final VoidCallback? onPressed;
final String? tooltip;

static const IconData priceIconData = Icons.label;
static const IconData userIconData = Icons.account_box;
static const IconData proofIconData = Icons.image;
static const IconData locationIconData = Icons.location_on;
static const IconData historyIconData = Icons.history;
static const IconData productIconData = Icons.category;
static const IconData warningIconData = Icons.warning;

@override
Widget build(BuildContext context) {
final Widget widget;
Expand Down
59 changes: 16 additions & 43 deletions packages/smooth_app/lib/pages/prices/price_count_widget.dart
Original file line number Diff line number Diff line change
@@ -1,71 +1,44 @@
import 'package:flutter/material.dart';
import 'package:openfoodfacts/openfoodfacts.dart';
import 'package:provider/provider.dart';
import 'package:smooth_app/database/dao_product.dart';
import 'package:smooth_app/database/local_database.dart';
import 'package:smooth_app/pages/prices/get_prices_model.dart';
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
import 'package:smooth_app/pages/prices/price_button.dart';
import 'package:smooth_app/pages/prices/price_meta_product.dart';
import 'package:smooth_app/pages/prices/prices_page.dart';

/// Price Count display.
class PriceCountWidget extends StatelessWidget {
const PriceCountWidget(
this.count, {
required this.priceProduct,
required this.enableCountButton,
const PriceCountWidget({
required this.count,
required this.onPressed,
});

final int count;
final PriceProduct priceProduct;
final bool enableCountButton;
final VoidCallback? onPressed;

@override
Widget build(BuildContext context) => PriceButton(
onPressed: !enableCountButton
? null
: () async {
final LocalDatabase localDatabase =
context.read<LocalDatabase>();
final Product? newProduct =
await DaoProduct(localDatabase).get(priceProduct.code);
if (!context.mounted) {
return;
}
return Navigator.of(context).push<void>(
MaterialPageRoute<void>(
builder: (BuildContext context) => PricesPage(
GetPricesModel.product(
product: newProduct != null
? PriceMetaProduct.product(newProduct)
: PriceMetaProduct.priceProduct(priceProduct),
context: context,
),
),
),
);
},
iconData: Icons.label,
onPressed: onPressed,
iconData: PriceButton.priceIconData,
title: '$count',
buttonStyle: ElevatedButton.styleFrom(
disabledForegroundColor:
enableCountButton ? null : getForegroundColor(count),
onPressed != null ? null : _getForegroundColor(count),
disabledBackgroundColor:
enableCountButton ? null : getBackgroundColor(count),
onPressed != null ? null : _getBackgroundColor(count),
foregroundColor:
!enableCountButton ? null : getForegroundColor(count),
onPressed == null ? null : _getForegroundColor(count),
backgroundColor:
!enableCountButton ? null : getBackgroundColor(count),
onPressed == null ? null : _getBackgroundColor(count),
),
tooltip: AppLocalizations.of(context).prices_button_count_price(
count,
),
);

static Color? getForegroundColor(final int count) => switch (count) {
static Color? _getForegroundColor(final int count) => switch (count) {
0 => Colors.red,
1 => Colors.orange,
_ => Colors.green,
};

static Color? getBackgroundColor(final int count) => switch (count) {
static Color? _getBackgroundColor(final int count) => switch (count) {
0 => Colors.red[100],
1 => Colors.orange[100],
_ => Colors.green[100],
Expand Down
Loading

0 comments on commit d14f49c

Please sign in to comment.