Skip to content

Commit

Permalink
fix: #2146 refresh product edition (#2201)
Browse files Browse the repository at this point in the history
* fix: #2146 refresh product edition

* fix: #2146 refresh product edition photo editing

* fix: #2146 refactoring

* fix: fix presubmit test

* fix: fix presubmit

* fix: #2146 refresh product edition v2

* fix: #2146 fix presubmit check

* fix: #2146 refactoring v3
  • Loading branch information
cli1005 authored Jun 10, 2022
1 parent d698ffb commit 316e9df
Show file tree
Hide file tree
Showing 10 changed files with 176 additions and 105 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -52,9 +52,9 @@ class ProductTitleCard extends StatelessWidget {
onTap: (getProductName(product, appLocalizations) ==
appLocalizations.unknownProductName)
? () async {
await Navigator.push<bool>(
await Navigator.push<Product?>(
context,
MaterialPageRoute<bool>(
MaterialPageRoute<Product>(
builder: (BuildContext context) =>
AddBasicDetailsPage(product),
),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -144,16 +144,16 @@ class KnowledgePanelsBuilder {
return;
}
//ignore: use_build_context_synchronously
final bool? refreshed = await Navigator.push<bool>(
final Product? refreshedProduct = await Navigator.push<Product>(
context,
MaterialPageRoute<bool>(
MaterialPageRoute<Product>(
builder: (BuildContext context) => NutritionPageLoaded(
product,
cache.orderedNutrients,
),
),
);
if (refreshed ?? false) {
if (refreshedProduct != null) {
setState?.call();
}
// TODO(monsieurtanuki): refresh the data if changed
Expand Down
87 changes: 39 additions & 48 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,13 @@ 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/product_query.dart';
import 'package:smooth_app/database/local_database.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 All @@ -25,23 +26,26 @@ class _AddBasicDetailsPageState extends State<AddBasicDetailsPage> {

final double _heightSpace = LARGE_SPACE;
final GlobalKey<FormState> _formKey = GlobalKey<FormState>();
late Product _product;

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

void _initializeProduct() {
_productNameController.text = widget.product.productName ?? '';
_weightController.text = widget.product.quantity ?? '';
_brandNameController.text = widget.product.brands ?? '';
_productNameController.text = _product.productName ?? '';
_weightController.text = _product.quantity ?? '';
_brandNameController.text = _product.brands ?? '';
}

@override
Widget build(BuildContext context) {
final AppLocalizations appLocalizations = AppLocalizations.of(context);
final Size size = MediaQuery.of(context).size;
final LocalDatabase localDatabase = context.read<LocalDatabase>();
return Scaffold(
appBar: AppBar(
title: Text(appLocalizations.basic_details),
Expand All @@ -57,19 +61,19 @@ class _AddBasicDetailsPageState extends State<AddBasicDetailsPage> {
Align(
alignment: Alignment.topLeft,
child: ProductImageCarousel(
widget.product,
_product,
height: size.height * 0.20,
onUpload: (_) {},
),
),
SizedBox(height: _heightSpace),
if (widget.product.barcode != null)
if (_product.barcode != null)
Padding(
padding: EdgeInsets.symmetric(horizontal: size.width * 0.05),
child: Column(
children: <Widget>[
Text(
appLocalizations.barcode_barcode(widget.product.barcode!),
appLocalizations.barcode_barcode(_product.barcode!),
style: Theme.of(context).textTheme.bodyText2?.copyWith(
fontWeight: FontWeight.bold,
),
Expand Down Expand Up @@ -125,19 +129,25 @@ class _AddBasicDetailsPageState extends State<AddBasicDetailsPage> {
if (!_formKey.currentState!.validate()) {
return;
}
final Status? status = await _saveData();
if (status == null || status.error != null) {
_errorMessageAlert(
appLocalizations.basic_details_add_error);
return;
}
if (!mounted) {
return;
final Product? refreshedProduct =
await _saveData(localDatabase);
if (refreshedProduct != null) {
setState(() {
_product = refreshedProduct;
});
if (!mounted) {
return;
}
ScaffoldMessenger.of(context).showSnackBar(SnackBar(
content: Text(
appLocalizations.basic_details_add_success)));
Navigator.pop(context, _product);
} else {
if (!mounted) {
return;
}
Navigator.pop(context);
}
ScaffoldMessenger.of(context).showSnackBar(SnackBar(
content: Text(
appLocalizations.basic_details_add_success)));
Navigator.pop(context, true);
}),
),
),
Expand All @@ -147,36 +157,17 @@ class _AddBasicDetailsPageState extends State<AddBasicDetailsPage> {
);
}

void _errorMessageAlert(final String message) => showDialog<void>(
context: context,
builder: (BuildContext context) => SmoothAlertDialog(
body: ListTile(
leading: const Icon(Icons.error_outline, color: Colors.red),
title: Text(message),
),
positiveAction: SmoothActionButton(
text: AppLocalizations.of(context).close,
onPressed: () => Navigator.pop(context),
),
),
);

Future<Status?> _saveData() async {
final AppLocalizations appLocalizations = AppLocalizations.of(context);
final Product product = Product(
productName: _productNameController.text,
quantity: _weightController.text,
brands: _brandNameController.text,
barcode: widget.product.barcode,
);
final Status? status = await LoadingDialog.run<Status>(
Future<Product?> _saveData(LocalDatabase localDatabase) async {
final Product? savedAndRefreshed = await ProductRefresher().saveAndRefresh(
context: context,
future: OpenFoodAPIClient.saveProduct(
ProductQuery.getUser(),
product,
localDatabase: localDatabase,
product: Product(
productName: _productNameController.text,
quantity: _weightController.text,
brands: _brandNameController.text,
barcode: _product.barcode,
),
title: appLocalizations.nutrition_page_update_running,
);
return status;
return savedAndRefreshed;
}
}
40 changes: 19 additions & 21 deletions packages/smooth_app/lib/pages/product/add_new_product_page.dart
Original file line number Diff line number Diff line change
Expand Up @@ -263,19 +263,18 @@ class _AddNewProductPageState extends State<AddNewProductPage> {
if (!mounted) {
return;
}
final bool result = await Navigator.push<bool>(
context,
MaterialPageRoute<bool>(
builder: (BuildContext context) => NutritionPageLoaded(
Product(barcode: widget.barcode),
cache.orderedNutrients,
),
),
) ??
false;
final Product? result = await Navigator.push<Product?>(
context,
MaterialPageRoute<Product>(
builder: (BuildContext context) => NutritionPageLoaded(
Product(barcode: widget.barcode),
cache.orderedNutrients,
),
),
);

setState(() {
_nutritionFactsAdded = result;
_nutritionFactsAdded = result != null;
});
},
),
Expand Down Expand Up @@ -314,17 +313,16 @@ class _AddNewProductPageState extends State<AddNewProductPage> {
text: AppLocalizations.of(context).completed_basic_details_btn_text,
icon: Icons.edit,
onPressed: () async {
final bool result = await Navigator.push<bool>(
context,
MaterialPageRoute<bool>(
builder: (BuildContext context) => AddBasicDetailsPage(
Product(barcode: widget.barcode),
),
),
) ??
false;
final Product? result = await Navigator.push<Product?>(
context,
MaterialPageRoute<Product>(
builder: (BuildContext context) => AddBasicDetailsPage(
Product(barcode: widget.barcode),
),
),
);
setState(() {
_basicDetailsAdded = result;
_basicDetailsAdded = result != null;
});
},
),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,49 @@ class ProductRefresher {
}
return const _MetaProductRefresher.error(null);
}

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

Future<_MetaProductRefresher> _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!);
localDatabase.notifyListeners();
return _MetaProductRefresher.product(result.product);
}
return const _MetaProductRefresher.error(null);
}
}

class _MetaProductRefresher {
Expand Down
Loading

0 comments on commit 316e9df

Please sign in to comment.