From e7ca8648b0be3744336ca116f7e349807d6c6d5c Mon Sep 17 00:00:00 2001 From: Andrey Molochko <36672245+AndreyMolochko@users.noreply.github.com> Date: Tue, 19 Nov 2024 16:26:49 +0300 Subject: [PATCH] fix: ewm-392 fix focus on current account (#625) Co-authored-by: Andrey Malochka --- .../request_permissions_widget.dart | 31 ++++++++++++++--- .../select_account/select_account_widget.dart | 28 ++++++++++++++++ .../widgets/private_key_item_widget.dart | 3 ++ .../widgets/public_key_item_widget.dart | 33 +++++++++++++++++++ 4 files changed, 91 insertions(+), 4 deletions(-) diff --git a/lib/feature/browser/approvals_listener/actions/request_permissions/request_permissions_widget.dart b/lib/feature/browser/approvals_listener/actions/request_permissions/request_permissions_widget.dart index eb6cd73e9..fdd7c99f9 100644 --- a/lib/feature/browser/approvals_listener/actions/request_permissions/request_permissions_widget.dart +++ b/lib/feature/browser/approvals_listener/actions/request_permissions/request_permissions_widget.dart @@ -35,16 +35,18 @@ class RequestPermissionsWidget Widget build(RequestPermissionsWidgetModel wm) => ValueListenableBuilder( valueListenable: wm.step, builder: (context, value, child) => switch (value) { - RequestPermissionsStep.account => _SelectAccountWidget(wm), + RequestPermissionsStep.account => + _SelectAccountWidget(wm, scrollController), RequestPermissionsStep.confirm => _ConfirmPermissionsWidget(wm), }, ); } class _SelectAccountWidget extends StatelessWidget { - const _SelectAccountWidget(this.wm); + const _SelectAccountWidget(this.wm, this.scrollController); final RequestPermissionsWidgetModel wm; + final ScrollController scrollController; @override Widget build(BuildContext context) { @@ -78,7 +80,12 @@ class _SelectAccountWidget extends StatelessWidget { child: DoubleSourceBuilder( firstSource: wm.accounts, secondSource: wm.selected, - builder: (_, accounts, selected) => ListView.separated( + builder: (_, accounts, selected) { + WidgetsBinding.instance.addPostFrameCallback((_) { + _scrollToActiveAccount(accounts, selected); + }); + return ListView.separated( + controller: scrollController, itemCount: accounts?.length ?? 0, itemBuilder: (_, index) { final account = accounts?[index]; @@ -95,7 +102,8 @@ class _SelectAccountWidget extends StatelessWidget { separatorBuilder: (_, __) => CommonDivider( color: theme.colors.border0, ), - ), + ); + }, ), ), ), @@ -113,6 +121,21 @@ class _SelectAccountWidget extends StatelessWidget { ], ); } + + void _scrollToActiveAccount(List? accounts, KeyAccount? selected) { + if (accounts != null && selected != null) { + final index = accounts!.indexWhere( + (account) => account.address == selected.address); + + if (index != -1) { + scrollController.animateTo( + index * DimensSizeV2.d72, + duration: const Duration(milliseconds: 300), + curve: Curves.easeInOut, + ); + } + } + } } class _ConfirmPermissionsWidget extends StatelessWidget { diff --git a/lib/feature/wallet/widgets/select_account/select_account_widget.dart b/lib/feature/wallet/widgets/select_account/select_account_widget.dart index 4d0304c8b..3ee9a4fd4 100644 --- a/lib/feature/wallet/widgets/select_account/select_account_widget.dart +++ b/lib/feature/wallet/widgets/select_account/select_account_widget.dart @@ -38,6 +38,7 @@ class SelectAccountWidget extends ElementaryWidget { secondSource: wm.currentAccount, builder: (_, list, currentAccount) { return SingleChildScrollView( + controller: scrollController, child: Column( mainAxisSize: MainAxisSize.min, children: List.generate( @@ -54,6 +55,7 @@ class SelectAccountWidget extends ElementaryWidget { currentAccount: currentAccount, onTapAccount: (item) => wm.onSelect(item), getBalanceEntity: wm.getBalanceEntity, + scrollController: scrollController, ), ); }, @@ -82,6 +84,29 @@ class SelectAccountWidget extends ElementaryWidget { ], ); } + + void _scrollToCurrentAccount({ + required KeyAccount? currentAccount, + required Map itemKeys, + required ScrollController scrollController, + }) { + if (currentAccount != null && itemKeys.containsKey(currentAccount)) { + final currentKey = itemKeys[currentAccount]; + final context = currentKey?.currentContext; + if (context != null) { + final renderObject = context.findRenderObject() as RenderBox?; + if (renderObject != null) { + final offset = renderObject.localToGlobal(Offset.zero); + final scrollOffset = scrollController.offset + offset.dy; + scrollController.animateTo( + scrollOffset, + duration: const Duration(milliseconds: 300), + curve: Curves.easeInOut, + ); + } + } + } + } } class _SeedItem extends StatefulWidget { @@ -91,6 +116,7 @@ class _SeedItem extends StatefulWidget { required this.currentAccount, required this.onTapAccount, required this.getBalanceEntity, + required this.scrollController, super.key, }); @@ -99,6 +125,7 @@ class _SeedItem extends StatefulWidget { final KeyAccount? currentAccount; final Function(KeyAccount) onTapAccount; final ListenableState Function(KeyAccount) getBalanceEntity; + final ScrollController scrollController; @override State<_SeedItem> createState() => _SeedItemState(); @@ -139,6 +166,7 @@ class _SeedItemState extends State<_SeedItem> { currentAccount: widget.currentAccount, onTap: widget.onTapAccount, getBalanceEntity: widget.getBalanceEntity, + scrollController: widget.scrollController, ) : const SizedBox.shrink(), ), diff --git a/lib/feature/wallet/widgets/select_account/widgets/private_key_item_widget.dart b/lib/feature/wallet/widgets/select_account/widgets/private_key_item_widget.dart index 3aaa415c0..c710f8a28 100644 --- a/lib/feature/wallet/widgets/select_account/widgets/private_key_item_widget.dart +++ b/lib/feature/wallet/widgets/select_account/widgets/private_key_item_widget.dart @@ -13,6 +13,7 @@ class PrivateKeyItemWidget extends StatelessWidget { required this.currentAccount, required this.onTap, required this.getBalanceEntity, + required this.scrollController, super.key, }); @@ -20,6 +21,7 @@ class PrivateKeyItemWidget extends StatelessWidget { final KeyAccount? currentAccount; final Function(KeyAccount) onTap; final ListenableState Function(KeyAccount) getBalanceEntity; + final ScrollController scrollController; @override Widget build(BuildContext context) { @@ -74,6 +76,7 @@ class PrivateKeyItemWidget extends StatelessWidget { currentAccount: currentAccount, onTap: onTap, getBalanceEntity: getBalanceEntity, + scrollController: scrollController, ), ], ), diff --git a/lib/feature/wallet/widgets/select_account/widgets/public_key_item_widget.dart b/lib/feature/wallet/widgets/select_account/widgets/public_key_item_widget.dart index ce8a652c3..4367b89c5 100644 --- a/lib/feature/wallet/widgets/select_account/widgets/public_key_item_widget.dart +++ b/lib/feature/wallet/widgets/select_account/widgets/public_key_item_widget.dart @@ -14,6 +14,7 @@ class PublicKeyItemWidget extends StatelessWidget { required this.currentAccount, required this.onTap, required this.getBalanceEntity, + required this.scrollController, super.key, }); @@ -21,14 +22,25 @@ class PublicKeyItemWidget extends StatelessWidget { final KeyAccount? currentAccount; final Function(KeyAccount) onTap; final ListenableState Function(KeyAccount) getBalanceEntity; + final ScrollController scrollController; @override Widget build(BuildContext context) { final theme = context.themeStyleV2; + + final Map itemKeys = { + for (var account in accounts) account: GlobalKey(), + }; + + WidgetsBinding.instance.addPostFrameCallback((_) { + _scrollToCurrentAccount(itemKeys); + }); + return Column( children: [ for (var i = 0; i < accounts.length; i++) GestureDetector( + key: itemKeys[accounts[i]], onTap: () => onTap(accounts[i]), child: Container( decoration: BoxDecoration( @@ -109,4 +121,25 @@ class PublicKeyItemWidget extends StatelessWidget { ], ); } + + void _scrollToCurrentAccount(Map itemKeys) { + if (currentAccount == null || !itemKeys.containsKey(currentAccount)) { + return; + } + + final currentKey = itemKeys[currentAccount]!; + final context = currentKey.currentContext; + + if (context != null) { + final renderBox = context.findRenderObject() as RenderBox; + final offset = renderBox.localToGlobal(Offset.zero); + final scrollOffset = scrollController.offset + offset.dy; + + scrollController.animateTo( + scrollOffset, + duration: const Duration(milliseconds: 300), + curve: Curves.easeInOut, + ); + } + } }