Skip to content

Commit

Permalink
feat: 5430 - "producer provided" icon for nutrients and 4 product fields
Browse files Browse the repository at this point in the history
Impacted files:
* `add_basic_details_page.dart`: display "producer provided" icon for name, brands and quantity
* `nutrition_page_loaded.dart`: display "producer provided" icon for serving size and each individual nutrient
* `product_query.dart`: set the icon to display when a product field value is "producer provided"
* `smooth_autocomplete_text_field.dart`: added parameter `suffixIcon`
* `smooth_text_form_field.dart`: added parameter `suffixIcon`
  • Loading branch information
monsieurtanuki committed Nov 1, 2024
1 parent 66a3492 commit bb276a7
Show file tree
Hide file tree
Showing 5 changed files with 82 additions and 12 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ class SmoothTextFormField extends StatefulWidget {
required this.hintText,
this.hintTextFontSize,
this.prefixIcon,
this.suffixIcon,
this.textInputType,
this.onChanged,
this.onFieldSubmitted,
Expand All @@ -34,6 +35,7 @@ class SmoothTextFormField extends StatefulWidget {
final TextEditingController? controller;
final String hintText;
final Widget? prefixIcon;
final Widget? suffixIcon;
final bool? enabled;
final TextInputAction? textInputAction;
final String? Function(String?)? validator;
Expand Down Expand Up @@ -121,18 +123,19 @@ class _SmoothTextFormFieldState extends State<SmoothTextFormField> {
width: 5.0,
),
),
suffixIcon: widget.type == TextFieldTypes.PASSWORD
? IconButton(
tooltip: appLocalization.show_password,
splashRadius: 10.0,
onPressed: () => setState(() {
_obscureText = !_obscureText;
}),
icon: _obscureText
? const Icon(Icons.visibility_off)
: const Icon(Icons.visibility),
)
: null,
suffixIcon: widget.suffixIcon ??
(widget.type == TextFieldTypes.PASSWORD
? IconButton(
tooltip: appLocalization.show_password,
splashRadius: 10.0,
onPressed: () => setState(() {
_obscureText = !_obscureText;
}),
icon: _obscureText
? const Icon(Icons.visibility_off)
: const Icon(Icons.visibility),
)
: null),
errorMaxLines: 2,
),
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ class SmoothAutocompleteTextField extends StatefulWidget {
required this.manager,
this.minLengthForSuggestions = 1,
this.allowEmojis = true,
this.suffixIcon,
});

