Skip to content

Commit

Permalink
Standard info tile about "owner fields"
Browse files Browse the repository at this point in the history
New file:
* `owner_field_info.dart`: Standard info tile about "owner fields".

Impacted files:
* `add_basic_details_page.dart`: now displaying `OwnerFieldInfo` if relevant; minor refactoring
* `nutrition_page_loaded.dart`: now displaying `OwnerFieldInfo` if relevant; minor refactoring
* `product_query.dart`: moved field to new file `owner_field_info.dart`
  • Loading branch information
monsieurtanuki committed Nov 3, 2024
1 parent 10278bf commit fabeed9
Show file tree
Hide file tree
Showing 4 changed files with 98 additions and 24 deletions.
56 changes: 40 additions & 16 deletions packages/smooth_app/lib/pages/product/add_basic_details_page.dart
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import 'package:smooth_app/pages/product/common/product_buttons.dart';
import 'package:smooth_app/pages/product/common/product_refresher.dart';
import 'package:smooth_app/pages/product/may_exit_page_helper.dart';
import 'package:smooth_app/pages/product/multilingual_helper.dart';
import 'package:smooth_app/pages/product/owner_field_info.dart';
import 'package:smooth_app/pages/text_field_helper.dart';
import 'package:smooth_app/query/product_query.dart';
import 'package:smooth_app/widgets/smooth_scaffold.dart';
Expand Down Expand Up @@ -99,7 +100,7 @@ class _AddBasicDetailsPageState extends State<AddBasicDetailsPage> {
appBar: buildEditProductAppBar(
context: context,
title: appLocalizations.basic_details,
product: widget.product,
product: _product,
),
body: Form(
key: _formKey,
Expand Down Expand Up @@ -143,7 +144,6 @@ class _AddBasicDetailsPageState extends State<AddBasicDetailsPage> {
if (_multilingualHelper.isMonolingual()) {
return SmoothTextFormField(
suffixIcon: _getOwnerFieldIcon(
_product,
ProductField.NAME,
),
controller: _productNameController,
Expand All @@ -169,7 +169,6 @@ class _AddBasicDetailsPageState extends State<AddBasicDetailsPage> {
padding: const EdgeInsets.all(8.0),
child: SmoothTextFormField(
suffixIcon: _getOwnerFieldIcon(
_product,
ProductField.NAME_IN_LANGUAGES,
language: _multilingualHelper
.getCurrentLanguage(),
Expand Down Expand Up @@ -208,7 +207,6 @@ class _AddBasicDetailsPageState extends State<AddBasicDetailsPage> {
hintText: appLocalizations.brand_name,
constraints: constraints,
suffixIcon: _getOwnerFieldIcon(
_product,
ProductField.BRANDS,
),
manager: AutocompleteManager(
Expand All @@ -222,7 +220,7 @@ class _AddBasicDetailsPageState extends State<AddBasicDetailsPage> {
limit: 25,
fuzziness: Fuzziness.none,
uriHelper: ProductQuery.getUriProductHelper(
productType: widget.product.productType,
productType: _product.productType,
),
),
),
Expand All @@ -231,13 +229,17 @@ class _AddBasicDetailsPageState extends State<AddBasicDetailsPage> {
SizedBox(height: _heightSpace),
SmoothTextFormField(
suffixIcon: _getOwnerFieldIcon(
_product,
ProductField.QUANTITY,
),
controller: _weightController,
type: TextFieldTypes.PLAIN_TEXT,
hintText: appLocalizations.quantity,
),
if (_hasOwnerField())
const Padding(
padding: EdgeInsets.only(top: LARGE_SPACE),
child: Card(child: OwnerFieldInfo()),
),
// in order to be able to scroll suggestions
SizedBox(height: MediaQuery.sizeOf(context).height),
],
Expand Down Expand Up @@ -352,17 +354,39 @@ class _AddBasicDetailsPageState extends State<AddBasicDetailsPage> {
}

Widget? _getOwnerFieldIcon(
final Product product,
final ProductField productField, {
final OpenFoodFactsLanguage? language,
}) =>
product.getOwnerFieldTimestamp(
OwnerField.productField(
productField,
language ?? ProductQuery.getLanguage(),
),
) ==
null
? null
: const Icon(ProductQuery.ownerFieldIconData);
_isOwnerField(productField, language: language)
? const Icon(OwnerFieldInfo.ownerFieldIconData)
: null;

bool _hasOwnerField() {
if (_multilingualHelper.isMonolingual()) {
if (_isOwnerField(ProductField.NAME)) {
return true;
}
} else {
if (_isOwnerField(
ProductField.NAME_IN_LANGUAGES,
language: _multilingualHelper.getCurrentLanguage(),
)) {
return true;
}
}
return _isOwnerField(ProductField.BRANDS) ||
_isOwnerField(ProductField.QUANTITY);
}

bool _isOwnerField(
final ProductField productField, {
final OpenFoodFactsLanguage? language,
}) =>
_product.getOwnerFieldTimestamp(
OwnerField.productField(
productField,
language ?? ProductQuery.getLanguage(),
),
) !=
null;
}
39 changes: 34 additions & 5 deletions packages/smooth_app/lib/pages/product/nutrition_page_loaded.dart
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import 'package:smooth_app/pages/product/may_exit_page_helper.dart';
import 'package:smooth_app/pages/product/nutrition_add_nutrient_button.dart';
import 'package:smooth_app/pages/product/nutrition_container.dart';
import 'package:smooth_app/pages/product/ordered_nutrients_cache.dart';
import 'package:smooth_app/pages/product/owner_field_info.dart';
import 'package:smooth_app/pages/product/simple_input_number_field.dart';
import 'package:smooth_app/pages/text_field_helper.dart';
import 'package:smooth_app/query/product_query.dart';
Expand Down Expand Up @@ -131,6 +132,9 @@ class _NutritionPageLoadedState extends State<NutritionPageLoaded>
children.add(_switchNoNutrition(appLocalizations));

if (!_nutritionContainer.noNutritionData) {
final Iterable<OrderedNutrient> displayableNutrients =
_nutritionContainer.getDisplayableNutrients();

children.add(
Padding(
padding: const EdgeInsets.symmetric(vertical: MEDIUM_SPACE),
Expand All @@ -141,12 +145,13 @@ class _NutritionPageLoadedState extends State<NutritionPageLoaded>
),
),
);
if (_hasOwnerField(displayableNutrients)) {
children.add(const OwnerFieldInfo());
}

children.add(_getServingField(appLocalizations));
children.add(_getServingSwitch(appLocalizations));

final Iterable<OrderedNutrient> displayableNutrients =
_nutritionContainer.getDisplayableNutrients();

if (_focusNodes.length != displayableNutrients.length) {
_focusNodes.clear();
_focusNodes.addAll(
Expand Down Expand Up @@ -227,6 +232,30 @@ class _NutritionPageLoadedState extends State<NutritionPageLoaded>
);
}

bool _hasOwnerField(
final Iterable<OrderedNutrient> displayableNutrients,
) {
if (upToDateProduct.getOwnerFieldTimestamp(
OwnerField.productField(
ProductField.SERVING_SIZE,
ProductQuery.getLanguage(),
),
) !=
null) {
return true;
}
for (final OrderedNutrient orderedNutrient in displayableNutrients) {
final Nutrient nutrient = _getNutrient(orderedNutrient);
if (upToDateProduct.getOwnerFieldTimestamp(
OwnerField.nutrient(nutrient),
) !=
null) {
return true;
}
}
return false;
}

Widget _getServingField(final AppLocalizations appLocalizations) {
final String value = _nutritionContainer.servingSize;

Expand Down Expand Up @@ -255,7 +284,7 @@ class _NutritionPageLoadedState extends State<NutritionPageLoaded>
) ==
null
? null
: const Icon(ProductQuery.ownerFieldIconData),
: const Icon(OwnerFieldInfo.ownerFieldIconData),
),
textInputAction: TextInputAction.next,
onFieldSubmitted: (_) {
Expand Down Expand Up @@ -536,7 +565,7 @@ class _NutrientValueCell extends StatelessWidget {
product.getOwnerFieldTimestamp(OwnerField.nutrient(nutrient)) ==
null
? null
: const Icon(ProductQuery.ownerFieldIconData),
: const Icon(OwnerFieldInfo.ownerFieldIconData),
),
keyboardType: const TextInputType.numberWithOptions(
signed: false,
Expand Down
24 changes: 24 additions & 0 deletions packages/smooth_app/lib/pages/product/owner_field_info.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import 'package:flutter/material.dart';

/// Standard info tile about "owner fields".
class OwnerFieldInfo extends StatelessWidget {
const OwnerFieldInfo({super.key});

/// Icon to display when the product field value is "producer provided".
static const IconData ownerFieldIconData = Icons.factory;

@override
Widget build(BuildContext context) {
final bool dark = Theme.of(context).brightness == Brightness.dark;
final Color? darkGrey = Colors.grey[700];
final Color? lightGrey = Colors.grey[300];
return ListTile(
tileColor: dark ? darkGrey : lightGrey,
leading: const Icon(ownerFieldIconData),
// TODO(monsieurtanuki): localize
title: const Text('Producer provided values'),
subtitle: const Text(
'With that logo we highlight data provided by the producer, and that may not be editable.'),
);
}
}
3 changes: 0 additions & 3 deletions packages/smooth_app/lib/query/product_query.dart
Original file line number Diff line number Diff line change
Expand Up @@ -238,9 +238,6 @@ abstract class ProductQuery {
);
}

/// Icon to display when the product field value is "producer provided".
static const IconData ownerFieldIconData = Icons.factory;

static List<ProductField> get fields => const <ProductField>[
ProductField.NAME,
ProductField.NAME_ALL_LANGUAGES,
Expand Down

0 comments on commit fabeed9

Please sign in to comment.