mirror of
https://github.com/cypherstack/stack_wallet.git
synced 2024-11-17 17:57:40 +00:00
Merge remote-tracking branch 'stack_wallet_origin/ui-fixes' into firo/spend-mints
This commit is contained in:
commit
d883aaf602
44 changed files with 975 additions and 828 deletions
|
@ -1,17 +1,14 @@
|
||||||
import 'dart:convert';
|
import 'dart:convert';
|
||||||
|
|
||||||
import 'package:stackwallet/utilities/amount/amount.dart';
|
import 'package:stackwallet/utilities/amount/amount.dart';
|
||||||
import 'package:stackwallet/utilities/enums/coin_enum.dart';
|
|
||||||
|
|
||||||
class Balance {
|
class Balance {
|
||||||
final Coin coin;
|
|
||||||
final Amount total;
|
final Amount total;
|
||||||
final Amount spendable;
|
final Amount spendable;
|
||||||
final Amount blockedTotal;
|
final Amount blockedTotal;
|
||||||
final Amount pendingSpendable;
|
final Amount pendingSpendable;
|
||||||
|
|
||||||
Balance({
|
Balance({
|
||||||
required this.coin,
|
|
||||||
required this.total,
|
required this.total,
|
||||||
required this.spendable,
|
required this.spendable,
|
||||||
required this.blockedTotal,
|
required this.blockedTotal,
|
||||||
|
@ -25,42 +22,40 @@ class Balance {
|
||||||
"pendingSpendable": pendingSpendable.toJsonString(),
|
"pendingSpendable": pendingSpendable.toJsonString(),
|
||||||
});
|
});
|
||||||
|
|
||||||
// need to fall back to parsing from in due to cached balances being previously
|
// need to fall back to parsing from int due to cached balances being previously
|
||||||
// stored as int values instead of Amounts
|
// stored as int values instead of Amounts
|
||||||
factory Balance.fromJson(String json, Coin coin) {
|
factory Balance.fromJson(String json, int deprecatedValue) {
|
||||||
final decoded = jsonDecode(json);
|
final decoded = jsonDecode(json);
|
||||||
return Balance(
|
return Balance(
|
||||||
coin: coin,
|
|
||||||
total: decoded["total"] is String
|
total: decoded["total"] is String
|
||||||
? Amount.fromSerializedJsonString(decoded["total"] as String)
|
? Amount.fromSerializedJsonString(decoded["total"] as String)
|
||||||
: Amount(
|
: Amount(
|
||||||
rawValue: BigInt.from(decoded["total"] as int),
|
rawValue: BigInt.from(decoded["total"] as int),
|
||||||
fractionDigits: coin.decimals,
|
fractionDigits: deprecatedValue,
|
||||||
),
|
),
|
||||||
spendable: decoded["spendable"] is String
|
spendable: decoded["spendable"] is String
|
||||||
? Amount.fromSerializedJsonString(decoded["spendable"] as String)
|
? Amount.fromSerializedJsonString(decoded["spendable"] as String)
|
||||||
: Amount(
|
: Amount(
|
||||||
rawValue: BigInt.from(decoded["spendable"] as int),
|
rawValue: BigInt.from(decoded["spendable"] as int),
|
||||||
fractionDigits: coin.decimals,
|
fractionDigits: deprecatedValue,
|
||||||
),
|
),
|
||||||
blockedTotal: decoded["blockedTotal"] is String
|
blockedTotal: decoded["blockedTotal"] is String
|
||||||
? Amount.fromSerializedJsonString(decoded["blockedTotal"] as String)
|
? Amount.fromSerializedJsonString(decoded["blockedTotal"] as String)
|
||||||
: Amount(
|
: Amount(
|
||||||
rawValue: BigInt.from(decoded["blockedTotal"] as int),
|
rawValue: BigInt.from(decoded["blockedTotal"] as int),
|
||||||
fractionDigits: coin.decimals,
|
fractionDigits: deprecatedValue,
|
||||||
),
|
),
|
||||||
pendingSpendable: decoded["pendingSpendable"] is String
|
pendingSpendable: decoded["pendingSpendable"] is String
|
||||||
? Amount.fromSerializedJsonString(
|
? Amount.fromSerializedJsonString(
|
||||||
decoded["pendingSpendable"] as String)
|
decoded["pendingSpendable"] as String)
|
||||||
: Amount(
|
: Amount(
|
||||||
rawValue: BigInt.from(decoded["pendingSpendable"] as int),
|
rawValue: BigInt.from(decoded["pendingSpendable"] as int),
|
||||||
fractionDigits: coin.decimals,
|
fractionDigits: deprecatedValue,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Map<String, dynamic> toMap() => {
|
Map<String, dynamic> toMap() => {
|
||||||
"coin": coin,
|
|
||||||
"total": total,
|
"total": total,
|
||||||
"spendable": spendable,
|
"spendable": spendable,
|
||||||
"blockedTotal": blockedTotal,
|
"blockedTotal": blockedTotal,
|
||||||
|
|
|
@ -1,62 +0,0 @@
|
||||||
import 'dart:convert';
|
|
||||||
|
|
||||||
import 'package:stackwallet/models/balance.dart';
|
|
||||||
import 'package:stackwallet/utilities/amount/amount.dart';
|
|
||||||
import 'package:stackwallet/utilities/enums/coin_enum.dart';
|
|
||||||
|
|
||||||
class TokenBalance extends Balance {
|
|
||||||
TokenBalance({
|
|
||||||
required this.contractAddress,
|
|
||||||
required super.total,
|
|
||||||
required super.spendable,
|
|
||||||
required super.blockedTotal,
|
|
||||||
required super.pendingSpendable,
|
|
||||||
super.coin = Coin.ethereum,
|
|
||||||
});
|
|
||||||
|
|
||||||
final String contractAddress;
|
|
||||||
|
|
||||||
@override
|
|
||||||
String toJsonIgnoreCoin() => jsonEncode({
|
|
||||||
"contractAddress": contractAddress,
|
|
||||||
"total": total.toJsonString(),
|
|
||||||
"spendable": spendable.toJsonString(),
|
|
||||||
"blockedTotal": blockedTotal.toJsonString(),
|
|
||||||
"pendingSpendable": pendingSpendable.toJsonString(),
|
|
||||||
});
|
|
||||||
|
|
||||||
factory TokenBalance.fromJson(
|
|
||||||
String json,
|
|
||||||
int fractionDigits,
|
|
||||||
) {
|
|
||||||
final decoded = jsonDecode(json);
|
|
||||||
return TokenBalance(
|
|
||||||
contractAddress: decoded["contractAddress"] as String,
|
|
||||||
total: decoded["total"] is String
|
|
||||||
? Amount.fromSerializedJsonString(decoded["total"] as String)
|
|
||||||
: Amount(
|
|
||||||
rawValue: BigInt.from(decoded["total"] as int),
|
|
||||||
fractionDigits: fractionDigits,
|
|
||||||
),
|
|
||||||
spendable: decoded["spendable"] is String
|
|
||||||
? Amount.fromSerializedJsonString(decoded["spendable"] as String)
|
|
||||||
: Amount(
|
|
||||||
rawValue: BigInt.from(decoded["spendable"] as int),
|
|
||||||
fractionDigits: fractionDigits,
|
|
||||||
),
|
|
||||||
blockedTotal: decoded["blockedTotal"] is String
|
|
||||||
? Amount.fromSerializedJsonString(decoded["blockedTotal"] as String)
|
|
||||||
: Amount(
|
|
||||||
rawValue: BigInt.from(decoded["blockedTotal"] as int),
|
|
||||||
fractionDigits: fractionDigits,
|
|
||||||
),
|
|
||||||
pendingSpendable: decoded["pendingSpendable"] is String
|
|
||||||
? Amount.fromSerializedJsonString(
|
|
||||||
decoded["pendingSpendable"] as String)
|
|
||||||
: Amount(
|
|
||||||
rawValue: BigInt.from(decoded["pendingSpendable"] as int),
|
|
||||||
fractionDigits: fractionDigits,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -11,6 +11,7 @@ import 'package:stackwallet/pages/add_wallet_views/add_token_view/add_custom_tok
|
||||||
import 'package:stackwallet/pages/add_wallet_views/add_token_view/sub_widgets/add_token_list.dart';
|
import 'package:stackwallet/pages/add_wallet_views/add_token_view/sub_widgets/add_token_list.dart';
|
||||||
import 'package:stackwallet/pages/add_wallet_views/add_token_view/sub_widgets/add_token_list_element.dart';
|
import 'package:stackwallet/pages/add_wallet_views/add_token_view/sub_widgets/add_token_list_element.dart';
|
||||||
import 'package:stackwallet/pages/add_wallet_views/add_token_view/sub_widgets/add_token_text.dart';
|
import 'package:stackwallet/pages/add_wallet_views/add_token_view/sub_widgets/add_token_text.dart';
|
||||||
|
import 'package:stackwallet/pages/home_view/home_view.dart';
|
||||||
import 'package:stackwallet/pages_desktop_specific/desktop_home_view.dart';
|
import 'package:stackwallet/pages_desktop_specific/desktop_home_view.dart';
|
||||||
import 'package:stackwallet/providers/global/wallets_provider.dart';
|
import 'package:stackwallet/providers/global/wallets_provider.dart';
|
||||||
import 'package:stackwallet/services/coins/ethereum/ethereum_wallet.dart';
|
import 'package:stackwallet/services/coins/ethereum/ethereum_wallet.dart';
|
||||||
|
@ -97,9 +98,17 @@ class _EditWalletTokensViewState extends ConsumerState<EditWalletTokensView> {
|
||||||
if (widget.contractsToMarkSelected == null) {
|
if (widget.contractsToMarkSelected == null) {
|
||||||
Navigator.of(context).pop(42);
|
Navigator.of(context).pop(42);
|
||||||
} else {
|
} else {
|
||||||
|
if (isDesktop) {
|
||||||
Navigator.of(context).popUntil(
|
Navigator.of(context).popUntil(
|
||||||
ModalRoute.withName(DesktopHomeView.routeName),
|
ModalRoute.withName(DesktopHomeView.routeName),
|
||||||
);
|
);
|
||||||
|
} else {
|
||||||
|
await Navigator.of(context).pushNamedAndRemoveUntil(
|
||||||
|
HomeView.routeName,
|
||||||
|
(route) => false,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
if (mounted) {
|
||||||
unawaited(
|
unawaited(
|
||||||
showFloatingFlushBar(
|
showFloatingFlushBar(
|
||||||
type: FlushBarType.success,
|
type: FlushBarType.success,
|
||||||
|
@ -110,6 +119,7 @@ class _EditWalletTokensViewState extends ConsumerState<EditWalletTokensView> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Future<void> _addToken() async {
|
Future<void> _addToken() async {
|
||||||
EthContract? contract;
|
EthContract? contract;
|
||||||
|
|
|
@ -8,7 +8,7 @@ import 'package:stackwallet/utilities/theme/stack_colors.dart';
|
||||||
import 'package:stackwallet/widgets/background.dart';
|
import 'package:stackwallet/widgets/background.dart';
|
||||||
import 'package:stackwallet/widgets/custom_buttons/app_bar_icon_button.dart';
|
import 'package:stackwallet/widgets/custom_buttons/app_bar_icon_button.dart';
|
||||||
import 'package:stackwallet/widgets/rounded_white_container.dart';
|
import 'package:stackwallet/widgets/rounded_white_container.dart';
|
||||||
import 'package:stackwallet/widgets/wallet_info_row/sub_widgets/wallet_info_row_balance_future.dart';
|
import 'package:stackwallet/widgets/wallet_info_row/sub_widgets/wallet_info_row_balance.dart';
|
||||||
import 'package:stackwallet/widgets/wallet_info_row/sub_widgets/wallet_info_row_coin_icon.dart';
|
import 'package:stackwallet/widgets/wallet_info_row/sub_widgets/wallet_info_row_coin_icon.dart';
|
||||||
|
|
||||||
class ChooseFromStackView extends ConsumerStatefulWidget {
|
class ChooseFromStackView extends ConsumerStatefulWidget {
|
||||||
|
|
|
@ -21,6 +21,7 @@ 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/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/widgets/conditional_parent.dart';
|
||||||
import 'package:stackwallet/widgets/rounded_container.dart';
|
import 'package:stackwallet/widgets/rounded_container.dart';
|
||||||
import 'package:tuple/tuple.dart';
|
import 'package:tuple/tuple.dart';
|
||||||
|
|
||||||
|
@ -44,8 +45,7 @@ class TokenSummary extends ConsumerWidget {
|
||||||
return Stack(
|
return Stack(
|
||||||
children: [
|
children: [
|
||||||
RoundedContainer(
|
RoundedContainer(
|
||||||
color: const Color(0xFFE9EAFF), // todo: fix color
|
color: Theme.of(context).extension<StackColors>()!.tokenSummaryBG,
|
||||||
// color: Theme.of(context).extension<StackColors>()!.,
|
|
||||||
padding: const EdgeInsets.all(24),
|
padding: const EdgeInsets.all(24),
|
||||||
child: Column(
|
child: Column(
|
||||||
children: [
|
children: [
|
||||||
|
@ -54,7 +54,9 @@ class TokenSummary extends ConsumerWidget {
|
||||||
children: [
|
children: [
|
||||||
SvgPicture.asset(
|
SvgPicture.asset(
|
||||||
Assets.svg.walletDesktop,
|
Assets.svg.walletDesktop,
|
||||||
color: const Color(0xFF8488AB), // todo: fix color
|
color: Theme.of(context)
|
||||||
|
.extension<StackColors>()!
|
||||||
|
.tokenSummaryTextSecondary,
|
||||||
width: 12,
|
width: 12,
|
||||||
height: 12,
|
height: 12,
|
||||||
),
|
),
|
||||||
|
@ -68,7 +70,9 @@ class TokenSummary extends ConsumerWidget {
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
style: STextStyles.w500_12(context).copyWith(
|
style: STextStyles.w500_12(context).copyWith(
|
||||||
color: const Color(0xFF8488AB), // todo: fix color
|
color: Theme.of(context)
|
||||||
|
.extension<StackColors>()!
|
||||||
|
.tokenSummaryTextSecondary,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
@ -88,7 +92,11 @@ class TokenSummary extends ConsumerWidget {
|
||||||
),
|
),
|
||||||
)}"
|
)}"
|
||||||
" ${token.symbol}",
|
" ${token.symbol}",
|
||||||
style: STextStyles.pageTitleH1(context),
|
style: STextStyles.pageTitleH1(context).copyWith(
|
||||||
|
color: Theme.of(context)
|
||||||
|
.extension<StackColors>()!
|
||||||
|
.tokenSummaryTextPrimary,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
const SizedBox(
|
const SizedBox(
|
||||||
width: 10,
|
width: 10,
|
||||||
|
@ -119,7 +127,11 @@ class TokenSummary extends ConsumerWidget {
|
||||||
(value) => value.currency,
|
(value) => value.currency,
|
||||||
),
|
),
|
||||||
)}",
|
)}",
|
||||||
style: STextStyles.subtitle500(context),
|
style: STextStyles.subtitle500(context).copyWith(
|
||||||
|
color: Theme.of(context)
|
||||||
|
.extension<StackColors>()!
|
||||||
|
.tokenSummaryTextPrimary,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
const SizedBox(
|
const SizedBox(
|
||||||
height: 20,
|
height: 20,
|
||||||
|
@ -137,8 +149,13 @@ class TokenSummary extends ConsumerWidget {
|
||||||
child: WalletRefreshButton(
|
child: WalletRefreshButton(
|
||||||
walletId: walletId,
|
walletId: walletId,
|
||||||
initialSyncStatus: initialSyncStatus,
|
initialSyncStatus: initialSyncStatus,
|
||||||
tokenContractAddress: ref.watch(tokenServiceProvider
|
tokenContractAddress: ref.watch(
|
||||||
.select((value) => value!.tokenContract.address)),
|
tokenServiceProvider.select(
|
||||||
|
(value) => value!.tokenContract.address,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
overrideIconColor:
|
||||||
|
Theme.of(context).extension<StackColors>()!.topNavIconPrimary,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
@ -197,7 +214,7 @@ class TokenWalletOptions extends StatelessWidget {
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
subLabel: "Receive",
|
subLabel: "Receive",
|
||||||
iconAssetSVG: Assets.svg.receive(context),
|
iconAssetSVG: Assets.svg.arrowDownLeft,
|
||||||
),
|
),
|
||||||
const SizedBox(
|
const SizedBox(
|
||||||
width: 16,
|
width: 16,
|
||||||
|
@ -214,7 +231,7 @@ class TokenWalletOptions extends StatelessWidget {
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
subLabel: "Send",
|
subLabel: "Send",
|
||||||
iconAssetSVG: Assets.svg.send(context),
|
iconAssetSVG: Assets.svg.arrowUpRight,
|
||||||
),
|
),
|
||||||
const SizedBox(
|
const SizedBox(
|
||||||
width: 16,
|
width: 16,
|
||||||
|
@ -251,12 +268,14 @@ class TokenOptionsButton extends StatelessWidget {
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
|
final iconSize = subLabel == "Send" || subLabel == "Receive" ? 12.0 : 24.0;
|
||||||
return Column(
|
return Column(
|
||||||
mainAxisSize: MainAxisSize.min,
|
mainAxisSize: MainAxisSize.min,
|
||||||
crossAxisAlignment: CrossAxisAlignment.center,
|
crossAxisAlignment: CrossAxisAlignment.center,
|
||||||
children: [
|
children: [
|
||||||
RawMaterialButton(
|
RawMaterialButton(
|
||||||
fillColor: Theme.of(context).extension<StackColors>()!.popupBG,
|
fillColor:
|
||||||
|
Theme.of(context).extension<StackColors>()!.tokenSummaryButtonBG,
|
||||||
elevation: 0,
|
elevation: 0,
|
||||||
focusElevation: 0,
|
focusElevation: 0,
|
||||||
hoverElevation: 0,
|
hoverElevation: 0,
|
||||||
|
@ -270,11 +289,27 @@ class TokenOptionsButton extends StatelessWidget {
|
||||||
onPressed: onPressed,
|
onPressed: onPressed,
|
||||||
child: Padding(
|
child: Padding(
|
||||||
padding: const EdgeInsets.all(10),
|
padding: const EdgeInsets.all(10),
|
||||||
|
child: ConditionalParent(
|
||||||
|
condition: iconSize < 24,
|
||||||
|
builder: (child) => RoundedContainer(
|
||||||
|
padding: const EdgeInsets.all(6),
|
||||||
|
color: Theme.of(context)
|
||||||
|
.extension<StackColors>()!
|
||||||
|
.tokenSummaryIcon
|
||||||
|
.withOpacity(0.4),
|
||||||
|
radiusMultiplier: 10,
|
||||||
|
child: Center(
|
||||||
|
child: child,
|
||||||
|
),
|
||||||
|
),
|
||||||
child: SvgPicture.asset(
|
child: SvgPicture.asset(
|
||||||
iconAssetSVG,
|
iconAssetSVG,
|
||||||
color: const Color(0xFF424A97), // todo: fix color
|
color: Theme.of(context)
|
||||||
width: 24,
|
.extension<StackColors>()!
|
||||||
height: 24,
|
.tokenSummaryIcon,
|
||||||
|
width: iconSize,
|
||||||
|
height: iconSize,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
@ -283,7 +318,11 @@ class TokenOptionsButton extends StatelessWidget {
|
||||||
),
|
),
|
||||||
Text(
|
Text(
|
||||||
subLabel,
|
subLabel,
|
||||||
style: STextStyles.w500_12(context),
|
style: STextStyles.w500_12(context).copyWith(
|
||||||
|
color: Theme.of(context)
|
||||||
|
.extension<StackColors>()!
|
||||||
|
.tokenSummaryTextPrimary,
|
||||||
|
),
|
||||||
)
|
)
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
|
@ -303,12 +342,14 @@ class CoinTickerTag extends ConsumerWidget {
|
||||||
return RoundedContainer(
|
return RoundedContainer(
|
||||||
padding: const EdgeInsets.symmetric(vertical: 2, horizontal: 4),
|
padding: const EdgeInsets.symmetric(vertical: 2, horizontal: 4),
|
||||||
radiusMultiplier: 0.25,
|
radiusMultiplier: 0.25,
|
||||||
color: const Color(0xFF4D5798), // TODO: color theme for multi themes
|
color: Theme.of(context).extension<StackColors>()!.ethTagBG,
|
||||||
child: Text(
|
child: Text(
|
||||||
ref.watch(walletsChangeNotifierProvider
|
ref.watch(
|
||||||
.select((value) => value.getManager(walletId).coin.ticker)),
|
walletsChangeNotifierProvider
|
||||||
|
.select((value) => value.getManager(walletId).coin.ticker),
|
||||||
|
),
|
||||||
style: STextStyles.w600_12(context).copyWith(
|
style: STextStyles.w600_12(context).copyWith(
|
||||||
color: Colors.white, // TODO: design is wrong?
|
color: Theme.of(context).extension<StackColors>()!.ethTagText,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
|
@ -110,6 +110,9 @@ class _TokenViewState extends ConsumerState<TokenView> {
|
||||||
child: AppBarIconButton(
|
child: AppBarIconButton(
|
||||||
icon: SvgPicture.asset(
|
icon: SvgPicture.asset(
|
||||||
Assets.svg.verticalEllipsis,
|
Assets.svg.verticalEllipsis,
|
||||||
|
color: Theme.of(context)
|
||||||
|
.extension<StackColors>()!
|
||||||
|
.topNavIconPrimary,
|
||||||
),
|
),
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
// todo: context menu
|
// todo: context menu
|
||||||
|
|
|
@ -22,6 +22,7 @@ class WalletRefreshButton extends ConsumerStatefulWidget {
|
||||||
this.tokenContractAddress,
|
this.tokenContractAddress,
|
||||||
this.onPressed,
|
this.onPressed,
|
||||||
this.eventBus,
|
this.eventBus,
|
||||||
|
this.overrideIconColor,
|
||||||
}) : super(key: key);
|
}) : super(key: key);
|
||||||
|
|
||||||
final String walletId;
|
final String walletId;
|
||||||
|
@ -29,6 +30,7 @@ class WalletRefreshButton extends ConsumerStatefulWidget {
|
||||||
final String? tokenContractAddress;
|
final String? tokenContractAddress;
|
||||||
final VoidCallback? onPressed;
|
final VoidCallback? onPressed;
|
||||||
final EventBus? eventBus;
|
final EventBus? eventBus;
|
||||||
|
final Color? overrideIconColor;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
ConsumerState<WalletRefreshButton> createState() => _RefreshButtonState();
|
ConsumerState<WalletRefreshButton> createState() => _RefreshButtonState();
|
||||||
|
@ -155,11 +157,15 @@ class _RefreshButtonState extends ConsumerState<WalletRefreshButton>
|
||||||
Assets.svg.arrowRotate,
|
Assets.svg.arrowRotate,
|
||||||
width: isDesktop ? 12 : 24,
|
width: isDesktop ? 12 : 24,
|
||||||
height: isDesktop ? 12 : 24,
|
height: isDesktop ? 12 : 24,
|
||||||
color: isDesktop
|
color: widget.overrideIconColor != null
|
||||||
|
? widget.overrideIconColor!
|
||||||
|
: isDesktop
|
||||||
? Theme.of(context)
|
? Theme.of(context)
|
||||||
.extension<StackColors>()!
|
.extension<StackColors>()!
|
||||||
.textFieldDefaultSearchIconRight
|
.textFieldDefaultSearchIconRight
|
||||||
: Theme.of(context).extension<StackColors>()!.textFavoriteCard,
|
: Theme.of(context)
|
||||||
|
.extension<StackColors>()!
|
||||||
|
.textFavoriteCard,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
|
@ -1,101 +0,0 @@
|
||||||
import 'package:flutter/material.dart';
|
|
||||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
|
||||||
import 'package:stackwallet/providers/providers.dart';
|
|
||||||
import 'package:stackwallet/utilities/constants.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/widgets/wallet_card.dart';
|
|
||||||
|
|
||||||
class WalletsSheet extends ConsumerWidget {
|
|
||||||
const WalletsSheet({
|
|
||||||
Key? key,
|
|
||||||
required this.coin,
|
|
||||||
}) : super(key: key);
|
|
||||||
|
|
||||||
final Coin coin;
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context, WidgetRef ref) {
|
|
||||||
final providers = ref
|
|
||||||
.watch(walletsChangeNotifierProvider
|
|
||||||
.select((value) => value.getManagerProvidersByCoin()))
|
|
||||||
.where((e) => e.item1 == coin)
|
|
||||||
.map((e) => e.item2)
|
|
||||||
.expand((e) => e)
|
|
||||||
.toList();
|
|
||||||
|
|
||||||
final maxHeight = MediaQuery.of(context).size.height * 0.60;
|
|
||||||
|
|
||||||
return Container(
|
|
||||||
decoration: BoxDecoration(
|
|
||||||
color: Theme.of(context).extension<StackColors>()!.popupBG,
|
|
||||||
borderRadius: const BorderRadius.vertical(
|
|
||||||
top: Radius.circular(20),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
child: LimitedBox(
|
|
||||||
maxHeight: maxHeight,
|
|
||||||
child: Padding(
|
|
||||||
padding: const EdgeInsets.only(
|
|
||||||
left: 24,
|
|
||||||
right: 24,
|
|
||||||
top: 10,
|
|
||||||
bottom: 0,
|
|
||||||
),
|
|
||||||
child: Column(
|
|
||||||
mainAxisSize: MainAxisSize.min,
|
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
|
||||||
children: [
|
|
||||||
Center(
|
|
||||||
child: Container(
|
|
||||||
decoration: BoxDecoration(
|
|
||||||
color: Theme.of(context)
|
|
||||||
.extension<StackColors>()!
|
|
||||||
.textFieldDefaultBG,
|
|
||||||
borderRadius: BorderRadius.circular(
|
|
||||||
Constants.size.circularBorderRadius,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
width: 60,
|
|
||||||
height: 4,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
const SizedBox(
|
|
||||||
height: 36,
|
|
||||||
),
|
|
||||||
Text(
|
|
||||||
"${coin.prettyName} (${coin.ticker}) wallets",
|
|
||||||
style: STextStyles.pageTitleH2(context),
|
|
||||||
textAlign: TextAlign.left,
|
|
||||||
),
|
|
||||||
const SizedBox(
|
|
||||||
height: 16,
|
|
||||||
),
|
|
||||||
Flexible(
|
|
||||||
child: ListView.builder(
|
|
||||||
shrinkWrap: true,
|
|
||||||
itemCount: providers.length,
|
|
||||||
itemBuilder: (builderContext, index) {
|
|
||||||
final walletId = ref.watch(
|
|
||||||
providers[index].select((value) => value.walletId));
|
|
||||||
return Padding(
|
|
||||||
padding: const EdgeInsets.symmetric(vertical: 4),
|
|
||||||
child: WalletSheetCard(
|
|
||||||
walletId: walletId,
|
|
||||||
popPrevious: true,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
},
|
|
||||||
),
|
|
||||||
),
|
|
||||||
const SizedBox(
|
|
||||||
height: 24,
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,73 +0,0 @@
|
||||||
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],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -4,8 +4,7 @@ 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/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_view/wallets_overview.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/amount/amount.dart';
|
import 'package:stackwallet/utilities/amount/amount.dart';
|
||||||
import 'package:stackwallet/utilities/assets.dart';
|
import 'package:stackwallet/utilities/assets.dart';
|
||||||
|
@ -46,13 +45,7 @@ class WalletListItem extends ConsumerWidget {
|
||||||
BorderRadius.circular(Constants.size.circularBorderRadius),
|
BorderRadius.circular(Constants.size.circularBorderRadius),
|
||||||
),
|
),
|
||||||
onPressed: () async {
|
onPressed: () async {
|
||||||
if (coin == Coin.ethereum) {
|
if (walletCount == 1 && 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()))
|
||||||
|
@ -77,15 +70,9 @@ class WalletListItem extends ConsumerWidget {
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
unawaited(
|
unawaited(
|
||||||
showModalBottomSheet<dynamic>(
|
Navigator.of(context).pushNamed(
|
||||||
backgroundColor: Colors.transparent,
|
WalletsOverview.routeName,
|
||||||
context: context,
|
arguments: coin,
|
||||||
shape: const RoundedRectangleBorder(
|
|
||||||
borderRadius: BorderRadius.vertical(
|
|
||||||
top: Radius.circular(20),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
builder: (_) => WalletsSheet(coin: coin),
|
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
308
lib/pages/wallets_view/wallets_overview.dart
Normal file
308
lib/pages/wallets_view/wallets_overview.dart
Normal file
|
@ -0,0 +1,308 @@
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||||
|
import 'package:flutter_svg/svg.dart';
|
||||||
|
import 'package:stackwallet/models/isar/models/ethereum/eth_contract.dart';
|
||||||
|
import 'package:stackwallet/pages_desktop_specific/my_stack_view/dialogs/desktop_expanding_wallet_card.dart';
|
||||||
|
import 'package:stackwallet/providers/db/main_db_provider.dart';
|
||||||
|
import 'package:stackwallet/providers/providers.dart';
|
||||||
|
import 'package:stackwallet/services/coins/ethereum/ethereum_wallet.dart';
|
||||||
|
import 'package:stackwallet/services/coins/manager.dart';
|
||||||
|
import 'package:stackwallet/utilities/assets.dart';
|
||||||
|
import 'package:stackwallet/utilities/constants.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/icon_widgets/x_icon.dart';
|
||||||
|
import 'package:stackwallet/widgets/master_wallet_card.dart';
|
||||||
|
import 'package:stackwallet/widgets/rounded_white_container.dart';
|
||||||
|
import 'package:stackwallet/widgets/stack_text_field.dart';
|
||||||
|
import 'package:stackwallet/widgets/textfield_icon_button.dart';
|
||||||
|
import 'package:stackwallet/widgets/wallet_card.dart';
|
||||||
|
import 'package:tuple/tuple.dart';
|
||||||
|
|
||||||
|
class WalletsOverview extends ConsumerStatefulWidget {
|
||||||
|
const WalletsOverview({
|
||||||
|
Key? key,
|
||||||
|
required this.coin,
|
||||||
|
this.navigatorState,
|
||||||
|
}) : super(key: key);
|
||||||
|
|
||||||
|
final Coin coin;
|
||||||
|
final NavigatorState? navigatorState;
|
||||||
|
|
||||||
|
static const routeName = "/walletsOverview";
|
||||||
|
|
||||||
|
@override
|
||||||
|
ConsumerState<WalletsOverview> createState() => _EthWalletsOverviewState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _EthWalletsOverviewState extends ConsumerState<WalletsOverview> {
|
||||||
|
final isDesktop = Util.isDesktop;
|
||||||
|
|
||||||
|
late final TextEditingController _searchController;
|
||||||
|
late final FocusNode searchFieldFocusNode;
|
||||||
|
|
||||||
|
String _searchString = "";
|
||||||
|
|
||||||
|
final List<Tuple2<Manager, List<EthContract>>> wallets = [];
|
||||||
|
|
||||||
|
List<Tuple2<Manager, List<EthContract>>> _filter(String searchTerm) {
|
||||||
|
if (searchTerm.isEmpty) {
|
||||||
|
return wallets;
|
||||||
|
}
|
||||||
|
|
||||||
|
final List<Tuple2<Manager, List<EthContract>>> results = [];
|
||||||
|
final term = searchTerm.toLowerCase();
|
||||||
|
|
||||||
|
for (final tuple in wallets) {
|
||||||
|
bool includeManager = false;
|
||||||
|
// search wallet name and total balance
|
||||||
|
includeManager |= _elementContains(tuple.item1.walletName, term);
|
||||||
|
includeManager |= _elementContains(
|
||||||
|
tuple.item1.balance.total.decimal.toString(),
|
||||||
|
term,
|
||||||
|
);
|
||||||
|
|
||||||
|
final List<EthContract> contracts = [];
|
||||||
|
|
||||||
|
for (final contract in tuple.item2) {
|
||||||
|
if (_elementContains(contract.name, term)) {
|
||||||
|
contracts.add(contract);
|
||||||
|
} else if (_elementContains(contract.symbol, term)) {
|
||||||
|
contracts.add(contract);
|
||||||
|
} else if (_elementContains(contract.type.name, term)) {
|
||||||
|
contracts.add(contract);
|
||||||
|
} else if (_elementContains(contract.address, term)) {
|
||||||
|
contracts.add(contract);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (includeManager || contracts.isNotEmpty) {
|
||||||
|
results.add(Tuple2(tuple.item1, contracts));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return results;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool _elementContains(String element, String term) {
|
||||||
|
return element.toLowerCase().contains(term);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
_searchController = TextEditingController();
|
||||||
|
searchFieldFocusNode = FocusNode();
|
||||||
|
|
||||||
|
final walletsData =
|
||||||
|
ref.read(walletsServiceChangeNotifierProvider).fetchWalletsData();
|
||||||
|
walletsData.removeWhere((key, value) => value.coin != widget.coin);
|
||||||
|
|
||||||
|
if (widget.coin == Coin.ethereum) {
|
||||||
|
for (final data in walletsData.values) {
|
||||||
|
final List<EthContract> contracts = [];
|
||||||
|
final manager =
|
||||||
|
ref.read(walletsChangeNotifierProvider).getManager(data.walletId);
|
||||||
|
final contractAddresses = (manager.wallet as EthereumWallet)
|
||||||
|
.getWalletTokenContractAddresses();
|
||||||
|
|
||||||
|
// fetch each contract
|
||||||
|
for (final contractAddress in contractAddresses) {
|
||||||
|
final contract = ref
|
||||||
|
.read(
|
||||||
|
mainDBProvider,
|
||||||
|
)
|
||||||
|
.getEthContractSync(
|
||||||
|
contractAddress,
|
||||||
|
);
|
||||||
|
|
||||||
|
// add it to list if it exists in DB
|
||||||
|
if (contract != null) {
|
||||||
|
contracts.add(contract);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// add tuple to list
|
||||||
|
wallets.add(
|
||||||
|
Tuple2(
|
||||||
|
ref.read(walletsChangeNotifierProvider).getManager(
|
||||||
|
data.walletId,
|
||||||
|
),
|
||||||
|
contracts,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// add non token wallet tuple to list
|
||||||
|
for (final data in walletsData.values) {
|
||||||
|
wallets.add(
|
||||||
|
Tuple2(
|
||||||
|
ref.read(walletsChangeNotifierProvider).getManager(
|
||||||
|
data.walletId,
|
||||||
|
),
|
||||||
|
[],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
super.initState();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void dispose() {
|
||||||
|
_searchController.dispose();
|
||||||
|
searchFieldFocusNode.dispose();
|
||||||
|
super.dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
@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(
|
||||||
|
"${widget.coin.prettyName} (${widget.coin.ticker}) wallets",
|
||||||
|
style: STextStyles.navBarTitle(context),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
body: SafeArea(
|
||||||
|
child: Padding(
|
||||||
|
padding: const EdgeInsets.all(16),
|
||||||
|
child: child,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
child: Column(
|
||||||
|
children: [
|
||||||
|
ClipRRect(
|
||||||
|
borderRadius: BorderRadius.circular(
|
||||||
|
Constants.size.circularBorderRadius,
|
||||||
|
),
|
||||||
|
child: TextField(
|
||||||
|
autocorrect: !isDesktop,
|
||||||
|
enableSuggestions: !isDesktop,
|
||||||
|
controller: _searchController,
|
||||||
|
focusNode: searchFieldFocusNode,
|
||||||
|
onChanged: (value) {
|
||||||
|
setState(() {
|
||||||
|
_searchString = value;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
style: isDesktop
|
||||||
|
? STextStyles.desktopTextExtraSmall(context).copyWith(
|
||||||
|
color: Theme.of(context)
|
||||||
|
.extension<StackColors>()!
|
||||||
|
.textFieldActiveText,
|
||||||
|
height: 1.8,
|
||||||
|
)
|
||||||
|
: STextStyles.field(context),
|
||||||
|
decoration: standardInputDecoration(
|
||||||
|
"Search...",
|
||||||
|
searchFieldFocusNode,
|
||||||
|
context,
|
||||||
|
desktopMed: isDesktop,
|
||||||
|
).copyWith(
|
||||||
|
prefixIcon: Padding(
|
||||||
|
padding: EdgeInsets.symmetric(
|
||||||
|
horizontal: isDesktop ? 12 : 10,
|
||||||
|
vertical: isDesktop ? 18 : 16,
|
||||||
|
),
|
||||||
|
child: SvgPicture.asset(
|
||||||
|
Assets.svg.search,
|
||||||
|
width: isDesktop ? 20 : 16,
|
||||||
|
height: isDesktop ? 20 : 16,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
suffixIcon: _searchController.text.isNotEmpty
|
||||||
|
? Padding(
|
||||||
|
padding: const EdgeInsets.only(right: 0),
|
||||||
|
child: UnconstrainedBox(
|
||||||
|
child: Row(
|
||||||
|
children: [
|
||||||
|
TextFieldIconButton(
|
||||||
|
child: const XIcon(),
|
||||||
|
onTap: () async {
|
||||||
|
setState(() {
|
||||||
|
_searchController.text = "";
|
||||||
|
_searchString = "";
|
||||||
|
});
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
: null,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(
|
||||||
|
height: 16,
|
||||||
|
),
|
||||||
|
Expanded(
|
||||||
|
child: Builder(
|
||||||
|
builder: (context) {
|
||||||
|
final data = _filter(_searchString);
|
||||||
|
return ListView.separated(
|
||||||
|
itemBuilder: (_, index) {
|
||||||
|
final element = data[index];
|
||||||
|
|
||||||
|
if (element.item1.hasTokenSupport) {
|
||||||
|
if (isDesktop) {
|
||||||
|
return DesktopExpandingWalletCard(
|
||||||
|
key: Key(
|
||||||
|
"${element.item1.walletName}_${element.item2.map((e) => e.address).join()}"),
|
||||||
|
data: element,
|
||||||
|
navigatorState: widget.navigatorState!,
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
return MasterWalletCard(
|
||||||
|
walletId: element.item1.walletId,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return ConditionalParent(
|
||||||
|
condition: isDesktop,
|
||||||
|
builder: (child) => RoundedWhiteContainer(
|
||||||
|
padding: const EdgeInsets.symmetric(
|
||||||
|
vertical: 14,
|
||||||
|
horizontal: 20,
|
||||||
|
),
|
||||||
|
borderColor: Theme.of(context)
|
||||||
|
.extension<StackColors>()!
|
||||||
|
.backgroundAppBar,
|
||||||
|
child: child,
|
||||||
|
),
|
||||||
|
child: SimpleWalletCard(
|
||||||
|
walletId: element.item1.walletId,
|
||||||
|
popPrevious: isDesktop,
|
||||||
|
desktopNavigatorState:
|
||||||
|
isDesktop ? widget.navigatorState : null,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
separatorBuilder: (_, __) => SizedBox(
|
||||||
|
height: isDesktop ? 10 : 8,
|
||||||
|
),
|
||||||
|
itemCount: data.length,
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,435 +0,0 @@
|
||||||
import 'package:flutter/material.dart';
|
|
||||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
|
||||||
import 'package:flutter_svg/flutter_svg.dart';
|
|
||||||
import 'package:flutter_svg/svg.dart';
|
|
||||||
import 'package:stackwallet/models/isar/models/ethereum/eth_contract.dart';
|
|
||||||
import 'package:stackwallet/providers/db/main_db_provider.dart';
|
|
||||||
import 'package:stackwallet/providers/providers.dart';
|
|
||||||
import 'package:stackwallet/services/coins/ethereum/ethereum_wallet.dart';
|
|
||||||
import 'package:stackwallet/services/coins/manager.dart';
|
|
||||||
import 'package:stackwallet/utilities/assets.dart';
|
|
||||||
import 'package:stackwallet/utilities/constants.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/animated_widgets/rotate_icon.dart';
|
|
||||||
import 'package:stackwallet/widgets/expandable.dart';
|
|
||||||
import 'package:stackwallet/widgets/icon_widgets/x_icon.dart';
|
|
||||||
import 'package:stackwallet/widgets/rounded_white_container.dart';
|
|
||||||
import 'package:stackwallet/widgets/stack_text_field.dart';
|
|
||||||
import 'package:stackwallet/widgets/textfield_icon_button.dart';
|
|
||||||
import 'package:stackwallet/widgets/wallet_card.dart';
|
|
||||||
import 'package:stackwallet/widgets/wallet_info_row/sub_widgets/wallet_info_row_balance_future.dart';
|
|
||||||
import 'package:stackwallet/widgets/wallet_info_row/sub_widgets/wallet_info_row_coin_icon.dart';
|
|
||||||
import 'package:tuple/tuple.dart';
|
|
||||||
|
|
||||||
class DesktopCoinWalletsDialog extends ConsumerStatefulWidget {
|
|
||||||
const DesktopCoinWalletsDialog({
|
|
||||||
Key? key,
|
|
||||||
required this.coin,
|
|
||||||
required this.navigatorState,
|
|
||||||
}) : super(key: key);
|
|
||||||
|
|
||||||
final Coin coin;
|
|
||||||
final NavigatorState navigatorState;
|
|
||||||
|
|
||||||
@override
|
|
||||||
ConsumerState<DesktopCoinWalletsDialog> createState() =>
|
|
||||||
_DesktopCoinWalletsDialogState();
|
|
||||||
}
|
|
||||||
|
|
||||||
class _DesktopCoinWalletsDialogState
|
|
||||||
extends ConsumerState<DesktopCoinWalletsDialog> {
|
|
||||||
final isDesktop = Util.isDesktop;
|
|
||||||
|
|
||||||
late final TextEditingController _searchController;
|
|
||||||
late final FocusNode searchFieldFocusNode;
|
|
||||||
|
|
||||||
String _searchString = "";
|
|
||||||
|
|
||||||
final List<Tuple2<Manager, List<EthContract>>> wallets = [];
|
|
||||||
|
|
||||||
List<Tuple2<Manager, List<EthContract>>> _filter(String searchTerm) {
|
|
||||||
if (searchTerm.isEmpty) {
|
|
||||||
return wallets;
|
|
||||||
}
|
|
||||||
|
|
||||||
final List<Tuple2<Manager, List<EthContract>>> results = [];
|
|
||||||
final term = searchTerm.toLowerCase();
|
|
||||||
|
|
||||||
for (final tuple in wallets) {
|
|
||||||
bool includeManager = false;
|
|
||||||
// search wallet name and total balance
|
|
||||||
includeManager |= _elementContains(tuple.item1.walletName, term);
|
|
||||||
includeManager |= _elementContains(
|
|
||||||
tuple.item1.balance.total.decimal.toString(),
|
|
||||||
term,
|
|
||||||
);
|
|
||||||
|
|
||||||
final List<EthContract> contracts = [];
|
|
||||||
|
|
||||||
for (final contract in tuple.item2) {
|
|
||||||
if (_elementContains(contract.name, term)) {
|
|
||||||
contracts.add(contract);
|
|
||||||
} else if (_elementContains(contract.symbol, term)) {
|
|
||||||
contracts.add(contract);
|
|
||||||
} else if (_elementContains(contract.type.name, term)) {
|
|
||||||
contracts.add(contract);
|
|
||||||
} else if (_elementContains(contract.address, term)) {
|
|
||||||
contracts.add(contract);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (includeManager || contracts.isNotEmpty) {
|
|
||||||
results.add(Tuple2(tuple.item1, contracts));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return results;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool _elementContains(String element, String term) {
|
|
||||||
return element.toLowerCase().contains(term);
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
void initState() {
|
|
||||||
_searchController = TextEditingController();
|
|
||||||
searchFieldFocusNode = FocusNode();
|
|
||||||
|
|
||||||
final walletsData =
|
|
||||||
ref.read(walletsServiceChangeNotifierProvider).fetchWalletsData();
|
|
||||||
walletsData.removeWhere((key, value) => value.coin != widget.coin);
|
|
||||||
|
|
||||||
if (widget.coin == Coin.ethereum) {
|
|
||||||
for (final data in walletsData.values) {
|
|
||||||
final List<EthContract> contracts = [];
|
|
||||||
final manager =
|
|
||||||
ref.read(walletsChangeNotifierProvider).getManager(data.walletId);
|
|
||||||
final contractAddresses = (manager.wallet as EthereumWallet)
|
|
||||||
.getWalletTokenContractAddresses();
|
|
||||||
|
|
||||||
// fetch each contract
|
|
||||||
for (final contractAddress in contractAddresses) {
|
|
||||||
final contract = ref
|
|
||||||
.read(
|
|
||||||
mainDBProvider,
|
|
||||||
)
|
|
||||||
.getEthContractSync(
|
|
||||||
contractAddress,
|
|
||||||
);
|
|
||||||
|
|
||||||
// add it to list if it exists in DB
|
|
||||||
if (contract != null) {
|
|
||||||
contracts.add(contract);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// add tuple to list
|
|
||||||
wallets.add(
|
|
||||||
Tuple2(
|
|
||||||
ref.read(walletsChangeNotifierProvider).getManager(
|
|
||||||
data.walletId,
|
|
||||||
),
|
|
||||||
contracts,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// add non token wallet tuple to list
|
|
||||||
for (final data in walletsData.values) {
|
|
||||||
wallets.add(
|
|
||||||
Tuple2(
|
|
||||||
ref.read(walletsChangeNotifierProvider).getManager(
|
|
||||||
data.walletId,
|
|
||||||
),
|
|
||||||
[],
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
super.initState();
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
void dispose() {
|
|
||||||
_searchController.dispose();
|
|
||||||
searchFieldFocusNode.dispose();
|
|
||||||
super.dispose();
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
return Column(
|
|
||||||
children: [
|
|
||||||
ClipRRect(
|
|
||||||
borderRadius: BorderRadius.circular(
|
|
||||||
Constants.size.circularBorderRadius,
|
|
||||||
),
|
|
||||||
child: TextField(
|
|
||||||
autocorrect: !isDesktop,
|
|
||||||
enableSuggestions: !isDesktop,
|
|
||||||
controller: _searchController,
|
|
||||||
focusNode: searchFieldFocusNode,
|
|
||||||
onChanged: (value) {
|
|
||||||
setState(() {
|
|
||||||
_searchString = value;
|
|
||||||
});
|
|
||||||
},
|
|
||||||
style: isDesktop
|
|
||||||
? STextStyles.desktopTextExtraSmall(context).copyWith(
|
|
||||||
color: Theme.of(context)
|
|
||||||
.extension<StackColors>()!
|
|
||||||
.textFieldActiveText,
|
|
||||||
height: 1.8,
|
|
||||||
)
|
|
||||||
: STextStyles.field(context),
|
|
||||||
decoration: standardInputDecoration(
|
|
||||||
"Search...",
|
|
||||||
searchFieldFocusNode,
|
|
||||||
context,
|
|
||||||
desktopMed: isDesktop,
|
|
||||||
).copyWith(
|
|
||||||
prefixIcon: Padding(
|
|
||||||
padding: EdgeInsets.symmetric(
|
|
||||||
horizontal: isDesktop ? 12 : 10,
|
|
||||||
vertical: isDesktop ? 18 : 16,
|
|
||||||
),
|
|
||||||
child: SvgPicture.asset(
|
|
||||||
Assets.svg.search,
|
|
||||||
width: isDesktop ? 20 : 16,
|
|
||||||
height: isDesktop ? 20 : 16,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
suffixIcon: _searchController.text.isNotEmpty
|
|
||||||
? Padding(
|
|
||||||
padding: const EdgeInsets.only(right: 0),
|
|
||||||
child: UnconstrainedBox(
|
|
||||||
child: Row(
|
|
||||||
children: [
|
|
||||||
TextFieldIconButton(
|
|
||||||
child: const XIcon(),
|
|
||||||
onTap: () async {
|
|
||||||
setState(() {
|
|
||||||
_searchController.text = "";
|
|
||||||
_searchString = "";
|
|
||||||
});
|
|
||||||
},
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
)
|
|
||||||
: null,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
const SizedBox(
|
|
||||||
height: 16,
|
|
||||||
),
|
|
||||||
Expanded(
|
|
||||||
child: Builder(builder: (context) {
|
|
||||||
final data = _filter(_searchString);
|
|
||||||
return ListView.separated(
|
|
||||||
itemBuilder: (_, index) => widget.coin == Coin.ethereum
|
|
||||||
? _DesktopWalletCard(
|
|
||||||
key: Key(
|
|
||||||
"${data[index].item1.walletName}_${data[index].item2.map((e) => e.address).join()}"),
|
|
||||||
data: data[index],
|
|
||||||
navigatorState: widget.navigatorState,
|
|
||||||
)
|
|
||||||
: RoundedWhiteContainer(
|
|
||||||
padding: const EdgeInsets.symmetric(
|
|
||||||
vertical: 14,
|
|
||||||
horizontal: 20,
|
|
||||||
),
|
|
||||||
borderColor: Theme.of(context)
|
|
||||||
.extension<StackColors>()!
|
|
||||||
.backgroundAppBar,
|
|
||||||
child: WalletSheetCard(
|
|
||||||
walletId: data[index].item1.walletId,
|
|
||||||
popPrevious: true,
|
|
||||||
desktopNavigatorState: widget.navigatorState,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
separatorBuilder: (_, __) => const SizedBox(
|
|
||||||
height: 10,
|
|
||||||
),
|
|
||||||
itemCount: data.length,
|
|
||||||
);
|
|
||||||
}),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class _DesktopWalletCard extends StatefulWidget {
|
|
||||||
const _DesktopWalletCard({
|
|
||||||
Key? key,
|
|
||||||
required this.data,
|
|
||||||
required this.navigatorState,
|
|
||||||
}) : super(key: key);
|
|
||||||
|
|
||||||
final Tuple2<Manager, List<EthContract>> data;
|
|
||||||
final NavigatorState navigatorState;
|
|
||||||
|
|
||||||
@override
|
|
||||||
State<_DesktopWalletCard> createState() => _DesktopWalletCardState();
|
|
||||||
}
|
|
||||||
|
|
||||||
class _DesktopWalletCardState extends State<_DesktopWalletCard> {
|
|
||||||
final expandableController = ExpandableController();
|
|
||||||
final rotateIconController = RotateIconController();
|
|
||||||
final List<String> tokenContractAddresses = [];
|
|
||||||
|
|
||||||
@override
|
|
||||||
void initState() {
|
|
||||||
if (widget.data.item1.hasTokenSupport) {
|
|
||||||
tokenContractAddresses.addAll(
|
|
||||||
widget.data.item2.map((e) => e.address),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
super.initState();
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
return RoundedWhiteContainer(
|
|
||||||
padding: EdgeInsets.zero,
|
|
||||||
borderColor: Theme.of(context).extension<StackColors>()!.backgroundAppBar,
|
|
||||||
child: Expandable(
|
|
||||||
initialState: widget.data.item1.hasTokenSupport
|
|
||||||
? ExpandableState.expanded
|
|
||||||
: ExpandableState.collapsed,
|
|
||||||
controller: expandableController,
|
|
||||||
expandOverride: () {},
|
|
||||||
header: Padding(
|
|
||||||
padding: const EdgeInsets.symmetric(
|
|
||||||
horizontal: 20,
|
|
||||||
vertical: 14,
|
|
||||||
),
|
|
||||||
child: Row(
|
|
||||||
children: [
|
|
||||||
Expanded(
|
|
||||||
child: Row(
|
|
||||||
children: [
|
|
||||||
Expanded(
|
|
||||||
flex: 2,
|
|
||||||
child: Row(
|
|
||||||
children: [
|
|
||||||
WalletInfoCoinIcon(
|
|
||||||
coin: widget.data.item1.coin,
|
|
||||||
),
|
|
||||||
const SizedBox(
|
|
||||||
width: 12,
|
|
||||||
),
|
|
||||||
Text(
|
|
||||||
widget.data.item1.walletName,
|
|
||||||
style: STextStyles.desktopTextExtraSmall(context)
|
|
||||||
.copyWith(
|
|
||||||
color: Theme.of(context)
|
|
||||||
.extension<StackColors>()!
|
|
||||||
.textDark,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
Expanded(
|
|
||||||
flex: 4,
|
|
||||||
child: WalletInfoRowBalance(
|
|
||||||
walletId: widget.data.item1.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: RotatedBox(
|
|
||||||
quarterTurns: 2,
|
|
||||||
child: SvgPicture.asset(
|
|
||||||
Assets.svg.chevronDown,
|
|
||||||
width: 14,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
curve: Curves.easeInOut,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
body: ListView(
|
|
||||||
shrinkWrap: true,
|
|
||||||
primary: false,
|
|
||||||
children: [
|
|
||||||
Container(
|
|
||||||
width: double.infinity,
|
|
||||||
height: 1,
|
|
||||||
color:
|
|
||||||
Theme.of(context).extension<StackColors>()!.backgroundAppBar,
|
|
||||||
),
|
|
||||||
Padding(
|
|
||||||
padding: const EdgeInsets.only(
|
|
||||||
left: 32,
|
|
||||||
right: 14,
|
|
||||||
top: 14,
|
|
||||||
bottom: 14,
|
|
||||||
),
|
|
||||||
child: WalletSheetCard(
|
|
||||||
walletId: widget.data.item1.walletId,
|
|
||||||
popPrevious: true,
|
|
||||||
desktopNavigatorState: widget.navigatorState,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
...tokenContractAddresses.map(
|
|
||||||
(e) => Padding(
|
|
||||||
padding: const EdgeInsets.only(
|
|
||||||
left: 32,
|
|
||||||
right: 14,
|
|
||||||
top: 14,
|
|
||||||
bottom: 14,
|
|
||||||
),
|
|
||||||
child: WalletSheetCard(
|
|
||||||
walletId: widget.data.item1.walletId,
|
|
||||||
contractAddress: e,
|
|
||||||
popPrevious: true,
|
|
||||||
desktopNavigatorState: widget.navigatorState,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -0,0 +1,192 @@
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_svg/flutter_svg.dart';
|
||||||
|
import 'package:flutter_svg/svg.dart';
|
||||||
|
import 'package:stackwallet/models/isar/models/ethereum/eth_contract.dart';
|
||||||
|
import 'package:stackwallet/services/coins/manager.dart';
|
||||||
|
import 'package:stackwallet/utilities/assets.dart';
|
||||||
|
import 'package:stackwallet/utilities/constants.dart';
|
||||||
|
import 'package:stackwallet/utilities/text_styles.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/sub_widgets/wallet_info_row_balance.dart';
|
||||||
|
import 'package:stackwallet/widgets/wallet_info_row/sub_widgets/wallet_info_row_coin_icon.dart';
|
||||||
|
import 'package:tuple/tuple.dart';
|
||||||
|
|
||||||
|
class DesktopExpandingWalletCard extends StatefulWidget {
|
||||||
|
const DesktopExpandingWalletCard({
|
||||||
|
Key? key,
|
||||||
|
required this.data,
|
||||||
|
required this.navigatorState,
|
||||||
|
}) : super(key: key);
|
||||||
|
|
||||||
|
final Tuple2<Manager, List<EthContract>> data;
|
||||||
|
final NavigatorState navigatorState;
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<DesktopExpandingWalletCard> createState() =>
|
||||||
|
_DesktopExpandingWalletCardState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _DesktopExpandingWalletCardState
|
||||||
|
extends State<DesktopExpandingWalletCard> {
|
||||||
|
final expandableController = ExpandableController();
|
||||||
|
final rotateIconController = RotateIconController();
|
||||||
|
final List<String> tokenContractAddresses = [];
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
if (widget.data.item1.hasTokenSupport) {
|
||||||
|
tokenContractAddresses.addAll(
|
||||||
|
widget.data.item2.map((e) => e.address),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
super.initState();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return RoundedWhiteContainer(
|
||||||
|
padding: EdgeInsets.zero,
|
||||||
|
borderColor: Theme.of(context).extension<StackColors>()!.backgroundAppBar,
|
||||||
|
child: Expandable(
|
||||||
|
initialState: widget.data.item1.hasTokenSupport
|
||||||
|
? ExpandableState.expanded
|
||||||
|
: ExpandableState.collapsed,
|
||||||
|
controller: expandableController,
|
||||||
|
onExpandWillChange: (toState) {
|
||||||
|
if (toState == ExpandableState.expanded) {
|
||||||
|
rotateIconController.forward?.call();
|
||||||
|
} else {
|
||||||
|
rotateIconController.reverse?.call();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
header: Padding(
|
||||||
|
padding: const EdgeInsets.symmetric(
|
||||||
|
horizontal: 20,
|
||||||
|
vertical: 14,
|
||||||
|
),
|
||||||
|
child: Row(
|
||||||
|
children: [
|
||||||
|
Expanded(
|
||||||
|
child: Row(
|
||||||
|
children: [
|
||||||
|
Expanded(
|
||||||
|
flex: 2,
|
||||||
|
child: Row(
|
||||||
|
children: [
|
||||||
|
WalletInfoCoinIcon(
|
||||||
|
coin: widget.data.item1.coin,
|
||||||
|
),
|
||||||
|
const SizedBox(
|
||||||
|
width: 12,
|
||||||
|
),
|
||||||
|
Text(
|
||||||
|
widget.data.item1.walletName,
|
||||||
|
style: STextStyles.desktopTextExtraSmall(context)
|
||||||
|
.copyWith(
|
||||||
|
color: Theme.of(context)
|
||||||
|
.extension<StackColors>()!
|
||||||
|
.textDark,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Expanded(
|
||||||
|
flex: 4,
|
||||||
|
child: WalletInfoRowBalance(
|
||||||
|
walletId: widget.data.item1.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: RotatedBox(
|
||||||
|
quarterTurns: 2,
|
||||||
|
child: SvgPicture.asset(
|
||||||
|
Assets.svg.chevronDown,
|
||||||
|
width: 14,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
curve: Curves.easeInOut,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
body: ListView(
|
||||||
|
shrinkWrap: true,
|
||||||
|
primary: false,
|
||||||
|
children: [
|
||||||
|
Container(
|
||||||
|
width: double.infinity,
|
||||||
|
height: 1,
|
||||||
|
color:
|
||||||
|
Theme.of(context).extension<StackColors>()!.backgroundAppBar,
|
||||||
|
),
|
||||||
|
Padding(
|
||||||
|
padding: const EdgeInsets.only(
|
||||||
|
left: 32,
|
||||||
|
right: 14,
|
||||||
|
top: 14,
|
||||||
|
bottom: 14,
|
||||||
|
),
|
||||||
|
child: SimpleWalletCard(
|
||||||
|
walletId: widget.data.item1.walletId,
|
||||||
|
popPrevious: true,
|
||||||
|
desktopNavigatorState: widget.navigatorState,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
...tokenContractAddresses.map(
|
||||||
|
(e) => Padding(
|
||||||
|
padding: const EdgeInsets.only(
|
||||||
|
left: 32,
|
||||||
|
right: 14,
|
||||||
|
top: 14,
|
||||||
|
bottom: 14,
|
||||||
|
),
|
||||||
|
child: SimpleWalletCard(
|
||||||
|
walletId: widget.data.item1.walletId,
|
||||||
|
contractAddress: e,
|
||||||
|
popPrevious: true,
|
||||||
|
desktopNavigatorState: widget.navigatorState,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,7 +1,7 @@
|
||||||
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/pages_desktop_specific/my_stack_view/dialogs/desktop_coin_wallets_dialog.dart';
|
import 'package:stackwallet/pages/wallets_view/wallets_overview.dart';
|
||||||
import 'package:stackwallet/providers/providers.dart';
|
import 'package:stackwallet/providers/providers.dart';
|
||||||
import 'package:stackwallet/utilities/amount/amount.dart';
|
import 'package:stackwallet/utilities/amount/amount.dart';
|
||||||
import 'package:stackwallet/utilities/assets.dart';
|
import 'package:stackwallet/utilities/assets.dart';
|
||||||
|
@ -103,7 +103,7 @@ class _DesktopWalletSummaryRowState extends State<DesktopWalletSummaryRow> {
|
||||||
right: 32,
|
right: 32,
|
||||||
bottom: 32,
|
bottom: 32,
|
||||||
),
|
),
|
||||||
child: DesktopCoinWalletsDialog(
|
child: WalletsOverview(
|
||||||
coin: widget.coin,
|
coin: widget.coin,
|
||||||
navigatorState: Navigator.of(context),
|
navigatorState: Navigator.of(context),
|
||||||
),
|
),
|
||||||
|
|
|
@ -106,7 +106,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_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/addresses/desktop_wallet_addresses_view.dart';
|
import 'package:stackwallet/pages_desktop_specific/addresses/desktop_wallet_addresses_view.dart';
|
||||||
|
@ -280,14 +280,19 @@ class RouteGenerator {
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
case EthWalletsOverview.routeName:
|
case WalletsOverview.routeName:
|
||||||
|
if (args is Coin) {
|
||||||
return getRoute(
|
return getRoute(
|
||||||
shouldUseMaterialRoute: useMaterialPageRoute,
|
shouldUseMaterialRoute: useMaterialPageRoute,
|
||||||
builder: (_) => const EthWalletsOverview(),
|
builder: (_) => WalletsOverview(
|
||||||
|
coin: args,
|
||||||
|
),
|
||||||
settings: RouteSettings(
|
settings: RouteSettings(
|
||||||
name: settings.name,
|
name: settings.name,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
}
|
||||||
|
return _routeError("${settings.name} invalid args: ${args.toString()}");
|
||||||
|
|
||||||
case TokenContractDetailsView.routeName:
|
case TokenContractDetailsView.routeName:
|
||||||
if (args is Tuple2<String, String>) {
|
if (args is Tuple2<String, String>) {
|
||||||
|
|
|
@ -1978,7 +1978,6 @@ class EpicCashWallet extends CoinServiceAPI
|
||||||
(jsonBalances['amount_awaiting_finalization'] as double).toString();
|
(jsonBalances['amount_awaiting_finalization'] as double).toString();
|
||||||
|
|
||||||
_balance = Balance(
|
_balance = Balance(
|
||||||
coin: coin,
|
|
||||||
total: Amount.fromDecimal(
|
total: Amount.fromDecimal(
|
||||||
Decimal.parse(total) + Decimal.parse(awaiting),
|
Decimal.parse(total) + Decimal.parse(awaiting),
|
||||||
fractionDigits: coin.decimals,
|
fractionDigits: coin.decimals,
|
||||||
|
|
|
@ -10,7 +10,6 @@ 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';
|
||||||
|
@ -78,14 +77,13 @@ class EthereumWallet extends CoinServiceAPI with WalletCache, WalletDB {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
TokenBalance getCachedTokenBalance(EthContract contract) {
|
Balance getCachedTokenBalance(EthContract contract) {
|
||||||
final jsonString = DB.instance.get<dynamic>(
|
final jsonString = DB.instance.get<dynamic>(
|
||||||
boxName: _walletId,
|
boxName: _walletId,
|
||||||
key: TokenCacheKeys.tokenBalance(contract.address),
|
key: TokenCacheKeys.tokenBalance(contract.address),
|
||||||
) as String?;
|
) as String?;
|
||||||
if (jsonString == null) {
|
if (jsonString == null) {
|
||||||
return TokenBalance(
|
return Balance(
|
||||||
contractAddress: contract.address,
|
|
||||||
total: Amount(
|
total: Amount(
|
||||||
rawValue: BigInt.zero,
|
rawValue: BigInt.zero,
|
||||||
fractionDigits: contract.decimals,
|
fractionDigits: contract.decimals,
|
||||||
|
@ -104,7 +102,7 @@ class EthereumWallet extends CoinServiceAPI with WalletCache, WalletDB {
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
return TokenBalance.fromJson(
|
return Balance.fromJson(
|
||||||
jsonString,
|
jsonString,
|
||||||
contract.decimals,
|
contract.decimals,
|
||||||
);
|
);
|
||||||
|
@ -222,7 +220,6 @@ class EthereumWallet extends CoinServiceAPI with WalletCache, WalletDB {
|
||||||
web3.Web3Client client = getEthClient();
|
web3.Web3Client client = getEthClient();
|
||||||
web3.EtherAmount ethBalance = await client.getBalance(_credentials.address);
|
web3.EtherAmount ethBalance = await client.getBalance(_credentials.address);
|
||||||
_balance = Balance(
|
_balance = Balance(
|
||||||
coin: coin,
|
|
||||||
total: Amount(
|
total: Amount(
|
||||||
rawValue: ethBalance.getInWei,
|
rawValue: ethBalance.getInWei,
|
||||||
fractionDigits: coin.decimals,
|
fractionDigits: coin.decimals,
|
||||||
|
|
|
@ -2522,7 +2522,6 @@ class FiroWallet extends CoinServiceAPI
|
||||||
}
|
}
|
||||||
|
|
||||||
_balancePrivate = Balance(
|
_balancePrivate = Balance(
|
||||||
coin: coin,
|
|
||||||
total: Amount(
|
total: Amount(
|
||||||
rawValue:
|
rawValue:
|
||||||
BigInt.from(intLelantusBalance + unconfirmedLelantusBalance),
|
BigInt.from(intLelantusBalance + unconfirmedLelantusBalance),
|
||||||
|
@ -3810,7 +3809,6 @@ class FiroWallet extends CoinServiceAPI
|
||||||
|
|
||||||
// finally update public balance
|
// finally update public balance
|
||||||
_balance = Balance(
|
_balance = Balance(
|
||||||
coin: coin,
|
|
||||||
total: satoshiBalanceTotal,
|
total: satoshiBalanceTotal,
|
||||||
spendable: satoshiBalanceSpendable,
|
spendable: satoshiBalanceSpendable,
|
||||||
blockedTotal: satoshiBalanceBlocked,
|
blockedTotal: satoshiBalanceBlocked,
|
||||||
|
|
|
@ -747,7 +747,6 @@ class MoneroWallet extends CoinServiceAPI with WalletCache, WalletDB {
|
||||||
final total = await _totalBalance;
|
final total = await _totalBalance;
|
||||||
final available = await _availableBalance;
|
final available = await _availableBalance;
|
||||||
_balance = Balance(
|
_balance = Balance(
|
||||||
coin: coin,
|
|
||||||
total: total,
|
total: total,
|
||||||
spendable: available,
|
spendable: available,
|
||||||
blockedTotal: Amount(
|
blockedTotal: Amount(
|
||||||
|
|
|
@ -774,7 +774,6 @@ class WowneroWallet extends CoinServiceAPI with WalletCache, WalletDB {
|
||||||
final total = await _totalBalance;
|
final total = await _totalBalance;
|
||||||
final available = await _availableBalance;
|
final available = await _availableBalance;
|
||||||
_balance = Balance(
|
_balance = Balance(
|
||||||
coin: coin,
|
|
||||||
total: total,
|
total: total,
|
||||||
spendable: available,
|
spendable: available,
|
||||||
blockedTotal: Amount(
|
blockedTotal: Amount(
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
|
import 'package:stackwallet/models/balance.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/services/ethereum/ethereum_api.dart';
|
import 'package:stackwallet/services/ethereum/ethereum_api.dart';
|
||||||
import 'package:stackwallet/services/mixins/eth_token_cache.dart';
|
import 'package:stackwallet/services/mixins/eth_token_cache.dart';
|
||||||
import 'package:stackwallet/utilities/amount/amount.dart';
|
import 'package:stackwallet/utilities/amount/amount.dart';
|
||||||
|
@ -21,8 +21,7 @@ class CachedEthTokenBalance with EthTokenCache {
|
||||||
|
|
||||||
if (response.value != null) {
|
if (response.value != null) {
|
||||||
await updateCachedBalance(
|
await updateCachedBalance(
|
||||||
TokenBalance(
|
Balance(
|
||||||
contractAddress: token.address,
|
|
||||||
total: response.value!,
|
total: response.value!,
|
||||||
spendable: response.value!,
|
spendable: response.value!,
|
||||||
blockedTotal: Amount(
|
blockedTotal: Amount(
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
|
|
||||||
import 'package:decimal/decimal.dart';
|
|
||||||
import 'package:ethereum_addresses/ethereum_addresses.dart';
|
import 'package:ethereum_addresses/ethereum_addresses.dart';
|
||||||
import 'package:flutter/widgets.dart';
|
import 'package:flutter/widgets.dart';
|
||||||
import 'package:http/http.dart';
|
import 'package:http/http.dart';
|
||||||
|
@ -8,10 +7,10 @@ import 'package:isar/isar.dart';
|
||||||
import 'package:stackwallet/db/isar/main_db.dart';
|
import 'package:stackwallet/db/isar/main_db.dart';
|
||||||
import 'package:stackwallet/dto/ethereum/eth_token_tx_dto.dart';
|
import 'package:stackwallet/dto/ethereum/eth_token_tx_dto.dart';
|
||||||
import 'package:stackwallet/dto/ethereum/eth_token_tx_extra_dto.dart';
|
import 'package:stackwallet/dto/ethereum/eth_token_tx_extra_dto.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/ethereum/ethereum_wallet.dart';
|
import 'package:stackwallet/services/coins/ethereum/ethereum_wallet.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/updated_in_background_event.dart';
|
import 'package:stackwallet/services/event_bus/events/global/updated_in_background_event.dart';
|
||||||
|
@ -40,7 +39,6 @@ class EthTokenWallet extends ChangeNotifier with EthTokenCache {
|
||||||
// late web3dart.EthereumAddress _contractAddress;
|
// late web3dart.EthereumAddress _contractAddress;
|
||||||
late web3dart.EthPrivateKey _credentials;
|
late web3dart.EthPrivateKey _credentials;
|
||||||
late web3dart.DeployedContract _deployedContract;
|
late web3dart.DeployedContract _deployedContract;
|
||||||
late web3dart.ContractFunction _balanceFunction;
|
|
||||||
late web3dart.ContractFunction _sendFunction;
|
late web3dart.ContractFunction _sendFunction;
|
||||||
late web3dart.Web3Client _client;
|
late web3dart.Web3Client _client;
|
||||||
|
|
||||||
|
@ -60,8 +58,8 @@ class EthTokenWallet extends ChangeNotifier with EthTokenCache {
|
||||||
EthContract get tokenContract => _tokenContract;
|
EthContract get tokenContract => _tokenContract;
|
||||||
EthContract _tokenContract;
|
EthContract _tokenContract;
|
||||||
|
|
||||||
TokenBalance get balance => _balance ??= getCachedBalance();
|
Balance get balance => _balance ??= getCachedBalance();
|
||||||
TokenBalance? _balance;
|
Balance? _balance;
|
||||||
|
|
||||||
Coin get coin => Coin.ethereum;
|
Coin get coin => Coin.ethereum;
|
||||||
|
|
||||||
|
@ -259,12 +257,12 @@ class EthTokenWallet extends ChangeNotifier with EthTokenCache {
|
||||||
final contractAddress =
|
final contractAddress =
|
||||||
web3dart.EthereumAddress.fromHex(tokenContract.address);
|
web3dart.EthereumAddress.fromHex(tokenContract.address);
|
||||||
|
|
||||||
// if (tokenContract.abi == null) {
|
if (tokenContract.abi == null) {
|
||||||
_tokenContract = await _updateTokenABI(
|
_tokenContract = await _updateTokenABI(
|
||||||
forContract: tokenContract,
|
forContract: tokenContract,
|
||||||
usingContractAddress: contractAddress.hex,
|
usingContractAddress: contractAddress.hex,
|
||||||
);
|
);
|
||||||
// }
|
}
|
||||||
|
|
||||||
String? mnemonicString = await ethWallet.mnemonicString;
|
String? mnemonicString = await ethWallet.mnemonicString;
|
||||||
|
|
||||||
|
@ -284,7 +282,6 @@ class EthTokenWallet extends ChangeNotifier with EthTokenCache {
|
||||||
);
|
);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
_balanceFunction = _deployedContract.function('balanceOf');
|
|
||||||
_sendFunction = _deployedContract.function('transfer');
|
_sendFunction = _deployedContract.function('transfer');
|
||||||
} catch (_) {
|
} catch (_) {
|
||||||
//====================================================================
|
//====================================================================
|
||||||
|
@ -359,7 +356,6 @@ class EthTokenWallet extends ChangeNotifier with EthTokenCache {
|
||||||
contractAddress,
|
contractAddress,
|
||||||
);
|
);
|
||||||
|
|
||||||
_balanceFunction = _deployedContract.function('balanceOf');
|
|
||||||
_sendFunction = _deployedContract.function('transfer');
|
_sendFunction = _deployedContract.function('transfer');
|
||||||
|
|
||||||
_client = await getEthClient();
|
_client = await getEthClient();
|
||||||
|
@ -405,24 +401,16 @@ class EthTokenWallet extends ChangeNotifier with EthTokenCache {
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> refreshCachedBalance() async {
|
Future<void> refreshCachedBalance() async {
|
||||||
final balanceRequest = await _client.call(
|
final response = await EthereumAPI.getWalletTokenBalance(
|
||||||
contract: _deployedContract,
|
address: _credentials.address.hex,
|
||||||
function: _balanceFunction,
|
contractAddress: tokenContract.address,
|
||||||
params: [_credentials.address],
|
|
||||||
);
|
);
|
||||||
|
|
||||||
String _balance = balanceRequest.first.toString();
|
if (response.value != null) {
|
||||||
|
await updateCachedBalance(
|
||||||
final newBalance = TokenBalance(
|
Balance(
|
||||||
contractAddress: tokenContract.address,
|
total: response.value!,
|
||||||
total: Amount.fromDecimal(
|
spendable: response.value!,
|
||||||
Decimal.parse(_balance),
|
|
||||||
fractionDigits: tokenContract.decimals,
|
|
||||||
),
|
|
||||||
spendable: Amount.fromDecimal(
|
|
||||||
Decimal.parse(_balance),
|
|
||||||
fractionDigits: tokenContract.decimals,
|
|
||||||
),
|
|
||||||
blockedTotal: Amount(
|
blockedTotal: Amount(
|
||||||
rawValue: BigInt.zero,
|
rawValue: BigInt.zero,
|
||||||
fractionDigits: tokenContract.decimals,
|
fractionDigits: tokenContract.decimals,
|
||||||
|
@ -431,9 +419,15 @@ class EthTokenWallet extends ChangeNotifier with EthTokenCache {
|
||||||
rawValue: BigInt.zero,
|
rawValue: BigInt.zero,
|
||||||
fractionDigits: tokenContract.decimals,
|
fractionDigits: tokenContract.decimals,
|
||||||
),
|
),
|
||||||
|
),
|
||||||
);
|
);
|
||||||
await updateCachedBalance(newBalance);
|
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
|
} else {
|
||||||
|
Logging.instance.log(
|
||||||
|
"CachedEthTokenBalance.fetchAndUpdateCachedBalance failed: ${response.exception}",
|
||||||
|
level: LogLevel.Warning,
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<List<Transaction>> get transactions => ethWallet.db
|
Future<List<Transaction>> get transactions => ethWallet.db
|
||||||
|
|
|
@ -76,7 +76,6 @@ mixin CoinControlInterface {
|
||||||
}
|
}
|
||||||
|
|
||||||
final balance = Balance(
|
final balance = Balance(
|
||||||
coin: _coin,
|
|
||||||
total: satoshiBalanceTotal,
|
total: satoshiBalanceTotal,
|
||||||
spendable: satoshiBalanceSpendable,
|
spendable: satoshiBalanceSpendable,
|
||||||
blockedTotal: satoshiBalanceBlocked,
|
blockedTotal: satoshiBalanceBlocked,
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import 'package:stackwallet/db/hive/db.dart';
|
import 'package:stackwallet/db/hive/db.dart';
|
||||||
|
import 'package:stackwallet/models/balance.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/utilities/amount/amount.dart';
|
import 'package:stackwallet/utilities/amount/amount.dart';
|
||||||
|
|
||||||
abstract class TokenCacheKeys {
|
abstract class TokenCacheKeys {
|
||||||
|
@ -19,14 +19,13 @@ mixin EthTokenCache {
|
||||||
}
|
}
|
||||||
|
|
||||||
// token balance cache
|
// token balance cache
|
||||||
TokenBalance getCachedBalance() {
|
Balance getCachedBalance() {
|
||||||
final jsonString = DB.instance.get<dynamic>(
|
final jsonString = DB.instance.get<dynamic>(
|
||||||
boxName: _walletId,
|
boxName: _walletId,
|
||||||
key: TokenCacheKeys.tokenBalance(_token.address),
|
key: TokenCacheKeys.tokenBalance(_token.address),
|
||||||
) as String?;
|
) as String?;
|
||||||
if (jsonString == null) {
|
if (jsonString == null) {
|
||||||
return TokenBalance(
|
return Balance(
|
||||||
contractAddress: _token.address,
|
|
||||||
total: Amount(
|
total: Amount(
|
||||||
rawValue: BigInt.zero,
|
rawValue: BigInt.zero,
|
||||||
fractionDigits: _token.decimals,
|
fractionDigits: _token.decimals,
|
||||||
|
@ -45,13 +44,13 @@ mixin EthTokenCache {
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
return TokenBalance.fromJson(
|
return Balance.fromJson(
|
||||||
jsonString,
|
jsonString,
|
||||||
_token.decimals,
|
_token.decimals,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> updateCachedBalance(TokenBalance balance) async {
|
Future<void> updateCachedBalance(Balance balance) async {
|
||||||
await DB.instance.put<dynamic>(
|
await DB.instance.put<dynamic>(
|
||||||
boxName: _walletId,
|
boxName: _walletId,
|
||||||
key: TokenCacheKeys.tokenBalance(_token.address),
|
key: TokenCacheKeys.tokenBalance(_token.address),
|
||||||
|
|
|
@ -70,7 +70,6 @@ mixin WalletCache {
|
||||||
) as String?;
|
) as String?;
|
||||||
if (jsonString == null) {
|
if (jsonString == null) {
|
||||||
return Balance(
|
return Balance(
|
||||||
coin: _coin,
|
|
||||||
total: Amount(rawValue: BigInt.zero, fractionDigits: _coin.decimals),
|
total: Amount(rawValue: BigInt.zero, fractionDigits: _coin.decimals),
|
||||||
spendable:
|
spendable:
|
||||||
Amount(rawValue: BigInt.zero, fractionDigits: _coin.decimals),
|
Amount(rawValue: BigInt.zero, fractionDigits: _coin.decimals),
|
||||||
|
@ -80,7 +79,7 @@ mixin WalletCache {
|
||||||
Amount(rawValue: BigInt.zero, fractionDigits: _coin.decimals),
|
Amount(rawValue: BigInt.zero, fractionDigits: _coin.decimals),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
return Balance.fromJson(jsonString, _coin);
|
return Balance.fromJson(jsonString, _coin.decimals);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> updateCachedBalance(Balance balance) async {
|
Future<void> updateCachedBalance(Balance balance) async {
|
||||||
|
@ -99,7 +98,6 @@ mixin WalletCache {
|
||||||
) as String?;
|
) as String?;
|
||||||
if (jsonString == null) {
|
if (jsonString == null) {
|
||||||
return Balance(
|
return Balance(
|
||||||
coin: _coin,
|
|
||||||
total: Amount(rawValue: BigInt.zero, fractionDigits: _coin.decimals),
|
total: Amount(rawValue: BigInt.zero, fractionDigits: _coin.decimals),
|
||||||
spendable:
|
spendable:
|
||||||
Amount(rawValue: BigInt.zero, fractionDigits: _coin.decimals),
|
Amount(rawValue: BigInt.zero, fractionDigits: _coin.decimals),
|
||||||
|
@ -109,7 +107,7 @@ mixin WalletCache {
|
||||||
Amount(rawValue: BigInt.zero, fractionDigits: _coin.decimals),
|
Amount(rawValue: BigInt.zero, fractionDigits: _coin.decimals),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
return Balance.fromJson(jsonString, _coin);
|
return Balance.fromJson(jsonString, _coin.decimals);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> updateCachedBalanceSecondary(Balance balance) async {
|
Future<void> updateCachedBalanceSecondary(Balance balance) async {
|
||||||
|
|
|
@ -335,6 +335,26 @@ class ChanColors extends StackColorTheme {
|
||||||
@override
|
@override
|
||||||
Color get rateTypeToggleDesktopColorOff => buttonBackSecondary;
|
Color get rateTypeToggleDesktopColorOff => buttonBackSecondary;
|
||||||
|
|
||||||
|
// token view colors
|
||||||
|
@override
|
||||||
|
Color get ethTagText => const Color(0xFFFFFFFF);
|
||||||
|
@override
|
||||||
|
Color get ethTagBG => const Color(0xFF4D5798);
|
||||||
|
@override
|
||||||
|
Color get ethWalletTagText => const Color(0xFF4D5798);
|
||||||
|
@override
|
||||||
|
Color get ethWalletTagBG => const Color(0xFFF0F3FD);
|
||||||
|
@override
|
||||||
|
Color get tokenSummaryTextPrimary => const Color(0xFF232323);
|
||||||
|
@override
|
||||||
|
Color get tokenSummaryTextSecondary => const Color(0xFF8488AB);
|
||||||
|
@override
|
||||||
|
Color get tokenSummaryBG => const Color(0xFFE9EAFF);
|
||||||
|
@override
|
||||||
|
Color get tokenSummaryButtonBG => const Color(0xFFFFFFFF);
|
||||||
|
@override
|
||||||
|
Color get tokenSummaryIcon => const Color(0xFF424A97);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
BoxShadow get standardBoxShadow => BoxShadow(
|
BoxShadow get standardBoxShadow => BoxShadow(
|
||||||
color: shadow,
|
color: shadow,
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:stackwallet/utilities/enums/coin_enum.dart';
|
import 'package:stackwallet/utilities/enums/coin_enum.dart';
|
||||||
|
import 'package:stackwallet/utilities/theme/chan_colors.dart';
|
||||||
import 'package:stackwallet/utilities/theme/dark_colors.dart';
|
import 'package:stackwallet/utilities/theme/dark_colors.dart';
|
||||||
import 'package:stackwallet/utilities/theme/forest_colors.dart';
|
import 'package:stackwallet/utilities/theme/forest_colors.dart';
|
||||||
import 'package:stackwallet/utilities/theme/fruit_sorbet_colors.dart';
|
import 'package:stackwallet/utilities/theme/fruit_sorbet_colors.dart';
|
||||||
|
@ -7,9 +8,7 @@ import 'package:stackwallet/utilities/theme/light_colors.dart';
|
||||||
import 'package:stackwallet/utilities/theme/ocean_breeze_colors.dart';
|
import 'package:stackwallet/utilities/theme/ocean_breeze_colors.dart';
|
||||||
import 'package:stackwallet/utilities/theme/oled_black_colors.dart';
|
import 'package:stackwallet/utilities/theme/oled_black_colors.dart';
|
||||||
import 'package:stackwallet/utilities/theme/oled_chans_colors.dart';
|
import 'package:stackwallet/utilities/theme/oled_chans_colors.dart';
|
||||||
|
import 'package:stackwallet/utilities/theme/orange_colors.dart';
|
||||||
import 'chan_colors.dart';
|
|
||||||
import 'orange_colors.dart';
|
|
||||||
|
|
||||||
enum ThemeType {
|
enum ThemeType {
|
||||||
light,
|
light,
|
||||||
|
@ -285,6 +284,17 @@ abstract class StackColorTheme {
|
||||||
Color get rateTypeToggleDesktopColorOn;
|
Color get rateTypeToggleDesktopColorOn;
|
||||||
Color get rateTypeToggleDesktopColorOff;
|
Color get rateTypeToggleDesktopColorOff;
|
||||||
|
|
||||||
|
// token view colors
|
||||||
|
Color get ethTagText;
|
||||||
|
Color get ethTagBG;
|
||||||
|
Color get ethWalletTagText;
|
||||||
|
Color get ethWalletTagBG;
|
||||||
|
Color get tokenSummaryTextPrimary;
|
||||||
|
Color get tokenSummaryTextSecondary;
|
||||||
|
Color get tokenSummaryBG;
|
||||||
|
Color get tokenSummaryButtonBG;
|
||||||
|
Color get tokenSummaryIcon;
|
||||||
|
|
||||||
BoxShadow get standardBoxShadow;
|
BoxShadow get standardBoxShadow;
|
||||||
BoxShadow? get homeViewButtonBarBoxShadow;
|
BoxShadow? get homeViewButtonBarBoxShadow;
|
||||||
}
|
}
|
||||||
|
|
|
@ -335,6 +335,26 @@ class DarkColors extends StackColorTheme {
|
||||||
@override
|
@override
|
||||||
Color get rateTypeToggleDesktopColorOff => buttonBackSecondary;
|
Color get rateTypeToggleDesktopColorOff => buttonBackSecondary;
|
||||||
|
|
||||||
|
// token view colors
|
||||||
|
@override
|
||||||
|
Color get ethTagText => const Color(0xFFFFFFFF);
|
||||||
|
@override
|
||||||
|
Color get ethTagBG => const Color(0xFF5761A2);
|
||||||
|
@override
|
||||||
|
Color get ethWalletTagText => const Color(0xFFE7EBFF);
|
||||||
|
@override
|
||||||
|
Color get ethWalletTagBG => const Color(0xFF414868);
|
||||||
|
@override
|
||||||
|
Color get tokenSummaryTextPrimary => const Color(0xFFFFFFFF);
|
||||||
|
@override
|
||||||
|
Color get tokenSummaryTextSecondary => const Color(0xFFC9D0FF);
|
||||||
|
@override
|
||||||
|
Color get tokenSummaryBG => const Color(0xFF464C73);
|
||||||
|
@override
|
||||||
|
Color get tokenSummaryButtonBG => const Color(0xFFC9D0FF);
|
||||||
|
@override
|
||||||
|
Color get tokenSummaryIcon => const Color(0xFF252C78);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
BoxShadow get standardBoxShadow => BoxShadow(
|
BoxShadow get standardBoxShadow => BoxShadow(
|
||||||
color: shadow,
|
color: shadow,
|
||||||
|
|
|
@ -335,6 +335,26 @@ class ForestColors extends StackColorTheme {
|
||||||
@override
|
@override
|
||||||
Color get rateTypeToggleDesktopColorOff => buttonBackSecondary;
|
Color get rateTypeToggleDesktopColorOff => buttonBackSecondary;
|
||||||
|
|
||||||
|
// token view colors
|
||||||
|
@override
|
||||||
|
Color get ethTagText => const Color(0xFFFFFFFF);
|
||||||
|
@override
|
||||||
|
Color get ethTagBG => const Color(0xFF4D5798);
|
||||||
|
@override
|
||||||
|
Color get ethWalletTagText => const Color(0xFF4D5798);
|
||||||
|
@override
|
||||||
|
Color get ethWalletTagBG => const Color(0xFFEBEFFE);
|
||||||
|
@override
|
||||||
|
Color get tokenSummaryTextPrimary => const Color(0xFF232323);
|
||||||
|
@override
|
||||||
|
Color get tokenSummaryTextSecondary => const Color(0xFF4D5798);
|
||||||
|
@override
|
||||||
|
Color get tokenSummaryBG => const Color(0xFFFFFFFF);
|
||||||
|
@override
|
||||||
|
Color get tokenSummaryButtonBG => const Color(0xFFE9FBEF);
|
||||||
|
@override
|
||||||
|
Color get tokenSummaryIcon => const Color(0xFF22867A);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
BoxShadow get standardBoxShadow => BoxShadow(
|
BoxShadow get standardBoxShadow => BoxShadow(
|
||||||
color: shadow,
|
color: shadow,
|
||||||
|
|
|
@ -335,6 +335,26 @@ class FruitSorbetColors extends StackColorTheme {
|
||||||
@override
|
@override
|
||||||
Color get rateTypeToggleDesktopColorOff => popupBG;
|
Color get rateTypeToggleDesktopColorOff => popupBG;
|
||||||
|
|
||||||
|
// token view colors
|
||||||
|
@override
|
||||||
|
Color get ethTagText => const Color(0xFFFFFFFF);
|
||||||
|
@override
|
||||||
|
Color get ethTagBG => const Color(0xFF4D5798);
|
||||||
|
@override
|
||||||
|
Color get ethWalletTagText => const Color(0xFF4D5798);
|
||||||
|
@override
|
||||||
|
Color get ethWalletTagBG => const Color(0xFFEBEFFE);
|
||||||
|
@override
|
||||||
|
Color get tokenSummaryTextPrimary => const Color(0xFF232323);
|
||||||
|
@override
|
||||||
|
Color get tokenSummaryTextSecondary => const Color(0xFF4D5798);
|
||||||
|
@override
|
||||||
|
Color get tokenSummaryBG => const Color(0xFFFFF8EE);
|
||||||
|
@override
|
||||||
|
Color get tokenSummaryButtonBG => const Color(0xFFFEDED4);
|
||||||
|
@override
|
||||||
|
Color get tokenSummaryIcon => const Color(0xFFF62A45);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
BoxShadow get standardBoxShadow => BoxShadow(
|
BoxShadow get standardBoxShadow => BoxShadow(
|
||||||
color: shadow,
|
color: shadow,
|
||||||
|
|
|
@ -335,6 +335,26 @@ class LightColors extends StackColorTheme {
|
||||||
@override
|
@override
|
||||||
Color get rateTypeToggleDesktopColorOff => buttonBackSecondary;
|
Color get rateTypeToggleDesktopColorOff => buttonBackSecondary;
|
||||||
|
|
||||||
|
// token view colors
|
||||||
|
@override
|
||||||
|
Color get ethTagText => const Color(0xFFFFFFFF);
|
||||||
|
@override
|
||||||
|
Color get ethTagBG => const Color(0xFF4D5798);
|
||||||
|
@override
|
||||||
|
Color get ethWalletTagText => const Color(0xFF4D5798);
|
||||||
|
@override
|
||||||
|
Color get ethWalletTagBG => const Color(0xFFF0F3FD);
|
||||||
|
@override
|
||||||
|
Color get tokenSummaryTextPrimary => const Color(0xFF232323);
|
||||||
|
@override
|
||||||
|
Color get tokenSummaryTextSecondary => const Color(0xFF8488AB);
|
||||||
|
@override
|
||||||
|
Color get tokenSummaryBG => const Color(0xFFE9EAFF);
|
||||||
|
@override
|
||||||
|
Color get tokenSummaryButtonBG => const Color(0xFFFFFFFF);
|
||||||
|
@override
|
||||||
|
Color get tokenSummaryIcon => const Color(0xFF424A97);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
BoxShadow get standardBoxShadow => BoxShadow(
|
BoxShadow get standardBoxShadow => BoxShadow(
|
||||||
color: shadow,
|
color: shadow,
|
||||||
|
|
|
@ -342,6 +342,26 @@ class OceanBreezeColors extends StackColorTheme {
|
||||||
@override
|
@override
|
||||||
Color get rateTypeToggleDesktopColorOff => buttonBackSecondary;
|
Color get rateTypeToggleDesktopColorOff => buttonBackSecondary;
|
||||||
|
|
||||||
|
// token view colors
|
||||||
|
@override
|
||||||
|
Color get ethTagText => const Color(0xFFFFFFFF);
|
||||||
|
@override
|
||||||
|
Color get ethTagBG => const Color(0xFF4D5798);
|
||||||
|
@override
|
||||||
|
Color get ethWalletTagText => const Color(0xFF4D5798);
|
||||||
|
@override
|
||||||
|
Color get ethWalletTagBG => const Color(0xFFEBEFFE);
|
||||||
|
@override
|
||||||
|
Color get tokenSummaryTextPrimary => const Color(0xFF232323);
|
||||||
|
@override
|
||||||
|
Color get tokenSummaryTextSecondary => const Color(0xFF4D5798);
|
||||||
|
@override
|
||||||
|
Color get tokenSummaryBG => const Color(0xFFFFFFFF);
|
||||||
|
@override
|
||||||
|
Color get tokenSummaryButtonBG => const Color(0xFFEDF4F9);
|
||||||
|
@override
|
||||||
|
Color get tokenSummaryIcon => const Color(0xFF197287);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
BoxShadow get standardBoxShadow => BoxShadow(
|
BoxShadow get standardBoxShadow => BoxShadow(
|
||||||
color: shadow,
|
color: shadow,
|
||||||
|
|
|
@ -338,6 +338,26 @@ class OledBlackColors extends StackColorTheme {
|
||||||
@override
|
@override
|
||||||
Color get rateTypeToggleDesktopColorOff => buttonBackSecondary;
|
Color get rateTypeToggleDesktopColorOff => buttonBackSecondary;
|
||||||
|
|
||||||
|
// token view colors
|
||||||
|
@override
|
||||||
|
Color get ethTagText => const Color(0xFFFFFFFF);
|
||||||
|
@override
|
||||||
|
Color get ethTagBG => const Color(0xFF5761A2);
|
||||||
|
@override
|
||||||
|
Color get ethWalletTagText => const Color(0xFFDEDEDE);
|
||||||
|
@override
|
||||||
|
Color get ethWalletTagBG => const Color(0xFF222539);
|
||||||
|
@override
|
||||||
|
Color get tokenSummaryTextPrimary => const Color(0xFFFFFFFF);
|
||||||
|
@override
|
||||||
|
Color get tokenSummaryTextSecondary => const Color(0xFFC9D0FF);
|
||||||
|
@override
|
||||||
|
Color get tokenSummaryBG => const Color(0xFF292D45);
|
||||||
|
@override
|
||||||
|
Color get tokenSummaryButtonBG => const Color(0xFFC9D0FF);
|
||||||
|
@override
|
||||||
|
Color get tokenSummaryIcon => const Color(0xFF252C78);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
BoxShadow get standardBoxShadow => BoxShadow(
|
BoxShadow get standardBoxShadow => BoxShadow(
|
||||||
color: shadow,
|
color: shadow,
|
||||||
|
|
|
@ -335,6 +335,26 @@ class DarkChansColors extends StackColorTheme {
|
||||||
@override
|
@override
|
||||||
Color get rateTypeToggleDesktopColorOff => buttonBackSecondary;
|
Color get rateTypeToggleDesktopColorOff => buttonBackSecondary;
|
||||||
|
|
||||||
|
// token view colors
|
||||||
|
@override
|
||||||
|
Color get ethTagText => const Color(0xFFFFFFFF);
|
||||||
|
@override
|
||||||
|
Color get ethTagBG => const Color(0xFF5761A2);
|
||||||
|
@override
|
||||||
|
Color get ethWalletTagText => const Color(0xFFDEDEDE);
|
||||||
|
@override
|
||||||
|
Color get ethWalletTagBG => const Color(0xFF222539);
|
||||||
|
@override
|
||||||
|
Color get tokenSummaryTextPrimary => const Color(0xFFFFFFFF);
|
||||||
|
@override
|
||||||
|
Color get tokenSummaryTextSecondary => const Color(0xFFC9D0FF);
|
||||||
|
@override
|
||||||
|
Color get tokenSummaryBG => const Color(0xFF292D45);
|
||||||
|
@override
|
||||||
|
Color get tokenSummaryButtonBG => const Color(0xFFC9D0FF);
|
||||||
|
@override
|
||||||
|
Color get tokenSummaryIcon => const Color(0xFF252C78);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
BoxShadow get standardBoxShadow => BoxShadow(
|
BoxShadow get standardBoxShadow => BoxShadow(
|
||||||
color: shadow,
|
color: shadow,
|
||||||
|
|
|
@ -335,6 +335,26 @@ class OrangeColors extends StackColorTheme {
|
||||||
@override
|
@override
|
||||||
Color get rateTypeToggleDesktopColorOff => buttonBackSecondary;
|
Color get rateTypeToggleDesktopColorOff => buttonBackSecondary;
|
||||||
|
|
||||||
|
// token view colors
|
||||||
|
@override
|
||||||
|
Color get ethTagText => const Color(0xFFFFFFFF);
|
||||||
|
@override
|
||||||
|
Color get ethTagBG => const Color(0xFF4D5798);
|
||||||
|
@override
|
||||||
|
Color get ethWalletTagText => const Color(0xFF4D5798);
|
||||||
|
@override
|
||||||
|
Color get ethWalletTagBG => const Color(0xFFEBEFFE);
|
||||||
|
@override
|
||||||
|
Color get tokenSummaryTextPrimary => const Color(0xFF232323);
|
||||||
|
@override
|
||||||
|
Color get tokenSummaryTextSecondary => const Color(0xFF4D5798);
|
||||||
|
@override
|
||||||
|
Color get tokenSummaryBG => const Color(0xFFFFFFFF);
|
||||||
|
@override
|
||||||
|
Color get tokenSummaryButtonBG => const Color(0xAAFFC58F);
|
||||||
|
@override
|
||||||
|
Color get tokenSummaryIcon => const Color(0xFFF36B43);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
BoxShadow get standardBoxShadow => BoxShadow(
|
BoxShadow get standardBoxShadow => BoxShadow(
|
||||||
color: shadow,
|
color: shadow,
|
||||||
|
|
|
@ -187,6 +187,17 @@ class StackColors extends ThemeExtension<StackColors> {
|
||||||
final Color rateTypeToggleDesktopColorOn;
|
final Color rateTypeToggleDesktopColorOn;
|
||||||
final Color rateTypeToggleDesktopColorOff;
|
final Color rateTypeToggleDesktopColorOff;
|
||||||
|
|
||||||
|
// token view colors
|
||||||
|
final Color ethTagText;
|
||||||
|
final Color ethTagBG;
|
||||||
|
final Color ethWalletTagText;
|
||||||
|
final Color ethWalletTagBG;
|
||||||
|
final Color tokenSummaryTextPrimary;
|
||||||
|
final Color tokenSummaryTextSecondary;
|
||||||
|
final Color tokenSummaryBG;
|
||||||
|
final Color tokenSummaryButtonBG;
|
||||||
|
final Color tokenSummaryIcon;
|
||||||
|
|
||||||
final BoxShadow standardBoxShadow;
|
final BoxShadow standardBoxShadow;
|
||||||
final BoxShadow? homeViewButtonBarBoxShadow;
|
final BoxShadow? homeViewButtonBarBoxShadow;
|
||||||
|
|
||||||
|
@ -337,6 +348,15 @@ class StackColors extends ThemeExtension<StackColors> {
|
||||||
required this.rateTypeToggleDesktopColorOff,
|
required this.rateTypeToggleDesktopColorOff,
|
||||||
required this.standardBoxShadow,
|
required this.standardBoxShadow,
|
||||||
required this.homeViewButtonBarBoxShadow,
|
required this.homeViewButtonBarBoxShadow,
|
||||||
|
required this.ethTagText,
|
||||||
|
required this.ethTagBG,
|
||||||
|
required this.ethWalletTagText,
|
||||||
|
required this.ethWalletTagBG,
|
||||||
|
required this.tokenSummaryTextPrimary,
|
||||||
|
required this.tokenSummaryTextSecondary,
|
||||||
|
required this.tokenSummaryBG,
|
||||||
|
required this.tokenSummaryButtonBG,
|
||||||
|
required this.tokenSummaryIcon,
|
||||||
});
|
});
|
||||||
|
|
||||||
factory StackColors.fromStackColorTheme(StackColorTheme colorTheme) {
|
factory StackColors.fromStackColorTheme(StackColorTheme colorTheme) {
|
||||||
|
@ -490,6 +510,15 @@ class StackColors extends ThemeExtension<StackColors> {
|
||||||
rateTypeToggleDesktopColorOff: colorTheme.rateTypeToggleDesktopColorOff,
|
rateTypeToggleDesktopColorOff: colorTheme.rateTypeToggleDesktopColorOff,
|
||||||
homeViewButtonBarBoxShadow: colorTheme.homeViewButtonBarBoxShadow,
|
homeViewButtonBarBoxShadow: colorTheme.homeViewButtonBarBoxShadow,
|
||||||
standardBoxShadow: colorTheme.standardBoxShadow,
|
standardBoxShadow: colorTheme.standardBoxShadow,
|
||||||
|
ethTagText: colorTheme.ethTagText,
|
||||||
|
ethTagBG: colorTheme.ethTagBG,
|
||||||
|
ethWalletTagText: colorTheme.ethWalletTagText,
|
||||||
|
ethWalletTagBG: colorTheme.ethWalletTagBG,
|
||||||
|
tokenSummaryTextPrimary: colorTheme.tokenSummaryTextPrimary,
|
||||||
|
tokenSummaryTextSecondary: colorTheme.tokenSummaryTextSecondary,
|
||||||
|
tokenSummaryBG: colorTheme.tokenSummaryBG,
|
||||||
|
tokenSummaryButtonBG: colorTheme.tokenSummaryButtonBG,
|
||||||
|
tokenSummaryIcon: colorTheme.tokenSummaryIcon,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -639,6 +668,15 @@ class StackColors extends ThemeExtension<StackColors> {
|
||||||
Color? rateTypeToggleColorOff,
|
Color? rateTypeToggleColorOff,
|
||||||
Color? rateTypeToggleDesktopColorOn,
|
Color? rateTypeToggleDesktopColorOn,
|
||||||
Color? rateTypeToggleDesktopColorOff,
|
Color? rateTypeToggleDesktopColorOff,
|
||||||
|
Color? ethTagText,
|
||||||
|
Color? ethTagBG,
|
||||||
|
Color? ethWalletTagText,
|
||||||
|
Color? ethWalletTagBG,
|
||||||
|
Color? tokenSummaryTextPrimary,
|
||||||
|
Color? tokenSummaryTextSecondary,
|
||||||
|
Color? tokenSummaryBG,
|
||||||
|
Color? tokenSummaryButtonBG,
|
||||||
|
Color? tokenSummaryIcon,
|
||||||
BoxShadow? homeViewButtonBarBoxShadow,
|
BoxShadow? homeViewButtonBarBoxShadow,
|
||||||
BoxShadow? standardBoxShadow,
|
BoxShadow? standardBoxShadow,
|
||||||
}) {
|
}) {
|
||||||
|
@ -833,6 +871,17 @@ class StackColors extends ThemeExtension<StackColors> {
|
||||||
rateTypeToggleDesktopColorOn ?? this.rateTypeToggleDesktopColorOn,
|
rateTypeToggleDesktopColorOn ?? this.rateTypeToggleDesktopColorOn,
|
||||||
rateTypeToggleDesktopColorOff:
|
rateTypeToggleDesktopColorOff:
|
||||||
rateTypeToggleDesktopColorOff ?? this.rateTypeToggleDesktopColorOff,
|
rateTypeToggleDesktopColorOff ?? this.rateTypeToggleDesktopColorOff,
|
||||||
|
ethTagText: ethTagText ?? this.ethTagText,
|
||||||
|
ethTagBG: ethTagBG ?? this.ethTagBG,
|
||||||
|
ethWalletTagText: ethWalletTagText ?? this.ethWalletTagText,
|
||||||
|
ethWalletTagBG: ethWalletTagBG ?? this.ethWalletTagBG,
|
||||||
|
tokenSummaryTextPrimary:
|
||||||
|
tokenSummaryTextPrimary ?? this.tokenSummaryTextPrimary,
|
||||||
|
tokenSummaryTextSecondary:
|
||||||
|
tokenSummaryTextSecondary ?? this.tokenSummaryTextSecondary,
|
||||||
|
tokenSummaryBG: tokenSummaryBG ?? this.tokenSummaryBG,
|
||||||
|
tokenSummaryButtonBG: tokenSummaryButtonBG ?? this.tokenSummaryButtonBG,
|
||||||
|
tokenSummaryIcon: tokenSummaryIcon ?? this.tokenSummaryIcon,
|
||||||
homeViewButtonBarBoxShadow:
|
homeViewButtonBarBoxShadow:
|
||||||
homeViewButtonBarBoxShadow ?? this.homeViewButtonBarBoxShadow,
|
homeViewButtonBarBoxShadow ?? this.homeViewButtonBarBoxShadow,
|
||||||
standardBoxShadow: standardBoxShadow ?? this.standardBoxShadow,
|
standardBoxShadow: standardBoxShadow ?? this.standardBoxShadow,
|
||||||
|
@ -1557,6 +1606,51 @@ class StackColors extends ThemeExtension<StackColors> {
|
||||||
other.rateTypeToggleDesktopColorOff,
|
other.rateTypeToggleDesktopColorOff,
|
||||||
t,
|
t,
|
||||||
)!,
|
)!,
|
||||||
|
ethTagText: Color.lerp(
|
||||||
|
ethTagText,
|
||||||
|
other.ethTagText,
|
||||||
|
t,
|
||||||
|
)!,
|
||||||
|
ethTagBG: Color.lerp(
|
||||||
|
ethTagBG,
|
||||||
|
other.ethTagBG,
|
||||||
|
t,
|
||||||
|
)!,
|
||||||
|
ethWalletTagText: Color.lerp(
|
||||||
|
ethWalletTagText,
|
||||||
|
other.ethWalletTagText,
|
||||||
|
t,
|
||||||
|
)!,
|
||||||
|
ethWalletTagBG: Color.lerp(
|
||||||
|
ethWalletTagBG,
|
||||||
|
other.ethWalletTagBG,
|
||||||
|
t,
|
||||||
|
)!,
|
||||||
|
tokenSummaryTextPrimary: Color.lerp(
|
||||||
|
tokenSummaryTextPrimary,
|
||||||
|
other.tokenSummaryTextPrimary,
|
||||||
|
t,
|
||||||
|
)!,
|
||||||
|
tokenSummaryTextSecondary: Color.lerp(
|
||||||
|
tokenSummaryTextSecondary,
|
||||||
|
other.tokenSummaryTextSecondary,
|
||||||
|
t,
|
||||||
|
)!,
|
||||||
|
tokenSummaryBG: Color.lerp(
|
||||||
|
tokenSummaryBG,
|
||||||
|
other.tokenSummaryBG,
|
||||||
|
t,
|
||||||
|
)!,
|
||||||
|
tokenSummaryButtonBG: Color.lerp(
|
||||||
|
tokenSummaryButtonBG,
|
||||||
|
other.tokenSummaryButtonBG,
|
||||||
|
t,
|
||||||
|
)!,
|
||||||
|
tokenSummaryIcon: Color.lerp(
|
||||||
|
tokenSummaryIcon,
|
||||||
|
other.tokenSummaryIcon,
|
||||||
|
t,
|
||||||
|
)!,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,7 @@ import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||||
import 'package:stackwallet/providers/providers.dart';
|
import 'package:stackwallet/providers/providers.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/widgets/wallet_info_row/sub_widgets/wallet_info_row_balance_future.dart';
|
import 'package:stackwallet/widgets/wallet_info_row/sub_widgets/wallet_info_row_balance.dart';
|
||||||
import 'package:stackwallet/widgets/wallet_info_row/sub_widgets/wallet_info_row_coin_icon.dart';
|
import 'package:stackwallet/widgets/wallet_info_row/sub_widgets/wallet_info_row_coin_icon.dart';
|
||||||
|
|
||||||
class EthWalletRadio extends ConsumerStatefulWidget {
|
class EthWalletRadio extends ConsumerStatefulWidget {
|
||||||
|
|
|
@ -49,7 +49,13 @@ class _MasterWalletCardState extends ConsumerState<MasterWalletCard> {
|
||||||
padding: EdgeInsets.zero,
|
padding: EdgeInsets.zero,
|
||||||
child: Expandable(
|
child: Expandable(
|
||||||
controller: expandableController,
|
controller: expandableController,
|
||||||
expandOverride: () {},
|
onExpandWillChange: (toState) {
|
||||||
|
if (toState == ExpandableState.expanded) {
|
||||||
|
rotateIconController.forward?.call();
|
||||||
|
} else {
|
||||||
|
rotateIconController.reverse?.call();
|
||||||
|
}
|
||||||
|
},
|
||||||
header: Padding(
|
header: Padding(
|
||||||
padding: const EdgeInsets.all(12),
|
padding: const EdgeInsets.all(12),
|
||||||
child: Row(
|
child: Row(
|
||||||
|
@ -110,7 +116,7 @@ class _MasterWalletCardState extends ConsumerState<MasterWalletCard> {
|
||||||
padding: const EdgeInsets.all(
|
padding: const EdgeInsets.all(
|
||||||
7,
|
7,
|
||||||
),
|
),
|
||||||
child: WalletSheetCard(
|
child: SimpleWalletCard(
|
||||||
walletId: widget.walletId,
|
walletId: widget.walletId,
|
||||||
popPrevious: true,
|
popPrevious: true,
|
||||||
),
|
),
|
||||||
|
@ -122,7 +128,7 @@ class _MasterWalletCardState extends ConsumerState<MasterWalletCard> {
|
||||||
right: 7,
|
right: 7,
|
||||||
bottom: 7,
|
bottom: 7,
|
||||||
),
|
),
|
||||||
child: WalletSheetCard(
|
child: SimpleWalletCard(
|
||||||
walletId: widget.walletId,
|
walletId: widget.walletId,
|
||||||
contractAddress: e,
|
contractAddress: e,
|
||||||
popPrevious: true,
|
popPrevious: true,
|
||||||
|
|
|
@ -21,8 +21,8 @@ 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';
|
||||||
|
|
||||||
class WalletSheetCard extends ConsumerWidget {
|
class SimpleWalletCard extends ConsumerWidget {
|
||||||
const WalletSheetCard({
|
const SimpleWalletCard({
|
||||||
Key? key,
|
Key? key,
|
||||||
required this.walletId,
|
required this.walletId,
|
||||||
this.contractAddress,
|
this.contractAddress,
|
||||||
|
@ -113,7 +113,7 @@ class WalletSheetCard extends ConsumerWidget {
|
||||||
child: MaterialButton(
|
child: MaterialButton(
|
||||||
// splashColor: Theme.of(context).extension<StackColors>()!.highlight,
|
// splashColor: Theme.of(context).extension<StackColors>()!.highlight,
|
||||||
key: Key("walletsSheetItemButtonKey_$walletId"),
|
key: Key("walletsSheetItemButtonKey_$walletId"),
|
||||||
padding: const EdgeInsets.all(5),
|
padding: const EdgeInsets.all(10),
|
||||||
materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
|
materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
|
||||||
shape: RoundedRectangleBorder(
|
shape: RoundedRectangleBorder(
|
||||||
borderRadius: BorderRadius.circular(
|
borderRadius: BorderRadius.circular(
|
||||||
|
|
|
@ -8,7 +8,7 @@ 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';
|
||||||
import 'package:stackwallet/widgets/custom_buttons/blue_text_button.dart';
|
import 'package:stackwallet/widgets/custom_buttons/blue_text_button.dart';
|
||||||
import 'package:stackwallet/widgets/wallet_info_row/sub_widgets/wallet_info_row_balance_future.dart';
|
import 'package:stackwallet/widgets/wallet_info_row/sub_widgets/wallet_info_row_balance.dart';
|
||||||
import 'package:stackwallet/widgets/wallet_info_row/sub_widgets/wallet_info_row_coin_icon.dart';
|
import 'package:stackwallet/widgets/wallet_info_row/sub_widgets/wallet_info_row_coin_icon.dart';
|
||||||
|
|
||||||
class WalletInfoRow extends ConsumerWidget {
|
class WalletInfoRow extends ConsumerWidget {
|
||||||
|
|
|
@ -84,7 +84,7 @@ void main() {
|
||||||
),
|
),
|
||||||
home: mockingjay.MockNavigatorProvider(
|
home: mockingjay.MockNavigatorProvider(
|
||||||
navigator: navigator,
|
navigator: navigator,
|
||||||
child: const WalletSheetCard(
|
child: const SimpleWalletCard(
|
||||||
walletId: "wallet id",
|
walletId: "wallet id",
|
||||||
)),
|
)),
|
||||||
),
|
),
|
||||||
|
@ -122,7 +122,7 @@ void main() {
|
||||||
mockito.when(wallets.getManagerProvider("wallet id")).thenAnswer(
|
mockito.when(wallets.getManagerProvider("wallet id")).thenAnswer(
|
||||||
(realInvocation) => ChangeNotifierProvider((ref) => manager));
|
(realInvocation) => ChangeNotifierProvider((ref) => manager));
|
||||||
|
|
||||||
const walletSheetCard = WalletSheetCard(
|
const walletSheetCard = SimpleWalletCard(
|
||||||
walletId: "wallet id",
|
walletId: "wallet id",
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
@ -15,7 +15,7 @@ import 'package:stackwallet/utilities/amount/amount.dart';
|
||||||
import 'package:stackwallet/utilities/enums/coin_enum.dart';
|
import 'package:stackwallet/utilities/enums/coin_enum.dart';
|
||||||
import 'package:stackwallet/utilities/theme/light_colors.dart';
|
import 'package:stackwallet/utilities/theme/light_colors.dart';
|
||||||
import 'package:stackwallet/utilities/theme/stack_colors.dart';
|
import 'package:stackwallet/utilities/theme/stack_colors.dart';
|
||||||
import 'package:stackwallet/widgets/wallet_info_row/sub_widgets/wallet_info_row_balance_future.dart';
|
import 'package:stackwallet/widgets/wallet_info_row/sub_widgets/wallet_info_row_balance.dart';
|
||||||
|
|
||||||
import 'wallet_info_row_balance_future_test.mocks.dart';
|
import 'wallet_info_row_balance_future_test.mocks.dart';
|
||||||
|
|
||||||
|
|
|
@ -15,7 +15,7 @@ import 'package:stackwallet/utilities/amount/amount.dart';
|
||||||
import 'package:stackwallet/utilities/enums/coin_enum.dart';
|
import 'package:stackwallet/utilities/enums/coin_enum.dart';
|
||||||
import 'package:stackwallet/utilities/theme/light_colors.dart';
|
import 'package:stackwallet/utilities/theme/light_colors.dart';
|
||||||
import 'package:stackwallet/utilities/theme/stack_colors.dart';
|
import 'package:stackwallet/utilities/theme/stack_colors.dart';
|
||||||
import 'package:stackwallet/widgets/wallet_info_row/sub_widgets/wallet_info_row_balance_future.dart';
|
import 'package:stackwallet/widgets/wallet_info_row/sub_widgets/wallet_info_row_balance.dart';
|
||||||
import 'package:stackwallet/widgets/wallet_info_row/wallet_info_row.dart';
|
import 'package:stackwallet/widgets/wallet_info_row/wallet_info_row.dart';
|
||||||
|
|
||||||
import 'wallet_info_row_test.mocks.dart';
|
import 'wallet_info_row_test.mocks.dart';
|
||||||
|
|
Loading…
Reference in a new issue