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(market-metrics): hd mode switching values shown, graph interaction, and loading speed #2558

Open
wants to merge 14 commits into
base: dev
Choose a base branch
from
Open
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
29 changes: 13 additions & 16 deletions lib/bloc/app_bloc_root.dart
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ import 'package:web_dex/bloc/auth_bloc/auth_bloc.dart';
import 'package:web_dex/bloc/bitrefill/bloc/bitrefill_bloc.dart';
import 'package:web_dex/bloc/bridge_form/bridge_bloc.dart';
import 'package:web_dex/bloc/bridge_form/bridge_repository.dart';
import 'package:web_dex/bloc/cex_market_data/mockup/generator.dart';
import 'package:web_dex/bloc/cex_market_data/mockup/mock_transaction_history_repository.dart';
import 'package:web_dex/bloc/cex_market_data/mockup/performance_mode.dart';
import 'package:web_dex/bloc/cex_market_data/portfolio_growth/portfolio_growth_bloc.dart';
import 'package:web_dex/bloc/cex_market_data/portfolio_growth/portfolio_growth_repository.dart';
Expand Down Expand Up @@ -76,7 +78,7 @@ class AppBlocRoot extends StatelessWidget {
final KomodoDefiSdk komodoDefiSdk;

// TODO: Refactor to clean up the bloat in this main file
void _clearCachesIfPerformanceModeChanged(
Future<void> _clearCachesIfPerformanceModeChanged(
PerformanceMode? performanceMode,
ProfitLossRepository profitLossRepo,
PortfolioGrowthRepository portfolioGrowthRepo,
Expand Down Expand Up @@ -115,33 +117,28 @@ class AppBlocRoot extends StatelessWidget {
final trezorRepo = RepositoryProvider.of<TrezorRepo>(context);
final trezorBloc = RepositoryProvider.of<TrezorCoinsBloc>(context);

// TODO: SDK Port needed, not sure about this part
final transactionsRepo = /*performanceMode != null
final transactionsRepo = performanceMode != null
? MockTransactionHistoryRepo(
api: mm2Api,
client: Client(),
performanceMode: performanceMode,
demoDataGenerator: DemoDataCache.withDefaults(),
)
: */
SdkTransactionHistoryRepository(sdk: komodoDefiSdk);
: SdkTransactionHistoryRepository(sdk: komodoDefiSdk);

final profitLossRepo = ProfitLossRepository.withDefaults(
transactionHistoryRepo: transactionsRepo,
cexRepository: binanceRepository,
// Returns real data if performanceMode is null. Consider changing the
// other repositories to use this pattern.
demoMode: performanceMode,
coinsRepository: coinsRepository,
mm2Api: mm2Api,
sdk: komodoDefiSdk,
);

final portfolioGrowthRepo = PortfolioGrowthRepository.withDefaults(
transactionHistoryRepo: transactionsRepo,
cexRepository: binanceRepository,
demoMode: performanceMode,
coinsRepository: coinsRepository,
mm2Api: mm2Api,
sdk: komodoDefiSdk,
);

_clearCachesIfPerformanceModeChanged(
Expand Down Expand Up @@ -201,21 +198,21 @@ class AppBlocRoot extends StatelessWidget {
),
BlocProvider<AssetOverviewBloc>(
create: (context) => AssetOverviewBloc(
investmentRepository: InvestmentRepository(
profitLossRepository: profitLossRepo,
),
profitLossRepository: profitLossRepo,
profitLossRepo,
InvestmentRepository(profitLossRepository: profitLossRepo),
komodoDefiSdk,
),
),
BlocProvider<ProfitLossBloc>(
create: (context) => ProfitLossBloc(
profitLossRepository: profitLossRepo,
profitLossRepo,
komodoDefiSdk,
),
),
BlocProvider<PortfolioGrowthBloc>(
create: (BuildContext ctx) => PortfolioGrowthBloc(
portfolioGrowthRepository: portfolioGrowthRepo,
coinsRepository: coinsRepository,
sdk: komodoDefiSdk,
),
),
BlocProvider<TransactionHistoryBloc>(
Expand Down
48 changes: 28 additions & 20 deletions lib/bloc/assets_overview/bloc/asset_overview_bloc.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,24 @@ import 'dart:async';

import 'package:bloc/bloc.dart';
import 'package:equatable/equatable.dart';
import 'package:komodo_defi_sdk/komodo_defi_sdk.dart';
import 'package:logging/logging.dart';
import 'package:web_dex/bloc/assets_overview/investment_repository.dart';
import 'package:web_dex/bloc/cex_market_data/profit_loss/models/fiat_value.dart';
import 'package:web_dex/bloc/cex_market_data/profit_loss/models/profit_loss.dart';
import 'package:web_dex/bloc/cex_market_data/profit_loss/profit_loss_repository.dart';
import 'package:web_dex/bloc/cex_market_data/sdk_auth_activation_extension.dart';
import 'package:web_dex/model/coin.dart';
import 'package:web_dex/shared/utils/utils.dart' as logger;

part 'asset_overview_event.dart';
part 'asset_overview_state.dart';

class AssetOverviewBloc extends Bloc<AssetOverviewEvent, AssetOverviewState> {
AssetOverviewBloc({
required this.profitLossRepository,
required this.investmentRepository,
}) : super(const AssetOverviewInitial()) {
AssetOverviewBloc(
this._profitLossRepository,
this._investmentRepository,
this._sdk,
) : super(const AssetOverviewInitial()) {
on<AssetOverviewLoadRequested>(_onLoad);
on<AssetOverviewClearRequested>(_onClear);
on<PortfolioAssetsOverviewLoadRequested>(_onLoadPortfolio);
Expand All @@ -26,9 +29,10 @@ class AssetOverviewBloc extends Bloc<AssetOverviewEvent, AssetOverviewState> {
on<PortfolioAssetsOverviewUnsubscriptionRequested>(_onUnsubscribePortfolio);
}

final ProfitLossRepository profitLossRepository;
final InvestmentRepository investmentRepository;

final ProfitLossRepository _profitLossRepository;
final InvestmentRepository _investmentRepository;
final KomodoDefiSdk _sdk;
final _log = Logger('AssetOverviewBloc');
Timer? _updateTimer;

Future<void> _onLoad(
Expand All @@ -38,14 +42,14 @@ class AssetOverviewBloc extends Bloc<AssetOverviewEvent, AssetOverviewState> {
emit(const AssetOverviewLoadInProgress());

try {
final profitLosses = await profitLossRepository.getProfitLoss(
final profitLosses = await _profitLossRepository.getProfitLoss(
event.coin.id,
'USDT',
event.walletId,
);

final totalInvestment =
await investmentRepository.calculateTotalInvestment(
await _investmentRepository.calculateTotalInvestment(
event.walletId,
[event.coin],
);
Expand All @@ -65,8 +69,8 @@ class AssetOverviewBloc extends Bloc<AssetOverviewEvent, AssetOverviewState> {
investmentReturnPercentage: investmentReturnPercentage,
),
);
} catch (e) {
logger.log('Failed to load asset overview: $e', isError: true);
} catch (e, s) {
_log.shout('Failed to load asset overview', e, s);
if (state is! AssetOverviewLoadSuccess) {
emit(AssetOverviewLoadFailure(error: e.toString()));
}
Expand All @@ -86,16 +90,20 @@ class AssetOverviewBloc extends Bloc<AssetOverviewEvent, AssetOverviewState> {
PortfolioAssetsOverviewLoadRequested event,
Emitter<AssetOverviewState> emit,
) async {
// nothing listens to this. The UI just resets to default values, i.e. 0
// emit(const AssetOverviewLoadInProgress());

try {
if (event.coins.isEmpty) {
_log.warning('No coins to load portfolio overview for');
return;
}

await _sdk.waitForEnabledCoinsToPassThreshold(event.coins);

final profitLossesFutures = event.coins.map((coin) async {
// Catch errors that occur for single coins and exclude them from the
// total so that transaction fetching errors for a single coin do not
// affect the total investment calculation.
try {
return await profitLossRepository.getProfitLoss(
return await _profitLossRepository.getProfitLoss(
coin.id,
'USDT',
event.walletId,
Expand All @@ -108,7 +116,7 @@ class AssetOverviewBloc extends Bloc<AssetOverviewEvent, AssetOverviewState> {
final profitLosses = await Future.wait(profitLossesFutures);

final totalInvestment =
await investmentRepository.calculateTotalInvestment(
await _investmentRepository.calculateTotalInvestment(
event.walletId,
event.coins,
);
Expand All @@ -125,16 +133,16 @@ class AssetOverviewBloc extends Bloc<AssetOverviewEvent, AssetOverviewState> {

emit(
PortfolioAssetsOverviewLoadSuccess(
selectedAssetIds: event.coins.map((coin) => coin.abbr).toList(),
selectedAssetIds: event.coins.map((coin) => coin.id.id).toList(),
assetPortionPercentages: assetPortionPercentages,
totalInvestment: totalInvestment,
totalValue: FiatValue.usd(profitAmount),
profitAmount: FiatValue.usd(profitAmount),
profitIncreasePercentage: portfolioInvestmentReturnPercentage,
),
);
} catch (e) {
logger.log('Failed to load portfolio assets overview: $e', isError: true);
} catch (e, s) {
_log.shout('Failed to load portfolio assets overview', e, s);
if (state is! PortfolioAssetsOverviewLoadSuccess) {
emit(AssetOverviewLoadFailure(error: e.toString()));
}
Expand Down
65 changes: 32 additions & 33 deletions lib/bloc/auth_bloc/auth_bloc.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,12 @@ import 'package:equatable/equatable.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:komodo_defi_sdk/komodo_defi_sdk.dart';
import 'package:komodo_defi_types/komodo_defi_types.dart';
import 'package:logging/logging.dart';
import 'package:web_dex/app_config/app_config.dart';
import 'package:web_dex/blocs/wallets_repository.dart';
import 'package:web_dex/model/authorize_mode.dart';
import 'package:web_dex/model/kdf_auth_metadata_extension.dart';
import 'package:web_dex/model/wallet.dart';
import 'package:web_dex/shared/utils/utils.dart';

part 'auth_bloc_event.dart';
part 'auth_bloc_state.dart';
Expand All @@ -33,6 +34,7 @@ class AuthBloc extends Bloc<AuthBlocEvent, AuthBlocState> {
final KomodoDefiSdk _kdfSdk;
final WalletsRepository _walletsRepository;
StreamSubscription<KdfUser?>? _authChangesSubscription;
final _log = Logger('AuthBloc');

@override
Future<void> close() async {
Expand All @@ -44,7 +46,7 @@ class AuthBloc extends Bloc<AuthBlocEvent, AuthBlocState> {
AuthSignOutRequested event,
Emitter<AuthBlocState> emit,
) async {
log('Logging out from a wallet', path: 'auth_bloc => _logOut').ignore();
_log.info('Logging out from a wallet');
emit(AuthBlocState.loading());
await _kdfSdk.auth.signOut();
await _authChangesSubscription?.cancel();
Expand All @@ -66,7 +68,7 @@ class AuthBloc extends Bloc<AuthBlocEvent, AuthBlocState> {
);
}

log('login from a wallet', path: 'auth_bloc => _reLogin').ignore();
_log.info('login from a wallet');
emit(AuthBlocState.loading());
await _kdfSdk.auth.signIn(
walletName: event.wallet.name,
Expand All @@ -82,13 +84,12 @@ class AuthBloc extends Bloc<AuthBlocEvent, AuthBlocState> {
return emit(AuthBlocState.error('Failed to login'));
}

log('logged in from a wallet', path: 'auth_bloc => _reLogin').ignore();
_log.info('logged in from a wallet');
emit(AuthBlocState.loggedIn(currentUser));
_listenToAuthStateChanges();
} catch (e, s) {
final error = 'Failed to login wallet ${event.wallet.name}';
log(error, isError: true, trace: s, path: 'auth_bloc -> onLogin')
.ignore();
_log.shout(error, e, s);
emit(AuthBlocState.error(error));
await _authChangesSubscription?.cancel();
}
Expand Down Expand Up @@ -119,7 +120,7 @@ class AuthBloc extends Bloc<AuthBlocEvent, AuthBlocState> {
return;
}

log('register from a wallet', path: 'auth_bloc => _register').ignore();
_log.info('register from a wallet');
await _kdfSdk.auth.register(
password: event.password,
walletName: event.wallet.name,
Expand All @@ -130,13 +131,11 @@ class AuthBloc extends Bloc<AuthBlocEvent, AuthBlocState> {
),
);

if (!await _kdfSdk.auth.isSignedIn()) {
throw Exception('Registration failed: user is not signed in');
}

log('registered from a wallet', path: 'auth_bloc => _register').ignore();
_log.info('registered from a wallet');
await _kdfSdk.setWalletType(event.wallet.config.type);
await _kdfSdk.confirmSeedBackup(hasBackup: false);
await _kdfSdk.addActivatedCoins(enabledByDefaultCoins);

final currentUser = await _kdfSdk.auth.currentUser;
if (currentUser == null) {
throw Exception('Registration failed: user is not signed in');
Expand All @@ -145,8 +144,7 @@ class AuthBloc extends Bloc<AuthBlocEvent, AuthBlocState> {
_listenToAuthStateChanges();
} catch (e, s) {
final error = 'Failed to register wallet ${event.wallet.name}';
log(error, isError: true, trace: s, path: 'auth_bloc -> onRegister')
.ignore();
_log.shout(error, e, s);
emit(AuthBlocState.error(error));
await _authChangesSubscription?.cancel();
}
Expand All @@ -162,7 +160,7 @@ class AuthBloc extends Bloc<AuthBlocEvent, AuthBlocState> {
return;
}

log('restore from a wallet', path: 'auth_bloc => _restore').ignore();
_log.info('restore from a wallet');
await _kdfSdk.auth.register(
password: event.password,
walletName: event.wallet.name,
Expand All @@ -174,13 +172,11 @@ class AuthBloc extends Bloc<AuthBlocEvent, AuthBlocState> {
),
);

if (!await _kdfSdk.auth.isSignedIn()) {
throw Exception('Registration failed: user is not signed in');
}

log('restored from a wallet', path: 'auth_bloc => _restore').ignore();
_log.info('restored from a wallet');
await _kdfSdk.setWalletType(event.wallet.config.type);
await _kdfSdk.confirmSeedBackup(hasBackup: event.wallet.config.hasBackup);
await _kdfSdk.addActivatedCoins(enabledByDefaultCoins);

final currentUser = await _kdfSdk.auth.currentUser;
if (currentUser == null) {
throw Exception('Registration failed: user is not signed in');
Expand All @@ -197,8 +193,7 @@ class AuthBloc extends Bloc<AuthBlocEvent, AuthBlocState> {
_listenToAuthStateChanges();
} catch (e, s) {
final error = 'Failed to restore existing wallet ${event.wallet.name}';
log(error, isError: true, trace: s, path: 'auth_bloc -> onRestore')
.ignore();
_log.shout(error, e, s);
emit(AuthBlocState.error(error));
await _authChangesSubscription?.cancel();
}
Expand All @@ -213,7 +208,7 @@ class AuthBloc extends Bloc<AuthBlocEvent, AuthBlocState> {
.any((KdfUser user) => user.walletId.name == wallet.name);
if (walletExists) {
add(AuthSignInRequested(wallet: wallet, password: password));
log('Wallet ${wallet.name} already exist, attempting sign-in').ignore();
_log.warning('Wallet ${wallet.name} already exist, attempting sign-in');
return true;
}

Expand All @@ -239,18 +234,22 @@ class AuthBloc extends Bloc<AuthBlocEvent, AuthBlocState> {
AuthWalletDownloadRequested event,
Emitter<AuthBlocState> emit,
) async {
final Wallet? wallet = (await _kdfSdk.auth.currentUser)?.wallet;
if (wallet == null) return;
try {
final Wallet? wallet = (await _kdfSdk.auth.currentUser)?.wallet;
if (wallet == null) return;

await _walletsRepository.downloadEncryptedWallet(wallet, event.password);
await _walletsRepository.downloadEncryptedWallet(wallet, event.password);

await _kdfSdk.confirmSeedBackup();
emit(
AuthBlocState(
mode: AuthorizeMode.logIn,
currentUser: await _kdfSdk.auth.currentUser,
),
);
await _kdfSdk.confirmSeedBackup();
emit(
AuthBlocState(
mode: AuthorizeMode.logIn,
currentUser: await _kdfSdk.auth.currentUser,
),
);
} catch (e, s) {
_log.shout('Failed to download wallet data', e, s);
}
}

void _listenToAuthStateChanges() {
Expand Down
Loading
Loading