Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: #2146 refresh product edition #2201

Merged
30 changes: 27 additions & 3 deletions packages/smooth_app/lib/pages/product/add_basic_details_page.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,15 @@ import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
import 'package:openfoodfacts/openfoodfacts.dart';
import 'package:provider/provider.dart';
import 'package:smooth_app/cards/product_cards/product_image_carousel.dart';
import 'package:smooth_app/database/local_database.dart';
import 'package:smooth_app/database/product_query.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/loading_dialog.dart';
import 'package:smooth_app/generic_lib/widgets/smooth_text_form_field.dart';
import 'package:smooth_app/pages/product/common/product_refresher.dart';

class AddBasicDetailsPage extends StatefulWidget {
const AddBasicDetailsPage(this.product);
Expand Down Expand Up @@ -130,13 +133,34 @@ class _AddBasicDetailsPageState extends State<AddBasicDetailsPage> {
_errorMessageAlert(
appLocalizations.basic_details_add_error);
return;
} else {
if (!mounted) {
return;
}
widget.product.productName =
_productNameController.text;
widget.product.quantity = _weightController.text;
widget.product.brands = _brandNameController.text;
final LocalDatabase localDatabase =
context.read<LocalDatabase>();
final bool savedAndRefreshed =
await ProductRefresher().saveAndRefresh(
context: context,
localDatabase: localDatabase,
product: widget.product,
);
if (savedAndRefreshed) {
if (!mounted) {
return;
}
ScaffoldMessenger.of(context).showSnackBar(SnackBar(
content: Text(
appLocalizations.basic_details_add_success)));
}
}
if (!mounted) {
return;
}
ScaffoldMessenger.of(context).showSnackBar(SnackBar(
content: Text(
appLocalizations.basic_details_add_success)));
Navigator.pop(context, true);
}),
),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,4 +72,46 @@ class ProductRefresher {
}
return false;
}

Future<bool> fetchAndRefresh({
required final BuildContext context,
required final LocalDatabase localDatabase,
required final String barcode,
}) async {
final AppLocalizations appLocalizations = AppLocalizations.of(context);
final bool? savedAndRefreshed = await LoadingDialog.run<bool>(
future: _fetchAndRefresh(localDatabase, barcode),
context: context,
title: appLocalizations.nutrition_page_update_running,
);
if (savedAndRefreshed == null) {
return false;
}
if (!savedAndRefreshed) {
await LoadingDialog.error(context: context);
return false;
}
return true;
}

