mirror of
https://github.com/cypherstack/stack_wallet.git
synced 2025-03-25 08:38:45 +00:00
eth token wallet general ui and wallet selection interface
This commit is contained in:
parent
9c0994aa00
commit
5e5730d5a5
12 changed files with 455 additions and 63 deletions
|
@ -112,7 +112,7 @@ class _ChooseFromStackViewState extends ConsumerState<ChooseFromStackView> {
|
||||||
const SizedBox(
|
const SizedBox(
|
||||||
height: 2,
|
height: 2,
|
||||||
),
|
),
|
||||||
WalletInfoRowBalanceFuture(
|
WalletInfoRowBalance(
|
||||||
walletId: walletIds[index],
|
walletId: walletIds[index],
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
|
|
@ -69,18 +69,8 @@ class TokenSummary extends ConsumerWidget {
|
||||||
const SizedBox(
|
const SizedBox(
|
||||||
width: 10,
|
width: 10,
|
||||||
),
|
),
|
||||||
RoundedContainer(
|
CoinTickerTag(
|
||||||
padding: const EdgeInsets.symmetric(vertical: 2, horizontal: 4),
|
walletId: walletId,
|
||||||
radiusMultiplier: 0.25,
|
|
||||||
color: const Color(
|
|
||||||
0xFF4D5798), // TODO: color theme for multi themes
|
|
||||||
child: Text(
|
|
||||||
ref.watch(walletsChangeNotifierProvider.select(
|
|
||||||
(value) => value.getManager(walletId).coin.ticker)),
|
|
||||||
style: STextStyles.w600_12(context).copyWith(
|
|
||||||
color: Colors.white, // TODO: design is wrong?
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
@ -195,3 +185,28 @@ class TokenOptionsButton extends StatelessWidget {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class CoinTickerTag extends ConsumerWidget {
|
||||||
|
const CoinTickerTag({
|
||||||
|
Key? key,
|
||||||
|
required this.walletId,
|
||||||
|
}) : super(key: key);
|
||||||
|
|
||||||
|
final String walletId;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context, WidgetRef ref) {
|
||||||
|
return RoundedContainer(
|
||||||
|
padding: const EdgeInsets.symmetric(vertical: 2, horizontal: 4),
|
||||||
|
radiusMultiplier: 0.25,
|
||||||
|
color: const Color(0xFF4D5798), // TODO: color theme for multi themes
|
||||||
|
child: Text(
|
||||||
|
ref.watch(walletsChangeNotifierProvider
|
||||||
|
.select((value) => value.getManager(walletId).coin.ticker)),
|
||||||
|
style: STextStyles.w600_12(context).copyWith(
|
||||||
|
color: Colors.white, // TODO: design is wrong?
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
73
lib/pages/wallets_view/eth_wallets_overview.dart
Normal file
73
lib/pages/wallets_view/eth_wallets_overview.dart
Normal file
|
@ -0,0 +1,73 @@
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||||
|
import 'package:stackwallet/providers/providers.dart';
|
||||||
|
import 'package:stackwallet/utilities/enums/coin_enum.dart';
|
||||||
|
import 'package:stackwallet/utilities/text_styles.dart';
|
||||||
|
import 'package:stackwallet/utilities/theme/stack_colors.dart';
|
||||||
|
import 'package:stackwallet/utilities/util.dart';
|
||||||
|
import 'package:stackwallet/widgets/background.dart';
|
||||||
|
import 'package:stackwallet/widgets/conditional_parent.dart';
|
||||||
|
import 'package:stackwallet/widgets/custom_buttons/app_bar_icon_button.dart';
|
||||||
|
import 'package:stackwallet/widgets/master_wallet_card.dart';
|
||||||
|
|
||||||
|
class EthWalletsOverview extends ConsumerStatefulWidget {
|
||||||
|
const EthWalletsOverview({Key? key}) : super(key: key);
|
||||||
|
|
||||||
|
static const routeName = "/ethWalletsOverview";
|
||||||
|
|
||||||
|
@override
|
||||||
|
ConsumerState<EthWalletsOverview> createState() => _EthWalletsOverviewState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _EthWalletsOverviewState extends ConsumerState<EthWalletsOverview> {
|
||||||
|
final isDesktop = Util.isDesktop;
|
||||||
|
|
||||||
|
final List<String> ethWalletIds = [];
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
final walletsData =
|
||||||
|
ref.read(walletsServiceChangeNotifierProvider).fetchWalletsData();
|
||||||
|
walletsData.removeWhere((key, value) => value.coin != Coin.ethereum);
|
||||||
|
ethWalletIds.clear();
|
||||||
|
|
||||||
|
ethWalletIds.addAll(walletsData.values.map((e) => e.walletId));
|
||||||
|
|
||||||
|
super.initState();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Background(
|
||||||
|
child: ConditionalParent(
|
||||||
|
condition: !isDesktop,
|
||||||
|
builder: (child) => Scaffold(
|
||||||
|
backgroundColor:
|
||||||
|
Theme.of(context).extension<StackColors>()!.background,
|
||||||
|
appBar: AppBar(
|
||||||
|
leading: const AppBarBackButton(),
|
||||||
|
title: Text(
|
||||||
|
"Ethereum (ETH) wallets",
|
||||||
|
style: STextStyles.navBarTitle(context),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
body: SafeArea(
|
||||||
|
child: Padding(
|
||||||
|
padding: const EdgeInsets.all(16),
|
||||||
|
child: child,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
child: ListView.separated(
|
||||||
|
itemCount: ethWalletIds.length,
|
||||||
|
separatorBuilder: (_, __) => const SizedBox(
|
||||||
|
height: 8,
|
||||||
|
),
|
||||||
|
itemBuilder: (_, index) => MasterWalletCard(
|
||||||
|
walletId: ethWalletIds[index],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
|
@ -5,6 +5,7 @@ import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||||
import 'package:flutter_svg/svg.dart';
|
import 'package:flutter_svg/svg.dart';
|
||||||
import 'package:stackwallet/pages/wallet_view/wallet_view.dart';
|
import 'package:stackwallet/pages/wallet_view/wallet_view.dart';
|
||||||
import 'package:stackwallet/pages/wallets_sheet/wallets_sheet.dart';
|
import 'package:stackwallet/pages/wallets_sheet/wallets_sheet.dart';
|
||||||
|
import 'package:stackwallet/pages/wallets_view/eth_wallets_overview.dart';
|
||||||
import 'package:stackwallet/providers/providers.dart';
|
import 'package:stackwallet/providers/providers.dart';
|
||||||
import 'package:stackwallet/utilities/assets.dart';
|
import 'package:stackwallet/utilities/assets.dart';
|
||||||
import 'package:stackwallet/utilities/constants.dart';
|
import 'package:stackwallet/utilities/constants.dart';
|
||||||
|
@ -45,7 +46,13 @@ class WalletListItem extends ConsumerWidget {
|
||||||
BorderRadius.circular(Constants.size.circularBorderRadius),
|
BorderRadius.circular(Constants.size.circularBorderRadius),
|
||||||
),
|
),
|
||||||
onPressed: () async {
|
onPressed: () async {
|
||||||
if (walletCount == 1) {
|
if (coin == Coin.ethereum) {
|
||||||
|
unawaited(
|
||||||
|
Navigator.of(context).pushNamed(
|
||||||
|
EthWalletsOverview.routeName,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
} else if (walletCount == 1) {
|
||||||
final providersByCoin = ref
|
final providersByCoin = ref
|
||||||
.watch(walletsChangeNotifierProvider
|
.watch(walletsChangeNotifierProvider
|
||||||
.select((value) => value.getManagerProvidersByCoin()))
|
.select((value) => value.getManagerProvidersByCoin()))
|
||||||
|
@ -57,15 +64,17 @@ class WalletListItem extends ConsumerWidget {
|
||||||
if (coin == Coin.monero || coin == Coin.wownero) {
|
if (coin == Coin.monero || coin == Coin.wownero) {
|
||||||
await manager.initializeExisting();
|
await manager.initializeExisting();
|
||||||
}
|
}
|
||||||
unawaited(
|
if (context.mounted) {
|
||||||
Navigator.of(context).pushNamed(
|
unawaited(
|
||||||
WalletView.routeName,
|
Navigator.of(context).pushNamed(
|
||||||
arguments: Tuple2(
|
WalletView.routeName,
|
||||||
manager.walletId,
|
arguments: Tuple2(
|
||||||
providersByCoin.first,
|
manager.walletId,
|
||||||
|
providersByCoin.first,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
);
|
||||||
);
|
}
|
||||||
} else {
|
} else {
|
||||||
unawaited(
|
unawaited(
|
||||||
showModalBottomSheet<dynamic>(
|
showModalBottomSheet<dynamic>(
|
||||||
|
|
|
@ -105,6 +105,7 @@ import 'package:stackwallet/pages/wallet_view/transaction_views/edit_note_view.d
|
||||||
import 'package:stackwallet/pages/wallet_view/transaction_views/transaction_details_view.dart';
|
import 'package:stackwallet/pages/wallet_view/transaction_views/transaction_details_view.dart';
|
||||||
import 'package:stackwallet/pages/wallet_view/transaction_views/transaction_search_filter_view.dart';
|
import 'package:stackwallet/pages/wallet_view/transaction_views/transaction_search_filter_view.dart';
|
||||||
import 'package:stackwallet/pages/wallet_view/wallet_view.dart';
|
import 'package:stackwallet/pages/wallet_view/wallet_view.dart';
|
||||||
|
import 'package:stackwallet/pages/wallets_view/eth_wallets_overview.dart';
|
||||||
import 'package:stackwallet/pages/wallets_view/wallets_view.dart';
|
import 'package:stackwallet/pages/wallets_view/wallets_view.dart';
|
||||||
import 'package:stackwallet/pages_desktop_specific/address_book_view/desktop_address_book.dart';
|
import 'package:stackwallet/pages_desktop_specific/address_book_view/desktop_address_book.dart';
|
||||||
import 'package:stackwallet/pages_desktop_specific/coin_control/desktop_coin_control_view.dart';
|
import 'package:stackwallet/pages_desktop_specific/coin_control/desktop_coin_control_view.dart';
|
||||||
|
@ -250,6 +251,15 @@ class RouteGenerator {
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
case EthWalletsOverview.routeName:
|
||||||
|
return getRoute(
|
||||||
|
shouldUseMaterialRoute: useMaterialPageRoute,
|
||||||
|
builder: (_) => const EthWalletsOverview(),
|
||||||
|
settings: RouteSettings(
|
||||||
|
name: settings.name,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
case TokenContractDetailsView.routeName:
|
case TokenContractDetailsView.routeName:
|
||||||
if (args is Tuple2<String, String>) {
|
if (args is Tuple2<String, String>) {
|
||||||
return getRoute(
|
return getRoute(
|
||||||
|
|
|
@ -5,11 +5,13 @@ import 'package:decimal/decimal.dart';
|
||||||
import 'package:ethereum_addresses/ethereum_addresses.dart';
|
import 'package:ethereum_addresses/ethereum_addresses.dart';
|
||||||
import 'package:http/http.dart';
|
import 'package:http/http.dart';
|
||||||
import 'package:isar/isar.dart';
|
import 'package:isar/isar.dart';
|
||||||
|
import 'package:stackwallet/db/hive/db.dart';
|
||||||
import 'package:stackwallet/db/isar/main_db.dart';
|
import 'package:stackwallet/db/isar/main_db.dart';
|
||||||
import 'package:stackwallet/models/balance.dart';
|
import 'package:stackwallet/models/balance.dart';
|
||||||
import 'package:stackwallet/models/isar/models/isar_models.dart';
|
import 'package:stackwallet/models/isar/models/isar_models.dart';
|
||||||
import 'package:stackwallet/models/node_model.dart';
|
import 'package:stackwallet/models/node_model.dart';
|
||||||
import 'package:stackwallet/models/paymint/fee_object_model.dart';
|
import 'package:stackwallet/models/paymint/fee_object_model.dart';
|
||||||
|
import 'package:stackwallet/models/token_balance.dart';
|
||||||
import 'package:stackwallet/services/coins/coin_service.dart';
|
import 'package:stackwallet/services/coins/coin_service.dart';
|
||||||
import 'package:stackwallet/services/ethereum/ethereum_api.dart';
|
import 'package:stackwallet/services/ethereum/ethereum_api.dart';
|
||||||
import 'package:stackwallet/services/event_bus/events/global/node_connection_status_changed_event.dart';
|
import 'package:stackwallet/services/event_bus/events/global/node_connection_status_changed_event.dart';
|
||||||
|
@ -17,6 +19,7 @@ import 'package:stackwallet/services/event_bus/events/global/refresh_percent_cha
|
||||||
import 'package:stackwallet/services/event_bus/events/global/updated_in_background_event.dart';
|
import 'package:stackwallet/services/event_bus/events/global/updated_in_background_event.dart';
|
||||||
import 'package:stackwallet/services/event_bus/events/global/wallet_sync_status_changed_event.dart';
|
import 'package:stackwallet/services/event_bus/events/global/wallet_sync_status_changed_event.dart';
|
||||||
import 'package:stackwallet/services/event_bus/global_event_bus.dart';
|
import 'package:stackwallet/services/event_bus/global_event_bus.dart';
|
||||||
|
import 'package:stackwallet/services/mixins/eth_token_cache.dart';
|
||||||
import 'package:stackwallet/services/mixins/wallet_cache.dart';
|
import 'package:stackwallet/services/mixins/wallet_cache.dart';
|
||||||
import 'package:stackwallet/services/mixins/wallet_db.dart';
|
import 'package:stackwallet/services/mixins/wallet_db.dart';
|
||||||
import 'package:stackwallet/services/node_service.dart';
|
import 'package:stackwallet/services/node_service.dart';
|
||||||
|
@ -76,6 +79,26 @@ class EthereumWallet extends CoinServiceAPI with WalletCache, WalletDB {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TokenBalance getCachedTokenBalance(EthContract contract) {
|
||||||
|
final jsonString = DB.instance.get<dynamic>(
|
||||||
|
boxName: _walletId,
|
||||||
|
key: TokenCacheKeys.tokenBalance(contract.address),
|
||||||
|
) as String?;
|
||||||
|
if (jsonString == null) {
|
||||||
|
return TokenBalance(
|
||||||
|
contractAddress: contract.address,
|
||||||
|
decimalPlaces: contract.decimals,
|
||||||
|
total: 0,
|
||||||
|
spendable: 0,
|
||||||
|
blockedTotal: 0,
|
||||||
|
pendingSpendable: 0,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return TokenBalance.fromJson(
|
||||||
|
jsonString,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
// Future<void> removeTokenContract(String contractAddress) async {
|
// Future<void> removeTokenContract(String contractAddress) async {
|
||||||
// final set = getWalletTokenContractAddresses().toSet();
|
// final set = getWalletTokenContractAddresses().toSet();
|
||||||
// set.removeWhere((e) => e == contractAddress);
|
// set.removeWhere((e) => e == contractAddress);
|
||||||
|
|
|
@ -2,7 +2,7 @@ import 'package:stackwallet/db/hive/db.dart';
|
||||||
import 'package:stackwallet/models/isar/models/ethereum/eth_contract.dart';
|
import 'package:stackwallet/models/isar/models/ethereum/eth_contract.dart';
|
||||||
import 'package:stackwallet/models/token_balance.dart';
|
import 'package:stackwallet/models/token_balance.dart';
|
||||||
|
|
||||||
abstract class _Keys {
|
abstract class TokenCacheKeys {
|
||||||
static String tokenBalance(String contractAddress) {
|
static String tokenBalance(String contractAddress) {
|
||||||
return "tokenBalanceCache_$contractAddress";
|
return "tokenBalanceCache_$contractAddress";
|
||||||
}
|
}
|
||||||
|
@ -21,7 +21,7 @@ mixin EthTokenCache {
|
||||||
TokenBalance getCachedBalance() {
|
TokenBalance getCachedBalance() {
|
||||||
final jsonString = DB.instance.get<dynamic>(
|
final jsonString = DB.instance.get<dynamic>(
|
||||||
boxName: _walletId,
|
boxName: _walletId,
|
||||||
key: _Keys.tokenBalance(_token.address),
|
key: TokenCacheKeys.tokenBalance(_token.address),
|
||||||
) as String?;
|
) as String?;
|
||||||
if (jsonString == null) {
|
if (jsonString == null) {
|
||||||
return TokenBalance(
|
return TokenBalance(
|
||||||
|
@ -41,7 +41,7 @@ mixin EthTokenCache {
|
||||||
Future<void> updateCachedBalance(TokenBalance balance) async {
|
Future<void> updateCachedBalance(TokenBalance balance) async {
|
||||||
await DB.instance.put<dynamic>(
|
await DB.instance.put<dynamic>(
|
||||||
boxName: _walletId,
|
boxName: _walletId,
|
||||||
key: _Keys.tokenBalance(_token.address),
|
key: TokenCacheKeys.tokenBalance(_token.address),
|
||||||
value: balance.toJsonIgnoreCoin(),
|
value: balance.toJsonIgnoreCoin(),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
137
lib/widgets/master_wallet_card.dart
Normal file
137
lib/widgets/master_wallet_card.dart
Normal file
|
@ -0,0 +1,137 @@
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||||
|
import 'package:flutter_svg/flutter_svg.dart';
|
||||||
|
import 'package:stackwallet/providers/providers.dart';
|
||||||
|
import 'package:stackwallet/services/coins/ethereum/ethereum_wallet.dart';
|
||||||
|
import 'package:stackwallet/utilities/assets.dart';
|
||||||
|
import 'package:stackwallet/utilities/constants.dart';
|
||||||
|
import 'package:stackwallet/utilities/theme/stack_colors.dart';
|
||||||
|
import 'package:stackwallet/widgets/animated_widgets/rotate_icon.dart';
|
||||||
|
import 'package:stackwallet/widgets/expandable.dart';
|
||||||
|
import 'package:stackwallet/widgets/rounded_white_container.dart';
|
||||||
|
import 'package:stackwallet/widgets/wallet_card.dart';
|
||||||
|
import 'package:stackwallet/widgets/wallet_info_row/wallet_info_row.dart';
|
||||||
|
|
||||||
|
class MasterWalletCard extends ConsumerStatefulWidget {
|
||||||
|
const MasterWalletCard({
|
||||||
|
Key? key,
|
||||||
|
required this.walletId,
|
||||||
|
this.popPrevious = false,
|
||||||
|
}) : super(key: key);
|
||||||
|
|
||||||
|
final String walletId;
|
||||||
|
final bool popPrevious;
|
||||||
|
|
||||||
|
@override
|
||||||
|
ConsumerState<MasterWalletCard> createState() => _MasterWalletCardState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _MasterWalletCardState extends ConsumerState<MasterWalletCard> {
|
||||||
|
final expandableController = ExpandableController();
|
||||||
|
final rotateIconController = RotateIconController();
|
||||||
|
late final List<String> tokenContractAddresses;
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
final ethWallet = ref
|
||||||
|
.read(walletsChangeNotifierProvider)
|
||||||
|
.getManager(widget.walletId)
|
||||||
|
.wallet as EthereumWallet;
|
||||||
|
|
||||||
|
tokenContractAddresses = ethWallet.getWalletTokenContractAddresses();
|
||||||
|
|
||||||
|
super.initState();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return RoundedWhiteContainer(
|
||||||
|
padding: EdgeInsets.zero,
|
||||||
|
child: Expandable(
|
||||||
|
controller: expandableController,
|
||||||
|
expandOverride: () {},
|
||||||
|
header: Padding(
|
||||||
|
padding: const EdgeInsets.all(12),
|
||||||
|
child: Row(
|
||||||
|
children: [
|
||||||
|
Expanded(
|
||||||
|
child: WalletInfoRow(
|
||||||
|
walletId: widget.walletId,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
MaterialButton(
|
||||||
|
padding: const EdgeInsets.all(5),
|
||||||
|
materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
|
||||||
|
minWidth: 32,
|
||||||
|
height: 32,
|
||||||
|
color: Theme.of(context)
|
||||||
|
.extension<StackColors>()!
|
||||||
|
.textFieldDefaultBG,
|
||||||
|
elevation: 0,
|
||||||
|
hoverElevation: 0,
|
||||||
|
disabledElevation: 0,
|
||||||
|
highlightElevation: 0,
|
||||||
|
shape: RoundedRectangleBorder(
|
||||||
|
borderRadius: BorderRadius.circular(
|
||||||
|
Constants.size.circularBorderRadius,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
onPressed: () {
|
||||||
|
if (expandableController.state == ExpandableState.collapsed) {
|
||||||
|
rotateIconController.forward?.call();
|
||||||
|
} else {
|
||||||
|
rotateIconController.reverse?.call();
|
||||||
|
}
|
||||||
|
expandableController.toggle?.call();
|
||||||
|
},
|
||||||
|
child: RotateIcon(
|
||||||
|
controller: rotateIconController,
|
||||||
|
icon: SvgPicture.asset(
|
||||||
|
Assets.svg.chevronDown,
|
||||||
|
width: 14,
|
||||||
|
),
|
||||||
|
curve: Curves.easeInOut,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
body: ListView(
|
||||||
|
shrinkWrap: true,
|
||||||
|
primary: false,
|
||||||
|
children: [
|
||||||
|
Container(
|
||||||
|
width: double.infinity,
|
||||||
|
height: 1.5,
|
||||||
|
color:
|
||||||
|
Theme.of(context).extension<StackColors>()!.backgroundAppBar,
|
||||||
|
),
|
||||||
|
Padding(
|
||||||
|
padding: const EdgeInsets.all(
|
||||||
|
7,
|
||||||
|
),
|
||||||
|
child: WalletSheetCard(
|
||||||
|
walletId: widget.walletId,
|
||||||
|
popPrevious: true,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
...tokenContractAddresses.map(
|
||||||
|
(e) => Padding(
|
||||||
|
padding: const EdgeInsets.only(
|
||||||
|
left: 7,
|
||||||
|
right: 7,
|
||||||
|
bottom: 7,
|
||||||
|
),
|
||||||
|
child: WalletSheetCard(
|
||||||
|
walletId: widget.walletId,
|
||||||
|
contractAddress: e,
|
||||||
|
// popPrevious: true,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,21 +1,33 @@
|
||||||
|
import 'dart:async';
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||||
|
import 'package:stackwallet/pages/token_view/token_view.dart';
|
||||||
import 'package:stackwallet/pages/wallet_view/wallet_view.dart';
|
import 'package:stackwallet/pages/wallet_view/wallet_view.dart';
|
||||||
|
import 'package:stackwallet/providers/db/main_db_provider.dart';
|
||||||
|
import 'package:stackwallet/providers/global/secure_store_provider.dart';
|
||||||
import 'package:stackwallet/providers/providers.dart';
|
import 'package:stackwallet/providers/providers.dart';
|
||||||
|
import 'package:stackwallet/services/coins/ethereum/ethereum_wallet.dart';
|
||||||
|
import 'package:stackwallet/services/ethereum/ethereum_token_service.dart';
|
||||||
|
import 'package:stackwallet/services/transaction_notification_tracker.dart';
|
||||||
import 'package:stackwallet/utilities/constants.dart';
|
import 'package:stackwallet/utilities/constants.dart';
|
||||||
import 'package:stackwallet/utilities/enums/coin_enum.dart';
|
import 'package:stackwallet/utilities/enums/coin_enum.dart';
|
||||||
import 'package:stackwallet/widgets/rounded_white_container.dart';
|
import 'package:stackwallet/widgets/rounded_white_container.dart';
|
||||||
import 'package:stackwallet/widgets/wallet_info_row/wallet_info_row.dart';
|
import 'package:stackwallet/widgets/wallet_info_row/wallet_info_row.dart';
|
||||||
import 'package:tuple/tuple.dart';
|
import 'package:tuple/tuple.dart';
|
||||||
|
|
||||||
|
import '../utilities/show_loading.dart';
|
||||||
|
|
||||||
class WalletSheetCard extends ConsumerWidget {
|
class WalletSheetCard extends ConsumerWidget {
|
||||||
const WalletSheetCard({
|
const WalletSheetCard({
|
||||||
Key? key,
|
Key? key,
|
||||||
required this.walletId,
|
required this.walletId,
|
||||||
|
this.contractAddress,
|
||||||
this.popPrevious = false,
|
this.popPrevious = false,
|
||||||
}) : super(key: key);
|
}) : super(key: key);
|
||||||
|
|
||||||
final String walletId;
|
final String walletId;
|
||||||
|
final String? contractAddress;
|
||||||
final bool popPrevious;
|
final bool popPrevious;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
@ -33,25 +45,56 @@ class WalletSheetCard extends ConsumerWidget {
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
onPressed: () async {
|
onPressed: () async {
|
||||||
final manager = ref
|
final manager =
|
||||||
.read(walletsChangeNotifierProvider)
|
ref.read(walletsChangeNotifierProvider).getManager(walletId);
|
||||||
.getManager(walletId);
|
if (manager.coin == Coin.monero || manager.coin == Coin.wownero) {
|
||||||
if (manager.coin == Coin.monero ||
|
|
||||||
manager.coin == Coin.wownero) {
|
|
||||||
await manager.initializeExisting();
|
await manager.initializeExisting();
|
||||||
}
|
}
|
||||||
if (popPrevious) Navigator.of(context).pop();
|
if (context.mounted) {
|
||||||
Navigator.of(context).pushNamed(
|
if (popPrevious) Navigator.of(context).pop();
|
||||||
WalletView.routeName,
|
unawaited(
|
||||||
arguments: Tuple2(
|
Navigator.of(context).pushNamed(
|
||||||
walletId,
|
WalletView.routeName,
|
||||||
ref
|
arguments: Tuple2(
|
||||||
.read(walletsChangeNotifierProvider)
|
walletId,
|
||||||
.getManagerProvider(walletId)),
|
ref
|
||||||
);
|
.read(walletsChangeNotifierProvider)
|
||||||
|
.getManagerProvider(walletId)),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
if (contractAddress != null) {
|
||||||
|
final contract = ref
|
||||||
|
.read(mainDBProvider)
|
||||||
|
.getEthContractSync(contractAddress!)!;
|
||||||
|
ref.read(tokenServiceStateProvider.state).state = EthTokenWallet(
|
||||||
|
token: contract,
|
||||||
|
secureStore: ref.read(secureStoreProvider),
|
||||||
|
ethWallet: manager.wallet as EthereumWallet,
|
||||||
|
tracker: TransactionNotificationTracker(
|
||||||
|
walletId: walletId,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
await showLoading<void>(
|
||||||
|
whileFuture: ref.read(tokenServiceProvider)!.initialize(),
|
||||||
|
context: context,
|
||||||
|
opaqueBG: true,
|
||||||
|
message: "Loading ${contract.name}",
|
||||||
|
);
|
||||||
|
|
||||||
|
if (context.mounted) {
|
||||||
|
await Navigator.of(context).pushNamed(
|
||||||
|
TokenView.routeName,
|
||||||
|
arguments: walletId,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
child: WalletInfoRow(
|
child: WalletInfoRow(
|
||||||
walletId: walletId,
|
walletId: walletId,
|
||||||
|
contractAddress: contractAddress,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
|
@ -1,20 +1,25 @@
|
||||||
import 'package:decimal/decimal.dart';
|
import 'package:decimal/decimal.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||||
|
import 'package:stackwallet/db/isar/main_db.dart';
|
||||||
import 'package:stackwallet/providers/providers.dart';
|
import 'package:stackwallet/providers/providers.dart';
|
||||||
|
import 'package:stackwallet/services/coins/ethereum/ethereum_wallet.dart';
|
||||||
import 'package:stackwallet/services/coins/firo/firo_wallet.dart';
|
import 'package:stackwallet/services/coins/firo/firo_wallet.dart';
|
||||||
import 'package:stackwallet/utilities/constants.dart';
|
|
||||||
import 'package:stackwallet/utilities/enums/coin_enum.dart';
|
import 'package:stackwallet/utilities/enums/coin_enum.dart';
|
||||||
import 'package:stackwallet/utilities/format.dart';
|
import 'package:stackwallet/utilities/format.dart';
|
||||||
import 'package:stackwallet/utilities/text_styles.dart';
|
import 'package:stackwallet/utilities/text_styles.dart';
|
||||||
import 'package:stackwallet/utilities/theme/stack_colors.dart';
|
import 'package:stackwallet/utilities/theme/stack_colors.dart';
|
||||||
import 'package:stackwallet/utilities/util.dart';
|
import 'package:stackwallet/utilities/util.dart';
|
||||||
|
|
||||||
class WalletInfoRowBalanceFuture extends ConsumerWidget {
|
class WalletInfoRowBalance extends ConsumerWidget {
|
||||||
const WalletInfoRowBalanceFuture({Key? key, required this.walletId})
|
const WalletInfoRowBalance({
|
||||||
: super(key: key);
|
Key? key,
|
||||||
|
required this.walletId,
|
||||||
|
this.contractAddress,
|
||||||
|
}) : super(key: key);
|
||||||
|
|
||||||
final String walletId;
|
final String walletId;
|
||||||
|
final String? contractAddress;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context, WidgetRef ref) {
|
Widget build(BuildContext context, WidgetRef ref) {
|
||||||
|
@ -28,18 +33,30 @@ class WalletInfoRowBalanceFuture extends ConsumerWidget {
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
Decimal balance = manager.balance.getTotal();
|
Decimal balance;
|
||||||
|
int decimals;
|
||||||
if (manager.coin == Coin.firo || manager.coin == Coin.firoTestNet) {
|
String unit;
|
||||||
balance += (manager.wallet as FiroWallet).balancePrivate.getTotal();
|
if (contractAddress == null) {
|
||||||
|
balance = manager.balance.getTotal();
|
||||||
|
if (manager.coin == Coin.firo || manager.coin == Coin.firoTestNet) {
|
||||||
|
balance += (manager.wallet as FiroWallet).balancePrivate.getTotal();
|
||||||
|
}
|
||||||
|
unit = manager.coin.ticker;
|
||||||
|
decimals = manager.coin.decimals;
|
||||||
|
} else {
|
||||||
|
final ethWallet = manager.wallet as EthereumWallet;
|
||||||
|
final contract = MainDB.instance.getEthContractSync(contractAddress!)!;
|
||||||
|
balance = ethWallet.getCachedTokenBalance(contract).getTotal();
|
||||||
|
unit = contract.symbol;
|
||||||
|
decimals = contract.decimals;
|
||||||
}
|
}
|
||||||
|
|
||||||
return Text(
|
return Text(
|
||||||
"${Format.localizedStringAsFixed(
|
"${Format.localizedStringAsFixed(
|
||||||
value: balance,
|
value: balance,
|
||||||
locale: locale,
|
locale: locale,
|
||||||
decimalPlaces: Constants.decimalPlacesForCoin(manager.coin),
|
decimalPlaces: decimals,
|
||||||
)} ${manager.coin.ticker}",
|
)} $unit",
|
||||||
style: Util.isDesktop
|
style: Util.isDesktop
|
||||||
? STextStyles.desktopTextExtraSmall(context).copyWith(
|
? STextStyles.desktopTextExtraSmall(context).copyWith(
|
||||||
color: Theme.of(context).extension<StackColors>()!.textSubtitle1,
|
color: Theme.of(context).extension<StackColors>()!.textSubtitle1,
|
||||||
|
|
|
@ -1,17 +1,41 @@
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_svg/svg.dart';
|
import 'package:flutter_svg/svg.dart';
|
||||||
|
import 'package:isar/isar.dart';
|
||||||
|
import 'package:stackwallet/models/isar/exchange_cache/currency.dart';
|
||||||
|
import 'package:stackwallet/services/exchange/change_now/change_now_exchange.dart';
|
||||||
|
import 'package:stackwallet/services/exchange/exchange_data_loading_service.dart';
|
||||||
import 'package:stackwallet/utilities/assets.dart';
|
import 'package:stackwallet/utilities/assets.dart';
|
||||||
import 'package:stackwallet/utilities/constants.dart';
|
import 'package:stackwallet/utilities/constants.dart';
|
||||||
import 'package:stackwallet/utilities/enums/coin_enum.dart';
|
import 'package:stackwallet/utilities/enums/coin_enum.dart';
|
||||||
import 'package:stackwallet/utilities/theme/stack_colors.dart';
|
import 'package:stackwallet/utilities/theme/stack_colors.dart';
|
||||||
|
|
||||||
class WalletInfoCoinIcon extends StatelessWidget {
|
class WalletInfoCoinIcon extends StatelessWidget {
|
||||||
const WalletInfoCoinIcon({Key? key, required this.coin}) : super(key: key);
|
const WalletInfoCoinIcon({
|
||||||
|
Key? key,
|
||||||
|
required this.coin,
|
||||||
|
this.contractAddress,
|
||||||
|
}) : super(key: key);
|
||||||
|
|
||||||
final Coin coin;
|
final Coin coin;
|
||||||
|
final String? contractAddress;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
|
Currency? currency;
|
||||||
|
if (contractAddress != null) {
|
||||||
|
currency = ExchangeDataLoadingService.instance.isar.currencies
|
||||||
|
.where()
|
||||||
|
.exchangeNameEqualTo(ChangeNowExchange.exchangeName)
|
||||||
|
.filter()
|
||||||
|
.tokenContractEqualTo(
|
||||||
|
contractAddress!,
|
||||||
|
caseSensitive: false,
|
||||||
|
)
|
||||||
|
.and()
|
||||||
|
.imageIsNotEmpty()
|
||||||
|
.findFirstSync();
|
||||||
|
}
|
||||||
|
|
||||||
return Container(
|
return Container(
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
color: Theme.of(context)
|
color: Theme.of(context)
|
||||||
|
@ -24,11 +48,17 @@ class WalletInfoCoinIcon extends StatelessWidget {
|
||||||
),
|
),
|
||||||
child: Padding(
|
child: Padding(
|
||||||
padding: const EdgeInsets.all(6),
|
padding: const EdgeInsets.all(6),
|
||||||
child: SvgPicture.asset(
|
child: currency != null && currency.image.isNotEmpty
|
||||||
Assets.svg.iconFor(coin: coin),
|
? SvgPicture.network(
|
||||||
width: 20,
|
currency.image,
|
||||||
height: 20,
|
width: 20,
|
||||||
),
|
height: 20,
|
||||||
|
)
|
||||||
|
: SvgPicture.asset(
|
||||||
|
Assets.svg.iconFor(coin: coin),
|
||||||
|
width: 20,
|
||||||
|
height: 20,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,9 @@
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||||
import 'package:flutter_svg/svg.dart';
|
import 'package:flutter_svg/svg.dart';
|
||||||
|
import 'package:stackwallet/models/isar/models/ethereum/eth_contract.dart';
|
||||||
|
import 'package:stackwallet/pages/token_view/sub_widgets/token_summary.dart';
|
||||||
|
import 'package:stackwallet/providers/db/main_db_provider.dart';
|
||||||
import 'package:stackwallet/providers/providers.dart';
|
import 'package:stackwallet/providers/providers.dart';
|
||||||
import 'package:stackwallet/utilities/assets.dart';
|
import 'package:stackwallet/utilities/assets.dart';
|
||||||
import 'package:stackwallet/utilities/text_styles.dart';
|
import 'package:stackwallet/utilities/text_styles.dart';
|
||||||
|
@ -14,10 +17,12 @@ class WalletInfoRow extends ConsumerWidget {
|
||||||
Key? key,
|
Key? key,
|
||||||
required this.walletId,
|
required this.walletId,
|
||||||
this.onPressedDesktop,
|
this.onPressedDesktop,
|
||||||
|
this.contractAddress,
|
||||||
this.padding = const EdgeInsets.all(0),
|
this.padding = const EdgeInsets.all(0),
|
||||||
}) : super(key: key);
|
}) : super(key: key);
|
||||||
|
|
||||||
final String walletId;
|
final String walletId;
|
||||||
|
final String? contractAddress;
|
||||||
final VoidCallback? onPressedDesktop;
|
final VoidCallback? onPressedDesktop;
|
||||||
final EdgeInsets padding;
|
final EdgeInsets padding;
|
||||||
|
|
||||||
|
@ -27,6 +32,12 @@ class WalletInfoRow extends ConsumerWidget {
|
||||||
.watch(walletsChangeNotifierProvider.notifier)
|
.watch(walletsChangeNotifierProvider.notifier)
|
||||||
.getManagerProvider(walletId));
|
.getManagerProvider(walletId));
|
||||||
|
|
||||||
|
EthContract? contract;
|
||||||
|
if (contractAddress != null) {
|
||||||
|
contract = ref.watch(mainDBProvider
|
||||||
|
.select((value) => value.getEthContractSync(contractAddress!)));
|
||||||
|
}
|
||||||
|
|
||||||
if (Util.isDesktop) {
|
if (Util.isDesktop) {
|
||||||
return MouseRegion(
|
return MouseRegion(
|
||||||
cursor: SystemMouseCursors.click,
|
cursor: SystemMouseCursors.click,
|
||||||
|
@ -42,7 +53,10 @@ class WalletInfoRow extends ConsumerWidget {
|
||||||
flex: 4,
|
flex: 4,
|
||||||
child: Row(
|
child: Row(
|
||||||
children: [
|
children: [
|
||||||
WalletInfoCoinIcon(coin: manager.coin),
|
WalletInfoCoinIcon(
|
||||||
|
coin: manager.coin,
|
||||||
|
contractAddress: contractAddress,
|
||||||
|
),
|
||||||
const SizedBox(
|
const SizedBox(
|
||||||
width: 12,
|
width: 12,
|
||||||
),
|
),
|
||||||
|
@ -60,7 +74,7 @@ class WalletInfoRow extends ConsumerWidget {
|
||||||
),
|
),
|
||||||
Expanded(
|
Expanded(
|
||||||
flex: 4,
|
flex: 4,
|
||||||
child: WalletInfoRowBalanceFuture(
|
child: WalletInfoRowBalance(
|
||||||
walletId: walletId,
|
walletId: walletId,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
@ -89,7 +103,10 @@ class WalletInfoRow extends ConsumerWidget {
|
||||||
} else {
|
} else {
|
||||||
return Row(
|
return Row(
|
||||||
children: [
|
children: [
|
||||||
WalletInfoCoinIcon(coin: manager.coin),
|
WalletInfoCoinIcon(
|
||||||
|
coin: manager.coin,
|
||||||
|
contractAddress: contractAddress,
|
||||||
|
),
|
||||||
const SizedBox(
|
const SizedBox(
|
||||||
width: 12,
|
width: 12,
|
||||||
),
|
),
|
||||||
|
@ -98,14 +115,32 @@ class WalletInfoRow extends ConsumerWidget {
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
Text(
|
contract != null
|
||||||
manager.walletName,
|
? Row(
|
||||||
style: STextStyles.titleBold12(context),
|
children: [
|
||||||
),
|
Text(
|
||||||
|
contract.name,
|
||||||
|
style: STextStyles.titleBold12(context),
|
||||||
|
),
|
||||||
|
const SizedBox(
|
||||||
|
width: 4,
|
||||||
|
),
|
||||||
|
CoinTickerTag(
|
||||||
|
walletId: walletId,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
: Text(
|
||||||
|
manager.walletName,
|
||||||
|
style: STextStyles.titleBold12(context),
|
||||||
|
),
|
||||||
const SizedBox(
|
const SizedBox(
|
||||||
height: 2,
|
height: 2,
|
||||||
),
|
),
|
||||||
WalletInfoRowBalanceFuture(walletId: walletId),
|
WalletInfoRowBalance(
|
||||||
|
walletId: walletId,
|
||||||
|
contractAddress: contractAddress,
|
||||||
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
Loading…
Reference in a new issue