balance display update events to properly reflect changes done in coin control, as well as clean up of old future builders no longer used

This commit is contained in:
julian 2023-03-08 13:21:25 -06:00
parent 2b1d438953
commit 79dc8e5329
4 changed files with 151 additions and 237 deletions

View file

@ -48,8 +48,10 @@ class WalletSummary extends StatelessWidget {
builder: (_, ref, __) {
return Container(
decoration: BoxDecoration(
color: Theme.of(context).extension<StackColors>()!.colorForCoin(ref
.watch(managerProvider.select((value) => value.coin))),
color: Theme.of(context)
.extension<StackColors>()!
.colorForCoin(ref.watch(
managerProvider.select((value) => value.coin))),
borderRadius: BorderRadius.circular(
Constants.size.circularBorderRadius,
),
@ -112,7 +114,6 @@ class WalletSummary extends StatelessWidget {
padding: const EdgeInsets.all(16.0),
child: WalletSummaryInfo(
walletId: walletId,
managerProvider: managerProvider,
initialSyncStatus: initialSyncStatus,
),
),

View file

@ -1,3 +1,5 @@
import 'dart:async';
import 'package:decimal/decimal.dart';
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
@ -7,35 +9,32 @@ import 'package:stackwallet/pages/wallet_view/sub_widgets/wallet_refresh_button.
import 'package:stackwallet/providers/providers.dart';
import 'package:stackwallet/providers/wallet/wallet_balance_toggle_state_provider.dart';
import 'package:stackwallet/services/coins/firo/firo_wallet.dart';
import 'package:stackwallet/services/coins/manager.dart';
import 'package:stackwallet/services/event_bus/events/global/balance_refreshed_event.dart';
import 'package:stackwallet/services/event_bus/events/global/wallet_sync_status_changed_event.dart';
import 'package:stackwallet/services/event_bus/global_event_bus.dart';
import 'package:stackwallet/utilities/assets.dart';
import 'package:stackwallet/utilities/enums/coin_enum.dart';
import 'package:stackwallet/utilities/enums/wallet_balance_toggle_state.dart';
import 'package:stackwallet/utilities/format.dart';
import 'package:stackwallet/utilities/text_styles.dart';
import 'package:stackwallet/utilities/theme/stack_colors.dart';
import 'package:stackwallet/widgets/animated_text.dart';
class WalletSummaryInfo extends StatefulWidget {
class WalletSummaryInfo extends ConsumerStatefulWidget {
const WalletSummaryInfo({
Key? key,
required this.walletId,
required this.managerProvider,
required this.initialSyncStatus,
}) : super(key: key);
final String walletId;
final ChangeNotifierProvider<Manager> managerProvider;
final WalletSyncStatus initialSyncStatus;
@override
State<WalletSummaryInfo> createState() => _WalletSummaryInfoState();
ConsumerState<WalletSummaryInfo> createState() => _WalletSummaryInfoState();
}
class _WalletSummaryInfoState extends State<WalletSummaryInfo> {
late final String walletId;
late final ChangeNotifierProvider<Manager> managerProvider;
class _WalletSummaryInfoState extends ConsumerState<WalletSummaryInfo> {
late StreamSubscription<BalanceRefreshedEvent> _balanceUpdated;
void showSheet() {
showModalBottomSheet<dynamic>(
@ -46,251 +45,154 @@ class _WalletSummaryInfoState extends State<WalletSummaryInfo> {
top: Radius.circular(20),
),
),
builder: (_) => WalletBalanceToggleSheet(walletId: walletId),
builder: (_) => WalletBalanceToggleSheet(walletId: widget.walletId),
);
}
Decimal? _balanceTotalCached;
Decimal? _balanceCached;
@override
void initState() {
walletId = widget.walletId;
managerProvider = widget.managerProvider;
_balanceUpdated =
GlobalEventBus.instance.on<BalanceRefreshedEvent>().listen(
(event) async {
if (event.walletId == widget.walletId) {
setState(() {});
}
},
);
super.initState();
}
@override
void dispose() {
_balanceUpdated.cancel();
super.dispose();
}
@override
Widget build(BuildContext context) {
debugPrint("BUILD: $runtimeType");
final externalCalls = ref.watch(
prefsChangeNotifierProvider.select((value) => value.externalCalls));
final coin = ref.watch(walletsChangeNotifierProvider
.select((value) => value.getManager(widget.walletId).coin));
final balance = ref.watch(walletsChangeNotifierProvider
.select((value) => value.getManager(widget.walletId).balance));
final locale = ref.watch(
localeServiceChangeNotifierProvider.select((value) => value.locale));
final baseCurrency = ref
.watch(prefsChangeNotifierProvider.select((value) => value.currency));
final priceTuple = ref.watch(priceAnd24hChangeNotifierProvider
.select((value) => value.getPrice(coin)));
final _showAvailable =
ref.watch(walletBalanceToggleStateProvider.state).state ==
WalletBalanceToggleState.available;
final Decimal totalBalance;
final Decimal availableBalance;
if (coin == Coin.firo || coin == Coin.firoTestNet) {
final firoWallet = ref.watch(walletsChangeNotifierProvider.select(
(value) => value.getManager(widget.walletId).wallet)) as FiroWallet;
totalBalance = firoWallet.balance.getSpendable();
availableBalance = firoWallet.balancePrivate.getSpendable();
} else {
totalBalance = balance.getTotal();
availableBalance = balance.getSpendable();
}
final balanceToShow = _showAvailable ? availableBalance : totalBalance;
return Row(
children: [
Expanded(
child: Consumer(
builder: (_, ref, __) {
final Coin coin =
ref.watch(managerProvider.select((value) => value.coin));
final externalCalls = ref.watch(prefsChangeNotifierProvider
.select((value) => value.externalCalls));
Future<Decimal>? totalBalanceFuture;
Future<Decimal>? availableBalanceFuture;
if (coin == Coin.firo || coin == Coin.firoTestNet) {
final firoWallet =
ref.watch(managerProvider.select((value) => value.wallet))
as FiroWallet;
totalBalanceFuture =
Future(() => firoWallet.balance.getSpendable());
availableBalanceFuture =
Future(() => firoWallet.balancePrivate.getSpendable());
} else {
final manager = ref.watch(walletsChangeNotifierProvider
.select((value) => value.getManager(walletId)));
totalBalanceFuture = Future(() => manager.balance.getTotal());
availableBalanceFuture =
Future(() => manager.balance.getSpendable());
}
final locale = ref.watch(localeServiceChangeNotifierProvider
.select((value) => value.locale));
final baseCurrency = ref.watch(prefsChangeNotifierProvider
.select((value) => value.currency));
final priceTuple = ref.watch(priceAnd24hChangeNotifierProvider
.select((value) => value.getPrice(coin)));
final _showAvailable =
ref.watch(walletBalanceToggleStateProvider.state).state ==
WalletBalanceToggleState.available;
return FutureBuilder(
future: _showAvailable
? availableBalanceFuture
: totalBalanceFuture,
builder: (fbContext, AsyncSnapshot<Decimal> snapshot) {
if (snapshot.connectionState == ConnectionState.done &&
snapshot.hasData &&
snapshot.data != null) {
if (_showAvailable) {
_balanceCached = snapshot.data!;
} else {
_balanceTotalCached = snapshot.data!;
}
}
Decimal? balanceToShow =
_showAvailable ? _balanceCached : _balanceTotalCached;
if (balanceToShow != null) {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
GestureDetector(
onTap: showSheet,
child: Row(
children: [
if (coin == Coin.firo || coin == Coin.firoTestNet)
Text(
"${_showAvailable ? "Private" : "Public"} Balance",
style:
STextStyles.subtitle500(context).copyWith(
color: Theme.of(context)
.extension<StackColors>()!
.textFavoriteCard,
),
),
if (coin != Coin.firo && coin != Coin.firoTestNet)
Text(
"${_showAvailable ? "Available" : "Full"} Balance",
style:
STextStyles.subtitle500(context).copyWith(
color: Theme.of(context)
.extension<StackColors>()!
.textFavoriteCard,
),
),
const SizedBox(
width: 4,
),
SvgPicture.asset(
Assets.svg.chevronDown,
color: Theme.of(context)
.extension<StackColors>()!
.textFavoriteCard,
width: 8,
height: 4,
),
],
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
GestureDetector(
onTap: showSheet,
child: Row(
children: [
if (coin == Coin.firo || coin == Coin.firoTestNet)
Text(
"${_showAvailable ? "Private" : "Public"} Balance",
style: STextStyles.subtitle500(context).copyWith(
color: Theme.of(context)
.extension<StackColors>()!
.textFavoriteCard,
),
const Spacer(),
FittedBox(
fit: BoxFit.scaleDown,
child: SelectableText(
"${Format.localizedStringAsFixed(
value: balanceToShow,
locale: locale,
decimalPlaces: 8,
)} ${coin.ticker}",
style: STextStyles.pageTitleH1(context).copyWith(
fontSize: 24,
color: Theme.of(context)
.extension<StackColors>()!
.textFavoriteCard,
),
),
),
if (coin != Coin.firo && coin != Coin.firoTestNet)
Text(
"${_showAvailable ? "Available" : "Full"} Balance",
style: STextStyles.subtitle500(context).copyWith(
color: Theme.of(context)
.extension<StackColors>()!
.textFavoriteCard,
),
if (externalCalls)
Text(
"${Format.localizedStringAsFixed(
value: priceTuple.item1 * balanceToShow,
locale: locale,
decimalPlaces: 2,
)} $baseCurrency",
style: STextStyles.subtitle500(context).copyWith(
color: Theme.of(context)
.extension<StackColors>()!
.textFavoriteCard,
),
),
],
);
} else {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
GestureDetector(
onTap: showSheet,
child: Row(
children: [
if (coin == Coin.firo || coin == Coin.firoTestNet)
Text(
"${_showAvailable ? "Private" : "Public"} Balance",
style:
STextStyles.subtitle500(context).copyWith(
color: Theme.of(context)
.extension<StackColors>()!
.textFavoriteCard,
),
),
if (coin != Coin.firo && coin != Coin.firoTestNet)
Text(
"${_showAvailable ? "Available" : "Full"} Balance",
style:
STextStyles.subtitle500(context).copyWith(
color: Theme.of(context)
.extension<StackColors>()!
.textFavoriteCard,
),
),
const SizedBox(
width: 4,
),
SvgPicture.asset(
Assets.svg.chevronDown,
width: 8,
height: 4,
color: Theme.of(context)
.extension<StackColors>()!
.textFavoriteCard,
),
],
),
),
const Spacer(),
AnimatedText(
stringsToLoopThrough: const [
"Loading balance",
"Loading balance.",
"Loading balance..",
"Loading balance..."
],
style: STextStyles.pageTitleH1(context).copyWith(
fontSize: 24,
color: Theme.of(context)
.extension<StackColors>()!
.textFavoriteCard,
),
),
AnimatedText(
stringsToLoopThrough: const [
"Loading balance",
"Loading balance.",
"Loading balance..",
"Loading balance..."
],
style: STextStyles.subtitle500(context).copyWith(
color: Theme.of(context)
.extension<StackColors>()!
.textFavoriteCard,
),
),
],
);
}
},
);
},
),
const SizedBox(
width: 4,
),
SvgPicture.asset(
Assets.svg.chevronDown,
color: Theme.of(context)
.extension<StackColors>()!
.textFavoriteCard,
width: 8,
height: 4,
),
],
),
),
const Spacer(),
FittedBox(
fit: BoxFit.scaleDown,
child: SelectableText(
"${Format.localizedStringAsFixed(
value: balanceToShow,
locale: locale,
decimalPlaces: 8,
)} ${coin.ticker}",
style: STextStyles.pageTitleH1(context).copyWith(
fontSize: 24,
color: Theme.of(context)
.extension<StackColors>()!
.textFavoriteCard,
),
),
),
if (externalCalls)
Text(
"${Format.localizedStringAsFixed(
value: priceTuple.item1 * balanceToShow,
locale: locale,
decimalPlaces: 2,
)} $baseCurrency",
style: STextStyles.subtitle500(context).copyWith(
color: Theme.of(context)
.extension<StackColors>()!
.textFavoriteCard,
),
),
],
),
),
Column(
children: [
Consumer(
builder: (_, ref, __) {
return SvgPicture.asset(
Assets.svg.iconFor(
coin: ref.watch(
managerProvider.select((value) => value.coin),
),
),
width: 24,
height: 24,
);
},
SvgPicture.asset(
Assets.svg.iconFor(
coin: coin,
),
width: 24,
height: 24,
),
const Spacer(),
WalletRefreshButton(
walletId: walletId,
walletId: widget.walletId,
initialSyncStatus: widget.initialSyncStatus,
),
],

View file

@ -0,0 +1,12 @@
import 'package:stackwallet/utilities/logger.dart';
class BalanceRefreshedEvent {
final String walletId;
BalanceRefreshedEvent(this.walletId) {
Logging.instance.log(
"BalanceRefreshedEvent fired on $walletId",
level: LogLevel.Info,
);
}
}

View file

@ -3,7 +3,7 @@ import 'dart:async';
import 'package:isar/isar.dart';
import 'package:stackwallet/db/main_db.dart';
import 'package:stackwallet/models/balance.dart';
import 'package:stackwallet/services/event_bus/events/global/updated_in_background_event.dart';
import 'package:stackwallet/services/event_bus/events/global/balance_refreshed_event.dart';
import 'package:stackwallet/services/event_bus/global_event_bus.dart';
import 'package:stackwallet/utilities/enums/coin_enum.dart';
@ -69,8 +69,7 @@ mixin CoinControlInterface {
if (notify) {
GlobalEventBus.instance.fire(
UpdatedInBackgroundEvent(
"coin control refresh balance in $_walletId $_walletName!",
BalanceRefreshedEvent(
_walletId,
),
);