Future<bool> _fetchAndRefresh(
final LocalDatabase localDatabase,
final String barcode,
) async {
final ProductQueryConfiguration configuration = ProductQueryConfiguration(
barcode,
fields: ProductQuery.fields,
language: ProductQuery.getLanguage(),
country: ProductQuery.getCountry(),
);
final ProductResult result = await OpenFoodAPIClient.getProduct(
configuration,
);
if (result.product != null) {
await DaoProduct(localDatabase).put(result.product!);
return true;
}

return false;
}
}
41 changes: 32 additions & 9 deletions packages/smooth_app/lib/pages/product/edit_product_page.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,10 @@ import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
import 'package:openfoodfacts/openfoodfacts.dart';
import 'package:provider/provider.dart';
import 'package:smooth_app/data_models/product_image_data.dart';
import 'package:smooth_app/database/dao_product.dart';
import 'package:smooth_app/database/local_database.dart';
import 'package:smooth_app/helpers/product_cards_helper.dart';
import 'package:smooth_app/pages/product/add_basic_details_page.dart';
import 'package:smooth_app/pages/product/edit_ingredients_page.dart';
Expand All @@ -23,14 +26,22 @@ class EditProductPage extends StatefulWidget {

class _EditProductPageState extends State<EditProductPage> {
int _changes = 0;
late Product _product;

@override
void initState() {
super.initState();
_product = widget.product;
}

@override
Widget build(BuildContext context) {
final AppLocalizations appLocalizations = AppLocalizations.of(context);

return Scaffold(
appBar: AppBar(
title: AutoSizeText(
getProductName(widget.product, appLocalizations),
getProductName(_product, appLocalizations),
maxLines: 2,
),
systemOverlayStyle: const SystemUiOverlayStyle(
Expand All @@ -52,9 +63,8 @@ class _EditProductPageState extends State<EditProductPage> {
title: Text(
appLocalizations.edit_product_form_item_barcode,
),
subtitle: widget.product.barcode == null
? null
: Text(widget.product.barcode!),
subtitle:
_product.barcode == null ? null : Text(_product.barcode!),
),
_ListTitleItem(
title: appLocalizations.edit_product_form_item_details_title,
Expand All @@ -65,11 +75,12 @@ class _EditProductPageState extends State<EditProductPage> {
context,
MaterialPageRoute<bool>(
builder: (BuildContext context) =>
AddBasicDetailsPage(widget.product),
AddBasicDetailsPage(_product),
),
);
if (refreshed ?? false) {
_changes++;
await _refreshProduct();
}
},
),
Expand All @@ -78,20 +89,21 @@ class _EditProductPageState extends State<EditProductPage> {
subtitle: appLocalizations.edit_product_form_item_photos_subtitle,
onTap: () async {
final List<ProductImageData> allProductImagesData =
getAllProductImagesData(widget.product, appLocalizations);
getAllProductImagesData(_product, appLocalizations);
final bool? refreshed = await Navigator.push<bool>(
context,
MaterialPageRoute<bool>(
builder: (BuildContext context) => ProductImageGalleryView(
productImageData: allProductImagesData.first,
allProductImagesData: allProductImagesData,
title: allProductImagesData.first.title,
barcode: widget.product.barcode,
barcode: _product.barcode,
),
),
);
if (refreshed ?? false) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I know you didn't write it, but I'm sure refreshed == true is easier to read than refreshed ?? false.

_changes++;
await _refreshProduct();
}
},
),
Expand All @@ -106,12 +118,13 @@ class _EditProductPageState extends State<EditProductPage> {
context,
MaterialPageRoute<bool>(
builder: (BuildContext context) => EditIngredientsPage(
product: widget.product,
product: _product,
),
),
);
if (refreshed ?? false) {
_changes++;
await _refreshProduct();
}
},
),
Expand All @@ -136,13 +149,14 @@ class _EditProductPageState extends State<EditProductPage> {
context,
MaterialPageRoute<bool>(
builder: (BuildContext context) => NutritionPageLoaded(
widget.product,
_product,
cache.orderedNutrients,
),
),
);
if (refreshed ?? false) {
_changes++;
await _refreshProduct();
}
},
)
Expand All @@ -151,6 +165,15 @@ class _EditProductPageState extends State<EditProductPage> {
),
);
}

Future<void> _refreshProduct() async {
final LocalDatabase localDatabase = context.read<LocalDatabase>();
final Product? refreshedProduct =
await DaoProduct(localDatabase).get(_product.barcode ?? '');
if (refreshedProduct != null) {
_product = refreshedProduct;
}
}
}

class _ListTitleItem extends StatelessWidget {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,15 @@ import 'package:http/http.dart' as http;
import 'package:path_provider/path_provider.dart';
import 'package:photo_view/photo_view.dart';
import 'package:photo_view/photo_view_gallery.dart';
import 'package:provider/provider.dart';
import 'package:smooth_app/data_models/product_image_data.dart';
import 'package:smooth_app/database/local_database.dart';
import 'package:smooth_app/generic_lib/design_constants.dart';
import 'package:smooth_app/generic_lib/loading_dialog.dart';
import 'package:smooth_app/generic_lib/widgets/smooth_gauge.dart';
import 'package:smooth_app/helpers/picture_capture_helper.dart';
import 'package:smooth_app/pages/image_crop_page.dart';
import 'package:smooth_app/pages/product/common/product_refresher.dart';
import 'package:smooth_app/pages/product/confirm_and_upload_picture.dart';
import 'package:smooth_app/themes/constant_icons.dart';

Expand Down Expand Up @@ -188,6 +191,16 @@ class _ProductImageGalleryViewState extends State<ProductImageGalleryView> {
if (!mounted) {
return;
}
final LocalDatabase localDatabase =
context.read<LocalDatabase>();
await ProductRefresher().fetchAndRefresh(
context: context,
localDatabase: localDatabase,
barcode: widget.barcode!,
);
if (!mounted) {
return;
}
final AppLocalizations appLocalizations =
AppLocalizations.of(context);
final String message = getImageUploadedMessage(
Expand Down Expand Up @@ -251,6 +264,18 @@ class _ProductImageGalleryViewState extends State<ProductImageGalleryView> {
);
if (photoUploaded != null) {
_isRefreshed = true;
if (!mounted) {
return;
}
final LocalDatabase localDatabase = context.read<LocalDatabase>();
await ProductRefresher().fetchAndRefresh(
context: context,
localDatabase: localDatabase,
barcode: widget.barcode!,
);
if (!mounted) {
return;
}
setState(() {
allProductImageProviders[currentIndex] = FileImage(photoUploaded);
});
Expand Down