From ebcbe320f7c491422d3898b56f429f3c11870199 Mon Sep 17 00:00:00 2001 From: Edouard Marquez Date: Wed, 22 Jan 2025 12:37:17 +0100 Subject: [PATCH] Knowledge panel page: shortcuts to edit mode (#6268) --- .../knowledge_panel_page.dart | 164 ++++++++++++------ packages/smooth_app/lib/l10n/app_en.arb | 14 +- 2 files changed, 125 insertions(+), 53 deletions(-) diff --git a/packages/smooth_app/lib/knowledge_panel/knowledge_panels/knowledge_panel_page.dart b/packages/smooth_app/lib/knowledge_panel/knowledge_panels/knowledge_panel_page.dart index fe21e1d6f8f4..7912ff01e5f2 100644 --- a/packages/smooth_app/lib/knowledge_panel/knowledge_panels/knowledge_panel_page.dart +++ b/packages/smooth_app/lib/knowledge_panel/knowledge_panels/knowledge_panel_page.dart @@ -12,13 +12,16 @@ import 'package:smooth_app/helpers/product_cards_helper.dart'; import 'package:smooth_app/knowledge_panel/knowledge_panels/knowledge_panel_expanded_card.dart'; import 'package:smooth_app/knowledge_panel/knowledge_panels_builder.dart'; import 'package:smooth_app/pages/product/common/product_refresher.dart'; +import 'package:smooth_app/pages/product/nutrition_page/nutrition_page_loader.dart'; import 'package:smooth_app/pages/product/portion_calculator.dart'; import 'package:smooth_app/pages/product/product_field_editor.dart'; +import 'package:smooth_app/pages/product/simple_input_page_helpers.dart'; import 'package:smooth_app/pages/scan/carousel/scan_carousel_manager.dart'; import 'package:smooth_app/themes/smooth_theme.dart'; import 'package:smooth_app/themes/smooth_theme_colors.dart'; import 'package:smooth_app/themes/theme_provider.dart'; import 'package:smooth_app/widgets/smooth_app_bar.dart'; +import 'package:smooth_app/widgets/smooth_menu_button.dart'; import 'package:smooth_app/widgets/smooth_scaffold.dart'; /// Detail page of knowledge panels (if you click on the forward/more button). @@ -63,60 +66,63 @@ class _KnowledgePanelPageState extends State context.watch(); refreshUpToDate(); - return SmoothScaffold( - backgroundColor: context.lightTheme() - ? context.extension().primaryLight - : null, - appBar: SmoothAppBar( - title: Semantics( - label: _getTitleForAccessibility(appLocalizations, title), - child: Text( - title, + return Provider.value( + value: upToDateProduct, + child: SmoothScaffold( + backgroundColor: context.lightTheme() + ? context.extension().primaryLight + : null, + appBar: SmoothAppBar( + title: Semantics( + label: _getTitleForAccessibility(appLocalizations, title), + child: Text( + title, + maxLines: 1, + overflow: TextOverflow.ellipsis, + ), + ), + subTitle: Text( + getProductNameAndBrands(upToDateProduct, appLocalizations), maxLines: 1, overflow: TextOverflow.ellipsis, ), + actions: _actions(), ), - subTitle: Text( - getProductNameAndBrands(upToDateProduct, appLocalizations), - maxLines: 1, - overflow: TextOverflow.ellipsis, - ), - actions: _actions(), - ), - body: RefreshIndicator( - onRefresh: () => _refreshProduct(context), - child: Scrollbar( - child: ListView( - physics: const AlwaysScrollableScrollPhysics(), - padding: EdgeInsetsDirectional.only( - top: SMALL_SPACE, - start: VERY_SMALL_SPACE, - end: VERY_SMALL_SPACE, - bottom: SMALL_SPACE + MediaQuery.viewPaddingOf(context).bottom, - ), - children: [ - SmoothCard( - padding: const EdgeInsetsDirectional.only( - bottom: LARGE_SPACE, - ), - child: DefaultTextStyle.merge( - style: const TextStyle(fontSize: 15.0, height: 1.5), - child: KnowledgePanelExpandedCard( - panelId: widget.panelId, - product: upToDateProduct, - isInitiallyExpanded: true, - isClickable: true, - ), - ), + body: RefreshIndicator( + onRefresh: () => _refreshProduct(context), + child: Scrollbar( + child: ListView( + physics: const AlwaysScrollableScrollPhysics(), + padding: EdgeInsetsDirectional.only( + top: SMALL_SPACE, + start: VERY_SMALL_SPACE, + end: VERY_SMALL_SPACE, + bottom: SMALL_SPACE + MediaQuery.viewPaddingOf(context).bottom, ), - if (PortionCalculator.isVisible(widget.panelId)) + children: [ SmoothCard( padding: const EdgeInsetsDirectional.only( bottom: LARGE_SPACE, ), - child: PortionCalculator(upToDateProduct), + child: DefaultTextStyle.merge( + style: const TextStyle(fontSize: 15.0, height: 1.5), + child: KnowledgePanelExpandedCard( + panelId: widget.panelId, + product: upToDateProduct, + isInitiallyExpanded: true, + isClickable: true, + ), + ), ), - ], + if (PortionCalculator.isVisible(widget.panelId)) + SmoothCard( + padding: const EdgeInsetsDirectional.only( + bottom: LARGE_SPACE, + ), + child: PortionCalculator(upToDateProduct), + ), + ], + ), ), ), ), @@ -174,17 +180,51 @@ class _KnowledgePanelPageState extends State } } - // TODO(g123k): Improve this mechanism to be more flexible List? _actions() { - if (widget.panelId == 'ingredients') { + if (['ingredients', 'ingredients_analysis_details'] + .contains(widget.panelId)) { return [ - IconButton( + _KnowledgePanelPageEditAction( + tooltip: AppLocalizations.of(context).ingredients_editing_title, onPressed: () async => ProductFieldOcrIngredientEditor().edit( context: context, product: upToDateProduct, ), - icon: const Icon(Icons.edit), - tooltip: AppLocalizations.of(context).ingredients_editing_title, + ), + ]; + } else if (widget.panelId == 'nutrition_facts_table') { + return [ + _KnowledgePanelPageEditAction( + tooltip: AppLocalizations.of(context).nutrition_facts_editing_title, + onPressed: () async => NutritionPageLoader.showNutritionPage( + product: upToDateProduct, + isLoggedInMandatory: true, + context: context, + ), + ), + ]; + } else if ([ + 'origins_of_ingredients', + 'environmental_score_origins_of_ingredients' + ].contains(widget.panelId)) { + return [ + _KnowledgePanelPageEditAction( + tooltip: AppLocalizations.of(context).origins_editing_title, + onPressed: () async => + ProductFieldSimpleEditor(SimpleInputPageOriginHelper()).edit( + context: context, + product: upToDateProduct, + ), + ), + ]; + } else if (widget.panelId == 'environmental_score_packaging') { + return [ + _KnowledgePanelPageEditAction( + tooltip: AppLocalizations.of(context).origins_editing_title, + onPressed: () async => ProductFieldPackagingEditor().edit( + context: context, + product: upToDateProduct, + ), ), ]; } @@ -198,3 +238,29 @@ class _KnowledgePanelPageState extends State properties.add(StringProperty('panelId', widget.panelId)); } } + +class _KnowledgePanelPageEditAction extends StatelessWidget { + const _KnowledgePanelPageEditAction({ + required this.tooltip, + required this.onPressed, + }); + + final String tooltip; + final VoidCallback onPressed; + + @override + Widget build(BuildContext context) { + return SmoothPopupMenuButton( + buttonIcon: const Icon(Icons.more_vert), + onSelected: (_) => onPressed(), + itemBuilder: (BuildContext context) { + return >[ + SmoothPopupMenuItem( + label: tooltip, + value: null, + icon: Icons.edit, + ), + ]; + }); + } +} diff --git a/packages/smooth_app/lib/l10n/app_en.arb b/packages/smooth_app/lib/l10n/app_en.arb index d3fcc305e8e6..5c24b65f643d 100644 --- a/packages/smooth_app/lib/l10n/app_en.arb +++ b/packages/smooth_app/lib/l10n/app_en.arb @@ -562,6 +562,10 @@ "@nutrition_facts_photo": { "description": "Button label: For adding a picture of the nutrition facts of a product" }, + "nutrition_facts_editing_title": "Edit Nutrition Facts", + "@nutrition_facts_editing_title": { + "description": "Title of the button where users can edit the nutrition facts of a product" + }, "packaging_information": "Packaging information", "@packaging_information": { "description": "Button label: For adding a picture of the packaging of a product" @@ -889,7 +893,7 @@ "description": "The name of the contributor who uploaded the image" }, "product_image_details_contributor_producer": "Contributor (producer)", - "@product_image_details_contributor": { + "@product_image_details_contributor_producer": { "description": "The name of the contributor (and also the owner field) who uploaded the image" }, "product_image_details_date": "Date", @@ -897,7 +901,7 @@ "description": "Text to indicate the date of the image" }, "product_image_details_date_unknown": "Unknown", - "@product_image_details_date": { + "@product_image_details_date_unknown": { "description": "Text to indicate the date of the image is unknown" }, "homepage_main_card_logo_description": "Welcome to Open Food Facts", @@ -1736,6 +1740,10 @@ "@product_field_website_title": { "description": "Title of a product field: website" }, + "origins_editing_title": "Edit Origins", + "@origins_editing_title": { + "description": "Title of the button where users can edit the origins of a product" + }, "completed_basic_details_btn_text": "Complete basic details", "not_implemented_snackbar_text": "Not implemented yet", "category_picker_page_appbar_text": "Categories", @@ -2259,8 +2267,6 @@ "prices_add_validation_error": "Validation error", "prices_privacy_warning_title": "Privacy warning", "prices_unknown_product": "Unknown product", - "prices_privacy_warning_title": "Privacy warning", - "prices_unknown_product": "Unknown product", "prices_privacy_warning_main_message": "Prices **will be public**, along with the store they refer to.\n\nThat might allow people who know about your Open Food Facts pseudonym to:\n", "prices_privacy_warning_message_bullet_1": "Infer in which area you live", "prices_privacy_warning_message_bullet_2": "Know what you are buying",