Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: ewm-365 change ui for accounts #610

Merged
merged 6 commits into from
Oct 30, 2024
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 32 additions & 0 deletions lib/feature/wallet/widgets/select_account/select_account_data.dart
Original file line number Diff line number Diff line change
@@ -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<SeedWithInfo> 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<KeyAccount> accounts;
}
Original file line number Diff line number Diff line change
@@ -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';

Expand All @@ -14,16 +15,26 @@ class SelectAccountModel extends ElementaryModel {
final CurrentKeyService _currentKeyService;
final CurrentAccountsService _currentAccountsService;

Stream<List<KeyAccount>> get accounts =>
Stream<List<SelectAccountData>> 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<KeyAccount?> get currentAccount =>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import 'package:ui_components_lib/ui_components_lib.dart';
Future<KeyAccount?> showSelectAccountSheet(BuildContext context) {
return showCommonBottomSheet<KeyAccount>(
context: context,
title: LocaleKeys.selectAccount.tr(),
title: LocaleKeys.myAccounts.tr(),
centerTitle: true,
expand: true,
body: (_, scrollController) => SelectAccountWidget(
Expand Down
104 changes: 84 additions & 20 deletions lib/feature/wallet/widgets/select_account/select_account_widget.dart
Original file line number Diff line number Diff line change
@@ -1,7 +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';
Expand Down Expand Up @@ -34,17 +37,20 @@ class SelectAccountWidget extends ElementaryWidget<SelectAccountWidgetModel> {
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,
);
},
),
Expand Down Expand Up @@ -72,23 +78,81 @@ class SelectAccountWidget extends ElementaryWidget<SelectAccountWidgetModel> {
}
}

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<Money> balance;
final bool active;
final VoidCallback onTap;
final SelectAccountData data;
final bool isExpanded;
final KeyAccount? currentAccount;
final Function(KeyAccount) onTapAccount;
final ListenableState<Money> Function(KeyAccount) getBalanceEntity;

@override
State<_SeedItem> createState() => _SeedItemState();
}

class _SeedItemState extends State<_SeedItem> {
bool _isExpanded = false;
AndreyMolochko marked this conversation as resolved.
Show resolved Hide resolved

@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(
Expand Down Expand Up @@ -145,6 +209,6 @@ class _AccountItem extends StatelessWidget {
],
),
),
);
);*/
}
}
38 changes: 32 additions & 6 deletions lib/feature/wallet/widgets/select_account/select_account_wm.dart
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand All @@ -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(
Expand All @@ -39,7 +40,7 @@ class SelectAccountWidgetModel
);
final _balances = <Address, ListenableState<Money>>{};

ListenableState<List<KeyAccount>> get list => _list;
ListenableState<List<SelectAccountData>> get list => _list;

ListenableState<KeyAccount?> get currentAccount => _currentAccount;

Expand All @@ -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(),
);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
// 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';
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 {
const PrivateKeyItemWidget({
required this.seedWithInfo,
required this.currentAccount,
required this.onTap,
required this.getBalanceEntity,
super.key,
});

final List<SeedWithInfo> seedWithInfo;
final KeyAccount? currentAccount;
final Function(KeyAccount) onTap;
final ListenableState<Money> Function(KeyAccount) getBalanceEntity;

@override
Widget build(BuildContext context) {
final theme = context.themeStyleV2;
return Column(
children: seedWithInfo
.map(
AndreyMolochko marked this conversation as resolved.
Show resolved Hide resolved
(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(),
);
}
}
Loading
Loading