Skip to content

Commit

Permalink
Merge branch 'develop' into edit_product_brands_reorderable
Browse files Browse the repository at this point in the history
  • Loading branch information
g123k authored Jan 10, 2025
2 parents e5a159a + 13f5594 commit e252b24
Show file tree
Hide file tree
Showing 31 changed files with 513 additions and 924 deletions.
944 changes: 202 additions & 742 deletions packages/smooth_app/assets/onboarding/sample_product_data.json

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ class ProductTitleCard extends StatelessWidget {
const SizedBox(height: SMALL_SPACE),
_ProductTitleCardBrand(
selectable: isSelectable,
dense: dense,
),
const SizedBox(height: 2.0),
trailing,
Expand Down Expand Up @@ -155,9 +156,11 @@ class _ProductTitleCardName extends StatelessWidget {
class _ProductTitleCardBrand extends StatelessWidget {
const _ProductTitleCardBrand({
required this.selectable,
this.dense = false,
});

final bool selectable;
final bool dense;

@override
Widget build(BuildContext context) {
Expand All @@ -168,6 +171,8 @@ class _ProductTitleCardBrand extends StatelessWidget {

return Text(
brands,
maxLines: dense ? 1 : 2,
overflow: dense ? TextOverflow.ellipsis : null,
style: Theme.of(context).textTheme.bodyMedium,
textAlign: TextAlign.start,
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ class SmoothLargeButtonWithIcon extends StatelessWidget {
this.foregroundColor,
this.textAlign,
this.textStyle,
this.elevation,
});

final String text;
Expand All @@ -24,6 +25,7 @@ class SmoothLargeButtonWithIcon extends StatelessWidget {
final Color? foregroundColor;
final TextAlign? textAlign;
final TextStyle? textStyle;
final WidgetStateProperty<double?>? elevation;

Color _getBackgroundColor(final ThemeData themeData) =>
backgroundColor ?? themeData.colorScheme.secondary;
Expand All @@ -44,6 +46,7 @@ class SmoothLargeButtonWithIcon extends StatelessWidget {
minWidth: double.infinity,
padding: padding ?? const EdgeInsets.all(10),
onPressed: onPressed,
elevation: elevation,
buttonColor: _getBackgroundColor(themeData),
child: Row(
mainAxisAlignment: MainAxisAlignment.start,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ class SmoothSimpleButton extends StatelessWidget {
this.borderRadius = ROUNDED_BORDER_RADIUS,
this.padding = const EdgeInsets.all(10),
this.buttonColor,
this.elevation,
});

final Widget child;
Expand All @@ -21,6 +22,7 @@ class SmoothSimpleButton extends StatelessWidget {
final BorderRadius borderRadius;
final EdgeInsetsGeometry padding;
final Color? buttonColor;
final WidgetStateProperty<double?>? elevation;

@override
Widget build(BuildContext context) {
Expand All @@ -31,6 +33,7 @@ class SmoothSimpleButton extends StatelessWidget {
),
child: ElevatedButton(
style: ButtonStyle(
elevation: elevation,
backgroundColor: buttonColor == null
? null
: WidgetStateProperty.all<Color>(buttonColor!),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ class LanguageSelector extends StatelessWidget {
this.padding,
this.borderRadius,
this.product,
this.checkedIcon,
});

/// What to do when the language is selected.
Expand All @@ -37,6 +38,7 @@ class LanguageSelector extends StatelessWidget {
final Widget? icon;
final EdgeInsetsGeometry? padding;
final BorderRadius? borderRadius;
final Widget? checkedIcon;

/// Product from which we can extract the languages that matter.
final Product? product;
Expand Down Expand Up @@ -67,6 +69,7 @@ class LanguageSelector extends StatelessWidget {
context,
selectedLanguages: selectedLanguages,
languagePriority: languagePriority,
checkedIcon: checkedIcon,
);
if (language != null) {
await daoStringList.add(
Expand Down Expand Up @@ -126,6 +129,7 @@ class LanguageSelector extends StatelessWidget {
final BuildContext context, {
final Iterable<OpenFoodFactsLanguage>? selectedLanguages,
required final LanguagePriority languagePriority,
final Widget? checkedIcon,
}) async {
final ScrollController scrollController = ScrollController();
final AppLocalizations appLocalizations = AppLocalizations.of(context);
Expand Down Expand Up @@ -190,7 +194,8 @@ class LanguageSelector extends StatelessWidget {
selectedLanguages.contains(language);
return ListTile(
dense: true,
trailing: selected ? const Icon(Icons.check) : null,
trailing:
selected ? (checkedIcon ?? const Icon(Icons.check)) : null,
title: TextHighlighter(
text: _getCompleteName(language),
filter: languageSelectorController.text,
Expand Down
38 changes: 38 additions & 0 deletions packages/smooth_app/lib/generic_lib/widgets/smooth_snackbar.dart
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,44 @@ class SmoothFloatingSnackbar extends SnackBar {
behavior: SnackBarBehavior.floating,
);

SmoothFloatingSnackbar.positive({
required BuildContext context,
required String text,
super.elevation,
super.padding,
super.width,
super.shape,
super.hitTestBehavior,
super.action,
super.actionOverflowThreshold,
super.showCloseIcon,
super.closeIconColor,
super.animation,
super.onVisible,
super.dismissDirection,
super.clipBehavior = Clip.hardEdge,
Duration? duration,
super.key,
}) : super(
margin: const EdgeInsetsDirectional.all(SMALL_SPACE),
duration: duration ??
(action != null
? const Duration(seconds: 10)
: SnackBarDuration.short),
behavior: SnackBarBehavior.floating,
backgroundColor:
context.extension<SmoothColorsThemeExtension>().success,
content: Row(
children: <Widget>[
Expanded(child: Text(text)),
const Icon(
Icons.check_circle,
color: Colors.white,
),
],
),
);

SmoothFloatingSnackbar.error({
required BuildContext context,
required String text,
Expand Down
2 changes: 2 additions & 0 deletions packages/smooth_app/lib/helpers/product_cards_helper.dart
Original file line number Diff line number Diff line change
Expand Up @@ -312,12 +312,14 @@ Widget addPanelButton(
final String? textAlign,
final EdgeInsetsGeometry? padding,
required final Function() onPressed,
WidgetStateProperty<double?>? elevation,
}) =>
Padding(
padding: const EdgeInsets.symmetric(vertical: SMALL_SPACE),
child: SmoothLargeButtonWithIcon(
text: label,
icon: iconData ?? Icons.add,
elevation: elevation,
onPressed: onPressed,
textAlign: iconData == null ? TextAlign.center : null,
padding: padding,
Expand Down
15 changes: 10 additions & 5 deletions packages/smooth_app/lib/l10n/app_en.arb
Original file line number Diff line number Diff line change
Expand Up @@ -794,6 +794,11 @@
}
},
"product_image_outdated": "This image may be outdated",
"product_image_outdated_explanations_title": "This image may be outdated",
"product_image_outdated_explanations_content": "This image was taken more than a year ago.\n**Please check that's it's still up-to-date**.\n\nThis is **just a warning**. If the content is still the same, you can ignore this message.",
"@product_image_outdated_explanations_content": {
"description": "Please keep the ** syntax to make the text bold"
},
"product_image_action_replace_photo": "Replace photo ({type})",
"@product_image_action_replace_photo": {
"description": "Action on the photo gallery to replace an existing picture",
Expand Down Expand Up @@ -1312,7 +1317,7 @@
}
},
"settings_app_app": "Application",
"settings_app_data": "Privacy & monitoring",
"settings_app_data": "Features & Crash monitoring",
"settings_app_camera": "Camera",
"settings_app_products": "Products",
"settings_app_miscellaneous": "Miscellaneous",
Expand All @@ -1339,19 +1344,19 @@
"@app_haptic_feedback_subtitle": {
"description": "SubTitle for the Haptic feedback toggle"
},
"crash_reporting_toggle_title": "Crash reporting",
"crash_reporting_toggle_title": "Report us bugs and crashes",
"@crash_reporting_toggle_title": {
"description": "Title for the Crash reporting toggle"
},
"crash_reporting_toggle_subtitle": "When enabled, crash reports are automatically submitted to Open Food Facts' error tracking system, so that bugs can be fixed and thus improve the app.",
"@crash_reporting_toggle_subtitle": {
"description": "SubTitle for the Crash reporting toggle"
},
"send_anonymous_data_toggle_title": "Send anonymous data",
"send_anonymous_data_toggle_title": "Report us feature usage",
"@send_anonymous_toggle_title": {
"description": "Title for the Send anonymous data toggle"
},
"send_anonymous_data_toggle_subtitle": "When enabled, some anonymous information regarding app usage will be sent to the Open Food Facts servers, so that we can understand how and how much features are used in order to improve them.",
"send_anonymous_data_toggle_subtitle": "When enabled, strictly anonymous information regarding feature usage will be sent to the Open Food Facts servers, so that we can understand how features are used in order to improve them. Otherwise, a 0 id will be sent.",
"@send_anonymous_toggle_subtitle": {
"description": "SubTitle for the Send anonymous data toggle"
},
Expand Down Expand Up @@ -3538,4 +3543,4 @@
"@not_applicable_short": {
"description": "Acronym for Not Applicable"
}
}
}
5 changes: 5 additions & 0 deletions packages/smooth_app/lib/l10n/app_fr.arb
Original file line number Diff line number Diff line change
Expand Up @@ -793,6 +793,11 @@
}
},
"product_image_outdated": "Cette image peut être obsolète",
"product_image_outdated_explanations_title": "Cette image peut-être obsolète",
"product_image_outdated_explanations_content": "Cette image a été prise il y a plus d'un an.\n**Merci de vérifier qu'elle est toujours d'actualité**.\n\nIl s'agit **uniquement d'une alerte**. Si le contenu n'a pas changé, vous pouvez ignorer ce message.",
"@product_image_outdated_explanations_content": {
"description": "Please keep the ** syntax to make the text bold"
},
"product_image_action_replace_photo": "Remplacer la photo ({type})",
"@product_image_action_replace_photo": {
"description": "Action on the photo gallery to replace an existing picture",
Expand Down
3 changes: 2 additions & 1 deletion packages/smooth_app/lib/pages/offline_data_page.dart
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import 'package:smooth_app/database/dao_product_last_access.dart';
import 'package:smooth_app/database/local_database.dart';
import 'package:smooth_app/generic_lib/design_constants.dart';
import 'package:smooth_app/generic_lib/duration_constants.dart';
import 'package:smooth_app/generic_lib/widgets/smooth_snackbar.dart';
import 'package:smooth_app/helpers/app_helper.dart';
import 'package:smooth_app/pages/product/product_type_extensions.dart';
import 'package:smooth_app/widgets/smooth_app_bar.dart';
Expand Down Expand Up @@ -93,7 +94,7 @@ class _OfflineDataPageState extends State<OfflineDataPage> {
await daoProductLastAccess.deleteAll();
if (context.mounted) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
SmoothFloatingSnackbar(
content: Text(
appLocalizations.deleted_products(totalProductsDeleted),
),
Expand Down
6 changes: 4 additions & 2 deletions packages/smooth_app/lib/pages/personalized_ranking_page.dart
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import 'package:smooth_app/database/local_database.dart';
import 'package:smooth_app/generic_lib/buttons/smooth_large_button_with_icon.dart';
import 'package:smooth_app/generic_lib/design_constants.dart';
import 'package:smooth_app/generic_lib/duration_constants.dart';
import 'package:smooth_app/generic_lib/widgets/smooth_snackbar.dart';
import 'package:smooth_app/helpers/product_compatibility_helper.dart';
import 'package:smooth_app/pages/product/common/loading_status.dart';
import 'package:smooth_app/pages/product/common/product_list_item_simple.dart';
Expand Down Expand Up @@ -67,7 +68,7 @@ class _PersonalizedRankingPageState extends State<PersonalizedRankingPage>
}
if (added != null && added) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
SmoothFloatingSnackbar(
content: Text(
appLocalizations.added_to_list_msg,
),
Expand Down Expand Up @@ -231,7 +232,7 @@ class _PersonalizedRankingPageState extends State<PersonalizedRankingPage>
onDismissed: (final DismissDirection direction) {
_model.dismiss(matchedProduct.barcode);
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
SmoothFloatingSnackbar(
content: Text(appLocalizations.product_removed_comparison),
duration: SnackBarDuration.medium,
),
Expand All @@ -250,6 +251,7 @@ class _PersonalizedRankingPageState extends State<PersonalizedRankingPage>
/// Virtual item in the list: either a product or a status header
class _VirtualItem {
const _VirtualItem.score(this.score) : status = null;

const _VirtualItem.status(this.status) : score = null;
final MatchedScoreV2? score;
final MatchedProductStatusV2? status;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
import 'package:smooth_app/generic_lib/design_constants.dart';
import 'package:smooth_app/generic_lib/widgets/smooth_snackbar.dart';
import 'package:smooth_app/helpers/entry_points_helper.dart';
import 'package:smooth_app/helpers/global_vars.dart';
import 'package:smooth_app/pages/preferences/user_preferences_item.dart';
Expand Down Expand Up @@ -46,13 +47,12 @@ class UserPreferencesRateUs extends StatelessWidget {

final ThemeData themeData = Theme.of(context);
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
SmoothFloatingSnackbar(
content: Text(
appLocalizations.error_occurred,
textAlign: TextAlign.center,
style: TextStyle(color: themeData.colorScheme.surface),
),
behavior: SnackBarBehavior.floating,
backgroundColor: themeData.colorScheme.onSurface,
),
);
Expand Down
14 changes: 8 additions & 6 deletions packages/smooth_app/lib/pages/prices/price_add_product_card.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import 'package:provider/provider.dart';
import 'package:smooth_app/data_models/preferences/user_preferences.dart';
import 'package:smooth_app/database/local_database.dart';
import 'package:smooth_app/generic_lib/buttons/smooth_large_button_with_icon.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/widgets/smooth_card.dart';
import 'package:smooth_app/generic_lib/widgets/smooth_text_form_field.dart';
Expand Down Expand Up @@ -40,14 +41,15 @@ class _PriceAddProductCardState extends State<PriceAddProductCard> {
@override
Widget build(BuildContext context) {
final AppLocalizations appLocalizations = AppLocalizations.of(context);
return SmoothCard(
return SmoothCardWithRoundedHeader(
title: appLocalizations.prices_add_an_item,
leading: const Icon(Icons.add_circle_outlined),
contentPadding: const EdgeInsetsDirectional.symmetric(
horizontal: SMALL_SPACE,
vertical: MEDIUM_SPACE,
),
child: Column(
children: <Widget>[
ListTile(
title: Text(
appLocalizations.prices_add_an_item,
),
),
SmoothLargeButtonWithIcon(
text: appLocalizations.prices_barcode_reader_action,
icon: Icons.barcode_reader,
Expand Down
13 changes: 8 additions & 5 deletions packages/smooth_app/lib/pages/prices/price_amount_card.dart
Original file line number Diff line number Diff line change
Expand Up @@ -51,13 +51,16 @@ class _PriceAmountCardState extends State<PriceAmountCard> {
final PriceAmountModel model = priceModel.elementAt(widget.index);
final int total = priceModel.length;

return SmoothCard(
return SmoothCardWithRoundedHeader(
title: '${appLocalizations.prices_amount_subtitle}'
'${total == 1 ? '' : ' (${widget.index + 1}/$total)'}',
leading: const Icon(Icons.calculate_rounded),
contentPadding: const EdgeInsetsDirectional.symmetric(
vertical: MEDIUM_SPACE,
horizontal: SMALL_SPACE,
),
child: Column(
children: <Widget>[
Text(
'${appLocalizations.prices_amount_subtitle}'
'${total == 1 ? '' : ' (${widget.index + 1}/$total)'}',
),
PriceProductListTile(
product: model.product,
trailingIconData: total == 1 ? null : Icons.clear,
Expand Down
14 changes: 8 additions & 6 deletions packages/smooth_app/lib/pages/prices/price_currency_card.dart
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import 'package:flutter/material.dart';
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
import 'package:smooth_app/generic_lib/design_constants.dart';
import 'package:smooth_app/generic_lib/widgets/smooth_card.dart';
import 'package:smooth_app/pages/prices/price_currency_selector.dart';

Expand All @@ -10,13 +11,14 @@ class PriceCurrencyCard extends StatelessWidget {
@override
Widget build(BuildContext context) {
final AppLocalizations appLocalizations = AppLocalizations.of(context);
return SmoothCard(
child: Column(
children: <Widget>[
Text(appLocalizations.prices_currency_subtitle),
PriceCurrencySelector(),
],
return SmoothCardWithRoundedHeader(
title: appLocalizations.prices_currency_subtitle,
leading: const Icon(Icons.price_change),
contentPadding: const EdgeInsetsDirectional.symmetric(
horizontal: SMALL_SPACE,
vertical: MEDIUM_SPACE,
),
child: PriceCurrencySelector(),
);
}
}
Loading

0 comments on commit e252b24

Please sign in to comment.