From 1d4d6c64562668ed9433b80459fa4afac6f2624a Mon Sep 17 00:00:00 2001 From: Andrey Malochka Date: Tue, 29 Oct 2024 08:11:17 +0300 Subject: [PATCH 1/5] feat: ewm-365 change ui for accounts --- .../select_account/select_account_data.dart | 32 +++++ .../select_account/select_account_model.dart | 29 ++-- .../select_account/select_account_sheet.dart | 2 +- .../select_account/select_account_widget.dart | 102 +++++++++++--- .../select_account/select_account_wm.dart | 38 ++++- .../widgets/private_key_item_widget.dart | 86 ++++++++++++ .../widgets/public_key_item_widget.dart | 132 ++++++++++++++++++ .../widgets/seed_phrase_item_widget.dart | 43 ++++++ .../wallet/widgets/wallet_accounts_body.dart | 16 --- .../wallet_app_bar/wallet_app_bar_widget.dart | 41 ++++-- lib/widgets/user_avatar/user_avatar.dart | 12 +- 11 files changed, 468 insertions(+), 65 deletions(-) create mode 100644 lib/feature/wallet/widgets/select_account/select_account_data.dart create mode 100644 lib/feature/wallet/widgets/select_account/widgets/private_key_item_widget.dart create mode 100644 lib/feature/wallet/widgets/select_account/widgets/public_key_item_widget.dart create mode 100644 lib/feature/wallet/widgets/select_account/widgets/seed_phrase_item_widget.dart diff --git a/lib/feature/wallet/widgets/select_account/select_account_data.dart b/lib/feature/wallet/widgets/select_account/select_account_data.dart new file mode 100644 index 000000000..239ac0a39 --- /dev/null +++ b/lib/feature/wallet/widgets/select_account/select_account_data.dart @@ -0,0 +1,32 @@ +import 'package:nekoton_repository/nekoton_repository.dart'; + +class SelectAccountData { + SelectAccountData({ + required this.name, + required this.privateKeys, + }); + + final String name; + final List privateKeys; + + bool hasCurrentAccount(KeyAccount? account) { + for (final seed in privateKeys) { + if (seed.accounts.contains(account)) { + return true; + } + } + return false; + } +} + +class SeedWithInfo { + SeedWithInfo({ + required this.keyName, + required this.key, + required this.accounts, + }); + + final String keyName; + final String key; + final List accounts; +} diff --git a/lib/feature/wallet/widgets/select_account/select_account_model.dart b/lib/feature/wallet/widgets/select_account/select_account_model.dart index 0d83949e7..ce40e810d 100644 --- a/lib/feature/wallet/widgets/select_account/select_account_model.dart +++ b/lib/feature/wallet/widgets/select_account/select_account_model.dart @@ -1,4 +1,5 @@ import 'package:app/app/service/service.dart'; +import 'package:app/feature/wallet/widgets/select_account/select_account_data.dart'; import 'package:elementary/elementary.dart'; import 'package:nekoton_repository/nekoton_repository.dart'; @@ -14,16 +15,26 @@ class SelectAccountModel extends ElementaryModel { final CurrentKeyService _currentKeyService; final CurrentAccountsService _currentAccountsService; - Stream> get accounts => + Stream> get seedWithAccounts => _nekotonRepository.seedListStream.map( - (seedList) => seedList.seeds - .expand( - (seed) => seed.allKeys.expand( - (key) => key.accountList.allAccounts, - ), - ) - .where((account) => !account.isHidden) - .toList(), + (seedList) { + return seedList.seeds.map((seed) { + final privateKeys = seed.allKeys.map((key) { + final accounts = key.accountList.allAccounts + .where((account) => !account.isHidden) + .toList(); + return SeedWithInfo( + keyName: key.name, + key: key.publicKey.toEllipseString(), + accounts: accounts, + ); + }).toList(); + return SelectAccountData( + name: seed.name, + privateKeys: privateKeys, + ); + }).toList(); + }, ); Stream get currentAccount => diff --git a/lib/feature/wallet/widgets/select_account/select_account_sheet.dart b/lib/feature/wallet/widgets/select_account/select_account_sheet.dart index 5861f5a8a..d6380d358 100644 --- a/lib/feature/wallet/widgets/select_account/select_account_sheet.dart +++ b/lib/feature/wallet/widgets/select_account/select_account_sheet.dart @@ -7,7 +7,7 @@ import 'package:ui_components_lib/ui_components_lib.dart'; Future showSelectAccountSheet(BuildContext context) { return showCommonBottomSheet( context: context, - title: LocaleKeys.selectAccount.tr(), + title: LocaleKeys.myAccounts.tr(), centerTitle: true, expand: true, body: (_, scrollController) => SelectAccountWidget( 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 614f5a4b5..bf4aa8076 100644 --- a/lib/feature/wallet/widgets/select_account/select_account_widget.dart +++ b/lib/feature/wallet/widgets/select_account/select_account_widget.dart @@ -1,4 +1,7 @@ +import 'package:app/feature/wallet/widgets/select_account/select_account_data.dart'; import 'package:app/feature/wallet/widgets/select_account/select_account_wm.dart'; +import 'package:app/feature/wallet/widgets/select_account/widgets/private_key_item_widget.dart'; +import 'package:app/feature/wallet/widgets/select_account/widgets/seed_phrase_item_widget.dart'; import 'package:app/generated/generated.dart'; import 'package:app/utils/utils.dart'; import 'package:app/widgets/user_avatar/user_avatar.dart'; @@ -34,17 +37,20 @@ class SelectAccountWidget extends ElementaryWidget { child: DoubleSourceBuilder( firstSource: wm.list, secondSource: wm.currentAccount, - builder: (_, list, currentAccount) => ListView.builder( + builder: (_, list, currentAccount) => ListView.separated( itemCount: list?.length ?? 0, + separatorBuilder: (_, __) => + const SizedBox(height: DimensSizeV2.d8), itemBuilder: (_, index) => list?.let( (list) { - final account = list[index]; - return _AccountItem( - key: ValueKey(account), - account: account, - balance: wm.getBalanceEntity(account), - active: account == currentAccount, - onTap: () => wm.onSelect(account), + final data = list[index]; + return _SeedItem( + data: data, + isExpanded: data.hasCurrentAccount(currentAccount), + key: ValueKey(data), + currentAccount: currentAccount, + onTapAccount: (item) => wm.onSelect(item), + getBalanceEntity: wm.getBalanceEntity, ); }, ), @@ -72,23 +78,81 @@ class SelectAccountWidget extends ElementaryWidget { } } -class _AccountItem extends StatelessWidget { - const _AccountItem({ - required this.account, - required this.balance, - required this.active, - required this.onTap, +class _SeedItem extends StatefulWidget { + const _SeedItem({ + required this.data, + required this.isExpanded, + required this.currentAccount, + required this.onTapAccount, + required this.getBalanceEntity, super.key, }); - final KeyAccount account; - final ListenableState balance; - final bool active; - final VoidCallback onTap; + final SelectAccountData data; + final bool isExpanded; + final KeyAccount? currentAccount; + final Function(KeyAccount) onTapAccount; + final ListenableState Function(KeyAccount) getBalanceEntity; + + @override + State<_SeedItem> createState() => _SeedItemState(); +} + +class _SeedItemState extends State<_SeedItem> { + bool _isExpanded = false; + + @override + void initState() { + super.initState(); + _isExpanded = widget.isExpanded; + } + + void _toggleExpand() { + setState(() { + _isExpanded = !_isExpanded; + }); + } @override Widget build(BuildContext context) { final theme = context.themeStyleV2; + return GestureDetector( + onTap: _toggleExpand, + child: Container( + padding: EdgeInsets.only( + top: DimensSizeV2.d16, + bottom: _isExpanded ? 0 : DimensSize.d16, + ), + decoration: BoxDecoration( + color: theme.colors.background2, + borderRadius: BorderRadius.circular(DimensRadiusV2.radius12), + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + SeedPhraseItemWidget( + name: widget.data.name, + isExpanded: _isExpanded, + ), + if (_isExpanded) const SizedBox(height: DimensSizeV2.d16), + if (_isExpanded) const CommonDivider(), + AnimatedSize( + duration: const Duration(milliseconds: 300), + curve: Curves.easeInOut, + child: _isExpanded + ? PrivateKeyItemWidget( + seedWithInfo: widget.data.privateKeys, + currentAccount: widget.currentAccount, + onTap: widget.onTapAccount, + getBalanceEntity: widget.getBalanceEntity, + ) + : const SizedBox.shrink(), + ), + ], + ), + ), + ); + /* final address = account.address.toEllipseString(); final pk = account.publicKey.toEllipseString(); final textStyle = theme.textStyles.labelXSmall.copyWith( @@ -145,6 +209,6 @@ class _AccountItem extends StatelessWidget { ], ), ), - ); + );*/ } } diff --git a/lib/feature/wallet/widgets/select_account/select_account_wm.dart b/lib/feature/wallet/widgets/select_account/select_account_wm.dart index 77e832531..e721c215e 100644 --- a/lib/feature/wallet/widgets/select_account/select_account_wm.dart +++ b/lib/feature/wallet/widgets/select_account/select_account_wm.dart @@ -4,6 +4,7 @@ import 'package:app/core/error_handler_factory.dart'; import 'package:app/core/wm/custom_wm.dart'; import 'package:app/di/di.dart'; import 'package:app/feature/wallet/add_account/add_account.dart'; +import 'package:app/feature/wallet/widgets/select_account/select_account_data.dart'; import 'package:app/feature/wallet/widgets/select_account/select_account_model.dart'; import 'package:app/feature/wallet/widgets/select_account/select_account_widget.dart'; import 'package:app/utils/utils.dart'; @@ -29,7 +30,7 @@ class SelectAccountWidgetModel SelectAccountWidgetModel(super.model); late final searchController = createTextEditingController(); - late final _accounts = createNotifierFromStream(model.accounts); + late final _accounts = createNotifierFromStream(model.seedWithAccounts); late final _currentAccount = createNotifierFromStream(model.currentAccount); late final _list = createNotifier(_accounts.value); late final _zeroBalance = Money.fromBigIntWithCurrency( @@ -39,7 +40,7 @@ class SelectAccountWidgetModel ); final _balances = >{}; - ListenableState> get list => _list; + ListenableState> get list => _list; ListenableState get currentAccount => _currentAccount; @@ -58,10 +59,35 @@ class SelectAccountWidgetModel } else { _list.accept( _accounts.value - ?.where( - (account) => - account.name.toLowerCase().contains(value) || - account.address.address.toLowerCase().contains(value), + ?.map((selectAccountData) { + final filteredPrivateKeys = selectAccountData.privateKeys + .map((keyInfo) { + final filteredAccounts = keyInfo.accounts.where( + (account) { + return account.name.toLowerCase().contains(value) || + account.address.address + .toLowerCase() + .contains(value); + }, + ).toList(); + + return SeedWithInfo( + keyName: keyInfo.keyName, + key: keyInfo.key, + accounts: filteredAccounts, + ); + }) + .where( + (keyInfo) => keyInfo.accounts.isNotEmpty, + ) + .toList(); + return SelectAccountData( + name: selectAccountData.name, + privateKeys: filteredPrivateKeys, + ); + }) + .where( + (selectAccountData) => selectAccountData.privateKeys.isNotEmpty, ) .toList(), ); 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 new file mode 100644 index 000000000..4b51abce1 --- /dev/null +++ b/lib/feature/wallet/widgets/select_account/widgets/private_key_item_widget.dart @@ -0,0 +1,86 @@ +import 'package:app/feature/wallet/widgets/select_account/select_account_data.dart'; +import 'package:app/feature/wallet/widgets/select_account/widgets/public_key_item_widget.dart'; +import 'package:elementary_helper/elementary_helper.dart'; +import 'package:flutter/material.dart'; +import 'package:lucide_icons_flutter/lucide_icons.dart'; +import 'package:nekoton_repository/nekoton_repository.dart'; +import 'package:ui_components_lib/ui_components_lib.dart'; + +class PrivateKeyItemWidget extends StatelessWidget { + PrivateKeyItemWidget({ + required this.seedWithInfo, + required this.currentAccount, + required this.onTap, + required this.getBalanceEntity, + super.key, + }); + + final List seedWithInfo; + final KeyAccount? currentAccount; + final Function(KeyAccount) onTap; + final ListenableState Function(KeyAccount) getBalanceEntity; + + @override + Widget build(BuildContext context) { + final theme = context.themeStyleV2; + return Column( + children: seedWithInfo + .map( + (privateKey) => Padding( + padding: const EdgeInsets.symmetric( + vertical: DimensSize.d12, + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + children: [ + const SizedBox(width: DimensSizeV2.d16), + Icon( + LucideIcons.keyRound, + color: theme.colors.content0, + size: DimensSizeV2.d20, + ), + const SizedBox(width: DimensSizeV2.d12), + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + children: [ + Expanded( + child: Text( + privateKey.keyName, + style: theme.textStyles.labelMedium, + overflow: TextOverflow.ellipsis, + ), + ), + ], + ), + const SizedBox(height: DimensSizeV2.d4), + Text( + privateKey.key, + style: theme.textStyles.labelXSmall.copyWith( + color: theme.colors.content3, + ), + ), + ], + ), + ), + ], + ), + const SizedBox(height: DimensSizeV2.d12), + PublicKeyItemWidget( + accounts: privateKey.accounts, + currentAccount: currentAccount, + onTap: onTap, + getBalanceEntity: getBalanceEntity, + ), + ], + ), + ), + ) + .toList(), + ); + } +} 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 new file mode 100644 index 000000000..65705fc71 --- /dev/null +++ b/lib/feature/wallet/widgets/select_account/widgets/public_key_item_widget.dart @@ -0,0 +1,132 @@ +import 'package:app/app/router/page_transitions.dart'; +import 'package:app/utils/utils.dart'; +import 'package:app/widgets/widgets.dart'; +import 'package:elementary_helper/elementary_helper.dart'; +import 'package:flutter/material.dart'; +import 'package:lucide_icons_flutter/lucide_icons.dart'; +import 'package:nekoton_repository/nekoton_repository.dart'; +import 'package:ui_components_lib/ui_components_lib.dart'; +import 'package:ui_components_lib/v2/ui_components_lib_v2.dart'; + +class PublicKeyItemWidget extends StatelessWidget { + const PublicKeyItemWidget({ + required this.accounts, + required this.currentAccount, + required this.onTap, + required this.getBalanceEntity, + super.key, + }); + + final List accounts; + final KeyAccount? currentAccount; + final Function(KeyAccount) onTap; + final ListenableState Function(KeyAccount) getBalanceEntity; + + @override + Widget build(BuildContext context) { + final theme = context.themeStyleV2; + return Column( + children: [ + for (var i = 0; i < accounts.length; i++) ...[ + GestureDetector( + onTap: () => onTap(accounts[i]), + child: Container( + decoration: BoxDecoration( + color: accounts[i] == currentAccount + ? theme.colors.background3 + : theme.colors.background2, + ), + padding: EdgeInsets.only( + top: (i != 0 || accounts[i] == currentAccount) + ? DimensSizeV2.d12 + : 0, + bottom: + (i < accounts.length - 1 || accounts[i] == currentAccount) + ? DimensSizeV2.d12 + : 0, + ), + child: Row( + children: [ + const SizedBox(width: DimensSizeV2.d24), + UserAvatar( + address: accounts[i].address.address, + size: DimensSizeV2.d28, + borderRadius: DimensRadiusV2.radius6, + ), + const SizedBox(width: DimensSizeV2.d12), + Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + accounts[i].name, + style: theme.textStyles.labelMedium, + ), + const SizedBox(height: DimensSizeV2.d4), + Row( + children: [ + Text( + '${accounts[i].address.toEllipseString()} • ', + style: theme.textStyles.labelXSmall.copyWith( + color: theme.colors.content3, + ), + ), + StateNotifierBuilder( + listenableState: getBalanceEntity(accounts[i]), + builder: (_, balance) => + getBalanceEntity(accounts[i]).let( + (value) => value.value != null + ? AmountWidget.fromMoney( + amount: value.value!, + style: + theme.textStyles.labelXSmall.copyWith( + color: theme.colors.content3, + ), + ) + : ProgressIndicatorWidget( + size: DimensSizeV2.d16, + color: theme.colors.content3, + ), + ), + ), + ], + ), + ], + ), + const Spacer(), + if (accounts[i] == currentAccount) + Padding( + padding: const EdgeInsets.only(right: DimensSizeV2.d16), + child: Icon( + LucideIcons.check, + size: DimensSizeV2.d20, + color: theme.colors.content0, + ), + ), + ], + ), + ), + ), + ], + ], + ); + } +} + +/*StateNotifierBuilder( + listenableState: balance, + builder: (_, balance) => + balance?.let( + (value) => Expanded( + child: AmountWidget.fromMoney( + amount: balance, + style: theme.textStyles.labelXSmall.copyWith( + color: theme.colors.content3, + ), + ), + ), + ) ?? + ProgressIndicatorWidget( + size: DimensSizeV2.d16, + color: theme.colors.content3, + ), + ),*/ diff --git a/lib/feature/wallet/widgets/select_account/widgets/seed_phrase_item_widget.dart b/lib/feature/wallet/widgets/select_account/widgets/seed_phrase_item_widget.dart new file mode 100644 index 000000000..db19990d9 --- /dev/null +++ b/lib/feature/wallet/widgets/select_account/widgets/seed_phrase_item_widget.dart @@ -0,0 +1,43 @@ +import 'package:flutter/material.dart'; +import 'package:lucide_icons_flutter/lucide_icons.dart'; +import 'package:ui_components_lib/v2/ui_components_lib_v2.dart'; + +class SeedPhraseItemWidget extends StatelessWidget { + const SeedPhraseItemWidget({ + required this.name, + required this.isExpanded, + super.key, + }); + + final String name; + final bool isExpanded; + + @override + Widget build(BuildContext context) { + final theme = context.themeStyleV2; + return Row( + children: [ + const SizedBox(width: DimensSizeV2.d16), + Icon( + LucideIcons.lockKeyhole, + color: theme.colors.content0, + size: DimensSizeV2.d16, + ), + const SizedBox(width: DimensSizeV2.d12), + Expanded( + child: Text( + name, + style: theme.textStyles.labelMedium, + overflow: TextOverflow.ellipsis, + ), + ), + Icon( + isExpanded ? LucideIcons.chevronUp : LucideIcons.chevronDown, + color: theme.colors.content0, + size: DimensSizeV2.d16, + ), + const SizedBox(width: DimensSizeV2.d16), + ], + ); + } +} diff --git a/lib/feature/wallet/widgets/wallet_accounts_body.dart b/lib/feature/wallet/widgets/wallet_accounts_body.dart index d2e0bfc01..a6bddd48b 100644 --- a/lib/feature/wallet/widgets/wallet_accounts_body.dart +++ b/lib/feature/wallet/widgets/wallet_accounts_body.dart @@ -1,8 +1,6 @@ import 'package:app/feature/wallet/wallet.dart'; import 'package:app/feature/wallet/wallet_backup/back_up_badge.dart'; -import 'package:app/generated/generated.dart'; import 'package:flutter/material.dart'; -import 'package:lucide_icons_flutter/lucide_icons.dart'; import 'package:nekoton_repository/nekoton_repository.dart'; import 'package:ui_components_lib/v2/ui_components_lib_v2.dart'; @@ -33,14 +31,6 @@ class WalletAccountsBody extends StatelessWidget { else const ProgressIndicatorWidget(size: DimensSizeV2.d80), const SizedBox(height: DimensSizeV2.d16), - PrimaryButton( - buttonShape: ButtonShape.pill, - buttonSize: ButtonSize.small, - icon: LucideIcons.dock, - title: LocaleKeys.accounts.tr(), - isFullWidth: false, - onPressed: () => _showSelectAccountSheet(context), - ), WalletAccountActions( currentAccount: account, ), @@ -52,10 +42,4 @@ class WalletAccountsBody extends StatelessWidget { ), ); } - - Future _showSelectAccountSheet(BuildContext context) async { - if (!context.mounted) return; - - await showSelectAccountSheet(context); - } } diff --git a/lib/feature/wallet/widgets/wallet_app_bar/wallet_app_bar_widget.dart b/lib/feature/wallet/widgets/wallet_app_bar/wallet_app_bar_widget.dart index d8136fed4..60206701f 100644 --- a/lib/feature/wallet/widgets/wallet_app_bar/wallet_app_bar_widget.dart +++ b/lib/feature/wallet/widgets/wallet_app_bar/wallet_app_bar_widget.dart @@ -1,4 +1,5 @@ import 'package:app/feature/network/network.dart'; +import 'package:app/feature/wallet/widgets/select_account/select_account_sheet.dart'; import 'package:app/feature/wallet/widgets/wallet_app_bar/wallet_app_bar_wm.dart'; import 'package:app/utils/utils.dart'; import 'package:app/widgets/user_avatar/user_avatar.dart'; @@ -8,6 +9,7 @@ import 'package:flutter/material.dart'; import 'package:lucide_icons_flutter/lucide_icons.dart'; import 'package:nekoton_repository/nekoton_repository.dart'; import 'package:ui_components_lib/ui_components_lib.dart'; +import 'package:ui_components_lib/v2/ui_components_lib_v2.dart'; class WalletAppBarWidget extends ElementaryWidget implements PreferredSizeWidget { @@ -42,28 +44,45 @@ class WalletAppBarWidget extends ElementaryWidget walletTypeName: wm.getWalletTypeName( account.account.tonWallet.contract, ), - onTap: wm.onSettings, + onTap: () => _showSelectAccountSheet(wm.context), ), ) ?? const SizedBox.shrink(), ), ), - StateNotifierBuilder( - listenableState: wm.connection, - builder: (_, connection) => - connection?.let( - (value) => GestureDetector( - onTap: wm.onNetwork, - child: NetworkIcon(type: value.networkType), - ), - ) ?? - const SizedBox.shrink(), + SeparatedRow( + separator: const SizedBox(width: DimensSizeV2.d12), + children: [ + FloatButton( + buttonShape: ButtonShape.circle, + buttonSize: ButtonSize.small, + icon: LucideIcons.cog, + onPressed: wm.onSettings, + ), + StateNotifierBuilder( + listenableState: wm.connection, + builder: (_, connection) => + connection?.let( + (value) => GestureDetector( + onTap: wm.onNetwork, + child: NetworkIcon(type: value.networkType), + ), + ) ?? + const SizedBox.shrink(), + ), + ], ), ], ), ), ); } + + Future _showSelectAccountSheet(BuildContext context) async { + if (!context.mounted) return; + + await showSelectAccountSheet(context); + } } class _AccountInfo extends StatelessWidget { diff --git a/lib/widgets/user_avatar/user_avatar.dart b/lib/widgets/user_avatar/user_avatar.dart index d513f8993..060747e8e 100644 --- a/lib/widgets/user_avatar/user_avatar.dart +++ b/lib/widgets/user_avatar/user_avatar.dart @@ -9,6 +9,8 @@ class UserAvatar extends ElementaryWidget { Key? key, WidgetModelFactory? wmFactory, this.address, + this.size, + this.borderRadius, }) : super( wmFactory ?? (ctx) => defaultUserAvatarWidgetModelFactory( @@ -19,12 +21,14 @@ class UserAvatar extends ElementaryWidget { ); final String? address; + final double? size; + final double? borderRadius; @override Widget build(UserAvatarWidgetModel wm) { return SizedBox( - width: DimensSizeV2.d40, - height: DimensSizeV2.d40, + width: size ?? DimensSizeV2.d40, + height: size ?? DimensSizeV2.d40, child: StateNotifierBuilder( listenableState: wm.avatarState, builder: (_, data) { @@ -41,7 +45,9 @@ class UserAvatar extends ElementaryWidget { colorBlendMode: BlendMode.modulate, ), AvatarType.raw => ClipRRect( - borderRadius: BorderRadius.circular(DimensRadiusV2.radius12), + borderRadius: BorderRadius.circular( + borderRadius ?? DimensRadiusV2.radius12, + ), child: SvgPicture.string( data.path, width: double.infinity, From 60b3e1b78c5ce9711ffb46aa6104192d80e0d5c5 Mon Sep 17 00:00:00 2001 From: Andrey Malochka Date: Tue, 29 Oct 2024 08:17:03 +0300 Subject: [PATCH 2/5] fix linter --- .../wallet/widgets/select_account/select_account_widget.dart | 2 +- .../wallet/widgets/wallet_app_bar/wallet_app_bar_widget.dart | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) 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 bf4aa8076..29a4f220a 100644 --- a/lib/feature/wallet/widgets/select_account/select_account_widget.dart +++ b/lib/feature/wallet/widgets/select_account/select_account_widget.dart @@ -1,10 +1,10 @@ +// ignore_for_file: inference_failure_on_function_return_type import 'package:app/feature/wallet/widgets/select_account/select_account_data.dart'; import 'package:app/feature/wallet/widgets/select_account/select_account_wm.dart'; import 'package:app/feature/wallet/widgets/select_account/widgets/private_key_item_widget.dart'; import 'package:app/feature/wallet/widgets/select_account/widgets/seed_phrase_item_widget.dart'; import 'package:app/generated/generated.dart'; import 'package:app/utils/utils.dart'; -import 'package:app/widgets/user_avatar/user_avatar.dart'; import 'package:elementary/elementary.dart'; import 'package:elementary_helper/elementary_helper.dart'; import 'package:flutter/material.dart'; diff --git a/lib/feature/wallet/widgets/wallet_app_bar/wallet_app_bar_widget.dart b/lib/feature/wallet/widgets/wallet_app_bar/wallet_app_bar_widget.dart index 60206701f..5ad847dff 100644 --- a/lib/feature/wallet/widgets/wallet_app_bar/wallet_app_bar_widget.dart +++ b/lib/feature/wallet/widgets/wallet_app_bar/wallet_app_bar_widget.dart @@ -1,3 +1,5 @@ +// ignore_for_file: invalid_use_of_visible_for_testing_member +// ignore_for_file: invalid_use_of_protected_member import 'package:app/feature/network/network.dart'; import 'package:app/feature/wallet/widgets/select_account/select_account_sheet.dart'; import 'package:app/feature/wallet/widgets/wallet_app_bar/wallet_app_bar_wm.dart'; From a66a7a7301854e1d5c491fe71b90bb8f91eb7774 Mon Sep 17 00:00:00 2001 From: Andrey Malochka Date: Tue, 29 Oct 2024 08:39:48 +0300 Subject: [PATCH 3/5] add const and fix linter --- .../select_account/widgets/private_key_item_widget.dart | 3 ++- .../widgets/select_account/widgets/public_key_item_widget.dart | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) 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 4b51abce1..b18e32ed0 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 @@ -1,3 +1,4 @@ +// ignore_for_file: inference_failure_on_function_return_type import 'package:app/feature/wallet/widgets/select_account/select_account_data.dart'; import 'package:app/feature/wallet/widgets/select_account/widgets/public_key_item_widget.dart'; import 'package:elementary_helper/elementary_helper.dart'; @@ -7,7 +8,7 @@ import 'package:nekoton_repository/nekoton_repository.dart'; import 'package:ui_components_lib/ui_components_lib.dart'; class PrivateKeyItemWidget extends StatelessWidget { - PrivateKeyItemWidget({ + const PrivateKeyItemWidget({ required this.seedWithInfo, required this.currentAccount, required this.onTap, 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 65705fc71..bee9168cb 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 @@ -1,4 +1,4 @@ -import 'package:app/app/router/page_transitions.dart'; +// ignore_for_file: inference_failure_on_function_return_type import 'package:app/utils/utils.dart'; import 'package:app/widgets/widgets.dart'; import 'package:elementary_helper/elementary_helper.dart'; From 7a5acf9751baf542b028fd6e70000d64f8b74ba6 Mon Sep 17 00:00:00 2001 From: Andrey Malochka Date: Wed, 30 Oct 2024 09:40:47 +0300 Subject: [PATCH 4/5] fix comment and fix bug with calling item builder --- .../select_account/select_account_widget.dart | 115 ++++++------------ .../widgets/private_key_item_widget.dart | 101 ++++++++------- .../widgets/public_key_item_widget.dart | 22 +--- 3 files changed, 84 insertions(+), 154 deletions(-) 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 29a4f220a..447d3dcc8 100644 --- a/lib/feature/wallet/widgets/select_account/select_account_widget.dart +++ b/lib/feature/wallet/widgets/select_account/select_account_widget.dart @@ -37,24 +37,35 @@ class SelectAccountWidget extends ElementaryWidget { child: DoubleSourceBuilder( firstSource: wm.list, secondSource: wm.currentAccount, - builder: (_, list, currentAccount) => ListView.separated( - itemCount: list?.length ?? 0, - separatorBuilder: (_, __) => - const SizedBox(height: DimensSizeV2.d8), - itemBuilder: (_, index) => list?.let( - (list) { - final data = list[index]; - return _SeedItem( - data: data, - isExpanded: data.hasCurrentAccount(currentAccount), - key: ValueKey(data), - currentAccount: currentAccount, - onTapAccount: (item) => wm.onSelect(item), - getBalanceEntity: wm.getBalanceEntity, - ); - }, - ), - ), + builder: (_, list, currentAccount) { + return SingleChildScrollView( + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + for (int index = 0; + index < (list?.length ?? 0); + index++) ...[ + Padding( + padding: const EdgeInsets.only(bottom: DimensSizeV2.d8), + child: list!.let((list) { + final data = list[index]; + final isExpanded = + data.hasCurrentAccount(currentAccount); + return _SeedItem( + data: data, + isExpanded: isExpanded, + key: ValueKey(data.name), + currentAccount: currentAccount, + onTapAccount: (item) => wm.onSelect(item), + getBalanceEntity: wm.getBalanceEntity, + ); + }), + ), + ], + ], + ), + ); + }, ), ), const SizedBox(height: DimensSizeV2.d16), @@ -107,12 +118,6 @@ class _SeedItemState extends State<_SeedItem> { _isExpanded = widget.isExpanded; } - void _toggleExpand() { - setState(() { - _isExpanded = !_isExpanded; - }); - } - @override Widget build(BuildContext context) { final theme = context.themeStyleV2; @@ -152,63 +157,11 @@ class _SeedItemState extends State<_SeedItem> { ), ), ); - /* - final address = account.address.toEllipseString(); - final pk = account.publicKey.toEllipseString(); - final textStyle = theme.textStyles.labelXSmall.copyWith( - color: theme.colors.content3, - ); + } - return GestureDetector( - behavior: HitTestBehavior.translucent, - onTap: onTap, - child: Padding( - padding: const EdgeInsets.symmetric(vertical: DimensSizeV2.d12), - child: SeparatedRow( - children: [ - UserAvatar( - address: account.address.address, - ), - Expanded( - child: SeparatedColumn( - separatorSize: DimensSizeV2.d4, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text( - account.name, - style: theme.textStyles.labelMedium, - overflow: TextOverflow.ellipsis, - softWrap: false, - maxLines: 1, - ), - Row( - children: [ - Text('$address • $pk • ', style: textStyle), - StateNotifierBuilder( - listenableState: balance, - builder: (_, balance) => - balance?.let( - (value) => Expanded( - child: AmountWidget.fromMoney( - amount: balance, - style: textStyle, - ), - ), - ) ?? - ProgressIndicatorWidget( - size: DimensSizeV2.d16, - color: theme.colors.content3, - ), - ), - ], - ), - ], - ), - ), - if (active) const Icon(LucideIcons.check, size: DimensSizeV2.d20), - ], - ), - ), - );*/ + void _toggleExpand() { + setState(() { + _isExpanded = !_isExpanded; + }); } } 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 b18e32ed0..3aaa415c0 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 @@ -25,63 +25,60 @@ class PrivateKeyItemWidget extends StatelessWidget { Widget build(BuildContext context) { final theme = context.themeStyleV2; return Column( - children: seedWithInfo - .map( - (privateKey) => Padding( - padding: const EdgeInsets.symmetric( - vertical: DimensSize.d12, - ), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Row( - children: [ - const SizedBox(width: DimensSizeV2.d16), - Icon( - LucideIcons.keyRound, - color: theme.colors.content0, - size: DimensSizeV2.d20, - ), - const SizedBox(width: DimensSizeV2.d12), - Expanded( - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Row( - children: [ - Expanded( - child: Text( - privateKey.keyName, - style: theme.textStyles.labelMedium, - overflow: TextOverflow.ellipsis, - ), + children: [ + for (final privateKey in seedWithInfo) + Padding( + padding: const EdgeInsets.symmetric(vertical: DimensSize.d12), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + children: [ + const SizedBox(width: DimensSizeV2.d16), + Icon( + LucideIcons.keyRound, + color: theme.colors.content0, + size: DimensSizeV2.d20, + ), + const SizedBox(width: DimensSizeV2.d12), + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + children: [ + Expanded( + child: Text( + privateKey.keyName, + style: theme.textStyles.labelMedium, + overflow: TextOverflow.ellipsis, ), - ], - ), - const SizedBox(height: DimensSizeV2.d4), - Text( - privateKey.key, - style: theme.textStyles.labelXSmall.copyWith( - color: theme.colors.content3, ), + ], + ), + const SizedBox(height: DimensSizeV2.d4), + Text( + privateKey.key, + style: theme.textStyles.labelXSmall.copyWith( + color: theme.colors.content3, ), - ], - ), + ), + ], ), - ], - ), - const SizedBox(height: DimensSizeV2.d12), - PublicKeyItemWidget( - accounts: privateKey.accounts, - currentAccount: currentAccount, - onTap: onTap, - getBalanceEntity: getBalanceEntity, - ), - ], - ), + ), + ], + ), + const SizedBox(height: DimensSizeV2.d12), + PublicKeyItemWidget( + accounts: privateKey.accounts, + currentAccount: currentAccount, + onTap: onTap, + getBalanceEntity: getBalanceEntity, + ), + ], ), - ) - .toList(), + ), + ], ); } } 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 bee9168cb..ce8a652c3 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 @@ -27,7 +27,7 @@ class PublicKeyItemWidget extends StatelessWidget { final theme = context.themeStyleV2; return Column( children: [ - for (var i = 0; i < accounts.length; i++) ...[ + for (var i = 0; i < accounts.length; i++) GestureDetector( onTap: () => onTap(accounts[i]), child: Container( @@ -106,27 +106,7 @@ class PublicKeyItemWidget extends StatelessWidget { ), ), ), - ], ], ); } } - -/*StateNotifierBuilder( - listenableState: balance, - builder: (_, balance) => - balance?.let( - (value) => Expanded( - child: AmountWidget.fromMoney( - amount: balance, - style: theme.textStyles.labelXSmall.copyWith( - color: theme.colors.content3, - ), - ), - ), - ) ?? - ProgressIndicatorWidget( - size: DimensSizeV2.d16, - color: theme.colors.content3, - ), - ),*/ From 2a45ca598e63680f9ad0fc0edf2029fc6b70a3de Mon Sep 17 00:00:00 2001 From: Andrey Malochka Date: Wed, 30 Oct 2024 12:23:22 +0300 Subject: [PATCH 5/5] remove unused loop --- .../select_account/select_account_widget.dart | 46 ++++++++----------- 1 file changed, 18 insertions(+), 28 deletions(-) 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 447d3dcc8..4b89494c9 100644 --- a/lib/feature/wallet/widgets/select_account/select_account_widget.dart +++ b/lib/feature/wallet/widgets/select_account/select_account_widget.dart @@ -41,28 +41,24 @@ class SelectAccountWidget extends ElementaryWidget { return SingleChildScrollView( child: Column( mainAxisSize: MainAxisSize.min, - children: [ - for (int index = 0; - index < (list?.length ?? 0); - index++) ...[ - Padding( + children: List.generate( + list?.length ?? 0, + (index) { + final data = list![index]; + final isExpanded = data.hasCurrentAccount(currentAccount); + return Padding( padding: const EdgeInsets.only(bottom: DimensSizeV2.d8), - child: list!.let((list) { - final data = list[index]; - final isExpanded = - data.hasCurrentAccount(currentAccount); - return _SeedItem( - data: data, - isExpanded: isExpanded, - key: ValueKey(data.name), - currentAccount: currentAccount, - onTapAccount: (item) => wm.onSelect(item), - getBalanceEntity: wm.getBalanceEntity, - ); - }), - ), - ], - ], + child: _SeedItem( + data: data, + isExpanded: isExpanded, + key: ValueKey(data.name), + currentAccount: currentAccount, + onTapAccount: (item) => wm.onSelect(item), + getBalanceEntity: wm.getBalanceEntity, + ), + ); + }, + ), ), ); }, @@ -110,13 +106,7 @@ class _SeedItem extends StatefulWidget { } class _SeedItemState extends State<_SeedItem> { - bool _isExpanded = false; - - @override - void initState() { - super.initState(); - _isExpanded = widget.isExpanded; - } + late bool _isExpanded = widget.isExpanded; @override Widget build(BuildContext context) {