centralize changenow loading

This commit is contained in:
julian 2022-10-04 08:46:22 -06:00
parent 3d5f6a8d12
commit 9189754363
5 changed files with 109 additions and 226 deletions

View file

@ -25,7 +25,6 @@ import 'package:stackwallet/models/models.dart';
import 'package:stackwallet/models/node_model.dart'; import 'package:stackwallet/models/node_model.dart';
import 'package:stackwallet/models/notification_model.dart'; import 'package:stackwallet/models/notification_model.dart';
import 'package:stackwallet/models/trade_wallet_lookup.dart'; import 'package:stackwallet/models/trade_wallet_lookup.dart';
import 'package:stackwallet/pages/exchange_view/exchange_view.dart';
import 'package:stackwallet/pages/home_view/home_view.dart'; import 'package:stackwallet/pages/home_view/home_view.dart';
import 'package:stackwallet/pages/intro_view.dart'; import 'package:stackwallet/pages/intro_view.dart';
import 'package:stackwallet/pages/loading_view.dart'; import 'package:stackwallet/pages/loading_view.dart';
@ -33,10 +32,6 @@ import 'package:stackwallet/pages/pinpad_views/create_pin_view.dart';
import 'package:stackwallet/pages/pinpad_views/lock_screen_view.dart'; import 'package:stackwallet/pages/pinpad_views/lock_screen_view.dart';
import 'package:stackwallet/pages/settings_views/global_settings_view/stack_backup_views/restore_from_encrypted_string_view.dart'; import 'package:stackwallet/pages/settings_views/global_settings_view/stack_backup_views/restore_from_encrypted_string_view.dart';
import 'package:stackwallet/pages_desktop_specific/home/desktop_home_view.dart'; import 'package:stackwallet/pages_desktop_specific/home/desktop_home_view.dart';
import 'package:stackwallet/providers/exchange/available_currencies_state_provider.dart';
import 'package:stackwallet/providers/exchange/available_floating_rate_pairs_state_provider.dart';
import 'package:stackwallet/providers/exchange/changenow_initial_load_status.dart';
import 'package:stackwallet/providers/exchange/fixed_rate_market_pairs_provider.dart';
import 'package:stackwallet/providers/global/auto_swb_service_provider.dart'; import 'package:stackwallet/providers/global/auto_swb_service_provider.dart';
import 'package:stackwallet/providers/global/base_currencies_provider.dart'; import 'package:stackwallet/providers/global/base_currencies_provider.dart';
// import 'package:stackwallet/providers/global/has_authenticated_start_state_provider.dart'; // import 'package:stackwallet/providers/global/has_authenticated_start_state_provider.dart';
@ -45,8 +40,8 @@ import 'package:stackwallet/providers/providers.dart';
import 'package:stackwallet/providers/ui/color_theme_provider.dart'; import 'package:stackwallet/providers/ui/color_theme_provider.dart';
import 'package:stackwallet/route_generator.dart'; import 'package:stackwallet/route_generator.dart';
import 'package:stackwallet/services/debug_service.dart'; import 'package:stackwallet/services/debug_service.dart';
import 'package:stackwallet/services/exchange/change_now/change_now_api.dart';
import 'package:stackwallet/services/exchange/change_now/change_now_exchange.dart'; import 'package:stackwallet/services/exchange/change_now/change_now_exchange.dart';
import 'package:stackwallet/services/exchange/change_now/change_now_loading_service.dart';
import 'package:stackwallet/services/locale_service.dart'; import 'package:stackwallet/services/locale_service.dart';
import 'package:stackwallet/services/node_service.dart'; import 'package:stackwallet/services/node_service.dart';
import 'package:stackwallet/services/notifications_api.dart'; import 'package:stackwallet/services/notifications_api.dart';
@ -232,6 +227,11 @@ class _MaterialAppWithThemeState extends ConsumerState<MaterialAppWithTheme>
// TODO: this should probably run unawaited. Keep commented out for now as proper community nodes ui hasn't been implemented yet // TODO: this should probably run unawaited. Keep commented out for now as proper community nodes ui hasn't been implemented yet
// unawaited(_nodeService.updateCommunityNodes()); // unawaited(_nodeService.updateCommunityNodes());
// run without awaiting
if (Constants.enableExchange) {
unawaited(ChangeNowLoadingService().loadAll(ref));
}
if (_prefs.isAutoBackupEnabled) { if (_prefs.isAutoBackupEnabled) {
switch (_prefs.backupFrequencyType) { switch (_prefs.backupFrequencyType) {
case BackupFrequencyType.everyTenMinutes: case BackupFrequencyType.everyTenMinutes:
@ -249,109 +249,101 @@ class _MaterialAppWithThemeState extends ConsumerState<MaterialAppWithTheme>
} }
} }
Future<void> _loadChangeNowStandardCurrencies() async { // Future<void> _loadChangeNowStandardCurrencies() async {
if (ref // if (ref
.read(availableChangeNowCurrenciesStateProvider.state) // .read(availableChangeNowCurrenciesStateProvider.state)
.state // .state
.isNotEmpty && // .isNotEmpty &&
ref // ref
.read(availableFloatingRatePairsStateProvider.state) // .read(availableFloatingRatePairsStateProvider.state)
.state // .state
.isNotEmpty) { // .isNotEmpty) {
return; // return;
} // }
final response = await ChangeNowAPI.instance.getAvailableCurrencies(); // final response = await ChangeNowAPI.instance.getAvailableCurrencies();
final response2 = // final response2 =
await ChangeNowAPI.instance.getAvailableFloatingRatePairs(); // await ChangeNowAPI.instance.getAvailableFloatingRatePairs();
if (response.value != null) { // if (response.value != null) {
ref.read(availableChangeNowCurrenciesStateProvider.state).state = // ref.read(availableChangeNowCurrenciesStateProvider.state).state =
response.value!; // response.value!;
if (response2.value != null) { // if (response2.value != null) {
ref.read(availableFloatingRatePairsStateProvider.state).state = // ref.read(availableFloatingRatePairsStateProvider.state).state =
response2.value!; // response2.value!;
//
// if (response.value!.length > 1) {
// if (ref.read(exchangeFormStateProvider).from == null) {
// if (response.value!.where((e) => e.ticker == "btc").isNotEmpty) {
// await ref.read(exchangeFormStateProvider).updateFrom(
// response.value!.firstWhere((e) => e.ticker == "btc"), false);
// }
// }
// if (ref.read(exchangeFormStateProvider).to == null) {
// if (response.value!.where((e) => e.ticker == "doge").isNotEmpty) {
// await ref.read(exchangeFormStateProvider).updateTo(
// response.value!.firstWhere((e) => e.ticker == "doge"), false);
// }
// }
// }
// } else {
// Logging.instance.log(
// "Failed to load changeNOW available floating rate pairs: ${response2.exception?.errorMessage}",
// level: LogLevel.Error);
// ref.read(changeNowEstimatedInitialLoadStatusStateProvider.state).state =
// ChangeNowLoadStatus.failed;
// return;
// }
// } else {
// Logging.instance.log(
// "Failed to load changeNOW currencies: ${response.exception?.errorMessage}",
// level: LogLevel.Error);
// await Future<void>.delayed(const Duration(seconds: 1));
// ref.read(changeNowEstimatedInitialLoadStatusStateProvider.state).state =
// ChangeNowLoadStatus.failed;
// return;
// }
//
// ref.read(changeNowEstimatedInitialLoadStatusStateProvider.state).state =
// ChangeNowLoadStatus.success;
// }
if (response.value!.length > 1) { // Future<void> _loadFixedRateMarkets() async {
if (ref.read(exchangeFormStateProvider).from == null) { // Logging.instance.log("Starting initial fixed rate market data loading...",
if (response.value!.where((e) => e.ticker == "btc").isNotEmpty) { // level: LogLevel.Info);
await ref.read(exchangeFormStateProvider).updateFrom( // if (ref.read(fixedRateMarketPairsStateProvider.state).state.isNotEmpty) {
response.value!.firstWhere((e) => e.ticker == "btc"), false); // return;
} // }
} //
if (ref.read(exchangeFormStateProvider).to == null) { // final response3 =
if (response.value!.where((e) => e.ticker == "doge").isNotEmpty) { // await ChangeNowAPI.instance.getAvailableFixedRateMarkets();
await ref.read(exchangeFormStateProvider).updateTo( // if (response3.value != null) {
response.value!.firstWhere((e) => e.ticker == "doge"), false); // ref.read(fixedRateMarketPairsStateProvider.state).state =
} // response3.value!;
} //
} // if (ref.read(exchangeFormStateProvider).market == null) {
} else { // final matchingMarkets =
Logging.instance.log( // response3.value!.where((e) => e.to == "doge" && e.from == "btc");
"Failed to load changeNOW available floating rate pairs: ${response2.exception?.errorMessage}", // if (matchingMarkets.isNotEmpty) {
level: LogLevel.Error); // await ref
ref.read(changeNowEstimatedInitialLoadStatusStateProvider.state).state = // .read(exchangeFormStateProvider)
ChangeNowLoadStatus.failed; // .updateMarket(matchingMarkets.first, true);
return; // }
} // }
} else { //
Logging.instance.log( // Logging.instance.log("Initial fixed rate market data loading complete.",
"Failed to load changeNOW currencies: ${response.exception?.errorMessage}", // level: LogLevel.Info);
level: LogLevel.Error); // } else {
await Future<void>.delayed(const Duration(seconds: 1)); // Logging.instance.log(
ref.read(changeNowEstimatedInitialLoadStatusStateProvider.state).state = // "Failed to load changeNOW fixed rate markets: ${response3.exception?.errorMessage}",
ChangeNowLoadStatus.failed; // level: LogLevel.Error);
return; //
} // ref.read(changeNowFixedInitialLoadStatusStateProvider.state).state =
// ChangeNowLoadStatus.failed;
ref.read(changeNowEstimatedInitialLoadStatusStateProvider.state).state = // return;
ChangeNowLoadStatus.success; // }
} //
// ref.read(changeNowFixedInitialLoadStatusStateProvider.state).state =
Future<void> _loadFixedRateMarkets() async { // ChangeNowLoadStatus.success;
Logging.instance.log("Starting initial fixed rate market data loading...", // }
level: LogLevel.Info);
if (ref.read(fixedRateMarketPairsStateProvider.state).state.isNotEmpty) {
return;
}
final response3 =
await ChangeNowAPI.instance.getAvailableFixedRateMarkets();
if (response3.value != null) {
ref.read(fixedRateMarketPairsStateProvider.state).state =
response3.value!;
if (ref.read(exchangeFormStateProvider).market == null) {
final matchingMarkets =
response3.value!.where((e) => e.to == "doge" && e.from == "btc");
if (matchingMarkets.isNotEmpty) {
await ref
.read(exchangeFormStateProvider)
.updateMarket(matchingMarkets.first, true);
}
}
Logging.instance.log("Initial fixed rate market data loading complete.",
level: LogLevel.Info);
} else {
Logging.instance.log(
"Failed to load changeNOW fixed rate markets: ${response3.exception?.errorMessage}",
level: LogLevel.Error);
ref.read(changeNowFixedInitialLoadStatusStateProvider.state).state =
ChangeNowLoadStatus.failed;
return;
}
ref.read(changeNowFixedInitialLoadStatusStateProvider.state).state =
ChangeNowLoadStatus.success;
}
Future<void> _loadChangeNowData() async {
List<Future<dynamic>> concurrentFutures = [];
concurrentFutures.add(_loadChangeNowStandardCurrencies());
if (kFixedRateEnabled) {
concurrentFutures.add(_loadFixedRateMarkets());
}
}
@override @override
void initState() { void initState() {
@ -636,11 +628,6 @@ class _MaterialAppWithThemeState extends ConsumerState<MaterialAppWithTheme>
if (_wallets.hasWallets || _prefs.hasPin) { if (_wallets.hasWallets || _prefs.hasPin) {
// return HomeView(); // return HomeView();
// run without awaiting
if (Constants.enableExchange) {
_loadChangeNowData();
}
String? startupWalletId; String? startupWalletId;
if (ref.read(prefsChangeNotifierProvider).gotoWalletOnStartup) { if (ref.read(prefsChangeNotifierProvider).gotoWalletOnStartup) {
startupWalletId = startupWalletId =

View file

@ -13,8 +13,6 @@ import 'package:stackwallet/utilities/theme/stack_colors.dart';
import 'package:stackwallet/widgets/trade_card.dart'; import 'package:stackwallet/widgets/trade_card.dart';
import 'package:tuple/tuple.dart'; import 'package:tuple/tuple.dart';
const kFixedRateEnabled = true;
class ExchangeView extends ConsumerStatefulWidget { class ExchangeView extends ConsumerStatefulWidget {
const ExchangeView({Key? key}) : super(key: key); const ExchangeView({Key? key}) : super(key: key);

View file

@ -1,16 +1,8 @@
import 'dart:async';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:stackwallet/models/exchange/exchange_form_state.dart'; import 'package:stackwallet/models/exchange/exchange_form_state.dart';
import 'package:stackwallet/pages/exchange_view/exchange_view.dart';
import 'package:stackwallet/providers/exchange/available_currencies_state_provider.dart';
import 'package:stackwallet/providers/exchange/available_floating_rate_pairs_state_provider.dart';
import 'package:stackwallet/providers/exchange/change_now_provider.dart';
import 'package:stackwallet/providers/exchange/fixed_rate_market_pairs_provider.dart';
import 'package:stackwallet/providers/providers.dart'; import 'package:stackwallet/providers/providers.dart';
import 'package:stackwallet/services/exchange/change_now/change_now_api.dart'; import 'package:stackwallet/services/exchange/change_now/change_now_loading_service.dart';
import 'package:stackwallet/utilities/logger.dart';
import 'package:stackwallet/utilities/text_styles.dart'; import 'package:stackwallet/utilities/text_styles.dart';
import 'package:stackwallet/utilities/theme/stack_colors.dart'; import 'package:stackwallet/utilities/theme/stack_colors.dart';
import 'package:stackwallet/widgets/stack_dialog.dart'; import 'package:stackwallet/widgets/stack_dialog.dart';
@ -26,103 +18,6 @@ class _HomeViewButtonBarState extends ConsumerState<HomeViewButtonBar> {
final DateTime _lastRefreshed = DateTime.now(); final DateTime _lastRefreshed = DateTime.now();
final Duration _refreshInterval = const Duration(hours: 1); final Duration _refreshInterval = const Duration(hours: 1);
Future<void> _loadChangeNowData(
BuildContext context,
WidgetRef ref,
) async {
List<Future<void>> futures = [];
if (kFixedRateEnabled) {
futures.add(_loadFixedRateMarkets(context, ref));
}
futures.add(_loadStandardCurrencies(context, ref));
await Future.wait(futures);
}
Future<void> _loadStandardCurrencies(
BuildContext context,
WidgetRef ref,
) async {
final response = await ref.read(changeNowProvider).getAllCurrencies(false);
final response2 =
await ChangeNowAPI.instance.getAvailableFloatingRatePairs();
if (response.value != null && response2.value != null) {
ref.read(availableChangeNowCurrenciesStateProvider.state).state =
response.value!;
ref.read(availableFloatingRatePairsStateProvider.state).state =
response2.value!;
if (response.value!.length > 1) {
if (ref.read(exchangeFormStateProvider).from == null) {
if (response.value!.where((e) => e.ticker == "btc").isNotEmpty) {
await ref.read(exchangeFormStateProvider).updateFrom(
response.value!.firstWhere((e) => e.ticker == "btc"), true);
}
}
if (ref.read(exchangeFormStateProvider).to == null) {
if (response.value!.where((e) => e.ticker == "doge").isNotEmpty) {
await ref.read(exchangeFormStateProvider).updateTo(
response.value!.firstWhere((e) => e.ticker == "doge"), true);
}
}
}
Logging.instance
.log("loaded floating rate change now data", level: LogLevel.Info);
} else {
Logging.instance.log(
"Failed to load changeNOW floating rate market data: \n${response.exception?.errorMessage}\n${response2.exception?.toString()}",
level: LogLevel.Error);
unawaited(showDialog<dynamic>(
context: context,
barrierDismissible: true,
builder: (_) => StackDialog(
title: "Failed to fetch available currencies",
message:
"${response.exception?.toString()}\n\n${response2.exception?.toString()}",
),
));
}
}
Future<void> _loadFixedRateMarkets(
BuildContext context,
WidgetRef ref,
) async {
final response3 =
await ChangeNowAPI.instance.getAvailableFixedRateMarkets();
if (response3.value != null) {
ref.read(fixedRateMarketPairsStateProvider.state).state =
response3.value!;
if (ref.read(exchangeFormStateProvider).market == null) {
final matchingMarkets =
response3.value!.where((e) => e.to == "doge" && e.from == "btc");
if (matchingMarkets.isNotEmpty) {
await ref
.read(exchangeFormStateProvider)
.updateMarket(matchingMarkets.first, true);
}
}
Logging.instance
.log("loaded fixed rate change now data", level: LogLevel.Info);
} else {
Logging.instance.log(
"Failed to load changeNOW fixed rate markets: ${response3.exception?.errorMessage}",
level: LogLevel.Error);
unawaited(showDialog<dynamic>(
context: context,
barrierDismissible: true,
builder: (_) => StackDialog(
title: "ChangeNOW API call failed",
message: "${response3.exception?.toString()}",
),
));
}
}
@override @override
void initState() { void initState() {
ref.read(exchangeFormStateProvider).setOnError( ref.read(exchangeFormStateProvider).setOnError(
@ -224,7 +119,7 @@ class _HomeViewButtonBarState extends ConsumerState<HomeViewButtonBar> {
// // }, // // },
// ), // ),
// ); // );
await _loadChangeNowData(context, ref); await ChangeNowLoadingService().loadAll(ref);
// if (!okPressed && mounted) { // if (!okPressed && mounted) {
// Navigator.of(context).pop(); // Navigator.of(context).pop();
// } // }

View file

@ -1,13 +1,14 @@
import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart';
enum ChangeNowLoadStatus { enum ChangeNowLoadStatus {
waiting,
loading, loading,
success, success,
failed, failed,
} }
final changeNowEstimatedInitialLoadStatusStateProvider = final changeNowEstimatedInitialLoadStatusStateProvider =
StateProvider<ChangeNowLoadStatus>((ref) => ChangeNowLoadStatus.loading); StateProvider<ChangeNowLoadStatus>((ref) => ChangeNowLoadStatus.waiting);
final changeNowFixedInitialLoadStatusStateProvider = final changeNowFixedInitialLoadStatusStateProvider =
StateProvider<ChangeNowLoadStatus>((ref) => ChangeNowLoadStatus.loading); StateProvider<ChangeNowLoadStatus>((ref) => ChangeNowLoadStatus.waiting);

View file

@ -67,8 +67,10 @@ class ChangeNowLoadingService {
ChangeNowLoadStatus.success; ChangeNowLoadStatus.success;
} }
Future<void> _loadChangeNowStandardCurrencies(WidgetRef ref, Future<void> _loadChangeNowStandardCurrencies(
{Coin? coin}) async { WidgetRef ref, {
Coin? coin,
}) async {
if (ref if (ref
.read(changeNowEstimatedInitialLoadStatusStateProvider.state) .read(changeNowEstimatedInitialLoadStatusStateProvider.state)
.state == .state ==