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

View file

@ -1,3 +1,5 @@
import 'dart:async';
import 'package:decimal/decimal.dart'; import 'package:decimal/decimal.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart';
@ -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/providers.dart';
import 'package:stackwallet/providers/wallet/wallet_balance_toggle_state_provider.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/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/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/assets.dart';
import 'package:stackwallet/utilities/enums/coin_enum.dart'; import 'package:stackwallet/utilities/enums/coin_enum.dart';
import 'package:stackwallet/utilities/enums/wallet_balance_toggle_state.dart'; import 'package:stackwallet/utilities/enums/wallet_balance_toggle_state.dart';
import 'package:stackwallet/utilities/format.dart'; import 'package:stackwallet/utilities/format.dart';
import 'package:stackwallet/utilities/text_styles.dart'; import 'package:stackwallet/utilities/text_styles.dart';
import 'package:stackwallet/utilities/theme/stack_colors.dart'; import 'package:stackwallet/utilities/theme/stack_colors.dart';
import 'package:stackwallet/widgets/animated_text.dart';
class WalletSummaryInfo extends StatefulWidget { class WalletSummaryInfo extends ConsumerStatefulWidget {
const WalletSummaryInfo({ const WalletSummaryInfo({
Key? key, Key? key,
required this.walletId, required this.walletId,
required this.managerProvider,
required this.initialSyncStatus, required this.initialSyncStatus,
}) : super(key: key); }) : super(key: key);
final String walletId; final String walletId;
final ChangeNotifierProvider<Manager> managerProvider;
final WalletSyncStatus initialSyncStatus; final WalletSyncStatus initialSyncStatus;
@override @override
State<WalletSummaryInfo> createState() => _WalletSummaryInfoState(); ConsumerState<WalletSummaryInfo> createState() => _WalletSummaryInfoState();
} }
class _WalletSummaryInfoState extends State<WalletSummaryInfo> { class _WalletSummaryInfoState extends ConsumerState<WalletSummaryInfo> {
late final String walletId; late StreamSubscription<BalanceRefreshedEvent> _balanceUpdated;
late final ChangeNotifierProvider<Manager> managerProvider;
void showSheet() { void showSheet() {
showModalBottomSheet<dynamic>( showModalBottomSheet<dynamic>(
@ -46,251 +45,154 @@ class _WalletSummaryInfoState extends State<WalletSummaryInfo> {
top: Radius.circular(20), top: Radius.circular(20),
), ),
), ),
builder: (_) => WalletBalanceToggleSheet(walletId: walletId), builder: (_) => WalletBalanceToggleSheet(walletId: widget.walletId),
); );
} }
Decimal? _balanceTotalCached;
Decimal? _balanceCached;
@override @override
void initState() { void initState() {
walletId = widget.walletId; _balanceUpdated =
managerProvider = widget.managerProvider; GlobalEventBus.instance.on<BalanceRefreshedEvent>().listen(
(event) async {
if (event.walletId == widget.walletId) {
setState(() {});
}
},
);
super.initState(); super.initState();
} }
@override
void dispose() {
_balanceUpdated.cancel();
super.dispose();
}
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
debugPrint("BUILD: $runtimeType"); 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( return Row(
children: [ children: [
Expanded( Expanded(
child: Consumer( child: Column(
builder: (_, ref, __) { crossAxisAlignment: CrossAxisAlignment.start,
final Coin coin = children: [
ref.watch(managerProvider.select((value) => value.coin)); GestureDetector(
final externalCalls = ref.watch(prefsChangeNotifierProvider onTap: showSheet,
.select((value) => value.externalCalls)); child: Row(
children: [
Future<Decimal>? totalBalanceFuture; if (coin == Coin.firo || coin == Coin.firoTestNet)
Future<Decimal>? availableBalanceFuture; Text(
if (coin == Coin.firo || coin == Coin.firoTestNet) { "${_showAvailable ? "Private" : "Public"} Balance",
final firoWallet = style: STextStyles.subtitle500(context).copyWith(
ref.watch(managerProvider.select((value) => value.wallet)) color: Theme.of(context)
as FiroWallet; .extension<StackColors>()!
totalBalanceFuture = .textFavoriteCard,
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,
),
],
),
), ),
const Spacer(), ),
FittedBox( if (coin != Coin.firo && coin != Coin.firoTestNet)
fit: BoxFit.scaleDown, Text(
child: SelectableText( "${_showAvailable ? "Available" : "Full"} Balance",
"${Format.localizedStringAsFixed( style: STextStyles.subtitle500(context).copyWith(
value: balanceToShow, color: Theme.of(context)
locale: locale, .extension<StackColors>()!
decimalPlaces: 8, .textFavoriteCard,
)} ${coin.ticker}",
style: STextStyles.pageTitleH1(context).copyWith(
fontSize: 24,
color: Theme.of(context)
.extension<StackColors>()!
.textFavoriteCard,
),
),
), ),
if (externalCalls) ),
Text( const SizedBox(
"${Format.localizedStringAsFixed( width: 4,
value: priceTuple.item1 * balanceToShow, ),
locale: locale, SvgPicture.asset(
decimalPlaces: 2, Assets.svg.chevronDown,
)} $baseCurrency", color: Theme.of(context)
style: STextStyles.subtitle500(context).copyWith( .extension<StackColors>()!
color: Theme.of(context) .textFavoriteCard,
.extension<StackColors>()! width: 8,
.textFavoriteCard, height: 4,
), ),
), ],
], ),
); ),
} else { const Spacer(),
return Column( FittedBox(
crossAxisAlignment: CrossAxisAlignment.start, fit: BoxFit.scaleDown,
children: [ child: SelectableText(
GestureDetector( "${Format.localizedStringAsFixed(
onTap: showSheet, value: balanceToShow,
child: Row( locale: locale,
children: [ decimalPlaces: 8,
if (coin == Coin.firo || coin == Coin.firoTestNet) )} ${coin.ticker}",
Text( style: STextStyles.pageTitleH1(context).copyWith(
"${_showAvailable ? "Private" : "Public"} Balance", fontSize: 24,
style: color: Theme.of(context)
STextStyles.subtitle500(context).copyWith( .extension<StackColors>()!
color: Theme.of(context) .textFavoriteCard,
.extension<StackColors>()! ),
.textFavoriteCard, ),
), ),
), if (externalCalls)
if (coin != Coin.firo && coin != Coin.firoTestNet) Text(
Text( "${Format.localizedStringAsFixed(
"${_showAvailable ? "Available" : "Full"} Balance", value: priceTuple.item1 * balanceToShow,
style: locale: locale,
STextStyles.subtitle500(context).copyWith( decimalPlaces: 2,
color: Theme.of(context) )} $baseCurrency",
.extension<StackColors>()! style: STextStyles.subtitle500(context).copyWith(
.textFavoriteCard, 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,
),
),
],
);
}
},
);
},
), ),
), ),
Column( Column(
children: [ children: [
Consumer( SvgPicture.asset(
builder: (_, ref, __) { Assets.svg.iconFor(
return SvgPicture.asset( coin: coin,
Assets.svg.iconFor( ),
coin: ref.watch( width: 24,
managerProvider.select((value) => value.coin), height: 24,
),
),
width: 24,
height: 24,
);
},
), ),
const Spacer(), const Spacer(),
WalletRefreshButton( WalletRefreshButton(
walletId: walletId, walletId: widget.walletId,
initialSyncStatus: widget.initialSyncStatus, 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:isar/isar.dart';
import 'package:stackwallet/db/main_db.dart'; import 'package:stackwallet/db/main_db.dart';
import 'package:stackwallet/models/balance.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/services/event_bus/global_event_bus.dart';
import 'package:stackwallet/utilities/enums/coin_enum.dart'; import 'package:stackwallet/utilities/enums/coin_enum.dart';
@ -69,8 +69,7 @@ mixin CoinControlInterface {
if (notify) { if (notify) {
GlobalEventBus.instance.fire( GlobalEventBus.instance.fire(
UpdatedInBackgroundEvent( BalanceRefreshedEvent(
"coin control refresh balance in $_walletId $_walletName!",
_walletId, _walletId,
), ),
); );