Skip to content

Commit

Permalink
feat: 5352 - now opening the related product price page from count bu…
Browse files Browse the repository at this point in the history
…tton (#5353)

Impacted files:
* `edit_product_page.dart`: minor refactoring
* `get_prices_model.dart`: refactored with 2 new constructors
* `price_count_widget.dart`: now opening the related product price page (if relevant)
* `price_product_widget.dart`: minor refactoring
* `prices_card.dart`: minor refactoring
* `product_price_add_page.dart`: minor refactoring
* `product_prices_list.dart`: minor refactoring; minor bug fix
* `user_preferences_account.dart`: minor refactoring
  • Loading branch information
monsieurtanuki authored Jun 10, 2024
1 parent 41abf73 commit 536eae4
Show file tree
Hide file tree
Showing 8 changed files with 196 additions and 52 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -242,7 +242,7 @@ class UserPreferencesAccount extends AbstractUserPreferences {
),
),
CupertinoIcons.money_dollar_circle,
myCount: _getMyPricesCount(),
myCount: _getPricesCount(owner: ProductQuery.getWriteUser().userId),
),
_getListTile(
appLocalizations.all_search_prices_latest_title,
Expand Down Expand Up @@ -271,6 +271,7 @@ class UserPreferencesAccount extends AbstractUserPreferences {
),
),
CupertinoIcons.money_dollar_circle,
myCount: _getPricesCount(),
),
_getPriceListTile(
appLocalizations.all_search_prices_top_user_title,
Expand Down Expand Up @@ -337,9 +338,8 @@ class UserPreferencesAccount extends AbstractUserPreferences {

UserPreferencesItem _getPriceListTile(
final String title,
final String path, {
final Future<int?>? myCount,
}) =>
final String path,
) =>
_getListTile(
title,
() async => LaunchUrlHelper.launchURL(
Expand All @@ -349,7 +349,6 @@ class UserPreferencesAccount extends AbstractUserPreferences {
).toString(),
),
Icons.open_in_new,
myCount: myCount,
);

Future<bool?> _confirmLogout() async => showDialog<bool>(
Expand Down Expand Up @@ -402,11 +401,11 @@ class UserPreferencesAccount extends AbstractUserPreferences {
}
}

Future<int?> _getMyPricesCount() async {
Future<int?> _getPricesCount({final String? owner}) async {
final MaybeError<GetPricesResult> result =
await OpenPricesAPIClient.getPrices(
GetPricesParameters()
..owner = ProductQuery.getWriteUser().userId
..owner = owner
..pageSize = 1,
uriHelper: ProductQuery.uriProductHelper,
);
Expand Down
73 changes: 73 additions & 0 deletions packages/smooth_app/lib/pages/prices/get_prices_model.dart
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
import 'package:flutter/material.dart';
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
import 'package:openfoodfacts/openfoodfacts.dart';
import 'package:smooth_app/helpers/product_cards_helper.dart';
import 'package:smooth_app/pages/prices/product_price_add_page.dart';
import 'package:smooth_app/query/product_query.dart';

/// Model that stores what we need to know for "get latest prices" queries.
class GetPricesModel {
Expand All @@ -9,10 +13,76 @@ class GetPricesModel {
required this.displayProduct,
required this.uri,
required this.title,
this.enableCountButton = true,
this.subtitle,
this.addButton,
});

/// Gets latest prices for a product.
factory GetPricesModel.product({
required final Product product,
required final BuildContext context,
}) =>
GetPricesModel(
parameters: _getProductPricesParameters(product.barcode!),
displayOwner: true,
displayProduct: false,
uri: _getProductPricesUri(product.barcode!),
title: getProductNameAndBrands(
product,
AppLocalizations.of(context),
),
subtitle: product.barcode,
addButton: () async => ProductPriceAddPage.showProductPage(
context: context,
product: product,
),
enableCountButton: false,
);

/// Gets latest prices for a barcode.
factory GetPricesModel.barcode({
required final String barcode,
required final String name,
required final BuildContext context,
}) =>
GetPricesModel(
parameters: _getProductPricesParameters(barcode),
displayOwner: true,
displayProduct: false,
uri: _getProductPricesUri(barcode),
title: name,
subtitle: barcode,
addButton: () async => ProductPriceAddPage.showBarcodePage(
context: context,
barcode: barcode,
title: name,
),
enableCountButton: false,
);

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

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

/// Query parameters.
final GetPricesParameters parameters;

Expand All @@ -34,5 +104,8 @@ class GetPricesModel {
/// "Add a price" callback.
final VoidCallback? addButton;

/// "Enable the count button?". Typically "false" for product price pages.
final bool enableCountButton;

static const int pageSize = 10;
}
55 changes: 51 additions & 4 deletions packages/smooth_app/lib/pages/prices/price_count_widget.dart
Original file line number Diff line number Diff line change
@@ -1,20 +1,67 @@
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:smooth_app/pages/prices/price_button.dart';
import 'package:smooth_app/pages/prices/prices_page.dart';

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

final int count;
final String barcode;

/// Product name to display in case we have only the barcode, not the product.
final String name;

final bool enableCountButton;

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

Expand Down
14 changes: 12 additions & 2 deletions packages/smooth_app/lib/pages/prices/price_product_widget.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,19 @@ import 'package:flutter_gen/gen_l10n/app_localizations.dart';
import 'package:openfoodfacts/openfoodfacts.dart';
import 'package:smooth_app/generic_lib/design_constants.dart';
import 'package:smooth_app/generic_lib/widgets/images/smooth_image.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_count_widget.dart';

/// Price Product display (no price data here).
class PriceProductWidget extends StatelessWidget {
const PriceProductWidget(this.priceProduct);
const PriceProductWidget(
this.priceProduct, {
required this.model,
});

final PriceProduct priceProduct;
final GetPricesModel model;

static const double _imageSize = 75;

Expand Down Expand Up @@ -65,7 +70,12 @@ class PriceProductWidget extends StatelessWidget {
crossAxisAlignment: WrapCrossAlignment.center,
runSpacing: 0,
children: <Widget>[
PriceCountWidget(priceCount),
PriceCountWidget(
priceCount,
barcode: priceProduct.code,
name: name,
enableCountButton: model.enableCountButton,
),
if (brands != null)
for (final String brand in brands)
PriceButton(
Expand Down
31 changes: 4 additions & 27 deletions packages/smooth_app/lib/pages/prices/prices_card.dart
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import 'package:smooth_app/helpers/product_cards_helper.dart';
import 'package:smooth_app/pages/prices/get_prices_model.dart';
import 'package:smooth_app/pages/prices/prices_page.dart';
import 'package:smooth_app/pages/prices/product_price_add_page.dart';
import 'package:smooth_app/query/product_query.dart';

/// Card that displays buttons related to prices.
class PricesCard extends StatelessWidget {
Expand Down Expand Up @@ -40,31 +39,9 @@ class PricesCard extends StatelessWidget {
onPressed: () async => Navigator.of(context).push(
MaterialPageRoute<void>(
builder: (BuildContext context) => PricesPage(
GetPricesModel(
parameters: GetPricesParameters()
..productCode = product.barcode
..orderBy = <OrderBy<GetPricesOrderField>>[
const OrderBy<GetPricesOrderField>(
field: GetPricesOrderField.created,
ascending: false,
),
]
..pageSize = GetPricesModel.pageSize
..pageNumber = 1,
displayOwner: true,
displayProduct: false,
uri: OpenPricesAPIClient.getUri(
path: 'app/products/${product.barcode!}',
uriHelper: ProductQuery.uriProductHelper,
),
title: getProductNameAndBrands(
product,
appLocalizations,
),
addButton: () async => ProductPriceAddPage.showPage(
context: context,
product: product,
),
GetPricesModel.product(
product: product,
context: context,
),
),
),
Expand All @@ -76,7 +53,7 @@ class PricesCard extends StatelessWidget {
child: SmoothLargeButtonWithIcon(
text: appLocalizations.prices_add_a_price,
icon: Icons.add,
onPressed: () async => ProductPriceAddPage.showPage(
onPressed: () async => ProductPriceAddPage.showProductPage(
context: context,
product: product,
),
Expand Down
44 changes: 36 additions & 8 deletions packages/smooth_app/lib/pages/prices/product_price_add_page.dart
Original file line number Diff line number Diff line change
Expand Up @@ -22,17 +22,44 @@ import 'package:smooth_app/widgets/smooth_scaffold.dart';

/// Single page that displays all the elements of price adding.
class ProductPriceAddPage extends StatefulWidget {
const ProductPriceAddPage(
this.product, {
const ProductPriceAddPage({
required this.barcode,
required this.title,
required this.latestOsmLocations,
});

final Product product;
final String barcode;
final String title;
final List<OsmLocation> latestOsmLocations;

static Future<void> showPage({
static Future<void> showBarcodePage({
required final BuildContext context,
required final String barcode,
required final String title,
}) async =>
_showPage(
context: context,
barcode: barcode,
title: title,
);

static Future<void> showProductPage({
required final BuildContext context,
required final Product product,
}) async =>
_showPage(
context: context,
barcode: product.barcode!,
title: getProductNameAndBrands(
product,
AppLocalizations.of(context),
),
);

static Future<void> _showPage({
required final BuildContext context,
required final String barcode,
required final String title,
}) async {
if (!await ProductRefresher().checkIfLoggedIn(
context,
Expand All @@ -52,7 +79,8 @@ class ProductPriceAddPage extends StatefulWidget {
await Navigator.of(context).push(
MaterialPageRoute<void>(
builder: (BuildContext context) => ProductPriceAddPage(
product,
barcode: barcode,
title: title,
latestOsmLocations: osmLocations,
),
),
Expand All @@ -67,7 +95,7 @@ class _ProductPriceAddPageState extends State<ProductPriceAddPage> {
late final PriceModel _model = PriceModel(
proofType: ProofType.priceTag,
locations: widget.latestOsmLocations,
barcode: widget.product.barcode!,
barcode: widget.barcode,
);

final GlobalKey<FormState> _formKey = GlobalKey<FormState>();
Expand All @@ -85,10 +113,10 @@ class _ProductPriceAddPageState extends State<ProductPriceAddPage> {
centerTitle: false,
leading: const SmoothBackButton(),
title: Text(
getProductNameAndBrands(widget.product, appLocalizations),
widget.title,
maxLines: 1,
),
subTitle: Text(widget.product.barcode!),
subTitle: Text(widget.barcode),
actions: <Widget>[
IconButton(
icon: const Icon(Icons.info),
Expand Down
Loading

0 comments on commit 536eae4

Please sign in to comment.