From 2221e6ad1e2de3f3aa30974eec43ed7b4bc89f47 Mon Sep 17 00:00:00 2001 From: Egor Komarov Date: Thu, 27 Feb 2025 13:15:50 +0100 Subject: [PATCH] fix: update token transactions handling and improve loading state management (#793) Co-authored-by: Egor Komarov --- .../view/token_wallet_details_page.dart | 1 + .../token_wallet_transactions_cubit.dart | 22 +++++++++++++------ .../view/ton_wallet_details_page.dart | 1 + .../account_transactions_tab_cubit.dart | 19 +++++++++++----- pubspec.yaml | 2 +- 5 files changed, 32 insertions(+), 13 deletions(-) diff --git a/lib/feature/wallet/token_wallet_details/view/token_wallet_details_page.dart b/lib/feature/wallet/token_wallet_details/view/token_wallet_details_page.dart index ced6a73c..cada6c84 100644 --- a/lib/feature/wallet/token_wallet_details/view/token_wallet_details_page.dart +++ b/lib/feature/wallet/token_wallet_details/view/token_wallet_details_page.dart @@ -110,6 +110,7 @@ class _Body extends StatelessWidget { final theme = context.themeStyleV2; return CustomScrollView( + controller: controller, slivers: [ SliverToBoxAdapter( child: Stack( diff --git a/lib/feature/wallet/token_wallet_details/widgets/token_wallet_transactions/token_wallet_transactions_cubit.dart b/lib/feature/wallet/token_wallet_details/widgets/token_wallet_transactions/token_wallet_transactions_cubit.dart index a6279077..308613b5 100644 --- a/lib/feature/wallet/token_wallet_details/widgets/token_wallet_transactions/token_wallet_transactions_cubit.dart +++ b/lib/feature/wallet/token_wallet_details/widgets/token_wallet_transactions/token_wallet_transactions_cubit.dart @@ -79,7 +79,7 @@ class TokenWalletTransactionsCubit extends Cubit ___, ____, ) => - _lastLt(transactions), + _lastLt(_transactions), ); final (isLoading, canLoadMore) = state.maybeWhen( transactions: (_, __, isLoading, canLoadMore, ___) => @@ -100,7 +100,9 @@ class TokenWalletTransactionsCubit extends Cubit /// List of ordinary transactions and flag that sign that transactions was /// loaded and mapped. bool _ordinaryLoaded = false; + bool _isPreloading = false; List _ordinary = []; + List> _transactions = []; StreamSubscription? _ordinaryTransactionsSub; late StreamSubscription _walletSubscription; @@ -141,6 +143,7 @@ class TokenWalletTransactionsCubit extends Cubit (_, b) => b ?? [], ).listen( (transactions) { + _transactions = transactions; _ordinary = nekotonRepository.mapOrdinaryTokenTransactions( rootTokenContract: rootTokenContract, transactions: transactions, @@ -169,14 +172,13 @@ class TokenWalletTransactionsCubit extends Cubit if (_ordinary.isEmpty) { emitSafe(const TokenWalletTransactionsState.empty()); } else { - final transactions = [..._ordinary] - ..sort((a, b) => b.date.compareTo(a.date)); + final transactions = _ordinary; var canLoadMore = state.maybeWhen( transactions: (_, __, ___, canLoadMore, ____) => canLoadMore, orElse: () => true, ); - final lastLt = _lastLt(transactions); + final lastLt = _lastLt(_transactions); if (_lastLtWhenPreloaded != null && !isLoading && fromStream) { // we must check this state every time, because we may have multiple // inputs for this method (different transactions streams, but not now, @@ -199,13 +201,18 @@ class TokenWalletTransactionsCubit extends Cubit /// Get last available prevTransactionLt String? _lastLt( - List transactions, + List> transactions, ) => transactions - .lastWhereOrNull((t) => t.prevTransactionLt != null) - ?.prevTransactionLt; + .lastWhereOrNull((t) => t.transaction.prevTransactionId != null) + ?.transaction + .prevTransactionId + ?.lt; Future _preloadTransactions(String lastPrevLt) async { + if (_isPreloading) return; + _isPreloading = true; + _transactionsState(isLoading: true); _lastLtWhenPreloaded = lastPrevLt; @@ -218,6 +225,7 @@ class TokenWalletTransactionsCubit extends Cubit } catch (e, t) { _logger.severe('_preloadTransactions', e, t); } finally { + _isPreloading = false; _transactionsState(); } } diff --git a/lib/feature/wallet/ton_wallet_details/view/ton_wallet_details_page.dart b/lib/feature/wallet/ton_wallet_details/view/ton_wallet_details_page.dart index 387677ab..529792f7 100644 --- a/lib/feature/wallet/ton_wallet_details/view/ton_wallet_details_page.dart +++ b/lib/feature/wallet/ton_wallet_details/view/ton_wallet_details_page.dart @@ -92,6 +92,7 @@ class _Body extends StatelessWidget { final theme = context.themeStyleV2; return CustomScrollView( + controller: controller, slivers: [ SliverToBoxAdapter( child: Stack( diff --git a/lib/feature/wallet/widgets/account_transactions_tab/account_transactions_tab_cubit.dart b/lib/feature/wallet/widgets/account_transactions_tab/account_transactions_tab_cubit.dart index 25e72c21..3fde0d1a 100644 --- a/lib/feature/wallet/widgets/account_transactions_tab/account_transactions_tab_cubit.dart +++ b/lib/feature/wallet/widgets/account_transactions_tab/account_transactions_tab_cubit.dart @@ -65,9 +65,11 @@ class AccountTransactionsTabCubit extends Cubit /// List of multisig transactions and flag that sign that multisig /// transactions was loaded and mapped. bool _multisigLoaded = false; + bool _isPreloading = false; List _multisigOrdinary = []; List _multisigPending = []; List _multisigExpired = []; + List> _transactions = []; bool _ordinaryLoaded = false; List _ordinary = []; @@ -88,7 +90,7 @@ class AccountTransactionsTabCubit extends Cubit /// NOTE: this method may be called multiple times void tryPreloadTransactions() { final lastPrevLt = state.whenOrNull( - transactions: (transactions, _, __, ___) => _lastLt(transactions), + transactions: (transactions, _, __, ___) => _lastLt(_transactions), ); final (isLoading, canLoadMore) = state.maybeWhen( transactions: (_, isLoading, canLoadMore, ___) => @@ -140,6 +142,7 @@ class AccountTransactionsTabCubit extends Cubit ).listen( (transactions) async { final multisigTransactions = wallet.unconfirmedTransactions; + _transactions = transactions; try { _multisigExpired = @@ -307,7 +310,7 @@ class AccountTransactionsTabCubit extends Cubit transactions: (_, __, canLoadMore, ___) => canLoadMore, orElse: () => true, ); - final lastLt = _lastLt(transactions); + final lastLt = _lastLt(_transactions); if (_lastLtWhenPreloaded != null && !isLoading && fromStream) { // we must check this state every time, because we have multiple @@ -329,13 +332,18 @@ class AccountTransactionsTabCubit extends Cubit /// Get last available prevTransactionLt String? _lastLt( - List> transactions, + List> transactions, ) => transactions - .lastWhereOrNull((t) => t.prevTransactionLt != null) - ?.prevTransactionLt; + .lastWhereOrNull((t) => t.transaction.prevTransactionId != null) + ?.transaction + .prevTransactionId + ?.lt; Future _preloadTransactions(String lastPrevLt) async { + if (_isPreloading) return; + _isPreloading = true; + _transactionsState(isLoading: true); _lastLtWhenPreloaded = lastPrevLt; @@ -347,6 +355,7 @@ class AccountTransactionsTabCubit extends Cubit } catch (e, t) { _logger.severe('_preloadTransactions', e, t); } finally { + _isPreloading = false; _transactionsState(); } } diff --git a/pubspec.yaml b/pubspec.yaml index d2e313d3..7d598c3a 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -56,7 +56,7 @@ dependencies: mobile_scanner: 5.2.3 money2: 5.3.0 # do not update to 5.4.0 due to json serialization issues money2_fixer: 2.0.0 - nekoton_repository: 0.51.0-dev.4 + nekoton_repository: 0.51.0-dev.5 nekoton_webview: 0.1.8 ntp: 2.0.0 package_info_plus: 8.1.3