Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(EWM-326): subscriptions refactor #564

Merged
merged 1 commit into from
Oct 4, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
79 changes: 35 additions & 44 deletions lib/app/service/current_accounts_service.dart
Original file line number Diff line number Diff line change
Expand Up @@ -85,9 +85,16 @@ class CurrentAccountsService {
);

currentActiveAccountStream
.map((account) => account?.address)
.distinct()
.listen(_tryStartPolling);
.distinct((prev, next) => prev == null && next == null)
.listen(
(account) async {
if (account != null) {
await _updateSubscriptions(account);
}

_tryStartPolling(account);
},
);

await _initCurrentAccount();

Expand All @@ -110,11 +117,6 @@ class CurrentAccountsService {
);
}

/// Subscriptions for listening Ton/Token wallets to start its polling when
/// their account is selected in [currentActiveAccount].
StreamSubscription<dynamic>? _tonWalletSubscription;
StreamSubscription<dynamic>? _tokenWalletSubscription;

Future<void> _initCurrentAccount() async {
final address = await _storage.get(
_currentAddress,
Expand All @@ -141,37 +143,26 @@ class CurrentAccountsService {

/// Start listening for wallet subscriptions and when subscription will be
/// created, start polling.
void _tryStartPolling(final Address? address) {
_tonWalletSubscription?.cancel();
_tokenWalletSubscription?.cancel();
void _tryStartPolling(final KeyAccount? account) {
_nekotonRepository
..stopPolling()
..stopPollingToken();

if (address == null) return;
if (account == null) return;

_tonWalletSubscription = _nekotonRepository.walletsStream.listen((wallets) {
if (_nekotonRepository.walletsMap.containsKey(address)) {
_nekotonRepository.startPolling(address);
_tonWalletSubscription?.cancel();
}
});

_tokenWalletSubscription =
_nekotonRepository.tokenWalletsStream.listen((wallets) {
wallets.where((w) => w.owner == address).forEach((w) {
final key = (w.owner, w.rootTokenContract);
if (_nekotonRepository.tokenWalletsMap.containsKey(key)) {
_nekotonRepository.startPollingToken(
w.owner,
w.rootTokenContract,
stopPrevious: false,
);
}
// ignore cancelling sub, because we do not know how many tokens could
// be here and duplicate startPolling will be ignored
});
});
_nekotonRepository.startPolling(account.address);

final networkGroup = _nekotonRepository.currentTransport.transport.group;
final tokenWallets =
account.account.additionalAssets[networkGroup]?.tokenWallets ?? [];

for (final wallet in tokenWallets) {
_nekotonRepository.startPollingToken(
account.address,
wallet.rootTokenContract,
stopPrevious: false,
);
}
}

void _tryUpdatingCurrentActiveAccount(AccountList? list) {
Expand Down Expand Up @@ -223,21 +214,21 @@ class CurrentAccountsService {

if (_currentAccountsSubject.valueOrNull != key.accountList) {
_currentAccountsSubject.add(key.accountList);
_updateSubscriptions(key.accountList);
}
}

/// Update Ton/Token wallet subscriptions when user changes current active key
///
/// Old subscriptions will be automatically cancelled if haven't complete yet.
Future<void> _updateSubscriptions(AccountList accountList) async {
final accounts = accountList.displayAccounts;

await _nekotonRepository.updateSubscriptions(
accounts.map((e) => (e.account.tonWallet, e.isExternal)).toList(),
);
await _nekotonRepository.updateTokenSubscriptions(
accounts.map((e) => e.account).toList(),
);
Future<void> _updateSubscriptions(KeyAccount? account) async {
if (account == null) {
await _nekotonRepository.updateSubscriptions([]);
await _nekotonRepository.updateTokenSubscriptions([]);
} else {
await _nekotonRepository.updateSubscriptions(
[(account.account.tonWallet, account.isExternal)],
);
await _nekotonRepository.updateTokenSubscriptions([account.account]);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ class AccountDetailCubit extends Cubit<AccountDetailState> {
required this.nekotonRepository,
required this.balanceService,
required this.convertService,
required this.currentAccountsService,
}) : super(const AccountDetailState.initial());

final _logger = Logger('AccountDetailCubit');
Expand All @@ -27,7 +26,6 @@ class AccountDetailCubit extends Cubit<AccountDetailState> {
final NekotonRepository nekotonRepository;
final BalanceService balanceService;
final CurrencyConvertService convertService;
final CurrentAccountsService currentAccountsService;

late StreamSubscription<SeedList> _seedListSubscription;
StreamSubscription<dynamic>? _balanceSub;
Expand Down Expand Up @@ -84,7 +82,6 @@ class AccountDetailCubit extends Cubit<AccountDetailState> {
_lastTransport!.name) {
_cachedBalance = convertBalance(Fixed.zero);
_lastTransport = nekotonRepository.currentTransport.transport;
final currentAccounts = currentAccountsService.currentAccounts;

_balanceSub =
balanceService.accountOverallBalance(address).listen((balance) {
Expand All @@ -97,10 +94,7 @@ class AccountDetailCubit extends Cubit<AccountDetailState> {

// if we explore not current account for which subscriptions are created
// automatically, create subs
if (currentAccounts != null &&
!currentAccounts.displayAccounts
.map((e) => e.address)
.contains(address)) {
if (!nekotonRepository.walletsMap.containsKey(address)) {
_subCreatedManually = true;
_subscribeNative();

Expand Down Expand Up @@ -166,6 +160,7 @@ class AccountDetailCubit extends Cubit<AccountDetailState> {
@override
Future<void> close() {
_seedListSubscription.cancel();
_balanceSub?.cancel();

return super.close();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ class AccountDetailPage extends StatelessWidget {
nekotonRepository: inject<NekotonRepository>(),
balanceService: inject(),
convertService: inject(),
currentAccountsService: inject(),
)..init(),
child: BlocConsumer<AccountDetailCubit, AccountDetailState>(
listener: (context, state) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:nekoton_repository/nekoton_repository.dart' hide Message;
import 'package:ui_components_lib/ui_components_lib.dart';
import 'package:ui_components_lib/v2/widgets/widgets.dart';

class AccountDetailView extends StatelessWidget {
const AccountDetailView({
Expand Down Expand Up @@ -51,9 +52,9 @@ class AccountDetailView extends StatelessWidget {
CommonCard(
backgroundColor: theme.colors.background2,
topSubtitleText: LocaleKeys.totalBalance.tr(),
titleChild: MoneyWidget(
money: balance,
style: MoneyWidgetStyle.primary,
titleChild: AmountWidget.dollars(
amount: balance,
style: theme.textStyles.labelMedium,
),
height: DimensSizeV2.d76,
width: double.infinity,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,6 @@ class DeleteAccountSheet extends StatelessWidget {
nekotonRepository: inject<NekotonRepository>(),
balanceService: inject(),
convertService: inject(),
currentAccountsService: inject(),
)..init(),
child: BlocBuilder<AccountDetailCubit, AccountDetailState>(
builder: (context, state) {
Expand Down
4 changes: 2 additions & 2 deletions lib/feature/wallet/staking/bloc/staking_bloc.dart
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@ class StakingBloc extends Bloc<StakingBlocEvent, StakingBlocState> {
final pair = (accountAddress, staking.stakingRootContractAddress);
final transport = nekotonRepository.currentTransport;

final ever = nekotonRepository.getWallet(accountAddress);
final ever = await nekotonRepository.getWallet(accountAddress);
if (ever.hasError) {
emit(StakingBlocState.subscribeError(ever.error!));

Expand All @@ -162,7 +162,7 @@ class StakingBloc extends Bloc<StakingBlocEvent, StakingBlocState> {
);
}

final stever = nekotonRepository.getTokenWallet(pair.$1, pair.$2);
final stever = await nekotonRepository.getTokenWallet(pair.$1, pair.$2);
if (stever.hasError) {
emit(StakingBlocState.subscribeError(stever.error!));

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,8 +61,6 @@ class TokenWalletDetailsCubit extends Cubit<TokenWalletDetailsState> {
);
} else {
final wallet = walletState.wallet!;
final local = nekotonRepository.getLocalCustodians(owner);
_canSend = local != null && local.isNotEmpty;

_thisWalletSubscription = wallet.fieldUpdatesStream.listen((_) {
_cachedTokenBalance = wallet.moneyBalance;
Expand All @@ -79,6 +77,8 @@ class TokenWalletDetailsCubit extends Cubit<TokenWalletDetailsState> {

_updateState();
});

_checkLocalCustodians();
}
}
});
Expand Down Expand Up @@ -129,4 +129,10 @@ class TokenWalletDetailsCubit extends Cubit<TokenWalletDetailsState> {
),
);
}

Future<void> _checkLocalCustodians() async {
final local = await nekotonRepository.getLocalCustodians(owner);
_canSend = local != null && local.isNotEmpty;
_updateState();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -139,20 +139,23 @@ class AccountTransactionsTabCubit extends Cubit<AccountTransactionsTabState> {
),
(_, b) => b ?? [],
).listen(
(transactions) {
(transactions) async {
final multisigTransactions = wallet.unconfirmedTransactions;

_multisigExpired = nekotonRepository.mapMultisigExpiredTransactions(
_multisigExpired =
await nekotonRepository.mapMultisigExpiredTransactions(
walletAddress: wallet.address,
transactions: transactions,
multisigPendingTransactions: multisigTransactions,
);
_multisigOrdinary = nekotonRepository.mapMultisigOrdinaryTransactions(
_multisigOrdinary =
await nekotonRepository.mapMultisigOrdinaryTransactions(
walletAddress: wallet.address,
transactions: transactions,
multisigPendingTransactions: multisigTransactions,
);
_multisigPending = nekotonRepository.mapMultisigPendingTransactions(
_multisigPending =
await nekotonRepository.mapMultisigPendingTransactions(
walletAddress: wallet.address,
transactions: transactions,
multisigPendingTransactions: multisigTransactions,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,8 +67,8 @@ class WalletAccountActionsCubit extends Cubit<WalletAccountActionsState> {
});
}

void _updateWalletData(TonWallet w) {
final localCustodians = nekotonRepository.getLocalCustodians(address);
Future<void> _updateWalletData(TonWallet w) async {
final localCustodians = await nekotonRepository.getLocalCustodians(address);
final details = w.details;
final contract = w.contractState;

Expand Down
4 changes: 2 additions & 2 deletions pubspec.lock
Original file line number Diff line number Diff line change
Expand Up @@ -1437,10 +1437,10 @@ packages:
dependency: "direct main"
description:
name: nekoton_repository
sha256: "1d8f4c61b2bf20fd06410d856ba3721a5e2dbea3adc8f23e1f928d683b339c4f"
sha256: "791ce8a6f197111b63c2cedd3d41aeea22bd2576be005bea093ab45226b7458e"
url: "https://pub.dev"
source: hosted
version: "0.37.0-dev.1"
version: "0.37.0-dev.3"
nekoton_webview:
dependency: "direct main"
description:
Expand Down
2 changes: 1 addition & 1 deletion pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ dependencies:
mobile_scanner: 3.4.1
money2: 5.2.1
money2_fixer: 2.0.0
nekoton_repository: 0.37.0-dev.1
nekoton_repository: 0.37.0-dev.3
# nekoton_webview: 0.1.8-dev.0
nekoton_webview:
git:
Expand Down
Loading