Skip to content

Commit

Permalink
Merge pull request #430 from kumulynja/refactor-homebloc-wallet-updates
Browse files Browse the repository at this point in the history
use streams to get updates in wallet services and WalletServiceData
  • Loading branch information
mocodesmo authored Jan 14, 2025
2 parents 7343ba4 + 38c2ca2 commit 1f2ac02
Show file tree
Hide file tree
Showing 6 changed files with 134 additions and 183 deletions.
9 changes: 9 additions & 0 deletions lib/_repository/app_wallets_repository.dart
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import 'dart:async';

import 'package:bb_mobile/_model/swap.dart';
import 'package:bb_mobile/_model/transaction.dart';
import 'package:bb_mobile/_model/wallet.dart';
Expand All @@ -11,6 +13,11 @@ class AppWalletsRepository {
final WalletsStorageRepository _walletsStorageRepository;

final List<WalletService> _walletServices = [];
final StreamController<List<WalletService>> _walletsController =
StreamController.broadcast();

Stream<List<WalletService>> get wallets =>
_walletsController.stream.asBroadcastStream();

Future<void> getWalletsFromStorage() async {
final (wallets, err) = await _walletsStorageRepository.readAllWallets();
Expand All @@ -28,6 +35,7 @@ class AppWalletsRepository {
.map((_) => createWalletService(wallet: _, fromStorage: true))
.toList(),
);
_walletsController.add(_walletServices);
}

List<Wallet> get allWallets => _walletServices.map((_) => _.wallet).toList();
Expand All @@ -46,6 +54,7 @@ class AppWalletsRepository {

void deleteWallet(String id) {
_walletServices.removeWhere((_) => _.wallet.id == id);
_walletsController.add(_walletServices);
}

List<WalletService> walletServiceFromNetwork(BBNetwork network) =>
Expand Down
54 changes: 50 additions & 4 deletions lib/home/bloc/home_bloc.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,10 @@ import 'dart:async';

import 'package:bb_mobile/_repository/app_wallets_repository.dart';
import 'package:bb_mobile/_repository/network_repository.dart';
import 'package:bb_mobile/_repository/wallet_service.dart';
import 'package:bb_mobile/home/bloc/home_event.dart';
import 'package:bb_mobile/home/bloc/home_state.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';

class HomeBloc extends Bloc<HomeEvent, HomeState> {
Expand All @@ -19,6 +21,11 @@ class HomeBloc extends Bloc<HomeEvent, HomeState> {
on<UpdatedNotifier>(_onUpdatedNotifier);
on<LoadWalletsForNetwork>(_onLoadWalletsForNetwork);
on<WalletUpdated>(_onWalletUpdated);

on<WalletServicesUpdated>(_onWalletServicesUpdated);

_walletServicesSubscription = _appWalletsRepository.wallets
.listen((walletServices) => add(WalletServicesUpdated(walletServices)));
// on<WalletsSubscribe>(
// (event, emit) async {
// print('wallets updated');
Expand All @@ -38,6 +45,43 @@ class HomeBloc extends Bloc<HomeEvent, HomeState> {

final AppWalletsRepository _appWalletsRepository;
final NetworkRepository _networkRepository;
late StreamSubscription _walletServicesSubscription;
final Map<String, StreamSubscription> _walletServiceDataUpdateSubscriptions =
{};

@override
Future<void> close() {
_walletServicesSubscription.cancel();
for (final sub in _walletServiceDataUpdateSubscriptions.values) {
sub.cancel();
}
return super.close();
}

Future<void> _onWalletServicesUpdated(
WalletServicesUpdated event,
Emitter<HomeState> emit,
) async {
debugPrint('wallet services updated: ${event.walletServices.length}');
final walletServicesData = event.walletServices
.map((_) => WalletServiceData(wallet: _.wallet))
.toList();
emit(state.copyWith(wallets: walletServicesData));

// Listen to wallet data updates
for (final ws in event.walletServices) {
if (_walletServiceDataUpdateSubscriptions.containsKey(ws.wallet.id)) {
_walletServiceDataUpdateSubscriptions[ws.wallet.id]!.cancel();
}
_walletServiceDataUpdateSubscriptions[ws.wallet.id] =
ws.dataStream.listen(
(data) {
debugPrint('wallet data updated from stream: ${data.wallet.id}');
add(WalletUpdated(data));
},
);
}
}

Future<void> _onLoadWalletsFromStorage(
LoadWalletsFromStorage event,
Expand All @@ -46,7 +90,8 @@ class HomeBloc extends Bloc<HomeEvent, HomeState> {
emit(state.copyWith(loadingWallets: true));
await _appWalletsRepository.getWalletsFromStorage();
final wallets = _appWalletsRepository.allWallets;
emit(state.copyWith(wallets: wallets));
emit(state.copyWith(
wallets: wallets.map((_) => WalletServiceData(wallet: _)).toList()));
await _appWalletsRepository
.loadAllInNetwork(_networkRepository.getBBNetwork);
_appWalletsRepository.syncAllInNetwork(_networkRepository.getBBNetwork);
Expand Down Expand Up @@ -97,11 +142,12 @@ class HomeBloc extends Bloc<HomeEvent, HomeState> {
WalletUpdated event,
Emitter<HomeState> emit,
) {
final wallet = event.wallet;
debugPrint('wallet updated: ${event.walletData.wallet.id}');
final walletData = event.walletData;
final wallets = state.wallets.toList();
final idx = wallets.indexWhere((w) => w.id == wallet.id);
final idx = wallets.indexWhere((w) => w.wallet.id == walletData.wallet.id);
if (idx == -1) return;
wallets[idx] = wallet;
wallets[idx] = walletData;
emit(state.copyWith(wallets: wallets));
}
}
10 changes: 8 additions & 2 deletions lib/home/bloc/home_event.dart
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import 'package:bb_mobile/_model/wallet.dart';
import 'package:bb_mobile/_repository/wallet_service.dart';

class HomeEvent {}

Expand All @@ -23,8 +24,13 @@ class LoadWalletsForNetwork extends HomeEvent {
}

class WalletUpdated extends HomeEvent {
WalletUpdated(this.wallet);
final Wallet wallet;
WalletUpdated(this.walletData);
final WalletServiceData walletData;
}

class WalletServicesUpdated extends HomeEvent {
WalletServicesUpdated(this.walletServices);
final List<WalletService> walletServices;
}

class WalletsSubscribe extends HomeEvent {}
106 changes: 52 additions & 54 deletions lib/home/bloc/home_state.dart
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
import 'package:bb_mobile/_model/swap.dart';
import 'package:bb_mobile/_model/transaction.dart';
import 'package:bb_mobile/_model/wallet.dart';
import 'package:bb_mobile/_repository/wallet_service.dart';
import 'package:freezed_annotation/freezed_annotation.dart';

part 'home_state.freezed.dart';

@freezed
class HomeState with _$HomeState {
const factory HomeState({
@Default([]) List<Wallet> wallets,
@Default([]) List<WalletServiceData> wallets,
// List<Wallet>? tempwallets,
// List<Wallet>? wallets,
@Default(true) bool loadingWallets,
Expand All @@ -23,49 +24,46 @@ class HomeState with _$HomeState {
}) = _HomeState;
const HomeState._();

bool hasWallets() =>
!loadingWallets && wallets != null && wallets!.isNotEmpty;
bool syncingAny() => wallets.any((_) => _.syncing);

bool hasWallets() => !loadingWallets && wallets.isNotEmpty;

// List<Wallet> walletsFromNetwork(BBNetwork network) =>
// wallets?.where((wallet) => wallet.network == network).toList().reversed.toList() ?? [];

bool hasMainWallets() => wallets?.any((_) => _.mainWallet) ?? false;
bool hasMainWallets() => wallets.any((_) => _.wallet.mainWallet);

List<Wallet> walletsFromNetwork(BBNetwork network) {
final blocs = wallets
?.where((_) => _.network == network)
//.toList()
//.reversed
.toList() ??
[];
final walletsData = wallets
.where((_) => _.wallet.network == network)
//.toList()
//.reversed
.toList();

return blocs;
return walletsData.map((e) => e.wallet).toList();
}

List<Wallet> walletsFromNetworkExcludeWatchOnly(BBNetwork network) {
final blocs = wallets
?.where(
(walletBloc) =>
walletBloc.network == network &&
walletBloc.watchOnly() == false,
)
.toList() ??
[];

return blocs;
final data = wallets
.where(
(d) => d.wallet.network == network && d.wallet.watchOnly() == false,
)
.toList();

return data.map((e) => e.wallet).toList();
}

List<Wallet> walletsNotMainFromNetwork(BBNetwork network) {
final blocs = wallets
?.where(
(wallet) => wallet.network == network && !wallet.mainWallet,
)
.toList()
.reversed
.toList() ??
[];

return blocs;
.where(
(wallet) =>
wallet.wallet.network == network && !wallet.wallet.mainWallet,
)
.toList()
.reversed
.toList();

return blocs.map((e) => e.wallet).toList();
}

int lenWalletsFromNetwork(BBNetwork network) =>
Expand Down Expand Up @@ -113,28 +111,25 @@ class HomeState with _$HomeState {
}

Wallet? getWalletFromTx(Transaction tx) {
if (wallets == null) return null;

for (final walletBloc in wallets!) {
for (final walletBloc in wallets) {
final wallet = walletBloc;
if (wallet.transactions.indexWhere((t) => t.txid == tx.txid) != -1) {
return walletBloc;
if (wallet.wallet.transactions.indexWhere((t) => t.txid == tx.txid) !=
-1) {
return walletBloc.wallet;
}
}

return null;
}

Wallet? getWalletFromSwapTx(SwapTx swaptx) {
if (wallets == null) return null;

for (final walletBloc in wallets!) {
for (final walletBloc in wallets) {
final wallet = walletBloc;
if (wallet.transactions.indexWhere(
if (wallet.wallet.transactions.indexWhere(
(t) => t.swapTx?.id == swaptx.id,
) !=
-1) {
return walletBloc;
return walletBloc.wallet;
}
}

Expand Down Expand Up @@ -162,9 +157,9 @@ class HomeState with _$HomeState {
// if (walletIdx == -1) return null;
// final wallet = wallets![walletIdx];
// final wallets = walletsFromNetwork(wallet.network);
final idx = wallets?.indexWhere((w) => id == w.id);
if (idx == -1 || idx == null) return null;
return wallets![idx];
final idx = wallets.indexWhere((w) => id == w.wallet.id);
if (idx == -1) return null;
return wallets[idx].wallet;
}

Wallet? getFirstWithSpendableAndBalance(BBNetwork network, {int amt = 0}) {
Expand All @@ -182,18 +177,19 @@ class HomeState with _$HomeState {
}

SwapTx? getSwapTxById(String id) {
for (final walletBloc in wallets!) {
for (final walletBloc in wallets) {
final wallet = walletBloc;
if (wallet.swaps.isEmpty) continue;
final idx = wallet.swaps.indexWhere((_) => _.id == id);
if (idx != -1) return wallet.swaps[idx];
if (wallet.wallet.swaps.isEmpty) continue;
final idx = wallet.wallet.swaps.indexWhere((_) => _.id == id);
if (idx != -1) return wallet.wallet.swaps[idx];
}

for (final walletBloc in wallets!) {
for (final walletBloc in wallets) {
final wallet = walletBloc;
if (wallet.transactions.isEmpty) continue;
final idx = wallet.transactions.indexWhere((_) => _.swapTx?.id == id);
if (idx != -1) return wallet.transactions[idx].swapTx;
if (wallet.wallet.transactions.isEmpty) continue;
final idx =
wallet.wallet.transactions.indexWhere((_) => _.swapTx?.id == id);
if (idx != -1) return wallet.wallet.transactions[idx].swapTx;
}

return null;
Expand Down Expand Up @@ -440,10 +436,12 @@ class HomeState with _$HomeState {
}

Wallet? findWalletWithSameFngr(Wallet wallet) {
for (final wb in wallets!) {
for (final wb in wallets) {
final w = wb;
if (w.id == wallet.id) continue;
if (w.sourceFingerprint == wallet.sourceFingerprint) return wb;
if (w.wallet.id == wallet.id) continue;
if (w.wallet.sourceFingerprint == wallet.sourceFingerprint) {
return wb.wallet;
}
}
return null;
}
Expand Down
16 changes: 3 additions & 13 deletions lib/home/home_page.dart
Original file line number Diff line number Diff line change
Expand Up @@ -48,12 +48,7 @@ class HomePage extends StatelessWidget {

@override
Widget build(BuildContext context) {
return BlocProvider.value(
value: HomeLoadingCubit(),
child: const HomeWalletLoadingListeners(
child: _Screen(),
),
);
return const _Screen();
}
}

Expand Down Expand Up @@ -879,13 +874,8 @@ class HomeLoadingTxsIndicator extends StatelessWidget {

@override
Widget build(BuildContext context) {
return BlocBuilder<HomeLoadingCubit, Map<String, bool>>(
buildWhen: (previous, current) => previous.values != current.values,
builder: (context, state) {
final isLoading = state.values.contains(true);
return _Loading(loading: isLoading);
},
);
final isSyncing = context.select((HomeBloc x) => x.state.syncingAny());
return _Loading(loading: isSyncing);
}
}

Expand Down
Loading

0 comments on commit 1f2ac02

Please sign in to comment.