From 615af20f14973516f416d2eb0a296b15f90a47f4 Mon Sep 17 00:00:00 2001 From: Robert Malikowski Date: Sun, 16 Nov 2025 19:52:25 +0100 Subject: [PATCH 1/6] add ui for evm switcher on eth --- assets/images/evm_switcher.svg | 4 + assets/images/evm_switcher_arrow_left.svg | 3 + assets/images/evm_switcher_arrow_right.svg | 3 + assets/images/evm_switcher_checkmark.svg | 10 + assets/images/evm_switcher_icons/arbitrum.svg | 20 ++ assets/images/evm_switcher_icons/base.svg | 10 + assets/images/evm_switcher_icons/ethereum.svg | 3 + assets/images/evm_switcher_icons/gnosis.svg | 18 ++ assets/images/evm_switcher_icons/polygon.svg | 3 + .../pages/balance/crypto_balance_widget.dart | 167 ++++++++++---- lib/src/widgets/evm_switcher.dart | 214 ++++++++++++++++++ lib/src/widgets/evm_switcher_row.dart | 76 +++++++ .../dashboard/balance_view_model.dart | 3 + 13 files changed, 486 insertions(+), 48 deletions(-) create mode 100644 assets/images/evm_switcher.svg create mode 100644 assets/images/evm_switcher_arrow_left.svg create mode 100644 assets/images/evm_switcher_arrow_right.svg create mode 100644 assets/images/evm_switcher_checkmark.svg create mode 100644 assets/images/evm_switcher_icons/arbitrum.svg create mode 100644 assets/images/evm_switcher_icons/base.svg create mode 100644 assets/images/evm_switcher_icons/ethereum.svg create mode 100644 assets/images/evm_switcher_icons/gnosis.svg create mode 100644 assets/images/evm_switcher_icons/polygon.svg create mode 100644 lib/src/widgets/evm_switcher.dart create mode 100644 lib/src/widgets/evm_switcher_row.dart diff --git a/assets/images/evm_switcher.svg b/assets/images/evm_switcher.svg new file mode 100644 index 0000000000..18ed0cf03c --- /dev/null +++ b/assets/images/evm_switcher.svg @@ -0,0 +1,4 @@ + + + + diff --git a/assets/images/evm_switcher_arrow_left.svg b/assets/images/evm_switcher_arrow_left.svg new file mode 100644 index 0000000000..dd12ab3ca0 --- /dev/null +++ b/assets/images/evm_switcher_arrow_left.svg @@ -0,0 +1,3 @@ + + + diff --git a/assets/images/evm_switcher_arrow_right.svg b/assets/images/evm_switcher_arrow_right.svg new file mode 100644 index 0000000000..e73ba2a6ba --- /dev/null +++ b/assets/images/evm_switcher_arrow_right.svg @@ -0,0 +1,3 @@ + + + diff --git a/assets/images/evm_switcher_checkmark.svg b/assets/images/evm_switcher_checkmark.svg new file mode 100644 index 0000000000..a634d871af --- /dev/null +++ b/assets/images/evm_switcher_checkmark.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/assets/images/evm_switcher_icons/arbitrum.svg b/assets/images/evm_switcher_icons/arbitrum.svg new file mode 100644 index 0000000000..c0720257f9 --- /dev/null +++ b/assets/images/evm_switcher_icons/arbitrum.svg @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/assets/images/evm_switcher_icons/base.svg b/assets/images/evm_switcher_icons/base.svg new file mode 100644 index 0000000000..6d51c92f9f --- /dev/null +++ b/assets/images/evm_switcher_icons/base.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/assets/images/evm_switcher_icons/ethereum.svg b/assets/images/evm_switcher_icons/ethereum.svg new file mode 100644 index 0000000000..b011052ded --- /dev/null +++ b/assets/images/evm_switcher_icons/ethereum.svg @@ -0,0 +1,3 @@ + + + diff --git a/assets/images/evm_switcher_icons/gnosis.svg b/assets/images/evm_switcher_icons/gnosis.svg new file mode 100644 index 0000000000..d9347d66a2 --- /dev/null +++ b/assets/images/evm_switcher_icons/gnosis.svg @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + + diff --git a/assets/images/evm_switcher_icons/polygon.svg b/assets/images/evm_switcher_icons/polygon.svg new file mode 100644 index 0000000000..65335cf6a8 --- /dev/null +++ b/assets/images/evm_switcher_icons/polygon.svg @@ -0,0 +1,3 @@ + + + diff --git a/lib/src/screens/dashboard/pages/balance/crypto_balance_widget.dart b/lib/src/screens/dashboard/pages/balance/crypto_balance_widget.dart index ac9a7966e1..68bfb12381 100644 --- a/lib/src/screens/dashboard/pages/balance/crypto_balance_widget.dart +++ b/lib/src/screens/dashboard/pages/balance/crypto_balance_widget.dart @@ -7,6 +7,7 @@ import 'package:cake_wallet/src/screens/dashboard/widgets/info_card.dart'; import 'package:cake_wallet/src/widgets/alert_with_one_action.dart'; import 'package:cake_wallet/src/widgets/alert_with_two_actions.dart'; import 'package:cake_wallet/src/widgets/dashboard_card_widget.dart'; +import 'package:cake_wallet/src/widgets/evm_switcher.dart'; import 'package:cake_wallet/src/widgets/introducing_card.dart'; import 'package:cake_wallet/src/widgets/standard_switch.dart'; import 'package:cake_wallet/themes/core/theme_extension.dart'; @@ -85,7 +86,8 @@ class CryptoBalanceWidget extends StatelessWidget { Observer( builder: (_) => dashboardViewModel.balanceViewModel.hasAccounts ? HomeScreenAccountWidget( - walletName: dashboardViewModel.name, accountName: dashboardViewModel.subname) + walletName: dashboardViewModel.name, + accountName: dashboardViewModel.subname) : Column( children: [ SizedBox(height: 16), @@ -97,9 +99,14 @@ class CryptoBalanceWidget extends StatelessWidget { children: [ Text( dashboardViewModel.balanceViewModel.asset, - style: Theme.of(context).textTheme.headlineSmall?.copyWith( + style: Theme.of(context) + .textTheme + .headlineSmall + ?.copyWith( fontWeight: FontWeight.w500, - color: Theme.of(context).colorScheme.onSurface, + color: Theme.of(context) + .colorScheme + .onSurface, height: 1, ), maxLines: 1, @@ -110,25 +117,52 @@ class CryptoBalanceWidget extends StatelessWidget { child: SvgPicture.asset( hardwareWalletIcon!, width: 24, - color: Theme.of(context).colorScheme.onSurface, + color: Theme.of(context) + .colorScheme + .onSurface, ), ), - if (dashboardViewModel - .balanceViewModel.isHomeScreenSettingsEnabled) + if (dashboardViewModel.balanceViewModel + .isHomeScreenSettingsEnabled) TextButton( style: TextButton.styleFrom( minimumSize: Size(50, 30), - tapTargetSize: MaterialTapTargetSize.shrinkWrap, + tapTargetSize: + MaterialTapTargetSize.shrinkWrap, alignment: Alignment.centerLeft), onPressed: () => Navigator.pushNamed( context, Routes.homeSettings, - arguments: dashboardViewModel.balanceViewModel, + arguments: + dashboardViewModel.balanceViewModel, ), child: Container( child: SvgPicture.asset( 'assets/images/home_screen_setting_icon.svg', - color: Theme.of(context).colorScheme.onSurfaceVariant, + color: Theme.of(context) + .colorScheme + .onSurfaceVariant, + height: 30), + ), + ), + if (dashboardViewModel + .balanceViewModel.isEVMCompatible) + TextButton( + style: TextButton.styleFrom( + minimumSize: Size(50, 30), + tapTargetSize: + MaterialTapTargetSize.shrinkWrap, + alignment: Alignment.centerLeft), + onPressed: () => showDialog( + context: context, + builder: (context) => EvmSwitcher(), + ), + child: Container( + child: SvgPicture.asset( + 'assets/images/evm_switcher.svg', + color: Theme.of(context) + .colorScheme + .onSurfaceVariant, height: 30), ), ), @@ -141,12 +175,14 @@ class CryptoBalanceWidget extends StatelessWidget { )), Observer( builder: (_) { - if (dashboardViewModel.balanceViewModel.isShowCard && FeatureFlag.isCakePayEnabled) { + if (dashboardViewModel.balanceViewModel.isShowCard && + FeatureFlag.isCakePayEnabled) { return IntroducingCard( title: S.of(context).introducing_cake_pay, subTitle: S.of(context).cake_pay_learn_more, borderColor: Theme.of(context).colorScheme.outline, - closeCard: dashboardViewModel.balanceViewModel.disableIntroCakePayCard); + closeCard: dashboardViewModel + .balanceViewModel.disableIntroCakePayCard); } return Container(); }, @@ -172,11 +208,14 @@ class CryptoBalanceWidget extends StatelessWidget { return ListView.separated( physics: NeverScrollableScrollPhysics(), shrinkWrap: true, - separatorBuilder: (_, __) => Container(padding: EdgeInsets.only(bottom: 10)), - itemCount: dashboardViewModel.balanceViewModel.formattedBalances.length, + separatorBuilder: (_, __) => + Container(padding: EdgeInsets.only(bottom: 10)), + itemCount: dashboardViewModel + .balanceViewModel.formattedBalances.length, itemBuilder: (__, index) { - final balance = - dashboardViewModel.balanceViewModel.formattedBalances.elementAt(index); + final balance = dashboardViewModel + .balanceViewModel.formattedBalances + .elementAt(index); return Observer(builder: (_) { return BalanceRowWidget( dashboardViewModel: dashboardViewModel, @@ -191,16 +230,18 @@ class CryptoBalanceWidget extends StatelessWidget { frozenBalance: balance.frozenBalance, frozenFiatBalance: balance.fiatFrozenBalance, currency: balance.asset, - hasAdditionalBalance: - dashboardViewModel.balanceViewModel.hasAdditionalBalance(balance.asset), - hasSecondAdditionalBalance: - dashboardViewModel.balanceViewModel.hasSecondAdditionalBalance, - hasSecondAvailableBalance: - dashboardViewModel.balanceViewModel.hasSecondAvailableBalance, + hasAdditionalBalance: dashboardViewModel.balanceViewModel + .hasAdditionalBalance(balance.asset), + hasSecondAdditionalBalance: dashboardViewModel + .balanceViewModel.hasSecondAdditionalBalance, + hasSecondAvailableBalance: dashboardViewModel + .balanceViewModel.hasSecondAvailableBalance, secondAdditionalBalance: balance.secondAdditionalBalance, - secondAdditionalFiatBalance: balance.fiatSecondAdditionalBalance, + secondAdditionalFiatBalance: + balance.fiatSecondAdditionalBalance, secondAvailableBalance: balance.secondAvailableBalance, - secondAvailableFiatBalance: balance.fiatSecondAvailableBalance, + secondAvailableFiatBalance: + balance.fiatSecondAvailableBalance, secondAdditionalBalanceLabel: '${dashboardViewModel.balanceViewModel.secondAdditionalBalanceLabel}', secondAvailableBalanceLabel: @@ -215,7 +256,8 @@ class CryptoBalanceWidget extends StatelessWidget { Observer(builder: (context) { return Column( children: [ - if (dashboardViewModel.isMoneroWalletBrokenReasons.isNotEmpty) ...[ + if (dashboardViewModel + .isMoneroWalletBrokenReasons.isNotEmpty) ...[ SizedBox(height: 10), Padding( padding: const EdgeInsets.fromLTRB(16, 0, 16, 8), @@ -223,7 +265,8 @@ class CryptoBalanceWidget extends StatelessWidget { customBorder: 30, title: "This wallet has encountered an issue", subTitle: "Here are the things that you should note:\n - " + - dashboardViewModel.isMoneroWalletBrokenReasons.join("\n - ") + + dashboardViewModel.isMoneroWalletBrokenReasons + .join("\n - ") + "\n\nPlease restart your wallet and if it doesn't help contact our support.", )) ], @@ -255,18 +298,26 @@ class CryptoBalanceWidget extends StatelessWidget { children: [ Text( S.of(context).what_is_silent_payments, - style: Theme.of(context).textTheme.bodySmall?.copyWith( - color: Theme.of(context).colorScheme.onSurfaceVariant, + style: Theme.of(context) + .textTheme + .bodySmall + ?.copyWith( + color: Theme.of(context) + .colorScheme + .onSurfaceVariant, height: 1, ), softWrap: true, ), Padding( - padding: const EdgeInsets.symmetric(horizontal: 4), + padding: const EdgeInsets.symmetric( + horizontal: 4), child: Icon( Icons.help_outline, size: 16, - color: Theme.of(context).colorScheme.onSurfaceVariant, + color: Theme.of(context) + .colorScheme + .onSurfaceVariant, ), ) ], @@ -274,8 +325,10 @@ class CryptoBalanceWidget extends StatelessWidget { ), Observer( builder: (_) => StandardSwitch( - value: dashboardViewModel.silentPaymentsScanningActive, - onTapped: () => _toggleSilentPaymentsScanning(context), + value: dashboardViewModel + .silentPaymentsScanningActive, + onTapped: () => + _toggleSilentPaymentsScanning(context), ), ) ], @@ -304,15 +357,19 @@ class CryptoBalanceWidget extends StatelessWidget { hintWidget: GestureDetector( behavior: HitTestBehavior.opaque, onTap: () => launchUrl( - Uri.parse("https://docs.cakewallet.com/cryptos/litecoin/#mweb"), + Uri.parse( + "https://docs.cakewallet.com/cryptos/litecoin/#mweb"), mode: LaunchMode.externalApplication, ), child: Text( S.of(context).learn_more, - style: Theme.of(context).textTheme.bodySmall?.copyWith( - color: Theme.of(context).colorScheme.onSurfaceVariant, - height: 1, - ), + style: + Theme.of(context).textTheme.bodySmall?.copyWith( + color: Theme.of(context) + .colorScheme + .onSurfaceVariant, + height: 1, + ), softWrap: true, ), ), @@ -329,9 +386,10 @@ class CryptoBalanceWidget extends StatelessWidget { image: 'assets/images/crypto/decred.webp', leftButtonTitle: S.of(context).litecoin_mweb_dismiss, rightButtonTitle: S.of(context).learn_more, - leftButtonAction: () => dashboardViewModel.dismissDecredInfoCard(), - rightButtonAction: () => launchUrl( - Uri.parse("https://docs.cakewallet.com/cryptos/decred/#spv-sync")), + leftButtonAction: () => + dashboardViewModel.dismissDecredInfoCard(), + rightButtonAction: () => launchUrl(Uri.parse( + "https://docs.cakewallet.com/cryptos/decred/#spv-sync")), ), ), ], @@ -345,25 +403,34 @@ class CryptoBalanceWidget extends StatelessWidget { hintWidget: GestureDetector( behavior: HitTestBehavior.opaque, onTap: () => launchUrl( - Uri.parse("https://docs.cakewallet.com/cryptos/bitcoin/#payjoin"), + Uri.parse( + "https://docs.cakewallet.com/cryptos/bitcoin/#payjoin"), mode: LaunchMode.externalApplication, ), child: Row( children: [ Text( S.of(context).what_is_payjoin, - style: Theme.of(context).textTheme.bodySmall?.copyWith( - color: Theme.of(context).colorScheme.onSurfaceVariant, + style: Theme.of(context) + .textTheme + .bodySmall + ?.copyWith( + color: Theme.of(context) + .colorScheme + .onSurfaceVariant, height: 1, ), softWrap: true, ), Padding( - padding: const EdgeInsets.symmetric(horizontal: 4), + padding: + const EdgeInsets.symmetric(horizontal: 4), child: Icon( Icons.help_outline, size: 16, - color: Theme.of(context).colorScheme.onSurfaceVariant, + color: Theme.of(context) + .colorScheme + .onSurfaceVariant, ), ) ], @@ -372,7 +439,8 @@ class CryptoBalanceWidget extends StatelessWidget { image: 'assets/images/payjoin.png', leftButtonTitle: S.of(context).litecoin_mweb_dismiss, rightButtonTitle: S.of(context).enable, - leftButtonAction: () => dashboardViewModel.dismissPayjoin(), + leftButtonAction: () => + dashboardViewModel.dismissPayjoin(), rightButtonAction: () => _enablePayjoin(context), ), ), @@ -387,13 +455,15 @@ class CryptoBalanceWidget extends StatelessWidget { } Future _toggleSilentPaymentsScanning(BuildContext context) async { - final isSilentPaymentsScanningActive = dashboardViewModel.silentPaymentsScanningActive; + final isSilentPaymentsScanningActive = + dashboardViewModel.silentPaymentsScanningActive; final newValue = !isSilentPaymentsScanningActive; dashboardViewModel.silentPaymentsScanningActive = newValue; final needsToSwitch = !isSilentPaymentsScanningActive && - await bitcoin!.getNodeIsElectrsSPEnabled(dashboardViewModel.wallet) == false; + await bitcoin!.getNodeIsElectrsSPEnabled(dashboardViewModel.wallet) == + false; if (needsToSwitch) { return showPopUp( @@ -408,7 +478,8 @@ class CryptoBalanceWidget extends StatelessWidget { Navigator.of(context).pop(); }, actionLeftButton: () { - dashboardViewModel.silentPaymentsScanningActive = isSilentPaymentsScanningActive; + dashboardViewModel.silentPaymentsScanningActive = + isSilentPaymentsScanningActive; Navigator.of(context).pop(); }, )); diff --git a/lib/src/widgets/evm_switcher.dart b/lib/src/widgets/evm_switcher.dart new file mode 100644 index 0000000000..94d74a16af --- /dev/null +++ b/lib/src/widgets/evm_switcher.dart @@ -0,0 +1,214 @@ +import 'package:flutter/material.dart'; +import 'package:flutter/rendering.dart'; +import 'package:flutter_svg/flutter_svg.dart'; + +import 'evm_switcher_row.dart'; + +class EvmSwitcherDataItem { + final String name; + final String svgPath; + + const EvmSwitcherDataItem({ + required this.name, + required this.svgPath, + }); + + static const ethereum = EvmSwitcherDataItem( + name: 'Ethereum', + svgPath: 'assets/images/evm_switcher_icons/ethereum.svg'); + + static const polygon = EvmSwitcherDataItem( + name: 'Polygon', svgPath: 'assets/images/evm_switcher_icons/polygon.svg'); + + static const arbitrum = EvmSwitcherDataItem( + name: 'Arbitrum', + svgPath: 'assets/images/evm_switcher_icons/arbitrum.svg'); + + static const base = EvmSwitcherDataItem( + name: 'Base', svgPath: 'assets/images/evm_switcher_icons/base.svg'); + + static const gnosis = EvmSwitcherDataItem( + name: 'Gnosis', svgPath: 'assets/images/evm_switcher_icons/gnosis.svg'); + + static const items = [ + ethereum, + polygon, + arbitrum, + base, + gnosis, + ]; +} + +class EvmSwitcher extends StatefulWidget { + const EvmSwitcher({super.key}); + + static const editModeAnimDuration = Duration(milliseconds: 150); + + @override + State createState() => _EvmSwitcherState(); +} + +class _EvmSwitcherState extends State { + bool _editMode = false; + int _selectedIndex = 0; + + @override + Widget build(BuildContext context) { + return Center( + child: Column( + spacing: 25.0, +mainAxisAlignment: MainAxisAlignment.center, + children: [ + Text(_editMode ? "Customize options":"Select Network", style: TextStyle(fontSize: 16,fontWeight: FontWeight.w500),), + ClipRRect( + borderRadius: BorderRadius.circular(20), + child: Container( + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(20), + color: Theme.of(context).colorScheme.surfaceContainer, + ), + width: 400, + // height: 300, + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + EvmSwitcherAdditionalOption( + title: "Back", + svgPath: "assets/images/evm_switcher_arrow_left.svg", + animDuration: EvmSwitcher.editModeAnimDuration, + topSeparator: false, + bottomSeparator: true, + visible: _editMode, + onTap: () { + setState(() { + _editMode = false; + }); + },iconOnRight: false), + ListView.separated( + shrinkWrap: true, + physics: const NeverScrollableScrollPhysics(), + itemBuilder: (context, index) { + return EvmSwitcherRow( + key: ValueKey(EvmSwitcherDataItem.items[index].name), + data: EvmSwitcherDataItem.items[index], + editMode: _editMode, + selected: index == _selectedIndex, + onTap: () { + setState(() { + _selectedIndex = index; + }); + }, + animDuration: EvmSwitcher.editModeAnimDuration, + ); + }, + separatorBuilder: (context, index) { + if (!(index == _selectedIndex || + index == _selectedIndex - 1) || + _editMode) + return Padding( + padding: const EdgeInsets.symmetric(horizontal: 18), + child: Container( + height: 1, + width: double.infinity, + color: Theme.of(context) + .colorScheme + .surfaceContainerHigh, + )); + else + return Container(height: 1); + }, + itemCount: EvmSwitcherDataItem.items.length), + EvmSwitcherAdditionalOption( + title: "Customize options", + svgPath: "assets/images/evm_switcher_arrow_right.svg", + animDuration: EvmSwitcher.editModeAnimDuration, + topSeparator: true, + bottomSeparator: false, + visible: !_editMode, + onTap: () { + setState(() { + _editMode = true; + }); + }, + iconOnRight: true + ) + ], + )), + ), + ], + ), + ); + } +} + +class EvmSwitcherAdditionalOption extends StatelessWidget { + const EvmSwitcherAdditionalOption( + {super.key, + required this.title, + required this.svgPath, + required this.animDuration, + required this.topSeparator, + required this.bottomSeparator, + required this.visible, + required this.onTap, required this.iconOnRight}); + + final String title; + final String svgPath; + final Duration animDuration; + final bool topSeparator; + final bool bottomSeparator; + final bool visible; + final VoidCallback onTap; + final bool iconOnRight; + + @override + Widget build(BuildContext context) { + return AnimatedSize( + curve: Curves.easeOutCubic, + duration: animDuration, + child: Container( + height: visible ? null : 0, + child: GestureDetector( + onTap: onTap, + child: Column( + mainAxisSize: MainAxisSize.max, + children: [ + if (topSeparator) + Padding( + padding: const EdgeInsets.symmetric(horizontal: 18), + child: Container( + height: 1, + width: double.infinity, + color: Theme.of(context).colorScheme.surfaceContainerHigh, + )), + Padding( + padding: const EdgeInsets.all(18), + child: Row( + mainAxisSize: MainAxisSize.max, + spacing: 8.0, + children: [ + if(!iconOnRight) SvgPicture.asset(svgPath, width: 16, height: 16), + Text( + title, + style: TextStyle( + color: Theme.of(context).colorScheme.primary), + ), + if(iconOnRight) SvgPicture.asset(svgPath, width: 16, height: 16), + ], + ), + ), + if (bottomSeparator) + Padding( + padding: const EdgeInsets.symmetric(horizontal: 18), + child: Container( + height: 1, + width: double.infinity, + color: Theme.of(context).colorScheme.surfaceContainerHigh, + )), + ], + ), + ), + ), + ); + } +} diff --git a/lib/src/widgets/evm_switcher_row.dart b/lib/src/widgets/evm_switcher_row.dart new file mode 100644 index 0000000000..896aa309e8 --- /dev/null +++ b/lib/src/widgets/evm_switcher_row.dart @@ -0,0 +1,76 @@ +import 'package:cake_wallet/src/widgets/evm_switcher.dart'; +import 'package:cake_wallet/src/widgets/standard_switch.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_svg/flutter_svg.dart'; + +class EvmSwitcherRow extends StatelessWidget { + const EvmSwitcherRow({ + super.key, + required this.editMode, + required this.selected, + required this.data, + required this.onTap, + required this.animDuration, + }); + + final bool editMode; + final bool selected; + final EvmSwitcherDataItem data; + final VoidCallback onTap; + final Duration animDuration; + + @override + Widget build(BuildContext context) { + final Color resolvedForegroundColor = editMode || selected + ? Theme.of(context).colorScheme.onSurface + : Theme.of(context).colorScheme.primary; + + final Color resolvedBackgroundColor = !editMode && selected + ? Theme.of(context).colorScheme.surfaceContainerHighest + : Theme.of(context).colorScheme.surfaceContainerHighest.withAlpha(0); + + return GestureDetector( + onTap: onTap, + child: AnimatedContainer( + duration: animDuration, + color: resolvedBackgroundColor, + child: Padding( + padding: const EdgeInsets.all(18.0), + child: Row( + mainAxisSize: MainAxisSize.max, + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Row( + spacing: 8.0, + children: [ + SvgPicture.asset( + data.svgPath, + width: 16, + height: 16, + colorFilter: ColorFilter.mode( + resolvedForegroundColor, BlendMode.srcIn), + ), + Text(data.name, + style: TextStyle( + color: resolvedForegroundColor, fontSize: 14)), + if (selected) + AnimatedOpacity( + opacity: editMode ? 0 : 1, + duration: animDuration, + child: SvgPicture.asset( + "assets/images/evm_switcher_checkmark.svg", + width: 18, + height: 18)), + ], + ), + AnimatedOpacity( + opacity: editMode ? 1 : 0, + duration: animDuration, + child: StandardSwitch(value: false, onTapped: () {})) + ], + ), + ), + ), + ); + } +} diff --git a/lib/view_model/dashboard/balance_view_model.dart b/lib/view_model/dashboard/balance_view_model.dart index 552d318e4a..2c2f2c215e 100644 --- a/lib/view_model/dashboard/balance_view_model.dart +++ b/lib/view_model/dashboard/balance_view_model.dart @@ -114,6 +114,9 @@ abstract class BalanceViewModelBase with Store { wallet.type == WalletType.tron || wallet.type == WalletType.zano; + @computed + bool get isEVMCompatible => isEVMCompatibleChain(wallet.type); + @computed bool get hasAccounts => wallet.type == WalletType.monero || wallet.type == WalletType.wownero; From 5efe18b80e7fcfab2f300d9128172b819f3cbae0 Mon Sep 17 00:00:00 2001 From: Robert Malikowski Date: Sun, 16 Nov 2025 19:58:45 +0100 Subject: [PATCH 2/6] add inputs for evm network list edit switches --- lib/src/widgets/evm_switcher.dart | 2 ++ lib/src/widgets/evm_switcher_row.dart | 6 +++++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/lib/src/widgets/evm_switcher.dart b/lib/src/widgets/evm_switcher.dart index 94d74a16af..6bf8327819 100644 --- a/lib/src/widgets/evm_switcher.dart +++ b/lib/src/widgets/evm_switcher.dart @@ -98,6 +98,8 @@ mainAxisAlignment: MainAxisAlignment.center, _selectedIndex = index; }); }, + onEditSwitchTapped: (){}, + editSwitchValue: true, animDuration: EvmSwitcher.editModeAnimDuration, ); }, diff --git a/lib/src/widgets/evm_switcher_row.dart b/lib/src/widgets/evm_switcher_row.dart index 896aa309e8..9fa37f4f33 100644 --- a/lib/src/widgets/evm_switcher_row.dart +++ b/lib/src/widgets/evm_switcher_row.dart @@ -11,6 +11,8 @@ class EvmSwitcherRow extends StatelessWidget { required this.data, required this.onTap, required this.animDuration, + required this.onEditSwitchTapped, + required this.editSwitchValue, }); final bool editMode; @@ -18,6 +20,8 @@ class EvmSwitcherRow extends StatelessWidget { final EvmSwitcherDataItem data; final VoidCallback onTap; final Duration animDuration; + final VoidCallback onEditSwitchTapped; + final bool editSwitchValue; @override Widget build(BuildContext context) { @@ -66,7 +70,7 @@ class EvmSwitcherRow extends StatelessWidget { AnimatedOpacity( opacity: editMode ? 1 : 0, duration: animDuration, - child: StandardSwitch(value: false, onTapped: () {})) + child: StandardSwitch(value: editSwitchValue, onTapped: onEditSwitchTapped)) ], ), ), From a0ec63bbfc63bbe96251550d82fe7d64fc7cad66 Mon Sep 17 00:00:00 2001 From: Robert Malikowski Date: Mon, 17 Nov 2025 18:13:33 +0100 Subject: [PATCH 3/6] add evm switcher icons to pubspec_base --- pubspec_base.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/pubspec_base.yaml b/pubspec_base.yaml index 274a97201e..395f1e5613 100644 --- a/pubspec_base.yaml +++ b/pubspec_base.yaml @@ -217,6 +217,7 @@ flutter: assets: - assets/images/ + - assets/images/evm_switcher_icons/ - assets/images/flags/ - assets/images/hardware_wallet/ - assets/images/crypto/ From 1a83cffd953d1d51a2f4c44a183c6c36c20a3578 Mon Sep 17 00:00:00 2001 From: Robert Malikowski Date: Mon, 17 Nov 2025 18:17:47 +0100 Subject: [PATCH 4/6] change evm switcher to sliding animation --- lib/src/widgets/evm_switcher.dart | 288 ++++++++++++++++---------- lib/src/widgets/evm_switcher_row.dart | 20 +- 2 files changed, 180 insertions(+), 128 deletions(-) diff --git a/lib/src/widgets/evm_switcher.dart b/lib/src/widgets/evm_switcher.dart index 6bf8327819..90e99ace93 100644 --- a/lib/src/widgets/evm_switcher.dart +++ b/lib/src/widgets/evm_switcher.dart @@ -51,6 +51,16 @@ class EvmSwitcher extends StatefulWidget { class _EvmSwitcherState extends State { bool _editMode = false; int _selectedIndex = 0; + var optionsEnabled = List.filled(EvmSwitcherDataItem.items.length, true); + + bool shouldBuildSeparator(int index) { + final nextEnabled = optionsEnabled.indexWhere( + (e) => e, + index + 1, + ); + + return index != _selectedIndex && optionsEnabled[index] && nextEnabled != _selectedIndex && nextEnabled != -1; + } @override Widget build(BuildContext context) { @@ -63,79 +73,133 @@ mainAxisAlignment: MainAxisAlignment.center, ClipRRect( borderRadius: BorderRadius.circular(20), child: Container( - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(20), - color: Theme.of(context).colorScheme.surfaceContainer, - ), - width: 400, - // height: 300, - child: Column( - mainAxisSize: MainAxisSize.min, - children: [ - EvmSwitcherAdditionalOption( - title: "Back", - svgPath: "assets/images/evm_switcher_arrow_left.svg", - animDuration: EvmSwitcher.editModeAnimDuration, - topSeparator: false, - bottomSeparator: true, - visible: _editMode, - onTap: () { - setState(() { - _editMode = false; - }); - },iconOnRight: false), - ListView.separated( - shrinkWrap: true, - physics: const NeverScrollableScrollPhysics(), - itemBuilder: (context, index) { - return EvmSwitcherRow( - key: ValueKey(EvmSwitcherDataItem.items[index].name), - data: EvmSwitcherDataItem.items[index], - editMode: _editMode, - selected: index == _selectedIndex, - onTap: () { - setState(() { - _selectedIndex = index; - }); - }, - onEditSwitchTapped: (){}, - editSwitchValue: true, - animDuration: EvmSwitcher.editModeAnimDuration, - ); - }, - separatorBuilder: (context, index) { - if (!(index == _selectedIndex || - index == _selectedIndex - 1) || - _editMode) - return Padding( - padding: const EdgeInsets.symmetric(horizontal: 18), - child: Container( - height: 1, - width: double.infinity, - color: Theme.of(context) - .colorScheme - .surfaceContainerHigh, - )); - else - return Container(height: 1); - }, - itemCount: EvmSwitcherDataItem.items.length), - EvmSwitcherAdditionalOption( - title: "Customize options", - svgPath: "assets/images/evm_switcher_arrow_right.svg", - animDuration: EvmSwitcher.editModeAnimDuration, - topSeparator: true, - bottomSeparator: false, - visible: !_editMode, - onTap: () { - setState(() { - _editMode = true; - }); - }, - iconOnRight: true - ) - ], - )), + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(20), + color: Theme.of(context).colorScheme.surfaceContainer, + ), + child: AnimatedContainer( + duration: EvmSwitcher.editModeAnimDuration, + width: 400, + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + AnimatedSize(curve: Curves.easeOutCubic, + duration: EvmSwitcher.editModeAnimDuration, + child: Container( + width:_editMode ? 0 : 400, + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + ListView.separated( + shrinkWrap: true, + physics: const NeverScrollableScrollPhysics(), + itemBuilder: (context, index) { + if(optionsEnabled[index]) + return EvmSwitcherRow( + key: ValueKey(EvmSwitcherDataItem.items[index].name), + data: EvmSwitcherDataItem.items[index], + editMode: false, + selected: index == _selectedIndex, + onTap: () { + setState(() { + _selectedIndex = index; + }); + }, + editSwitchValue: true, + animDuration: EvmSwitcher.editModeAnimDuration, + ); else return Container(); + }, + separatorBuilder: (context, index) { + if (shouldBuildSeparator(index)) + return Padding( + padding: const EdgeInsets.symmetric(horizontal: 18), + child: Container( + height: 1, + width: double.infinity, + color: Theme.of(context) + .colorScheme + .surfaceContainerHigh, + )); + else + return Container(height: 1); + }, + itemCount: EvmSwitcherDataItem.items.length), + EvmSwitcherAdditionalOption( + title: "Customize options", + svgPath: "assets/images/evm_switcher_arrow_right.svg", + animDuration: EvmSwitcher.editModeAnimDuration, + topSeparator: true, + bottomSeparator: false, + visible: true, + onTap: () { + setState(() { + _editMode = true; + }); + }, + iconOnRight: true + ) + ], + ), + ), + ), + AnimatedSize( + curve: Curves.easeOutCubic, + duration: EvmSwitcher.editModeAnimDuration, + child: Container( + width:_editMode ? 400 : 0, + height: _editMode ? null : 0, + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + EvmSwitcherAdditionalOption( + title: "Back", + svgPath: "assets/images/evm_switcher_arrow_left.svg", + animDuration: EvmSwitcher.editModeAnimDuration, + topSeparator: false, + bottomSeparator: true, + visible: true, + onTap: () { + setState(() { + _editMode = false; + }); + },iconOnRight: false), + ListView.separated( + shrinkWrap: true, + physics: const NeverScrollableScrollPhysics(), + itemBuilder: (context, index) { + return EvmSwitcherRow( + key: ValueKey(EvmSwitcherDataItem.items[index].name), + data: EvmSwitcherDataItem.items[index], + editMode: _editMode, + selected: index == _selectedIndex, + onTap: () { + setState(() { + optionsEnabled[index] = !optionsEnabled[index]; + }); + }, + editSwitchValue: optionsEnabled[index], + animDuration: EvmSwitcher.editModeAnimDuration, + ); + }, + separatorBuilder: (context, index) { + return Padding( + padding: const EdgeInsets.symmetric(horizontal: 18), + child: Container( + height: 1, + width: double.infinity, + color: Theme.of(context) + .colorScheme + .surfaceContainerHigh, + )); + }, + itemCount: EvmSwitcherDataItem.items.length), + ], + ), + ), + ), + ], + )), + ), ), ], ), @@ -165,50 +229,46 @@ class EvmSwitcherAdditionalOption extends StatelessWidget { @override Widget build(BuildContext context) { - return AnimatedSize( - curve: Curves.easeOutCubic, - duration: animDuration, + return GestureDetector( + onTap: onTap, + behavior: HitTestBehavior.translucent, child: Container( - height: visible ? null : 0, - child: GestureDetector( - onTap: onTap, - child: Column( - mainAxisSize: MainAxisSize.max, - children: [ - if (topSeparator) - Padding( - padding: const EdgeInsets.symmetric(horizontal: 18), - child: Container( - height: 1, - width: double.infinity, - color: Theme.of(context).colorScheme.surfaceContainerHigh, - )), + child: Column( + mainAxisSize: MainAxisSize.max, + children: [ + if (topSeparator) Padding( - padding: const EdgeInsets.all(18), - child: Row( - mainAxisSize: MainAxisSize.max, - spacing: 8.0, - children: [ - if(!iconOnRight) SvgPicture.asset(svgPath, width: 16, height: 16), - Text( - title, - style: TextStyle( - color: Theme.of(context).colorScheme.primary), - ), - if(iconOnRight) SvgPicture.asset(svgPath, width: 16, height: 16), - ], - ), + padding: const EdgeInsets.symmetric(horizontal: 18), + child: Container( + height: 1, + width: double.infinity, + color: Theme.of(context).colorScheme.surfaceContainerHigh, + )), + Padding( + padding: const EdgeInsets.all(18), + child: Row( + mainAxisSize: MainAxisSize.max, + spacing: 8.0, + children: [ + if(!iconOnRight) SvgPicture.asset(svgPath, width: 16, height: 16), + Text( + title, + style: TextStyle( + color: Theme.of(context).colorScheme.primary), + ), + if(iconOnRight) SvgPicture.asset(svgPath, width: 16, height: 16), + ], ), - if (bottomSeparator) - Padding( - padding: const EdgeInsets.symmetric(horizontal: 18), - child: Container( - height: 1, - width: double.infinity, - color: Theme.of(context).colorScheme.surfaceContainerHigh, - )), - ], - ), + ), + if (bottomSeparator) + Padding( + padding: const EdgeInsets.symmetric(horizontal: 18), + child: Container( + height: 1, + width: double.infinity, + color: Theme.of(context).colorScheme.surfaceContainerHigh, + )), + ], ), ), ); diff --git a/lib/src/widgets/evm_switcher_row.dart b/lib/src/widgets/evm_switcher_row.dart index 9fa37f4f33..9d4de87ac5 100644 --- a/lib/src/widgets/evm_switcher_row.dart +++ b/lib/src/widgets/evm_switcher_row.dart @@ -11,7 +11,6 @@ class EvmSwitcherRow extends StatelessWidget { required this.data, required this.onTap, required this.animDuration, - required this.onEditSwitchTapped, required this.editSwitchValue, }); @@ -20,7 +19,6 @@ class EvmSwitcherRow extends StatelessWidget { final EvmSwitcherDataItem data; final VoidCallback onTap; final Duration animDuration; - final VoidCallback onEditSwitchTapped; final bool editSwitchValue; @override @@ -57,20 +55,14 @@ class EvmSwitcherRow extends StatelessWidget { Text(data.name, style: TextStyle( color: resolvedForegroundColor, fontSize: 14)), - if (selected) - AnimatedOpacity( - opacity: editMode ? 0 : 1, - duration: animDuration, - child: SvgPicture.asset( - "assets/images/evm_switcher_checkmark.svg", - width: 18, - height: 18)), + if (selected && !editMode) + SvgPicture.asset( + "assets/images/evm_switcher_checkmark.svg", + width: 18, + height: 18), ], ), - AnimatedOpacity( - opacity: editMode ? 1 : 0, - duration: animDuration, - child: StandardSwitch(value: editSwitchValue, onTapped: onEditSwitchTapped)) + if(editMode) StandardSwitch(value: editSwitchValue, onTapped: onTap) ], ), ), From e83abee681b5edd5059a6d8acb1dc6485d57d924 Mon Sep 17 00:00:00 2001 From: Robert Malikowski Date: Mon, 17 Nov 2025 18:19:07 +0100 Subject: [PATCH 5/6] formatting fix --- lib/src/widgets/evm_switcher.dart | 117 +++++++++++++++----------- lib/src/widgets/evm_switcher_row.dart | 9 +- 2 files changed, 74 insertions(+), 52 deletions(-) diff --git a/lib/src/widgets/evm_switcher.dart b/lib/src/widgets/evm_switcher.dart index 90e99ace93..a090276913 100644 --- a/lib/src/widgets/evm_switcher.dart +++ b/lib/src/widgets/evm_switcher.dart @@ -55,11 +55,14 @@ class _EvmSwitcherState extends State { bool shouldBuildSeparator(int index) { final nextEnabled = optionsEnabled.indexWhere( - (e) => e, + (e) => e, index + 1, ); - return index != _selectedIndex && optionsEnabled[index] && nextEnabled != _selectedIndex && nextEnabled != -1; + return index != _selectedIndex && + optionsEnabled[index] && + nextEnabled != _selectedIndex && + nextEnabled != -1; } @override @@ -67,9 +70,12 @@ class _EvmSwitcherState extends State { return Center( child: Column( spacing: 25.0, -mainAxisAlignment: MainAxisAlignment.center, + mainAxisAlignment: MainAxisAlignment.center, children: [ - Text(_editMode ? "Customize options":"Select Network", style: TextStyle(fontSize: 16,fontWeight: FontWeight.w500),), + Text( + _editMode ? "Customize options" : "Select Network", + style: TextStyle(fontSize: 16, fontWeight: FontWeight.w500), + ), ClipRRect( borderRadius: BorderRadius.circular(20), child: Container( @@ -78,15 +84,16 @@ mainAxisAlignment: MainAxisAlignment.center, color: Theme.of(context).colorScheme.surfaceContainer, ), child: AnimatedContainer( - duration: EvmSwitcher.editModeAnimDuration, + duration: EvmSwitcher.editModeAnimDuration, width: 400, child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ - AnimatedSize(curve: Curves.easeOutCubic, + AnimatedSize( + curve: Curves.easeOutCubic, duration: EvmSwitcher.editModeAnimDuration, child: Container( - width:_editMode ? 0 : 400, + width: _editMode ? 0 : 400, child: Column( mainAxisSize: MainAxisSize.min, children: [ @@ -94,25 +101,30 @@ mainAxisAlignment: MainAxisAlignment.center, shrinkWrap: true, physics: const NeverScrollableScrollPhysics(), itemBuilder: (context, index) { - if(optionsEnabled[index]) - return EvmSwitcherRow( - key: ValueKey(EvmSwitcherDataItem.items[index].name), - data: EvmSwitcherDataItem.items[index], - editMode: false, - selected: index == _selectedIndex, - onTap: () { - setState(() { - _selectedIndex = index; - }); - }, - editSwitchValue: true, - animDuration: EvmSwitcher.editModeAnimDuration, - ); else return Container(); + if (optionsEnabled[index]) + return EvmSwitcherRow( + key: ValueKey(EvmSwitcherDataItem + .items[index].name), + data: EvmSwitcherDataItem.items[index], + editMode: false, + selected: index == _selectedIndex, + onTap: () { + setState(() { + _selectedIndex = index; + }); + }, + editSwitchValue: true, + animDuration: + EvmSwitcher.editModeAnimDuration, + ); + else + return Container(); }, separatorBuilder: (context, index) { if (shouldBuildSeparator(index)) return Padding( - padding: const EdgeInsets.symmetric(horizontal: 18), + padding: const EdgeInsets.symmetric( + horizontal: 18), child: Container( height: 1, width: double.infinity, @@ -126,8 +138,10 @@ mainAxisAlignment: MainAxisAlignment.center, itemCount: EvmSwitcherDataItem.items.length), EvmSwitcherAdditionalOption( title: "Customize options", - svgPath: "assets/images/evm_switcher_arrow_right.svg", - animDuration: EvmSwitcher.editModeAnimDuration, + svgPath: + "assets/images/evm_switcher_arrow_right.svg", + animDuration: + EvmSwitcher.editModeAnimDuration, topSeparator: true, bottomSeparator: false, visible: true, @@ -136,8 +150,7 @@ mainAxisAlignment: MainAxisAlignment.center, _editMode = true; }); }, - iconOnRight: true - ) + iconOnRight: true) ], ), ), @@ -146,15 +159,17 @@ mainAxisAlignment: MainAxisAlignment.center, curve: Curves.easeOutCubic, duration: EvmSwitcher.editModeAnimDuration, child: Container( - width:_editMode ? 400 : 0, + width: _editMode ? 400 : 0, height: _editMode ? null : 0, child: Column( mainAxisSize: MainAxisSize.min, children: [ EvmSwitcherAdditionalOption( title: "Back", - svgPath: "assets/images/evm_switcher_arrow_left.svg", - animDuration: EvmSwitcher.editModeAnimDuration, + svgPath: + "assets/images/evm_switcher_arrow_left.svg", + animDuration: + EvmSwitcher.editModeAnimDuration, topSeparator: false, bottomSeparator: true, visible: true, @@ -162,35 +177,40 @@ mainAxisAlignment: MainAxisAlignment.center, setState(() { _editMode = false; }); - },iconOnRight: false), + }, + iconOnRight: false), ListView.separated( shrinkWrap: true, physics: const NeverScrollableScrollPhysics(), itemBuilder: (context, index) { return EvmSwitcherRow( - key: ValueKey(EvmSwitcherDataItem.items[index].name), + key: ValueKey(EvmSwitcherDataItem + .items[index].name), data: EvmSwitcherDataItem.items[index], editMode: _editMode, selected: index == _selectedIndex, onTap: () { setState(() { - optionsEnabled[index] = !optionsEnabled[index]; + optionsEnabled[index] = + !optionsEnabled[index]; }); }, editSwitchValue: optionsEnabled[index], - animDuration: EvmSwitcher.editModeAnimDuration, + animDuration: + EvmSwitcher.editModeAnimDuration, ); }, separatorBuilder: (context, index) { - return Padding( - padding: const EdgeInsets.symmetric(horizontal: 18), - child: Container( - height: 1, - width: double.infinity, - color: Theme.of(context) - .colorScheme - .surfaceContainerHigh, - )); + return Padding( + padding: const EdgeInsets.symmetric( + horizontal: 18), + child: Container( + height: 1, + width: double.infinity, + color: Theme.of(context) + .colorScheme + .surfaceContainerHigh, + )); }, itemCount: EvmSwitcherDataItem.items.length), ], @@ -216,7 +236,8 @@ class EvmSwitcherAdditionalOption extends StatelessWidget { required this.topSeparator, required this.bottomSeparator, required this.visible, - required this.onTap, required this.iconOnRight}); + required this.onTap, + required this.iconOnRight}); final String title; final String svgPath; @@ -250,13 +271,15 @@ class EvmSwitcherAdditionalOption extends StatelessWidget { mainAxisSize: MainAxisSize.max, spacing: 8.0, children: [ - if(!iconOnRight) SvgPicture.asset(svgPath, width: 16, height: 16), + if (!iconOnRight) + SvgPicture.asset(svgPath, width: 16, height: 16), Text( title, - style: TextStyle( - color: Theme.of(context).colorScheme.primary), + style: + TextStyle(color: Theme.of(context).colorScheme.primary), ), - if(iconOnRight) SvgPicture.asset(svgPath, width: 16, height: 16), + if (iconOnRight) + SvgPicture.asset(svgPath, width: 16, height: 16), ], ), ), diff --git a/lib/src/widgets/evm_switcher_row.dart b/lib/src/widgets/evm_switcher_row.dart index 9d4de87ac5..d655002174 100644 --- a/lib/src/widgets/evm_switcher_row.dart +++ b/lib/src/widgets/evm_switcher_row.dart @@ -56,13 +56,12 @@ class EvmSwitcherRow extends StatelessWidget { style: TextStyle( color: resolvedForegroundColor, fontSize: 14)), if (selected && !editMode) - SvgPicture.asset( - "assets/images/evm_switcher_checkmark.svg", - width: 18, - height: 18), + SvgPicture.asset("assets/images/evm_switcher_checkmark.svg", + width: 18, height: 18), ], ), - if(editMode) StandardSwitch(value: editSwitchValue, onTapped: onTap) + if (editMode) + StandardSwitch(value: editSwitchValue, onTapped: onTap) ], ), ), From f23f8e8539eb19677e9b37ab32bbc7d5ddd35958 Mon Sep 17 00:00:00 2001 From: Robert Malikowski Date: Mon, 17 Nov 2025 19:19:16 +0100 Subject: [PATCH 6/6] dpi agnostic width --- lib/src/widgets/evm_switcher.dart | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/lib/src/widgets/evm_switcher.dart b/lib/src/widgets/evm_switcher.dart index a090276913..b2a1f14de7 100644 --- a/lib/src/widgets/evm_switcher.dart +++ b/lib/src/widgets/evm_switcher.dart @@ -42,7 +42,7 @@ class EvmSwitcherDataItem { class EvmSwitcher extends StatefulWidget { const EvmSwitcher({super.key}); - static const editModeAnimDuration = Duration(milliseconds: 150); + static const editModeAnimDuration = Duration(milliseconds: 200); @override State createState() => _EvmSwitcherState(); @@ -67,6 +67,7 @@ class _EvmSwitcherState extends State { @override Widget build(BuildContext context) { + final double popupWidth = MediaQuery.of(context).size.width*0.9; return Center( child: Column( spacing: 25.0, @@ -85,7 +86,7 @@ class _EvmSwitcherState extends State { ), child: AnimatedContainer( duration: EvmSwitcher.editModeAnimDuration, - width: 400, + width: popupWidth, child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ @@ -93,7 +94,7 @@ class _EvmSwitcherState extends State { curve: Curves.easeOutCubic, duration: EvmSwitcher.editModeAnimDuration, child: Container( - width: _editMode ? 0 : 400, + width: _editMode ? 0 : popupWidth, child: Column( mainAxisSize: MainAxisSize.min, children: [ @@ -159,7 +160,7 @@ class _EvmSwitcherState extends State { curve: Curves.easeOutCubic, duration: EvmSwitcher.editModeAnimDuration, child: Container( - width: _editMode ? 400 : 0, + width: _editMode ? popupWidth : 0, height: _editMode ? null : 0, child: Column( mainAxisSize: MainAxisSize.min,