mirror of
https://github.com/cypherstack/stack_wallet.git
synced 2025-01-23 19:05:51 +00:00
add loading screen if not exchange data cache exists while waiting for it to be populated for the first time. Added checks for incognito mode
This commit is contained in:
parent
b9d006b6ea
commit
8206972309
5 changed files with 468 additions and 268 deletions
|
@ -17,6 +17,7 @@ import 'package:hive_flutter/hive_flutter.dart';
|
|||
import 'package:isar/isar.dart';
|
||||
import 'package:keyboard_dismisser/keyboard_dismisser.dart';
|
||||
import 'package:path_provider/path_provider.dart';
|
||||
import 'package:stackwallet/db/main_db.dart';
|
||||
import 'package:stackwallet/hive/db.dart';
|
||||
import 'package:stackwallet/models/exchange/change_now/exchange_transaction.dart';
|
||||
import 'package:stackwallet/models/exchange/change_now/exchange_transaction_status.dart';
|
||||
|
@ -65,8 +66,6 @@ import 'package:stackwallet/utilities/theme/stack_colors.dart';
|
|||
import 'package:stackwallet/utilities/util.dart';
|
||||
import 'package:window_size/window_size.dart';
|
||||
|
||||
import 'db/main_db.dart';
|
||||
|
||||
final openedFromSWBFileStringStateProvider =
|
||||
StateProvider<String?>((ref) => null);
|
||||
|
||||
|
@ -290,10 +289,6 @@ 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
|
||||
// unawaited(_nodeService.updateCommunityNodes());
|
||||
|
||||
print("================================================");
|
||||
print("${ref.read(prefsChangeNotifierProvider).externalCalls}");
|
||||
print("${await ref.read(prefsChangeNotifierProvider).isExternalCallsSet()}");
|
||||
print("================================================");
|
||||
// run without awaiting
|
||||
if (ref.read(prefsChangeNotifierProvider).externalCalls &&
|
||||
await ref.read(prefsChangeNotifierProvider).isExternalCallsSet()) {
|
||||
|
|
|
@ -8,9 +8,12 @@ import 'package:stackwallet/pages/exchange_view/exchange_form.dart';
|
|||
import 'package:stackwallet/pages/exchange_view/trade_details_view.dart';
|
||||
import 'package:stackwallet/providers/global/trades_service_provider.dart';
|
||||
import 'package:stackwallet/providers/providers.dart';
|
||||
import 'package:stackwallet/services/exchange/exchange_data_loading_service.dart';
|
||||
import 'package:stackwallet/utilities/constants.dart';
|
||||
import 'package:stackwallet/utilities/text_styles.dart';
|
||||
import 'package:stackwallet/utilities/theme/stack_colors.dart';
|
||||
import 'package:stackwallet/widgets/conditional_parent.dart';
|
||||
import 'package:stackwallet/widgets/custom_loading_overlay.dart';
|
||||
import 'package:stackwallet/widgets/trade_card.dart';
|
||||
import 'package:tuple/tuple.dart';
|
||||
|
||||
|
@ -24,8 +27,38 @@ class ExchangeView extends ConsumerStatefulWidget {
|
|||
}
|
||||
|
||||
class _ExchangeViewState extends ConsumerState<ExchangeView> {
|
||||
bool _initialCachePopulationUnderway = false;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
if (!ref.read(prefsChangeNotifierProvider).externalCalls) {
|
||||
if (ExchangeDataLoadingService.currentCacheVersion <
|
||||
ExchangeDataLoadingService.cacheVersion) {
|
||||
_initialCachePopulationUnderway = true;
|
||||
ExchangeDataLoadingService.instance.onLoadingComplete = () {
|
||||
WidgetsBinding.instance.addPostFrameCallback((timeStamp) {
|
||||
setState(() {
|
||||
_initialCachePopulationUnderway = false;
|
||||
});
|
||||
});
|
||||
};
|
||||
}
|
||||
ExchangeDataLoadingService.instance
|
||||
.init()
|
||||
.then((_) => ExchangeDataLoadingService.instance.loadAll());
|
||||
} else if (ExchangeDataLoadingService.instance.isLoading &&
|
||||
ExchangeDataLoadingService.currentCacheVersion <
|
||||
ExchangeDataLoadingService.cacheVersion) {
|
||||
_initialCachePopulationUnderway = true;
|
||||
ExchangeDataLoadingService.instance.onLoadingComplete = () {
|
||||
WidgetsBinding.instance.addPostFrameCallback((timeStamp) {
|
||||
setState(() {
|
||||
_initialCachePopulationUnderway = false;
|
||||
});
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
super.initState();
|
||||
}
|
||||
|
||||
|
@ -38,13 +71,34 @@ class _ExchangeViewState extends ConsumerState<ExchangeView> {
|
|||
Widget build(BuildContext context) {
|
||||
debugPrint("BUILD: $runtimeType");
|
||||
|
||||
return SafeArea(
|
||||
return ConditionalParent(
|
||||
condition: _initialCachePopulationUnderway,
|
||||
builder: (child) {
|
||||
return Stack(
|
||||
children: [
|
||||
child,
|
||||
Material(
|
||||
color: Theme.of(context)
|
||||
.extension<StackColors>()!
|
||||
.overlay
|
||||
.withOpacity(0.6),
|
||||
child: const CustomLoadingOverlay(
|
||||
message: "Updating exchange data",
|
||||
subMessage: "This could take a few minutes",
|
||||
eventBus: null,
|
||||
),
|
||||
)
|
||||
],
|
||||
);
|
||||
},
|
||||
child: SafeArea(
|
||||
child: NestedScrollView(
|
||||
floatHeaderSlivers: true,
|
||||
headerSliverBuilder: (context, innerBoxIsScrolled) {
|
||||
return [
|
||||
SliverOverlapAbsorber(
|
||||
handle: NestedScrollView.sliverOverlapAbsorberHandleFor(context),
|
||||
handle:
|
||||
NestedScrollView.sliverOverlapAbsorberHandleFor(context),
|
||||
sliver: const SliverToBoxAdapter(
|
||||
child: Padding(
|
||||
padding: EdgeInsets.only(
|
||||
|
@ -188,6 +242,7 @@ class _ExchangeViewState extends ConsumerState<ExchangeView> {
|
|||
},
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,11 +4,15 @@ import 'package:flutter/material.dart';
|
|||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:stackwallet/pages/exchange_view/exchange_form.dart';
|
||||
import 'package:stackwallet/pages/exchange_view/sub_widgets/step_row.dart';
|
||||
import 'package:stackwallet/providers/global/prefs_provider.dart';
|
||||
import 'package:stackwallet/services/exchange/exchange_data_loading_service.dart';
|
||||
import 'package:stackwallet/utilities/enums/coin_enum.dart';
|
||||
import 'package:stackwallet/utilities/text_styles.dart';
|
||||
import 'package:stackwallet/utilities/theme/stack_colors.dart';
|
||||
import 'package:stackwallet/widgets/background.dart';
|
||||
import 'package:stackwallet/widgets/conditional_parent.dart';
|
||||
import 'package:stackwallet/widgets/custom_buttons/app_bar_icon_button.dart';
|
||||
import 'package:stackwallet/widgets/custom_loading_overlay.dart';
|
||||
|
||||
class WalletInitiatedExchangeView extends ConsumerStatefulWidget {
|
||||
const WalletInitiatedExchangeView({
|
||||
|
@ -32,10 +36,41 @@ class _WalletInitiatedExchangeViewState
|
|||
late final String walletId;
|
||||
late final Coin coin;
|
||||
|
||||
bool _initialCachePopulationUnderway = false;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
walletId = widget.walletId;
|
||||
coin = widget.coin;
|
||||
|
||||
if (!ref.read(prefsChangeNotifierProvider).externalCalls) {
|
||||
if (ExchangeDataLoadingService.currentCacheVersion <
|
||||
ExchangeDataLoadingService.cacheVersion) {
|
||||
_initialCachePopulationUnderway = true;
|
||||
ExchangeDataLoadingService.instance.onLoadingComplete = () {
|
||||
WidgetsBinding.instance.addPostFrameCallback((timeStamp) {
|
||||
setState(() {
|
||||
_initialCachePopulationUnderway = false;
|
||||
});
|
||||
});
|
||||
};
|
||||
}
|
||||
ExchangeDataLoadingService.instance
|
||||
.init()
|
||||
.then((_) => ExchangeDataLoadingService.instance.loadAll());
|
||||
} else if (ExchangeDataLoadingService.instance.isLoading &&
|
||||
ExchangeDataLoadingService.currentCacheVersion <
|
||||
ExchangeDataLoadingService.cacheVersion) {
|
||||
_initialCachePopulationUnderway = true;
|
||||
ExchangeDataLoadingService.instance.onLoadingComplete = () {
|
||||
WidgetsBinding.instance.addPostFrameCallback((timeStamp) {
|
||||
setState(() {
|
||||
_initialCachePopulationUnderway = false;
|
||||
});
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
super.initState();
|
||||
}
|
||||
|
||||
|
@ -48,9 +83,30 @@ class _WalletInitiatedExchangeViewState
|
|||
Widget build(BuildContext context) {
|
||||
debugPrint("BUILD: $runtimeType");
|
||||
|
||||
return Background(
|
||||
return ConditionalParent(
|
||||
condition: _initialCachePopulationUnderway,
|
||||
builder: (child) {
|
||||
return Stack(
|
||||
children: [
|
||||
child,
|
||||
Material(
|
||||
color: Theme.of(context)
|
||||
.extension<StackColors>()!
|
||||
.overlay
|
||||
.withOpacity(0.6),
|
||||
child: const CustomLoadingOverlay(
|
||||
message: "Updating exchange data",
|
||||
subMessage: "This could take a few minutes",
|
||||
eventBus: null,
|
||||
),
|
||||
)
|
||||
],
|
||||
);
|
||||
},
|
||||
child: Background(
|
||||
child: Scaffold(
|
||||
backgroundColor: Theme.of(context).extension<StackColors>()!.background,
|
||||
backgroundColor:
|
||||
Theme.of(context).extension<StackColors>()!.background,
|
||||
appBar: AppBar(
|
||||
leading: AppBarBackButton(
|
||||
onPressed: () async {
|
||||
|
@ -120,6 +176,7 @@ class _WalletInitiatedExchangeViewState
|
|||
},
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,24 +1,86 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:stackwallet/pages/exchange_view/exchange_form.dart';
|
||||
import 'package:stackwallet/pages_desktop_specific/desktop_exchange/subwidgets/desktop_trade_history.dart';
|
||||
import 'package:stackwallet/providers/global/prefs_provider.dart';
|
||||
import 'package:stackwallet/services/exchange/exchange_data_loading_service.dart';
|
||||
import 'package:stackwallet/utilities/text_styles.dart';
|
||||
import 'package:stackwallet/utilities/theme/stack_colors.dart';
|
||||
import 'package:stackwallet/widgets/conditional_parent.dart';
|
||||
import 'package:stackwallet/widgets/custom_loading_overlay.dart';
|
||||
import 'package:stackwallet/widgets/desktop/desktop_app_bar.dart';
|
||||
import 'package:stackwallet/widgets/desktop/desktop_scaffold.dart';
|
||||
import 'package:stackwallet/widgets/rounded_white_container.dart';
|
||||
|
||||
class DesktopExchangeView extends StatefulWidget {
|
||||
class DesktopExchangeView extends ConsumerStatefulWidget {
|
||||
const DesktopExchangeView({Key? key}) : super(key: key);
|
||||
|
||||
static const String routeName = "/desktopExchange";
|
||||
|
||||
@override
|
||||
State<DesktopExchangeView> createState() => _DesktopExchangeViewState();
|
||||
ConsumerState<DesktopExchangeView> createState() =>
|
||||
_DesktopExchangeViewState();
|
||||
}
|
||||
|
||||
class _DesktopExchangeViewState extends State<DesktopExchangeView> {
|
||||
class _DesktopExchangeViewState extends ConsumerState<DesktopExchangeView> {
|
||||
bool _initialCachePopulationUnderway = false;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
if (!ref.read(prefsChangeNotifierProvider).externalCalls) {
|
||||
if (ExchangeDataLoadingService.currentCacheVersion <
|
||||
ExchangeDataLoadingService.cacheVersion) {
|
||||
_initialCachePopulationUnderway = true;
|
||||
ExchangeDataLoadingService.instance.onLoadingComplete = () {
|
||||
WidgetsBinding.instance.addPostFrameCallback((timeStamp) {
|
||||
setState(() {
|
||||
_initialCachePopulationUnderway = false;
|
||||
});
|
||||
});
|
||||
};
|
||||
}
|
||||
ExchangeDataLoadingService.instance
|
||||
.init()
|
||||
.then((_) => ExchangeDataLoadingService.instance.loadAll());
|
||||
} else if (ExchangeDataLoadingService.instance.isLoading &&
|
||||
ExchangeDataLoadingService.currentCacheVersion <
|
||||
ExchangeDataLoadingService.cacheVersion) {
|
||||
_initialCachePopulationUnderway = true;
|
||||
ExchangeDataLoadingService.instance.onLoadingComplete = () {
|
||||
WidgetsBinding.instance.addPostFrameCallback((timeStamp) {
|
||||
setState(() {
|
||||
_initialCachePopulationUnderway = false;
|
||||
});
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
super.initState();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return DesktopScaffold(
|
||||
return ConditionalParent(
|
||||
condition: _initialCachePopulationUnderway,
|
||||
builder: (child) {
|
||||
return Stack(
|
||||
children: [
|
||||
child,
|
||||
Material(
|
||||
color: Theme.of(context)
|
||||
.extension<StackColors>()!
|
||||
.overlay
|
||||
.withOpacity(0.6),
|
||||
child: const CustomLoadingOverlay(
|
||||
message: "Updating exchange data",
|
||||
subMessage: "This could take a few minutes",
|
||||
eventBus: null,
|
||||
),
|
||||
)
|
||||
],
|
||||
);
|
||||
},
|
||||
child: DesktopScaffold(
|
||||
appBar: DesktopAppBar(
|
||||
isCompactHeight: true,
|
||||
leading: Padding(
|
||||
|
@ -74,6 +136,7 @@ class _DesktopExchangeViewState extends State<DesktopExchangeView> {
|
|||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import 'package:flutter/foundation.dart';
|
||||
import 'package:isar/isar.dart';
|
||||
import 'package:stackwallet/hive/db.dart';
|
||||
import 'package:stackwallet/models/isar/exchange_cache/currency.dart';
|
||||
import 'package:stackwallet/models/isar/exchange_cache/pair.dart';
|
||||
import 'package:stackwallet/services/exchange/change_now/change_now_exchange.dart';
|
||||
|
@ -16,6 +17,25 @@ class ExchangeDataLoadingService {
|
|||
Isar? _isar;
|
||||
Isar get isar => _isar!;
|
||||
|
||||
VoidCallback? onLoadingError;
|
||||
VoidCallback? onLoadingComplete;
|
||||
|
||||
static const int cacheVersion = 1;
|
||||
|
||||
static int get currentCacheVersion =>
|
||||
DB.instance.get<dynamic>(
|
||||
boxName: DB.boxNameDBInfo,
|
||||
key: "exchange_data_cache_version") as int? ??
|
||||
0;
|
||||
|
||||
Future<void> _updateCurrentCacheVersion(int version) async {
|
||||
await DB.instance.put<dynamic>(
|
||||
boxName: DB.boxNameDBInfo,
|
||||
key: "exchange_data_cache_version",
|
||||
value: version,
|
||||
);
|
||||
}
|
||||
|
||||
Future<void> init() async {
|
||||
if (_isar != null && isar.isOpen) return;
|
||||
_isar = await Isar.open(
|
||||
|
@ -25,18 +45,23 @@ class ExchangeDataLoadingService {
|
|||
],
|
||||
directory: (await StackFileSystem.applicationIsarDirectory()).path,
|
||||
inspector: kDebugMode,
|
||||
// inspector: false,
|
||||
name: "exchange_cache",
|
||||
);
|
||||
}
|
||||
|
||||
bool get isLoading => _locked;
|
||||
|
||||
bool _locked = false;
|
||||
|
||||
Future<void> loadAll() async {
|
||||
print("LOADINGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG: LOCKED=$_locked");
|
||||
if (!_locked) {
|
||||
_locked = true;
|
||||
print("LOADINGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG");
|
||||
final time = DateTime.now();
|
||||
Logging.instance.log(
|
||||
"ExchangeDataLoadingService.loadAll starting...",
|
||||
level: LogLevel.Info,
|
||||
);
|
||||
final start = DateTime.now();
|
||||
try {
|
||||
await Future.wait([
|
||||
_loadChangeNowCurrencies(),
|
||||
|
@ -46,13 +71,18 @@ class ExchangeDataLoadingService {
|
|||
// loadSimpleswapFloatingRateCurrencies(ref),
|
||||
loadMajesticBankCurrencies(),
|
||||
]);
|
||||
|
||||
print(
|
||||
"LOADINGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG done in ${DateTime.now().difference(time).inSeconds} seconds");
|
||||
Logging.instance.log(
|
||||
"ExchangeDataLoadingService.loadAll finished in ${DateTime.now().difference(start).inSeconds} seconds",
|
||||
level: LogLevel.Info,
|
||||
);
|
||||
onLoadingComplete?.call();
|
||||
await _updateCurrentCacheVersion(cacheVersion);
|
||||
} catch (e, s) {
|
||||
Logging.instance.log(
|
||||
"ExchangeDataLoadingService.loadAll failed: $e\n$s",
|
||||
level: LogLevel.Error);
|
||||
"ExchangeDataLoadingService.loadAll failed after ${DateTime.now().difference(start).inSeconds} seconds: $e\n$s",
|
||||
level: LogLevel.Error,
|
||||
);
|
||||
onLoadingError?.call();
|
||||
}
|
||||
_locked = false;
|
||||
}
|
||||
|
@ -82,7 +112,7 @@ class ExchangeDataLoadingService {
|
|||
Future<void> _loadChangeNowFixedRatePairs() async {
|
||||
final exchange = ChangeNowExchange.instance;
|
||||
|
||||
final responsePairs = await exchange.getAllPairs(true);
|
||||
final responsePairs = await compute(exchange.getAllPairs, true);
|
||||
|
||||
if (responsePairs.value != null) {
|
||||
await isar.writeTxn(() async {
|
||||
|
@ -107,7 +137,7 @@ class ExchangeDataLoadingService {
|
|||
Future<void> _loadChangeNowEstimatedRatePairs() async {
|
||||
final exchange = ChangeNowExchange.instance;
|
||||
|
||||
final responsePairs = await exchange.getAllPairs(false);
|
||||
final responsePairs = await compute(exchange.getAllPairs, false);
|
||||
|
||||
if (responsePairs.value != null) {
|
||||
await isar.writeTxn(() async {
|
||||
|
|
Loading…
Reference in a new issue