From ac410f40c92fb7a3c058eefe30fe5d14b974513e Mon Sep 17 00:00:00 2001 From: malik1004x Date: Thu, 2 Apr 2026 13:04:57 +0200 Subject: [PATCH] improve dialog box design (#3145) --- lib/src/screens/backup/backup_page.dart | 3 + lib/src/widgets/alert_with_one_action.dart | 63 +++--- lib/src/widgets/alert_with_two_actions.dart | 6 + lib/src/widgets/base_alert_dialog.dart | 224 +++++++++++--------- 4 files changed, 169 insertions(+), 127 deletions(-) diff --git a/lib/src/screens/backup/backup_page.dart b/lib/src/screens/backup/backup_page.dart index 3f108f302..cab867bf5 100644 --- a/lib/src/screens/backup/backup_page.dart +++ b/lib/src/screens/backup/backup_page.dart @@ -3,6 +3,7 @@ import 'dart:ui'; import 'package:cake_wallet/core/execution_state.dart'; import 'package:cake_wallet/src/screens/base_page.dart'; import 'package:cake_wallet/src/widgets/alert_with_two_actions.dart'; +import 'package:cake_wallet/src/widgets/base_alert_dialog.dart'; import 'package:cake_wallet/src/widgets/primary_button.dart'; import 'package:cake_wallet/generated/i18n.dart'; import 'package:cake_wallet/routes.dart'; @@ -116,6 +117,8 @@ class BackupPage extends BasePage { alertContent: S.of(context).save_backup_password, rightButtonText: S.of(context).seed_alert_yes, leftButtonText: S.of(context).seed_alert_back, + leftAlertButtonStyle: AlertButtonStyle.error(context), + rightAlertButtonStyle: AlertButtonStyle.secondary(context), actionRightButton: () async { Navigator.of(dialogContext).pop(); final backupFuture = backupViewModelBase.exportBackup(); diff --git a/lib/src/widgets/alert_with_one_action.dart b/lib/src/widgets/alert_with_one_action.dart index f66cae177..de6c0a870 100644 --- a/lib/src/widgets/alert_with_one_action.dart +++ b/lib/src/widgets/alert_with_one_action.dart @@ -39,32 +39,39 @@ class AlertWithOneAction extends BaseAlertDialog { String? get headerText => headerTitleText; @override - Widget actionButtons(BuildContext context) { - return Container( - width: 300, - height: 52, - padding: EdgeInsets.only(left: 12, right: 12), - color: Theme.of(context).colorScheme.surface, - child: ButtonTheme( - minWidth: double.infinity, - child: TextButton( - key: buttonKey, - onPressed: buttonAction, - // FIX-ME: Style - //highlightColor: Colors.transparent, - //splashColor: Colors.transparent, - child: Text( - buttonText, - textAlign: TextAlign.center, - style: Theme.of(context).textTheme.bodyMedium!.copyWith( - fontSize: 15, - fontWeight: FontWeight.w600, - color: Theme.of(context).colorScheme.primary, - decoration: TextDecoration.none, - ), - ), - ), - ), - ); - } + VoidCallback get actionRight => buttonAction; + + @override + bool get showLeftButton => false; + + @override + String get rightActionButtonText => buttonText; + + // @override + // Widget actionButtons(BuildContext context) { + // return Container( + // padding: EdgeInsets.only(left: 12, right: 12), + // color: Theme.of(context).colorScheme.surface, + // child: ButtonTheme( + // minWidth: double.infinity, + // child: TextButton( + // key: buttonKey, + // onPressed: buttonAction, + // // FIX-ME: Style + // //highlightColor: Colors.transparent, + // //splashColor: Colors.transparent, + // child: Text( + // buttonText, + // textAlign: TextAlign.center, + // style: Theme.of(context).textTheme.bodyMedium!.copyWith( + // fontSize: 15, + // fontWeight: FontWeight.w600, + // color: Theme.of(context).colorScheme.primary, + // decoration: TextDecoration.none, + // ), + // ), + // ), + // ), + // ); + // } } diff --git a/lib/src/widgets/alert_with_two_actions.dart b/lib/src/widgets/alert_with_two_actions.dart index bbbc1d64d..520f57837 100644 --- a/lib/src/widgets/alert_with_two_actions.dart +++ b/lib/src/widgets/alert_with_two_actions.dart @@ -14,6 +14,8 @@ class AlertWithTwoActions extends BaseAlertDialog { this.isDividerExist = false, // this.leftActionColor, // this.rightActionColor, + this.leftAlertButtonStyle, + this.rightAlertButtonStyle, this.alertRightActionButtonKey, this.alertLeftActionButtonKey, this.alertDialogKey, @@ -29,6 +31,10 @@ class AlertWithTwoActions extends BaseAlertDialog { final bool alertBarrierDismissible; // final Color leftActionColor; // final Color rightActionColor; + @override + final AlertButtonStyle? leftAlertButtonStyle; + @override + final AlertButtonStyle? rightAlertButtonStyle; final bool isDividerExist; final Key? alertRightActionButtonKey; final Key? alertLeftActionButtonKey; diff --git a/lib/src/widgets/base_alert_dialog.dart b/lib/src/widgets/base_alert_dialog.dart index a27f79724..a9b97c986 100644 --- a/lib/src/widgets/base_alert_dialog.dart +++ b/lib/src/widgets/base_alert_dialog.dart @@ -1,14 +1,45 @@ import 'dart:ui'; +import 'package:auto_size_text/auto_size_text.dart'; import 'package:cake_wallet/src/widgets/section_divider.dart'; import 'package:flutter/material.dart'; + +class AlertButtonStyle { + final Color backgroundColor; + final Color textColor; + final FontWeight fontWeight; + + const AlertButtonStyle({ + required this.backgroundColor, + required this.textColor, + this.fontWeight = FontWeight.w400 + }); + + factory AlertButtonStyle.primary(BuildContext context) => AlertButtonStyle( + backgroundColor: Theme.of(context).colorScheme.primary, + textColor: Theme.of(context).colorScheme.onPrimary, + ); + + factory AlertButtonStyle.secondary(BuildContext context) => AlertButtonStyle( + backgroundColor: Theme.of(context).colorScheme.surfaceContainer, + textColor: Theme.of(context).colorScheme.primary, + ); + + factory AlertButtonStyle.error(BuildContext context) => AlertButtonStyle( + backgroundColor: Theme.of(context).colorScheme.errorContainer, + textColor: Theme.of(context).colorScheme.error, + fontWeight: FontWeight.w500 + ); +} + + class BaseAlertDialog extends StatelessWidget { String? get headerText => ''; String? get titleText => ''; - double? get titleTextSize => 20; + double? get titleTextSize => 18; String get contentText => ''; @@ -28,14 +59,6 @@ class BaseAlertDialog extends StatelessWidget { bool get barrierDismissible => true; - Color? get leftActionButtonTextColor => null; - - Color? get rightActionButtonTextColor => null; - - Color? get leftActionButtonColor => null; - - Color? get rightActionButtonColor => null; - String? get headerImageUrl => null; Key? leftActionButtonKey; @@ -43,6 +66,12 @@ class BaseAlertDialog extends StatelessWidget { Key? rightActionButtonKey; Key? dialogKey; + + AlertButtonStyle? get leftAlertButtonStyle => null; + + AlertButtonStyle? get rightAlertButtonStyle => null; + + bool get showLeftButton => true; Widget title(BuildContext context) { return Text( @@ -83,7 +112,7 @@ class BaseAlertDialog extends StatelessWidget { contentText, textAlign: TextAlign.center, style: Theme.of(context).textTheme.bodyMedium?.copyWith( - fontSize: 16, + fontSize: 14, decoration: TextDecoration.none, ), ), @@ -93,59 +122,56 @@ class BaseAlertDialog extends StatelessWidget { } Widget actionButtons(BuildContext context) { - return Container( - height: 60, - child: Row( - mainAxisSize: MainAxisSize.max, - crossAxisAlignment: CrossAxisAlignment.stretch, - children: [ - Expanded( - child: TextButton( - key: leftActionButtonKey, - onPressed: actionLeft, - style: TextButton.styleFrom( - backgroundColor: leftActionButtonColor ?? Theme.of(context).colorScheme.surface, - shape: const RoundedRectangleBorder( - borderRadius: BorderRadius.all(Radius.zero), + final rightButtonStyle = rightAlertButtonStyle ?? AlertButtonStyle.primary(context); + final leftButtonStyle = leftAlertButtonStyle ?? AlertButtonStyle.secondary(context); + + return Row( + mainAxisAlignment: MainAxisAlignment.center, + mainAxisSize: MainAxisSize.max, + spacing:8, + children: [ + if(showLeftButton) + Expanded( + child: GestureDetector( + key: leftActionButtonKey, + onTap: actionLeft, + child: Container( + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(999999), + color: leftButtonStyle.backgroundColor + ), + child: Padding( + padding: EdgeInsets.symmetric(vertical: 16, horizontal: 8), + child: AutoSizeText( + maxLines:1, + leftActionButtonText, + textAlign: TextAlign.center, + style: TextStyle(fontSize: 16, color: leftButtonStyle.textColor, fontWeight: leftButtonStyle.fontWeight) ), ), - child: Text( - leftActionButtonText, - textAlign: TextAlign.center, - style: Theme.of(context).textTheme.bodyMedium!.copyWith( - fontSize: 15, - fontWeight: FontWeight.w600, - color: leftActionButtonTextColor ?? - Theme.of(context).colorScheme.errorContainer, - decoration: TextDecoration.none, - ), - )), - ), - const VerticalSectionDivider(), - Expanded( - child: TextButton( + )), + ), + Expanded( + child: GestureDetector( key: rightActionButtonKey, - onPressed: actionRight, - style: TextButton.styleFrom( - backgroundColor: rightActionButtonColor ?? Theme.of(context).colorScheme.surface, - shape: const RoundedRectangleBorder( - borderRadius: BorderRadius.all(Radius.zero), + onTap: actionRight, + child: Container( + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(999999), + color: rightButtonStyle.backgroundColor ), - ), - child: Text( - rightActionButtonText, - textAlign: TextAlign.center, - style: Theme.of(context).textTheme.bodyMedium!.copyWith( - fontSize: 15, - fontWeight: FontWeight.w600, - color: rightActionButtonTextColor ?? Theme.of(context).colorScheme.onSurface, - decoration: TextDecoration.none, - ), - ), - ), - ), - ], - ), + child: Padding( + padding: EdgeInsets.symmetric(vertical: 16, horizontal: 8), + child: AutoSizeText( + maxLines: 1, + rightActionButtonText, + textAlign: TextAlign.center, + style: TextStyle(fontSize: 16, color: rightButtonStyle.textColor, fontWeight: rightButtonStyle.fontWeight) + ), + ), + )), + ), + ], ); } @@ -178,53 +204,53 @@ class BaseAlertDialog extends StatelessWidget { filter: ImageFilter.blur(sigmaX: 3.0, sigmaY: 3.0), child: Container( decoration: - BoxDecoration(color: Theme.of(context).colorScheme.surface.withOpacity(0.8)), + BoxDecoration(color: Theme.of(context).colorScheme.onSurface.withAlpha(25)), child: Center( - child: GestureDetector( - onTap: () => null, - child: Container( - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(30), - color: Theme.of(context).colorScheme.surface, - ), - width: 300, - child: Stack( - clipBehavior: Clip.none, - children: [ - if (headerImageUrl != null) headerImage(context, headerImageUrl!), - Column( - mainAxisSize: MainAxisSize.min, - children: [ - if (headerImageUrl != null) const SizedBox(height: 50), + child: Padding( + padding: const EdgeInsets.all(16.0), + child: GestureDetector( + onTap: () => null, + child: Container( + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(24), + color: Theme.of(context).colorScheme.surface, + ), + child: Padding( + padding: const EdgeInsets.all(24.0), + child: Stack( + clipBehavior: Clip.none, + children: [ + if (headerImageUrl != null) headerImage(context, headerImageUrl!), Column( - crossAxisAlignment: CrossAxisAlignment.center, + mainAxisSize: MainAxisSize.min, children: [ - if (headerText?.isNotEmpty ?? false) headerTitle(context), - titleText != null - ? Padding( - padding: EdgeInsets.fromLTRB(24, 20, 24, 0), - child: title(context), - ) - : SizedBox(height: 16), - isDividerExists - ? Padding( - padding: EdgeInsets.only(top: 16, bottom: 8), - child: const HorizontalSectionDivider(), - ) - : Offstage(), - Padding( - padding: EdgeInsets.fromLTRB(24, 8, 24, 32), - child: content(context), - ) + if (headerImageUrl != null) const SizedBox(height: 50), + Column( + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + if (headerText?.isNotEmpty ?? false) headerTitle(context), + titleText != null + ? title(context) + : SizedBox(height: 16), + isDividerExists + ? Padding( + padding: EdgeInsets.only(top: 16, bottom: 8), + child: const HorizontalSectionDivider(), + ) + : Offstage(), + Padding( + padding: EdgeInsets.symmetric(vertical: 25), + child: content(context), + ) + ], + ), + // if (isBottomDividerExists) const HorizontalSectionDivider(), + actionButtons(context) ], ), - if (isBottomDividerExists) const HorizontalSectionDivider(), - ClipRRect( - borderRadius: BorderRadius.all(Radius.circular(30)), - child: actionButtons(context)) ], ), - ], + ), ), ), ),