diff --git a/packages/smooth_app/lib/generic_lib/dialogs/smooth_alert_dialog.dart b/packages/smooth_app/lib/generic_lib/dialogs/smooth_alert_dialog.dart index be77eea6e9f..7bd4ec145fe 100644 --- a/packages/smooth_app/lib/generic_lib/dialogs/smooth_alert_dialog.dart +++ b/packages/smooth_app/lib/generic_lib/dialogs/smooth_alert_dialog.dart @@ -31,8 +31,12 @@ class SmoothAlertDialog extends StatelessWidget { this.actionsAxis, this.actionsOrder, this.close = false, + this.margin, this.contentPadding, - }); + }) : assert( + body is! LayoutBuilder, + "LayoutBuilder isn't supported with Dialogs", + ); final String? title; final bool close; @@ -41,8 +45,15 @@ class SmoothAlertDialog extends StatelessWidget { final SmoothActionButton? negativeAction; final Axis? actionsAxis; final SmoothButtonsBarOrder? actionsOrder; + final EdgeInsets? margin; final EdgeInsetsDirectional? contentPadding; + /// Default value [_defaultInsetPadding] in dialog.dart + static const EdgeInsets defaultMargin = EdgeInsets.symmetric( + horizontal: 40.0, + vertical: 24.0, + ); + static const EdgeInsetsDirectional _smallContentPadding = EdgeInsetsDirectional.only( start: SMALL_SPACE, @@ -62,12 +73,13 @@ class SmoothAlertDialog extends StatelessWidget { @override Widget build(BuildContext context) { final Widget content = _buildContent(context); - final EdgeInsetsDirectional padding = contentPadding ?? - (context.isSmallDevice() ? _smallContentPadding : _contentPadding); + final EdgeInsetsDirectional padding = + contentPadding ?? defaultContentPadding(context); return AlertDialog( scrollable: false, elevation: 4.0, + insetPadding: margin ?? defaultMargin, contentPadding: EdgeInsets.zero, shape: const RoundedRectangleBorder(borderRadius: ROUNDED_BORDER_RADIUS), content: ClipRRect( @@ -93,7 +105,7 @@ class SmoothAlertDialog extends StatelessWidget { return Padding( padding: EdgeInsetsDirectional.only( top: padding.bottom, - start: SMALL_SPACE, + start: actionsAxis == Axis.horizontal ? SMALL_SPACE : 0.0, end: positiveAction != null && negativeAction != null ? 0.0 : SMALL_SPACE, @@ -119,6 +131,10 @@ class SmoothAlertDialog extends StatelessWidget { ], ), ); + + static EdgeInsetsDirectional defaultContentPadding(BuildContext context) { + return (context.isSmallDevice() ? _smallContentPadding : _contentPadding); + } } class _SmoothDialogTitle extends StatelessWidget { diff --git a/packages/smooth_app/lib/generic_lib/widgets/smooth_responsive.dart b/packages/smooth_app/lib/generic_lib/widgets/smooth_responsive.dart index 266e42f2548..29995691caa 100644 --- a/packages/smooth_app/lib/generic_lib/widgets/smooth_responsive.dart +++ b/packages/smooth_app/lib/generic_lib/widgets/smooth_responsive.dart @@ -40,6 +40,18 @@ extension MediaQueryResponsiveExtensions on MediaQueryData { bool isLargeDevice() { return size.width > _MAX_TABLET_WIDTH; } + + DeviceType get _deviceType { + if (size.width <= _MAX_SMALL_DEVICE_WIDTH) { + return DeviceType.small; + } else if (size.width <= _MAX_SMARTPHONE_WIDTH) { + return DeviceType.smartphone; + } else if (size.width <= _MAX_TABLET_WIDTH) { + return DeviceType.tablet; + } else { + return DeviceType.large; + } + } } extension BuildContextResponsiveExtensions on BuildContext { @@ -58,6 +70,8 @@ extension BuildContextResponsiveExtensions on BuildContext { bool isLargeDevice() { return SmoothResponsive.isLargeDevice(this); } + + DeviceType get deviceType => MediaQuery.of(this)._deviceType; } /// Custom Widget to provide a responsive behavior. @@ -89,3 +103,10 @@ class SmoothResponsiveBuilder extends StatelessWidget { } } } + +enum DeviceType { + small, + smartphone, + tablet, + large, +} diff --git a/packages/smooth_app/lib/pages/product/common/product_dialog_helper.dart b/packages/smooth_app/lib/pages/product/common/product_dialog_helper.dart index 853e70ee856..807ea6db89a 100644 --- a/packages/smooth_app/lib/pages/product/common/product_dialog_helper.dart +++ b/packages/smooth_app/lib/pages/product/common/product_dialog_helper.dart @@ -1,4 +1,5 @@ -import 'package:auto_size_text/auto_size_text.dart'; +import 'dart:math' as math; + import 'package:flutter/material.dart'; import 'package:flutter_gen/gen_l10n/app_localizations.dart'; import 'package:flutter_svg/flutter_svg.dart'; @@ -10,6 +11,7 @@ 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_responsive.dart'; import 'package:smooth_app/helpers/app_helper.dart'; import 'package:smooth_app/pages/navigator/app_navigator.dart'; import 'package:smooth_app/query/barcode_product_query.dart'; @@ -53,83 +55,80 @@ class ProductDialogHelper { FetchedProduct.error(FetchedProductStatus.userCancelled); void _openProductNotFoundDialog() => showDialog( - context: context, - builder: (BuildContext context) => SmoothAlertDialog( - body: LayoutBuilder( - builder: ( - final BuildContext context, - final BoxConstraints constraints, - ) { - final MediaQueryData mediaQueryData = MediaQuery.of(context); - final AppLocalizations appLocalizations = - AppLocalizations.of(context); - const double svgPadding = SMALL_SPACE; - final double svgWidth = (constraints.maxWidth - svgPadding) / 2; - return SizedBox( - height: mediaQueryData.size.height * .5, - child: Column( - mainAxisSize: MainAxisSize.max, - mainAxisAlignment: MainAxisAlignment.spaceBetween, - crossAxisAlignment: CrossAxisAlignment.center, - children: [ - Expanded( - flex: 25, - child: SvgPicture.asset( - 'assets/onboarding/birthday-cake.svg', - package: AppHelper.APP_PACKAGE, - ), - ), - const SizedBox(height: SMALL_SPACE), - Expanded( - flex: 25, - child: AutoSizeText( - appLocalizations.new_product_dialog_title, - style: Theme.of(context).textTheme.displayMedium, - textAlign: TextAlign.center, - maxLines: 2, - ), - ), - const SizedBox(height: SMALL_SPACE), - Expanded( - flex: 10, - child: Text( - appLocalizations.barcode_barcode(barcode), - textAlign: TextAlign.center, - ), - ), - const SizedBox(height: SMALL_SPACE), - Expanded( - flex: 15, - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - crossAxisAlignment: CrossAxisAlignment.center, - children: [ - SvgCache( - unknownSvgNutriscore, - width: svgWidth, - ), - const SizedBox(width: svgPadding), - SvgCache( - unknownSvgEcoscore, - width: svgWidth, - ), - ], - ), + context: context, + builder: (BuildContext context) { + final double availableWidth = MediaQuery.of(context).size.width - + SmoothAlertDialog.defaultMargin.horizontal - + SmoothAlertDialog.defaultContentPadding(context).horizontal; + + /// The nutriscore logo is 240*130 + final double svgHeight = math.min( + (availableWidth * 0.4) / 240.0 * 130.0, + 175.0, + ); + + final double heightMultiplier = switch (context.deviceType) { + DeviceType.small => 1, + DeviceType.smartphone => 2, + DeviceType.tablet => 2.5, + DeviceType.large => 4, + }; + + final AppLocalizations appLocalizations = AppLocalizations.of(context); + return SmoothAlertDialog( + body: Column( + mainAxisSize: MainAxisSize.max, + mainAxisAlignment: MainAxisAlignment.spaceBetween, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + SvgPicture.asset( + 'assets/onboarding/birthday-cake.svg', + package: AppHelper.APP_PACKAGE, + ), + SizedBox(height: SMALL_SPACE * heightMultiplier), + Text( + appLocalizations.new_product_dialog_title, + style: Theme.of(context).textTheme.displayMedium, + textAlign: TextAlign.center, + maxLines: 2, + ), + SizedBox(height: SMALL_SPACE * heightMultiplier), + Text( + appLocalizations.barcode_barcode(barcode), + textAlign: TextAlign.center, + ), + SizedBox(height: MEDIUM_SPACE * heightMultiplier), + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Expanded( + flex: 4, + child: SvgCache( + unknownSvgNutriscore, + height: svgHeight, ), - const SizedBox(height: SMALL_SPACE), - Expanded( - flex: 25, - child: AutoSizeText( - appLocalizations.new_product_dialog_description, - textAlign: TextAlign.center, - maxLines: 3, - ), + ), + const Spacer(), + Expanded( + flex: 4, + child: SvgCache( + unknownSvgEcoscore, + height: svgHeight, ), - ], - ), - ); - }, + ), + ], + ), + SizedBox(height: SMALL_SPACE * heightMultiplier), + Text( + appLocalizations.new_product_dialog_description, + textAlign: TextAlign.center, + overflow: TextOverflow.ellipsis, + maxLines: 3, + ), + ], ), + actionsAxis: Axis.vertical, positiveAction: SmoothActionButton( text: AppLocalizations.of(context).contribute, onPressed: () => AppNavigator.of(context).push( @@ -140,8 +139,8 @@ class ProductDialogHelper { text: AppLocalizations.of(context).close, onPressed: () => Navigator.pop(context), ), - ), - ); + ); + }); static Widget getErrorMessage(final String message) => Row( children: [