From fa75ae243daa9ade452e09098342ba324e04ea3f Mon Sep 17 00:00:00 2001 From: Erdem Yerebasmaz Date: Mon, 17 Jul 2023 13:26:45 +0300 Subject: [PATCH] Convert WalletDashboard and it's child widgets to StatefulWidget's --- .../home/widgets/dashboard/balance_text.dart | 112 ++++---- .../widgets/dashboard/fiat_balance_text.dart | 98 +++++++ .../widgets/dashboard/wallet_dashboard.dart | 251 ++++++------------ .../wallet_dashboard_header_delegate.dart | 4 +- 4 files changed, 231 insertions(+), 234 deletions(-) create mode 100644 lib/routes/home/widgets/dashboard/fiat_balance_text.dart diff --git a/lib/routes/home/widgets/dashboard/balance_text.dart b/lib/routes/home/widgets/dashboard/balance_text.dart index 85283104e..db284dcef 100644 --- a/lib/routes/home/widgets/dashboard/balance_text.dart +++ b/lib/routes/home/widgets/dashboard/balance_text.dart @@ -1,86 +1,66 @@ import 'package:breez_translations/breez_translations_locales.dart'; -import 'package:c_breez/bloc/account/account_bloc.dart'; import 'package:c_breez/bloc/account/account_state.dart'; -import 'package:c_breez/bloc/currency/currency_bloc.dart'; import 'package:c_breez/bloc/currency/currency_state.dart'; -import 'package:c_breez/bloc/user_profile/user_profile_bloc.dart'; import 'package:c_breez/bloc/user_profile/user_profile_state.dart'; import 'package:c_breez/theme/theme_provider.dart' as theme; import 'package:flutter/material.dart'; -import 'package:flutter_bloc/flutter_bloc.dart'; -class BalanceText extends StatelessWidget { - final double offset; +class BalanceText extends StatefulWidget { + final UserProfileState userProfileState; + final CurrencyState currencyState; + final AccountState accountState; + final double offsetFactor; - const BalanceText( - this.offset, { + const BalanceText({ Key? key, + required this.userProfileState, + required this.currencyState, + required this.accountState, + required this.offsetFactor, }) : super(key: key); @override - Widget build(BuildContext context) { - return BlocBuilder( - builder: (context, currencyState) { - return BlocBuilder( - builder: (context, accountState) { - return BlocBuilder( - builder: (context, userProfileState) { - return userProfileState.profileSettings.hideBalance - ? _balanceHide(context) - : _balanceRichText(context, currencyState, accountState); - }, - ); - }, - ); - }, - ); - } - - Widget _balanceHide(BuildContext context) { - final themeData = Theme.of(context); - final texts = context.texts(); + State createState() => _BalanceTextState(); +} - return Text( - texts.wallet_dashboard_balance_hide, - style: theme.balanceAmountTextStyle.copyWith( - color: themeData.colorScheme.onSecondary, - fontSize: startSize - (startSize - endSize) * offset, - ), - ); - } +class _BalanceTextState extends State { + double get startSize => theme.balanceAmountTextStyle.fontSize!; + double get endSize => startSize - 8.0; - Widget _balanceRichText( - BuildContext context, - CurrencyState currencyState, - AccountState accountState, - ) { + @override + Widget build(BuildContext context) { + final texts = context.texts(); final themeData = Theme.of(context); - return RichText( - text: TextSpan( - style: theme.balanceAmountTextStyle.copyWith( - color: themeData.colorScheme.onSecondary, - fontSize: startSize - (startSize - endSize) * offset, - ), - text: currencyState.bitcoinCurrency.format( - accountState.balance, - removeTrailingZeros: true, - includeDisplayName: false, - ), - children: [ - TextSpan( - text: " ${currencyState.bitcoinCurrency.displayName}", - style: theme.balanceCurrencyTextStyle.copyWith( + return widget.userProfileState.profileSettings.hideBalance + ? Text( + texts.wallet_dashboard_balance_hide, + style: theme.balanceAmountTextStyle.copyWith( color: themeData.colorScheme.onSecondary, - fontSize: startSize * 0.6 - (startSize * 0.6 - endSize) * offset, + fontSize: startSize - (startSize - endSize) * widget.offsetFactor, + ), + ) + : RichText( + text: TextSpan( + style: theme.balanceAmountTextStyle.copyWith( + color: themeData.colorScheme.onSecondary, + fontSize: startSize - (startSize - endSize) * widget.offsetFactor, + ), + text: widget.currencyState.bitcoinCurrency.format( + widget.accountState.balance, + removeTrailingZeros: true, + includeDisplayName: false, + ), + children: [ + TextSpan( + text: " ${widget.currencyState.bitcoinCurrency.displayName}", + style: theme.balanceCurrencyTextStyle.copyWith( + color: themeData.colorScheme.onSecondary, + fontSize: startSize * 0.6 - (startSize * 0.6 - endSize) * widget.offsetFactor, + ), + ), + ], ), - ), - ], - ), - ); + ); } - - double get startSize => theme.balanceAmountTextStyle.fontSize!; - - double get endSize => startSize - 8.0; } diff --git a/lib/routes/home/widgets/dashboard/fiat_balance_text.dart b/lib/routes/home/widgets/dashboard/fiat_balance_text.dart new file mode 100644 index 000000000..9842579ee --- /dev/null +++ b/lib/routes/home/widgets/dashboard/fiat_balance_text.dart @@ -0,0 +1,98 @@ +import 'dart:math'; + +import 'package:c_breez/bloc/account/account_state.dart'; +import 'package:c_breez/bloc/currency/currency_bloc.dart'; +import 'package:c_breez/bloc/currency/currency_state.dart'; +import 'package:c_breez/theme/theme_provider.dart' as theme; +import 'package:c_breez/utils/fiat_conversion.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; + +class FiatBalanceText extends StatefulWidget { + final CurrencyState currencyState; + final AccountState accountState; + final double offsetFactor; + + const FiatBalanceText({ + Key? key, + required this.currencyState, + required this.accountState, + required this.offsetFactor, + }) : super(key: key); + + @override + State createState() => _FiatBalanceTextState(); +} + +class _FiatBalanceTextState extends State { + @override + Widget build(BuildContext context) { + final themeData = Theme.of(context); + + return TextButton( + style: ButtonStyle( + overlayColor: MaterialStateProperty.resolveWith((states) { + if (states.contains(MaterialState.focused)) { + return themeData.customData.paymentListBgColor; + } + if (states.contains(MaterialState.hovered)) { + return themeData.customData.paymentListBgColor; + } + return null; + }), + ), + onPressed: () { + final newFiatConversion = nextValidFiatConversion( + widget.currencyState, + widget.accountState, + ); + if (newFiatConversion != null) { + context.read().setFiatId( + newFiatConversion.currencyData.id, + ); + } + }, + child: Text( + widget.currencyState.fiatConversion()?.format(widget.accountState.balance) ?? "", + style: theme.balanceFiatConversionTextStyle.copyWith( + color: themeData.colorScheme.onSecondary.withOpacity( + pow(1.00 - widget.offsetFactor, 2).toDouble(), + ), + ), + ), + ); + } + + FiatConversion? nextValidFiatConversion( + CurrencyState currencyState, + AccountState accountState, + ) { + final currencies = currencyState.preferredCurrencies; + final currentIndex = currencies.indexOf(currencyState.fiatId); + for (var i = 1; i < currencies.length; i++) { + final nextIndex = (i + currentIndex) % currencies.length; + if (isAboveMinAmount(currencyState, accountState)) { + final conversion = currencyState.fiatById(currencies[nextIndex]); + final exchangeRate = currencyState.fiatExchangeRate; + if (conversion != null && exchangeRate != null) { + return FiatConversion(conversion, exchangeRate); + } + } + } + return null; + } + + bool isAboveMinAmount( + CurrencyState currencyState, + AccountState accountState, + ) { + final fiatConversion = currencyState.fiatConversion(); + if (fiatConversion == null) return false; + + double fiatValue = fiatConversion.satToFiat(accountState.balance); + int fractionSize = fiatConversion.currencyData.info.fractionSize; + double minimumAmount = 1 / (pow(10, fractionSize)); + + return fiatValue > minimumAmount; + } +} diff --git a/lib/routes/home/widgets/dashboard/wallet_dashboard.dart b/lib/routes/home/widgets/dashboard/wallet_dashboard.dart index 706f79603..d2304dbb9 100644 --- a/lib/routes/home/widgets/dashboard/wallet_dashboard.dart +++ b/lib/routes/home/widgets/dashboard/wallet_dashboard.dart @@ -1,5 +1,3 @@ -import 'dart:math'; - import 'package:c_breez/bloc/account/account_bloc.dart'; import 'package:c_breez/bloc/account/account_state.dart'; import 'package:c_breez/bloc/currency/currency_bloc.dart'; @@ -7,8 +5,8 @@ import 'package:c_breez/bloc/currency/currency_state.dart'; import 'package:c_breez/bloc/user_profile/user_profile_bloc.dart'; import 'package:c_breez/bloc/user_profile/user_profile_state.dart'; import 'package:c_breez/models/currency.dart'; +import 'package:c_breez/routes/home/widgets/dashboard/fiat_balance_text.dart'; import 'package:c_breez/theme/theme_provider.dart' as theme; -import 'package:c_breez/utils/fiat_conversion.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; @@ -16,29 +14,102 @@ import 'balance_text.dart'; const _kBalanceOffsetTransition = 60.0; -class WalletDashboard extends StatelessWidget { - final double _height; - final double _offsetFactor; +class WalletDashboard extends StatefulWidget { + final double height; + final double offsetFactor; - const WalletDashboard( - this._height, - this._offsetFactor, { + const WalletDashboard({ Key? key, + required this.height, + required this.offsetFactor, }) : super(key: key); + @override + State createState() => _WalletDashboardState(); +} + +class _WalletDashboardState extends State { @override Widget build(BuildContext context) { + final userProfileBloc = context.read(); + final currencyBloc = context.read(); + final themeData = Theme.of(context); + return BlocBuilder( builder: (context, currencyState) { return BlocBuilder( builder: (context, userProfileState) { + final profileSettings = userProfileState.profileSettings; + return BlocBuilder( builder: (context, accountState) { - return _build( - context, - currencyState, - userProfileState, - accountState, + return GestureDetector( + behavior: HitTestBehavior.translucent, + child: Stack( + alignment: AlignmentDirectional.topCenter, + children: [ + Container( + width: MediaQuery.of(context).size.width, + height: widget.height, + decoration: BoxDecoration( + color: themeData.customData.dashboardBgColor, + ), + ), + Positioned( + top: 60 - _kBalanceOffsetTransition * widget.offsetFactor, + child: Center( + child: !accountState.initial + ? TextButton( + style: ButtonStyle( + overlayColor: MaterialStateProperty.resolveWith((states) { + if (states.contains(MaterialState.focused)) { + return themeData.customData.paymentListBgColor; + } + if (states.contains(MaterialState.hovered)) { + return themeData.customData.paymentListBgColor; + } + return null; + }), + ), + onPressed: () { + if (profileSettings.hideBalance == true) { + userProfileBloc.updateProfile(hideBalance: false); + return; + } + final list = BitcoinCurrency.currencies; + final index = list.indexOf( + BitcoinCurrency.fromTickerSymbol(currencyState.bitcoinTicker), + ); + final nextCurrencyIndex = (index + 1) % list.length; + if (nextCurrencyIndex == 1) { + userProfileBloc.updateProfile(hideBalance: true); + } + currencyBloc.setBitcoinTicker(list[nextCurrencyIndex].tickerSymbol); + }, + child: BalanceText( + userProfileState: userProfileState, + currencyState: currencyState, + accountState: accountState, + offsetFactor: widget.offsetFactor, + ), + ) + : const SizedBox(), + ), + ), + Positioned( + top: 100 - _kBalanceOffsetTransition * widget.offsetFactor, + child: Center( + child: currencyState.fiatEnabled && !profileSettings.hideBalance + ? FiatBalanceText( + currencyState: currencyState, + accountState: accountState, + offsetFactor: widget.offsetFactor, + ) + : const SizedBox(), + ), + ), + ], + ), ); }, ); @@ -47,156 +118,4 @@ class WalletDashboard extends StatelessWidget { }, ); } - - Widget _build( - BuildContext context, - CurrencyState currencyState, - UserProfileState userProfileState, - AccountState accountState, - ) { - final profileSettings = userProfileState.profileSettings; - final themeData = Theme.of(context); - - return GestureDetector( - behavior: HitTestBehavior.translucent, - child: Stack( - alignment: AlignmentDirectional.topCenter, - children: [ - Container( - width: MediaQuery.of(context).size.width, - height: _height, - decoration: BoxDecoration( - color: themeData.customData.dashboardBgColor, - ), - ), - Positioned( - top: 60 - _kBalanceOffsetTransition * _offsetFactor, - child: Center( - child: !accountState.initial - ? TextButton( - style: _balanceStyle(themeData), - onPressed: () { - if (profileSettings.hideBalance == true) { - _onPrivacyChanged(context, false); - return; - } - final list = BitcoinCurrency.currencies; - final index = list.indexOf( - BitcoinCurrency.fromTickerSymbol( - currencyState.bitcoinTicker, - ), - ); - final nextCurrencyIndex = (index + 1) % list.length; - if (nextCurrencyIndex == 1) { - _onPrivacyChanged(context, true); - } - context.read().setBitcoinTicker( - list[nextCurrencyIndex].tickerSymbol, - ); - }, - child: BalanceText(_offsetFactor), - ) - : const SizedBox(), - ), - ), - Positioned( - top: 100 - _kBalanceOffsetTransition * _offsetFactor, - child: Center( - child: currencyState.fiatEnabled && - isAboveMinAmount(currencyState, accountState) && - !profileSettings.hideBalance - ? _fiatButton(context, currencyState, accountState) - : const SizedBox(), - ), - ), - ], - ), - ); - } - - ButtonStyle _balanceStyle(ThemeData themeData) { - return ButtonStyle( - overlayColor: MaterialStateProperty.resolveWith((states) { - if (states.contains(MaterialState.focused)) { - return themeData.customData.paymentListBgColor; - } - if (states.contains(MaterialState.hovered)) { - return themeData.customData.paymentListBgColor; - } - return null; - }), - ); - } - - Widget _fiatButton( - BuildContext context, - CurrencyState currencyState, - AccountState accountState, - ) { - final themeData = Theme.of(context); - const fiatConversionTextStyle = theme.balanceFiatConversionTextStyle; - - return TextButton( - style: _balanceStyle(themeData), - onPressed: () { - final newFiatConversion = nextValidFiatConversion( - currencyState, - accountState, - ); - if (newFiatConversion != null) { - context.read().setFiatId( - newFiatConversion.currencyData.id, - ); - } - }, - child: Text( - currencyState.fiatConversion()?.format(accountState.balance) ?? "", - style: fiatConversionTextStyle.copyWith( - color: themeData.colorScheme.onSecondary.withOpacity( - pow(1.00 - _offsetFactor, 2).toDouble(), - ), - ), - ), - ); - } - - FiatConversion? nextValidFiatConversion( - CurrencyState currencyState, - AccountState accountState, - ) { - final currencies = currencyState.preferredCurrencies; - final currentIndex = currencies.indexOf(currencyState.fiatId); - for (var i = 1; i < currencies.length; i++) { - final nextIndex = (i + currentIndex) % currencies.length; - if (isAboveMinAmount(currencyState, accountState)) { - final conversion = currencyState.fiatById(currencies[nextIndex]); - final exchangeRate = currencyState.fiatExchangeRate; - if (conversion != null && exchangeRate != null) { - return FiatConversion(conversion, exchangeRate); - } - } - } - return null; - } - - bool isAboveMinAmount( - CurrencyState currencyState, - AccountState accountState, - ) { - final fiatConversion = currencyState.fiatConversion(); - if (fiatConversion == null) return false; - - double fiatValue = fiatConversion.satToFiat(accountState.balance); - int fractionSize = fiatConversion.currencyData.info.fractionSize; - double minimumAmount = 1 / (pow(10, fractionSize)); - - return fiatValue > minimumAmount; - } - - void _onPrivacyChanged( - BuildContext context, - bool hideBalance, - ) { - context.read().updateProfile(hideBalance: hideBalance); - } } diff --git a/lib/routes/home/widgets/dashboard/wallet_dashboard_header_delegate.dart b/lib/routes/home/widgets/dashboard/wallet_dashboard_header_delegate.dart index 9ac66e9ef..d452091cd 100644 --- a/lib/routes/home/widgets/dashboard/wallet_dashboard_header_delegate.dart +++ b/lib/routes/home/widgets/dashboard/wallet_dashboard_header_delegate.dart @@ -15,8 +15,8 @@ class WalletDashboardHeaderDelegate extends SliverPersistentHeaderDelegate { bool overlapsContent, ) { return WalletDashboard( - (kMaxExtent - shrinkOffset).clamp(kMinExtent, kMaxExtent), - (shrinkOffset / (kMaxExtent - kMinExtent)).clamp(0.0, 1.0), + height: (kMaxExtent - shrinkOffset).clamp(kMinExtent, kMaxExtent), + offsetFactor: (shrinkOffset / (kMaxExtent - kMinExtent)).clamp(0.0, 1.0), ); }