final FocusNode focusNode;
Expand All @@ -29,6 +30,7 @@ class SmoothAutocompleteTextField extends StatefulWidget {
final int minLengthForSuggestions;
final AutocompleteManager? manager;
final bool allowEmojis;
final Widget? suffixIcon;

@override
State<SmoothAutocompleteTextField> createState() =>
Expand Down Expand Up @@ -82,6 +84,7 @@ class _SmoothAutocompleteTextFieldState
FilteringTextInputFormatter.deny(TextHelper.emojiRegex),
],
decoration: InputDecoration(
suffixIcon: widget.suffixIcon,
filled: true,
border: const OutlineInputBorder(
borderRadius: ANGULAR_BORDER_RADIUS,
Expand Down
38 changes: 38 additions & 0 deletions packages/smooth_app/lib/pages/product/add_basic_details_page.dart
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,11 @@ class _AddBasicDetailsPageState extends State<AddBasicDetailsPage> {
Widget? child) {
if (_multilingualHelper.isMonolingual()) {
return SmoothTextFormField(
suffixIcon: _getOwnerFieldIcon(
_product,
ProductField.NAME,
appLocalizations.product_name,
),
controller: _productNameController,
type: TextFieldTypes.PLAIN_TEXT,
hintText: appLocalizations.product_name,
Expand All @@ -164,6 +169,13 @@ class _AddBasicDetailsPageState extends State<AddBasicDetailsPage> {
Padding(
padding: const EdgeInsets.all(8.0),
child: SmoothTextFormField(
suffixIcon: _getOwnerFieldIcon(
_product,
ProductField.NAME_IN_LANGUAGES,
appLocalizations.product_name,
language: _multilingualHelper
.getCurrentLanguage(),
),
controller: _productNameController,
type: TextFieldTypes.PLAIN_TEXT,
hintText: appLocalizations.product_name,
Expand Down Expand Up @@ -197,6 +209,11 @@ class _AddBasicDetailsPageState extends State<AddBasicDetailsPage> {
allowEmojis: false,
hintText: appLocalizations.brand_name,
constraints: constraints,
suffixIcon: _getOwnerFieldIcon(
_product,
ProductField.BRANDS,
appLocalizations.brand_name,
),
manager: AutocompleteManager(
TaxonomyNameAutocompleter(
taxonomyNames: <TaxonomyName>[
Expand All @@ -216,6 +233,11 @@ class _AddBasicDetailsPageState extends State<AddBasicDetailsPage> {
),
SizedBox(height: _heightSpace),
SmoothTextFormField(
suffixIcon: _getOwnerFieldIcon(
_product,
ProductField.QUANTITY,
appLocalizations.quantity,
),
controller: _weightController,
type: TextFieldTypes.PLAIN_TEXT,
hintText: appLocalizations.quantity,
Expand Down Expand Up @@ -332,4 +354,20 @@ class _AddBasicDetailsPageState extends State<AddBasicDetailsPage> {
}
return result;
}

Widget? _getOwnerFieldIcon(
final Product product,
final ProductField productField,
final String title, {
final OpenFoodFactsLanguage? language,
}) =>
product.getOwnerFieldTimestamp(
OwnerField.productField(
productField,
language ?? ProductQuery.getLanguage(),
),
) ==
null
? null
: const Icon(ProductQuery.ownerFieldIconData);
}
23 changes: 23 additions & 0 deletions packages/smooth_app/lib/pages/product/nutrition_page_loaded.dart
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ 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/simple_input_number_field.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';
import 'package:smooth_app/widgets/will_pop_scope.dart';

Expand Down Expand Up @@ -177,6 +178,7 @@ class _NutritionPageLoadedState extends State<NutritionPageLoaded>
_decimalNumberFormat,
orderedNutrient,
i,
upToDateProduct,
),
),
);
Expand Down Expand Up @@ -245,6 +247,15 @@ class _NutritionPageLoadedState extends State<NutritionPageLoaded>
decoration: InputDecoration(
enabledBorder: const UnderlineInputBorder(),
labelText: appLocalizations.nutrition_page_serving_size,
suffixIcon: widget.product.getOwnerFieldTimestamp(
OwnerField.productField(
ProductField.SERVING_SIZE,
ProductQuery.getLanguage(),
),
) ==
null
? null
: const Icon(ProductQuery.ownerFieldIconData),
),
textInputAction: TextInputAction.next,
onFieldSubmitted: (_) {
Expand Down Expand Up @@ -442,12 +453,14 @@ class _NutrientRow extends StatelessWidget {
this.decimalNumberFormat,
this.orderedNutrient,
this.position,
this.product,
);

final NutritionContainer nutritionContainer;
final NumberFormat decimalNumberFormat;
final OrderedNutrient orderedNutrient;
final int position;
final Product product;

@override
Widget build(BuildContext context) {
Expand All @@ -465,6 +478,7 @@ class _NutrientRow extends StatelessWidget {
decimalNumberFormat,
orderedNutrient,
position,
product,
),
),
),
Expand Down Expand Up @@ -492,11 +506,13 @@ class _NutrientValueCell extends StatelessWidget {
this.decimalNumberFormat,
this.orderedNutrient,
this.position,
this.product,
);

final NumberFormat decimalNumberFormat;
final OrderedNutrient orderedNutrient;
final int position;
final Product product;

@override
Widget build(BuildContext context) {
Expand All @@ -507,6 +523,12 @@ class _NutrientValueCell extends StatelessWidget {
final TextEditingControllerWithHistory controller =
context.watch<TextEditingControllerWithHistory>();
final bool isLast = position == focusNodes.length - 1;
final Nutrient? nutrient = orderedNutrient.nutrient;
final Widget? ownerFieldIcon = nutrient == null ||
product.getOwnerFieldTimestamp(OwnerField.nutrient(nutrient)) ==
null
? null
: const Icon(ProductQuery.ownerFieldIconData);

return TextFormField(
controller: controller,
Expand All @@ -515,6 +537,7 @@ class _NutrientValueCell extends StatelessWidget {
decoration: InputDecoration(
enabledBorder: const UnderlineInputBorder(),
labelText: orderedNutrient.name,
suffixIcon: ownerFieldIcon,
),
keyboardType: const TextInputType.numberWithOptions(
signed: false,
Expand Down
3 changes: 3 additions & 0 deletions packages/smooth_app/lib/query/product_query.dart
Original file line number Diff line number Diff line change
Expand Up @@ -238,6 +238,9 @@ 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 bb276a7

Please sign in to comment.