mirror of
https://github.com/cypherstack/stack_wallet.git
synced 2024-12-23 03:49:22 +00:00
all wallets sync changes for better ui performance
This commit is contained in:
parent
3f4ebe0229
commit
20438da655
5 changed files with 218 additions and 65 deletions
|
@ -11,7 +11,6 @@
|
||||||
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/pages/settings_views/global_settings_view/syncing_preferences_views/wallet_syncing_options_view.dart';
|
import 'package:stackwallet/pages/settings_views/global_settings_view/syncing_preferences_views/wallet_syncing_options_view.dart';
|
||||||
import 'package:stackwallet/providers/global/active_wallet_provider.dart';
|
|
||||||
import 'package:stackwallet/providers/providers.dart';
|
import 'package:stackwallet/providers/providers.dart';
|
||||||
import 'package:stackwallet/themes/stack_colors.dart';
|
import 'package:stackwallet/themes/stack_colors.dart';
|
||||||
import 'package:stackwallet/utilities/constants.dart';
|
import 'package:stackwallet/utilities/constants.dart';
|
||||||
|
@ -95,12 +94,12 @@ class SyncingOptionsView extends ConsumerWidget {
|
||||||
ref.read(prefsChangeNotifierProvider).syncType =
|
ref.read(prefsChangeNotifierProvider).syncType =
|
||||||
SyncingType.currentWalletOnly;
|
SyncingType.currentWalletOnly;
|
||||||
|
|
||||||
// disable auto sync on all wallets that aren't active/current
|
// // disable auto sync on all wallets that aren't active/current
|
||||||
ref.read(pWallets).wallets.forEach((e) {
|
// ref.read(pWallets).wallets.forEach((e) {
|
||||||
if (e.walletId != ref.read(currentWalletIdProvider)) {
|
// if (e.walletId != ref.read(currentWalletIdProvider)) {
|
||||||
e.shouldAutoSync = false;
|
// e.shouldAutoSync = false;
|
||||||
}
|
// }
|
||||||
});
|
// });
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
child: Container(
|
child: Container(
|
||||||
|
@ -174,11 +173,11 @@ class SyncingOptionsView extends ConsumerWidget {
|
||||||
ref.read(prefsChangeNotifierProvider).syncType =
|
ref.read(prefsChangeNotifierProvider).syncType =
|
||||||
SyncingType.allWalletsOnStartup;
|
SyncingType.allWalletsOnStartup;
|
||||||
|
|
||||||
// enable auto sync on all wallets
|
// // enable auto sync on all wallets
|
||||||
ref
|
// ref
|
||||||
.read(pWallets)
|
// .read(pWallets)
|
||||||
.wallets
|
// .wallets
|
||||||
.forEach((e) => e.shouldAutoSync = true);
|
// .forEach((e) => e.shouldAutoSync = true);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
child: Container(
|
child: Container(
|
||||||
|
@ -252,13 +251,13 @@ class SyncingOptionsView extends ConsumerWidget {
|
||||||
ref.read(prefsChangeNotifierProvider).syncType =
|
ref.read(prefsChangeNotifierProvider).syncType =
|
||||||
SyncingType.selectedWalletsAtStartup;
|
SyncingType.selectedWalletsAtStartup;
|
||||||
|
|
||||||
final ids = ref
|
// final ids = ref
|
||||||
.read(prefsChangeNotifierProvider)
|
// .read(prefsChangeNotifierProvider)
|
||||||
.walletIdsSyncOnStartup;
|
// .walletIdsSyncOnStartup;
|
||||||
|
//
|
||||||
// enable auto sync on selected wallets only
|
// // enable auto sync on selected wallets only
|
||||||
ref.read(pWallets).wallets.forEach(
|
// ref.read(pWallets).wallets.forEach(
|
||||||
(e) => e.shouldAutoSync = ids.contains(e.walletId));
|
// (e) => e.shouldAutoSync = ids.contains(e.walletId));
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
child: Container(
|
child: Container(
|
||||||
|
|
|
@ -13,13 +13,11 @@ import 'dart:io';
|
||||||
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:flutter_svg/svg.dart';
|
import 'package:flutter_svg/svg.dart';
|
||||||
import 'package:stackwallet/providers/global/active_wallet_provider.dart';
|
|
||||||
import 'package:stackwallet/providers/providers.dart';
|
import 'package:stackwallet/providers/providers.dart';
|
||||||
import 'package:stackwallet/themes/coin_icon_provider.dart';
|
import 'package:stackwallet/themes/coin_icon_provider.dart';
|
||||||
import 'package:stackwallet/themes/stack_colors.dart';
|
import 'package:stackwallet/themes/stack_colors.dart';
|
||||||
import 'package:stackwallet/utilities/amount/amount_formatter.dart';
|
import 'package:stackwallet/utilities/amount/amount_formatter.dart';
|
||||||
import 'package:stackwallet/utilities/constants.dart';
|
import 'package:stackwallet/utilities/constants.dart';
|
||||||
import 'package:stackwallet/utilities/enums/sync_type_enum.dart';
|
|
||||||
import 'package:stackwallet/utilities/text_styles.dart';
|
import 'package:stackwallet/utilities/text_styles.dart';
|
||||||
import 'package:stackwallet/utilities/util.dart';
|
import 'package:stackwallet/utilities/util.dart';
|
||||||
import 'package:stackwallet/wallets/isar/providers/wallet_info_provider.dart';
|
import 'package:stackwallet/wallets/isar/providers/wallet_info_provider.dart';
|
||||||
|
@ -181,9 +179,9 @@ class WalletSyncingOptionsView extends ConsumerWidget {
|
||||||
.walletIdsSyncOnStartup))
|
.walletIdsSyncOnStartup))
|
||||||
.contains(info.walletId),
|
.contains(info.walletId),
|
||||||
onValueChanged: (value) {
|
onValueChanged: (value) {
|
||||||
final syncType = ref
|
// final syncType = ref
|
||||||
.read(prefsChangeNotifierProvider)
|
// .read(prefsChangeNotifierProvider)
|
||||||
.syncType;
|
// .syncType;
|
||||||
final ids = ref
|
final ids = ref
|
||||||
.read(prefsChangeNotifierProvider)
|
.read(prefsChangeNotifierProvider)
|
||||||
.walletIdsSyncOnStartup
|
.walletIdsSyncOnStartup
|
||||||
|
@ -194,25 +192,25 @@ class WalletSyncingOptionsView extends ConsumerWidget {
|
||||||
ids.remove(info.walletId);
|
ids.remove(info.walletId);
|
||||||
}
|
}
|
||||||
|
|
||||||
final wallet = ref
|
// final wallet = ref
|
||||||
.read(pWallets)
|
// .read(pWallets)
|
||||||
.getWallet(info.walletId);
|
// .getWallet(info.walletId);
|
||||||
|
//
|
||||||
switch (syncType) {
|
// switch (syncType) {
|
||||||
case SyncingType.currentWalletOnly:
|
// case SyncingType.currentWalletOnly:
|
||||||
if (info.walletId ==
|
// if (info.walletId ==
|
||||||
ref.read(
|
// ref.read(
|
||||||
currentWalletIdProvider)) {
|
// currentWalletIdProvider)) {
|
||||||
wallet.shouldAutoSync = value;
|
// wallet.shouldAutoSync = value;
|
||||||
}
|
// }
|
||||||
break;
|
// break;
|
||||||
case SyncingType
|
// case SyncingType
|
||||||
.selectedWalletsAtStartup:
|
// .selectedWalletsAtStartup:
|
||||||
case SyncingType
|
// case SyncingType
|
||||||
.allWalletsOnStartup:
|
// .allWalletsOnStartup:
|
||||||
wallet.shouldAutoSync = value;
|
// wallet.shouldAutoSync = value;
|
||||||
break;
|
// break;
|
||||||
}
|
// }
|
||||||
|
|
||||||
ref
|
ref
|
||||||
.read(prefsChangeNotifierProvider)
|
.read(prefsChangeNotifierProvider)
|
||||||
|
|
|
@ -124,7 +124,7 @@ class _WalletViewState extends ConsumerState<WalletView> {
|
||||||
|
|
||||||
late final bool isSparkWallet;
|
late final bool isSparkWallet;
|
||||||
|
|
||||||
late final bool _shouldDisableAutoSyncOnLogOut;
|
// late final bool _shouldDisableAutoSyncOnLogOut;
|
||||||
|
|
||||||
late WalletSyncStatus _currentSyncStatus;
|
late WalletSyncStatus _currentSyncStatus;
|
||||||
late NodeConnectionStatus _currentNodeStatus;
|
late NodeConnectionStatus _currentNodeStatus;
|
||||||
|
@ -177,9 +177,9 @@ class _WalletViewState extends ConsumerState<WalletView> {
|
||||||
if (!wallet.shouldAutoSync) {
|
if (!wallet.shouldAutoSync) {
|
||||||
// enable auto sync if it wasn't enabled when loading wallet
|
// enable auto sync if it wasn't enabled when loading wallet
|
||||||
wallet.shouldAutoSync = true;
|
wallet.shouldAutoSync = true;
|
||||||
_shouldDisableAutoSyncOnLogOut = true;
|
// _shouldDisableAutoSyncOnLogOut = true;
|
||||||
} else {
|
// } else {
|
||||||
_shouldDisableAutoSyncOnLogOut = false;
|
// _shouldDisableAutoSyncOnLogOut = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
isSparkWallet = wallet is SparkInterface;
|
isSparkWallet = wallet is SparkInterface;
|
||||||
|
@ -303,10 +303,10 @@ class _WalletViewState extends ConsumerState<WalletView> {
|
||||||
}
|
}
|
||||||
|
|
||||||
void _logout() async {
|
void _logout() async {
|
||||||
if (_shouldDisableAutoSyncOnLogOut) {
|
// if (_shouldDisableAutoSyncOnLogOut) {
|
||||||
// disable auto sync if it was enabled only when loading wallet
|
// // disable auto sync if it was enabled only when loading wallet
|
||||||
ref.read(pWallets).getWallet(walletId).shouldAutoSync = false;
|
ref.read(pWallets).getWallet(walletId).shouldAutoSync = false;
|
||||||
}
|
// }
|
||||||
|
|
||||||
ref.read(currentWalletIdProvider.notifier).state = null;
|
ref.read(currentWalletIdProvider.notifier).state = null;
|
||||||
ref.read(transactionFilterProvider.state).state = null;
|
ref.read(transactionFilterProvider.state).state = null;
|
||||||
|
|
|
@ -72,7 +72,7 @@ class _DesktopWalletViewState extends ConsumerState<DesktopWalletView> {
|
||||||
late final TextEditingController controller;
|
late final TextEditingController controller;
|
||||||
late final EventBus eventBus;
|
late final EventBus eventBus;
|
||||||
|
|
||||||
late final bool _shouldDisableAutoSyncOnLogOut;
|
// late final bool _shouldDisableAutoSyncOnLogOut;
|
||||||
|
|
||||||
Future<void> onBackPressed() async {
|
Future<void> onBackPressed() async {
|
||||||
await _logout();
|
await _logout();
|
||||||
|
@ -83,10 +83,10 @@ class _DesktopWalletViewState extends ConsumerState<DesktopWalletView> {
|
||||||
|
|
||||||
Future<void> _logout() async {
|
Future<void> _logout() async {
|
||||||
final wallet = ref.read(pWallets).getWallet(widget.walletId);
|
final wallet = ref.read(pWallets).getWallet(widget.walletId);
|
||||||
if (_shouldDisableAutoSyncOnLogOut) {
|
// if (_shouldDisableAutoSyncOnLogOut) {
|
||||||
// disable auto sync if it was enabled only when loading wallet
|
// // disable auto sync if it was enabled only when loading wallet
|
||||||
wallet.shouldAutoSync = false;
|
wallet.shouldAutoSync = false;
|
||||||
}
|
// }
|
||||||
ref.read(transactionFilterProvider.state).state = null;
|
ref.read(transactionFilterProvider.state).state = null;
|
||||||
if (ref.read(prefsChangeNotifierProvider).isAutoBackupEnabled &&
|
if (ref.read(prefsChangeNotifierProvider).isAutoBackupEnabled &&
|
||||||
ref.read(prefsChangeNotifierProvider).backupFrequencyType ==
|
ref.read(prefsChangeNotifierProvider).backupFrequencyType ==
|
||||||
|
@ -131,11 +131,11 @@ class _DesktopWalletViewState extends ConsumerState<DesktopWalletView> {
|
||||||
ref.read(currentWalletIdProvider.notifier).state = wallet.walletId);
|
ref.read(currentWalletIdProvider.notifier).state = wallet.walletId);
|
||||||
|
|
||||||
if (!wallet.shouldAutoSync) {
|
if (!wallet.shouldAutoSync) {
|
||||||
// enable auto sync if it wasn't enabled when loading wallet
|
// // enable auto sync if it wasn't enabled when loading wallet
|
||||||
wallet.shouldAutoSync = true;
|
wallet.shouldAutoSync = true;
|
||||||
_shouldDisableAutoSyncOnLogOut = true;
|
// _shouldDisableAutoSyncOnLogOut = true;
|
||||||
} else {
|
// } else {
|
||||||
_shouldDisableAutoSyncOnLogOut = false;
|
// _shouldDisableAutoSyncOnLogOut = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
wallet.refresh();
|
wallet.refresh();
|
||||||
|
|
|
@ -136,7 +136,8 @@ class Wallets {
|
||||||
|
|
||||||
Future<void> load(Prefs prefs, MainDB mainDB) async {
|
Future<void> load(Prefs prefs, MainDB mainDB) async {
|
||||||
// return await _loadV1(prefs, mainDB);
|
// return await _loadV1(prefs, mainDB);
|
||||||
return await _loadV2(prefs, mainDB);
|
// return await _loadV2(prefs, mainDB);
|
||||||
|
return await _loadV3(prefs, mainDB);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> _loadV1(Prefs prefs, MainDB mainDB) async {
|
Future<void> _loadV1(Prefs prefs, MainDB mainDB) async {
|
||||||
|
@ -240,6 +241,7 @@ class Wallets {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// should be fastest but big ui performance hit
|
||||||
Future<void> _loadV2(Prefs prefs, MainDB mainDB) async {
|
Future<void> _loadV2(Prefs prefs, MainDB mainDB) async {
|
||||||
if (hasLoaded) {
|
if (hasLoaded) {
|
||||||
return;
|
return;
|
||||||
|
@ -358,6 +360,160 @@ class Wallets {
|
||||||
await Future.wait(deleteFutures);
|
await Future.wait(deleteFutures);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// should be best performance
|
||||||
|
Future<void> _loadV3(Prefs prefs, MainDB mainDB) async {
|
||||||
|
if (hasLoaded) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
hasLoaded = true;
|
||||||
|
|
||||||
|
// clear out any wallet hive boxes where the wallet was deleted in previous app run
|
||||||
|
for (final walletId in DB.instance
|
||||||
|
.values<String>(boxName: DB.boxNameWalletsToDeleteOnStart)) {
|
||||||
|
await mainDB.isar.writeTxn(() async => await mainDB.isar.walletInfo
|
||||||
|
.where()
|
||||||
|
.walletIdEqualTo(walletId)
|
||||||
|
.deleteAll());
|
||||||
|
}
|
||||||
|
// clear list
|
||||||
|
await DB.instance
|
||||||
|
.deleteAll<String>(boxName: DB.boxNameWalletsToDeleteOnStart);
|
||||||
|
|
||||||
|
final walletInfoList = await mainDB.isar.walletInfo.where().findAll();
|
||||||
|
if (walletInfoList.isEmpty) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
final List<Future<String>> walletIDInitFutures = [];
|
||||||
|
final List<Future<void>> deleteFutures = [];
|
||||||
|
final List<({Wallet wallet, bool shouldAutoSync})> walletsToInitLinearly =
|
||||||
|
[];
|
||||||
|
|
||||||
|
final List<String> walletIdsToSyncOnceOnStartup = [];
|
||||||
|
bool shouldSyncAllOnceOnStartup = false;
|
||||||
|
switch (prefs.syncType) {
|
||||||
|
case SyncingType.currentWalletOnly:
|
||||||
|
// do nothing as this will be set when going into a wallet from the main screen
|
||||||
|
break;
|
||||||
|
case SyncingType.selectedWalletsAtStartup:
|
||||||
|
walletIdsToSyncOnceOnStartup.addAll(prefs.walletIdsSyncOnStartup);
|
||||||
|
break;
|
||||||
|
case SyncingType.allWalletsOnStartup:
|
||||||
|
shouldSyncAllOnceOnStartup = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (final walletInfo in walletInfoList) {
|
||||||
|
try {
|
||||||
|
final isVerified = await walletInfo.isMnemonicVerified(mainDB.isar);
|
||||||
|
Logging.instance.log(
|
||||||
|
"LOADING WALLET: ${walletInfo.name}:${walletInfo.walletId} "
|
||||||
|
"IS VERIFIED: $isVerified",
|
||||||
|
level: LogLevel.Info,
|
||||||
|
);
|
||||||
|
|
||||||
|
if (isVerified) {
|
||||||
|
// TODO: integrate this into the new wallets somehow?
|
||||||
|
// requires some thinking
|
||||||
|
// final txTracker =
|
||||||
|
// TransactionNotificationTracker(walletId: walletInfo.walletId);
|
||||||
|
|
||||||
|
final walletIdCompleter = Completer<String>();
|
||||||
|
|
||||||
|
walletIDInitFutures.add(walletIdCompleter.future);
|
||||||
|
|
||||||
|
await Wallet.load(
|
||||||
|
walletId: walletInfo.walletId,
|
||||||
|
mainDB: mainDB,
|
||||||
|
secureStorageInterface: nodeService.secureStorageInterface,
|
||||||
|
nodeService: nodeService,
|
||||||
|
prefs: prefs,
|
||||||
|
).then((wallet) {
|
||||||
|
if (wallet is CwBasedInterface) {
|
||||||
|
// walletsToInitLinearly.add(Tuple2(manager, shouldSetAutoSync));
|
||||||
|
|
||||||
|
walletIdCompleter.complete("dummy_ignore");
|
||||||
|
} else {
|
||||||
|
walletIdCompleter.complete(wallet.walletId);
|
||||||
|
}
|
||||||
|
|
||||||
|
_wallets[wallet.walletId] = wallet;
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
// wallet creation was not completed by user so we remove it completely
|
||||||
|
deleteFutures.add(_deleteWallet(walletInfo.walletId));
|
||||||
|
}
|
||||||
|
} catch (e, s) {
|
||||||
|
Logging.instance.log("$e $s", level: LogLevel.Fatal);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
final asyncWalletIds = await Future.wait(walletIDInitFutures);
|
||||||
|
asyncWalletIds.removeWhere((e) => e == "dummy_ignore");
|
||||||
|
|
||||||
|
final List<String> idsToRefresh = [];
|
||||||
|
final List<Future<void>> walletInitFutures = asyncWalletIds
|
||||||
|
.map(
|
||||||
|
(id) => _wallets[id]!.init().then(
|
||||||
|
(_) {
|
||||||
|
if (shouldSyncAllOnceOnStartup ||
|
||||||
|
walletIdsToSyncOnceOnStartup.contains(id)) {
|
||||||
|
idsToRefresh.add(id);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
),
|
||||||
|
)
|
||||||
|
.toList();
|
||||||
|
|
||||||
|
Future<void> _refreshFutures(List<String> idsToRefresh) async {
|
||||||
|
final start = DateTime.now();
|
||||||
|
Logging.instance.log(
|
||||||
|
"Initial refresh start: ${start.toUtc()}",
|
||||||
|
level: LogLevel.Warning,
|
||||||
|
);
|
||||||
|
const groupCount = 3;
|
||||||
|
for (int i = 0; i < idsToRefresh.length; i += groupCount) {
|
||||||
|
final List<Future<void>> futures = [];
|
||||||
|
for (int j = 0; j < groupCount; j++) {
|
||||||
|
if (i + j >= idsToRefresh.length) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
futures.add(
|
||||||
|
_wallets[idsToRefresh[i + j]]!.refresh(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
await Future.wait(futures);
|
||||||
|
}
|
||||||
|
Logging.instance.log(
|
||||||
|
"Initial refresh duration: ${DateTime.now().difference(start)}",
|
||||||
|
level: LogLevel.Warning,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (walletInitFutures.isNotEmpty && walletsToInitLinearly.isNotEmpty) {
|
||||||
|
unawaited(
|
||||||
|
Future.wait([
|
||||||
|
_initLinearly(walletsToInitLinearly),
|
||||||
|
...walletInitFutures,
|
||||||
|
]).then(
|
||||||
|
(value) => _refreshFutures(idsToRefresh),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
} else if (walletInitFutures.isNotEmpty) {
|
||||||
|
unawaited(
|
||||||
|
Future.wait(walletInitFutures).then(
|
||||||
|
(value) => _refreshFutures(idsToRefresh),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
} else if (walletsToInitLinearly.isNotEmpty) {
|
||||||
|
unawaited(_initLinearly(walletsToInitLinearly));
|
||||||
|
}
|
||||||
|
|
||||||
|
// finally await any deletions that haven't completed yet
|
||||||
|
await Future.wait(deleteFutures);
|
||||||
|
}
|
||||||
|
|
||||||
Future<void> loadAfterStackRestore(
|
Future<void> loadAfterStackRestore(
|
||||||
Prefs prefs,
|
Prefs prefs,
|
||||||
List<Wallet> wallets,
|
List<Wallet> wallets,
|
||||||
|
@ -396,10 +552,10 @@ class Wallets {
|
||||||
if (wallet is CwBasedInterface) {
|
if (wallet is CwBasedInterface) {
|
||||||
// walletsToInitLinearly.add(Tuple2(manager, shouldSetAutoSync));
|
// walletsToInitLinearly.add(Tuple2(manager, shouldSetAutoSync));
|
||||||
} else {
|
} else {
|
||||||
walletInitFutures.add(wallet.init().then((value) {
|
walletInitFutures.add(wallet.init().then((_) {
|
||||||
if (shouldSetAutoSync) {
|
// if (shouldSetAutoSync) {
|
||||||
wallet.shouldAutoSync = true;
|
// wallet.shouldAutoSync = true;
|
||||||
}
|
// }
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue