infinite changenow loading fix

This commit is contained in:
julian 2022-09-09 08:03:36 -06:00
parent 006a4de121
commit a67f6f97e9
5 changed files with 162 additions and 124 deletions

View file

@ -1,20 +1,18 @@
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.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/changenow_initial_load_status.dart';
import 'package:stackwallet/providers/exchange/estimate_rate_exchange_form_provider.dart';
import 'package:stackwallet/providers/exchange/fixed_rate_exchange_form_provider.dart';
import 'package:stackwallet/providers/exchange/fixed_rate_market_pairs_provider.dart';
import 'package:stackwallet/utilities/cfcolors.dart';
import 'package:stackwallet/utilities/logger.dart';
import 'package:stackwallet/utilities/text_styles.dart';
import 'package:stackwallet/widgets/custom_loading_overlay.dart';
import 'package:stackwallet/widgets/stack_dialog.dart';
class ExchangeLoadingOverlayView extends ConsumerStatefulWidget {
const ExchangeLoadingOverlayView({Key? key}) : super(key: key);
const ExchangeLoadingOverlayView({
Key? key,
required this.unawaitedLoad,
}) : super(key: key);
final VoidCallback unawaitedLoad;
@override
ConsumerState<ExchangeLoadingOverlayView> createState() =>
@ -28,103 +26,6 @@ class _ExchangeLoadingOverlayViewState
bool userReloaded = false;
Future<void> _loadFixedRateMarkets() async {
if (ref.read(changeNowFixedInitialLoadStatusStateProvider.state).state ==
ChangeNowLoadStatus.loading) {
// already in progress so just
return;
}
ref.read(changeNowFixedInitialLoadStatusStateProvider.state).state =
ChangeNowLoadStatus.loading;
final response3 =
await ref.read(changeNowProvider).getAvailableFixedRateMarkets();
if (response3.value != null) {
ref.read(fixedRateMarketPairsStateProvider.state).state =
response3.value!;
if (ref.read(fixedRateExchangeFormProvider).market == null) {
final matchingMarkets =
response3.value!.where((e) => e.to == "doge" && e.from == "btc");
if (matchingMarkets.isNotEmpty) {
await ref
.read(fixedRateExchangeFormProvider)
.updateMarket(matchingMarkets.first, true);
}
}
} 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> _loadChangeNowStandardCurrencies() async {
if (ref
.read(changeNowEstimatedInitialLoadStatusStateProvider.state)
.state ==
ChangeNowLoadStatus.loading) {
// already in progress so just
return;
}
ref.read(changeNowEstimatedInitialLoadStatusStateProvider.state).state =
ChangeNowLoadStatus.loading;
final response = await ref.read(changeNowProvider).getAvailableCurrencies();
final response2 =
await ref.read(changeNowProvider).getAvailableFloatingRatePairs();
if (response.value != null) {
ref.read(availableChangeNowCurrenciesStateProvider.state).state =
response.value!;
if (response2.value != null) {
ref.read(availableFloatingRatePairsStateProvider.state).state =
response2.value!;
if (response.value!.length > 1) {
if (ref.read(estimatedRateExchangeFormProvider).from == null) {
if (response.value!.where((e) => e.ticker == "btc").isNotEmpty) {
await ref.read(estimatedRateExchangeFormProvider).updateFrom(
response.value!.firstWhere((e) => e.ticker == "btc"), false);
}
}
if (ref.read(estimatedRateExchangeFormProvider).to == null) {
if (response.value!.where((e) => e.ticker == "doge").isNotEmpty) {
await ref.read(estimatedRateExchangeFormProvider).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: 3));
ref.read(changeNowEstimatedInitialLoadStatusStateProvider.state).state =
ChangeNowLoadStatus.failed;
return;
}
ref.read(changeNowEstimatedInitialLoadStatusStateProvider.state).state =
ChangeNowLoadStatus.success;
}
@override
void initState() {
_statusEst =
@ -168,8 +69,10 @@ class _ExchangeLoadingOverlayViewState
child: const CustomLoadingOverlay(
message: "Loading ChangeNOW data", eventBus: null),
),
if (_statusEst == ChangeNowLoadStatus.failed ||
_statusFixed == ChangeNowLoadStatus.failed)
if ((_statusEst == ChangeNowLoadStatus.failed ||
_statusFixed == ChangeNowLoadStatus.failed) &&
_statusEst != ChangeNowLoadStatus.loading &&
_statusFixed != ChangeNowLoadStatus.loading)
Container(
color: CFColors.stackAccent.withOpacity(0.7),
child: Column(
@ -186,13 +89,8 @@ class _ExchangeLoadingOverlayViewState
.copyWith(color: CFColors.stackAccent),
),
onPressed: () {
if (_statusEst == ChangeNowLoadStatus.failed) {
_loadChangeNowStandardCurrencies();
}
if (_statusFixed == ChangeNowLoadStatus.failed) {
userReloaded = true;
_loadFixedRateMarkets();
}
userReloaded = true;
widget.unawaitedLoad();
},
),
),

View file

@ -13,6 +13,7 @@ import 'package:stackwallet/pages/wallets_view/wallets_view.dart';
import 'package:stackwallet/providers/global/notifications_provider.dart';
import 'package:stackwallet/providers/ui/home_view_index_provider.dart';
import 'package:stackwallet/providers/ui/unread_notifications_provider.dart';
import 'package:stackwallet/services/change_now/change_now_loading_service.dart';
import 'package:stackwallet/utilities/assets.dart';
import 'package:stackwallet/utilities/cfcolors.dart';
import 'package:stackwallet/utilities/constants.dart';
@ -40,6 +41,8 @@ class _HomeViewState extends ConsumerState<HomeView> {
bool _exitEnabled = false;
final _cnLoadingService = ChangeNowLoadingService();
Future<bool> _onWillPop() async {
if (_exitEnabled) {
return true;
@ -70,6 +73,11 @@ class _HomeViewState extends ConsumerState<HomeView> {
return _exitEnabled;
}
void _loadCNData() {
// unawaited future
_cnLoadingService.loadAll(ref);
}
@override
void initState() {
_pageController = PageController();
@ -77,9 +85,11 @@ class _HomeViewState extends ConsumerState<HomeView> {
const WalletsView(),
if (Constants.enableExchange)
Stack(
children: const [
ExchangeView(),
ExchangeLoadingOverlayView(),
children: [
const ExchangeView(),
ExchangeLoadingOverlayView(
unawaitedLoad: _loadCNData,
),
],
),
// const BuyView(),

View file

@ -24,6 +24,9 @@ import 'package:stackwallet/providers/global/auto_swb_service_provider.dart';
import 'package:stackwallet/providers/providers.dart';
import 'package:stackwallet/providers/ui/transaction_filter_provider.dart';
import 'package:stackwallet/providers/ui/unread_notifications_provider.dart';
import 'package:stackwallet/providers/wallet/public_private_balance_state_provider.dart';
import 'package:stackwallet/providers/wallet/wallet_balance_toggle_state_provider.dart';
import 'package:stackwallet/services/change_now/change_now_loading_service.dart';
import 'package:stackwallet/services/coins/firo/firo_wallet.dart';
import 'package:stackwallet/services/coins/manager.dart';
import 'package:stackwallet/services/event_bus/events/global/node_connection_status_changed_event.dart';
@ -35,6 +38,7 @@ import 'package:stackwallet/utilities/constants.dart';
import 'package:stackwallet/utilities/enums/backup_frequency_type.dart';
import 'package:stackwallet/utilities/enums/coin_enum.dart';
import 'package:stackwallet/utilities/enums/flush_bar_type.dart';
import 'package:stackwallet/utilities/enums/wallet_balance_toggle_state.dart';
import 'package:stackwallet/utilities/text_styles.dart';
import 'package:stackwallet/widgets/custom_buttons/app_bar_icon_button.dart';
import 'package:stackwallet/widgets/custom_buttons/blue_text_button.dart';
@ -42,10 +46,6 @@ import 'package:stackwallet/widgets/custom_loading_overlay.dart';
import 'package:stackwallet/widgets/stack_dialog.dart';
import 'package:tuple/tuple.dart';
import '../../providers/wallet/public_private_balance_state_provider.dart';
import '../../providers/wallet/wallet_balance_toggle_state_provider.dart';
import '../../utilities/enums/wallet_balance_toggle_state.dart';
/// [eventBus] should only be set during testing
class WalletView extends ConsumerStatefulWidget {
const WalletView({
@ -79,6 +79,8 @@ class _WalletViewState extends ConsumerState<WalletView> {
late StreamSubscription<dynamic> _syncStatusSubscription;
late StreamSubscription<dynamic> _nodeStatusSubscription;
final _cnLoadingService = ChangeNowLoadingService();
@override
void initState() {
walletId = widget.walletId;
@ -272,9 +274,10 @@ class _WalletViewState extends ConsumerState<WalletView> {
unawaited(Navigator.of(context).pushNamed(
WalletInitiatedExchangeView.routeName,
arguments: Tuple2(
arguments: Tuple3(
walletId,
coin,
_loadCNData,
),
));
}
@ -346,6 +349,11 @@ class _WalletViewState extends ConsumerState<WalletView> {
}
}
void _loadCNData() {
// unawaited future
_cnLoadingService.loadAll(ref);
}
@override
Widget build(BuildContext context) {
debugPrint("BUILD: $runtimeType");

View file

@ -719,7 +719,7 @@ class RouteGenerator {
return _routeError("${settings.name} invalid args: ${args.toString()}");
case WalletInitiatedExchangeView.routeName:
if (args is Tuple2<String, Coin>) {
if (args is Tuple3<String, Coin, VoidCallback>) {
return getRoute(
shouldUseMaterialRoute: useMaterialPageRoute,
builder: (_) => Stack(
@ -728,7 +728,9 @@ class RouteGenerator {
walletId: args.item1,
coin: args.item2,
),
const ExchangeLoadingOverlayView(),
ExchangeLoadingOverlayView(
unawaitedLoad: args.item3,
),
],
),
settings: RouteSettings(

View file

@ -0,0 +1,120 @@
import 'package:flutter_riverpod/flutter_riverpod.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/changenow_initial_load_status.dart';
import 'package:stackwallet/providers/exchange/estimate_rate_exchange_form_provider.dart';
import 'package:stackwallet/providers/exchange/fixed_rate_exchange_form_provider.dart';
import 'package:stackwallet/providers/exchange/fixed_rate_market_pairs_provider.dart';
import 'package:stackwallet/utilities/logger.dart';
class ChangeNowLoadingService {
Future<void> loadAll(WidgetRef ref) async {
try {
await Future.wait([
_loadFixedRateMarkets(ref),
_loadChangeNowStandardCurrencies(ref),
]);
} catch (e, s) {
Logging.instance.log("ChangeNowLoadingService.loadAll failed: $e\n$s",
level: LogLevel.Error);
}
}
Future<void> _loadFixedRateMarkets(WidgetRef ref) async {
if (ref.read(changeNowFixedInitialLoadStatusStateProvider.state).state ==
ChangeNowLoadStatus.loading) {
// already in progress so just
return;
}
ref.read(changeNowFixedInitialLoadStatusStateProvider.state).state =
ChangeNowLoadStatus.loading;
final response3 =
await ref.read(changeNowProvider).getAvailableFixedRateMarkets();
if (response3.value != null) {
ref.read(fixedRateMarketPairsStateProvider.state).state =
response3.value!;
if (ref.read(fixedRateExchangeFormProvider).market == null) {
final matchingMarkets =
response3.value!.where((e) => e.to == "doge" && e.from == "btc");
if (matchingMarkets.isNotEmpty) {
await ref
.read(fixedRateExchangeFormProvider)
.updateMarket(matchingMarkets.first, true);
}
}
} 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> _loadChangeNowStandardCurrencies(WidgetRef ref) async {
if (ref
.read(changeNowEstimatedInitialLoadStatusStateProvider.state)
.state ==
ChangeNowLoadStatus.loading) {
// already in progress so just
return;
}
ref.read(changeNowEstimatedInitialLoadStatusStateProvider.state).state =
ChangeNowLoadStatus.loading;
final response = await ref.read(changeNowProvider).getAvailableCurrencies();
final response2 =
await ref.read(changeNowProvider).getAvailableFloatingRatePairs();
if (response.value != null) {
ref.read(availableChangeNowCurrenciesStateProvider.state).state =
response.value!;
if (response2.value != null) {
ref.read(availableFloatingRatePairsStateProvider.state).state =
response2.value!;
if (response.value!.length > 1) {
if (ref.read(estimatedRateExchangeFormProvider).from == null) {
if (response.value!.where((e) => e.ticker == "btc").isNotEmpty) {
await ref.read(estimatedRateExchangeFormProvider).updateFrom(
response.value!.firstWhere((e) => e.ticker == "btc"), false);
}
}
if (ref.read(estimatedRateExchangeFormProvider).to == null) {
if (response.value!.where((e) => e.ticker == "doge").isNotEmpty) {
await ref.read(estimatedRateExchangeFormProvider).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: 3));
ref.read(changeNowEstimatedInitialLoadStatusStateProvider.state).state =
ChangeNowLoadStatus.failed;
return;
}
ref.read(changeNowEstimatedInitialLoadStatusStateProvider.state).state =
ChangeNowLoadStatus.success;
}
}