This commit is contained in:
Matthew Fosse 2024-09-11 12:33:11 -07:00
parent 9f1b9548c3
commit 180b967c18
5 changed files with 107 additions and 38 deletions

View file

@ -456,7 +456,8 @@ abstract class ElectrumWalletBase
await updateBalance();
await updateFeeRates();
_updateFeeRateTimer ??=
_updateFeeRateTimer?.cancel();
_updateFeeRateTimer =
Timer.periodic(const Duration(minutes: 1), (timer) async => await updateFeeRates());
if (alwaysScan == true) {
@ -471,6 +472,13 @@ abstract class ElectrumWalletBase
}
}
@action
@override
Future<void> stopSync() async {
syncStatus = StoppedSyncingSyncStatus();
_updateFeeRateTimer?.cancel();
}
@action
Future<void> updateFeeRates() async {
if (await checkIfMempoolAPIIsEnabled()) {
@ -1113,7 +1121,8 @@ abstract class ElectrumWalletBase
});
}
unspentCoins.removeWhere((utxo) => estimatedTx.utxos.any((e) => e.utxo.txHash == utxo.hash));
unspentCoins
.removeWhere((utxo) => estimatedTx.utxos.any((e) => e.utxo.txHash == utxo.hash));
await updateBalance();
});
@ -2069,7 +2078,8 @@ abstract class ElectrumWalletBase
_isTryingToConnect = true;
Timer(Duration(seconds: 5), () {
if (this.syncStatus is NotConnectedSyncStatus || this.syncStatus is LostConnectionSyncStatus) {
if (this.syncStatus is NotConnectedSyncStatus ||
this.syncStatus is LostConnectionSyncStatus) {
this.electrumClient.connectToUri(
node!.uri,
useSSL: node!.useSSL ?? false,

View file

@ -32,6 +32,7 @@ const notificationChannelDescription = 'Cake Wallet Background Service';
const DELAY_SECONDS_BEFORE_SYNC_START = 15;
void setNotificationStandby(FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin) async {
flutterLocalNotificationsPlugin.cancelAll();
flutterLocalNotificationsPlugin.show(
notificationId,
initialNotificationTitle,
@ -181,22 +182,37 @@ Future<void> onStart(ServiceInstance service) async {
for (int i = 0; i < syncingWallets.length; i++) {
final wallet = syncingWallets[i];
final syncProgress = ((wallet!.syncStatus.progress()) * 100).toStringAsPrecision(5);
title += "${wallet.name}-${syncProgress}% ";
// title += "${wallet.name}-${syncProgress}% ";
String title = "${wallet.type} - ${wallet.name} - ${syncProgress}% Synced";
flutterLocalNotificationsPlugin.show(
notificationId,
title,
'Background sync - ${DateTime.now()}',
NotificationDetails(
android: AndroidNotificationDetails(
"${notificationChannelId}_$i",
"${notificationChannelName}_$i",
icon: 'ic_bg_service_small',
ongoing: true,
),
),
);
}
flutterLocalNotificationsPlugin.show(
notificationId,
title,
'Background sync - ${DateTime.now()}',
const NotificationDetails(
android: AndroidNotificationDetails(
notificationChannelId,
notificationChannelName,
icon: 'ic_bg_service_small',
ongoing: true,
),
),
);
// flutterLocalNotificationsPlugin.show(
// notificationId,
// title,
// 'Background sync - ${DateTime.now()}',
// const NotificationDetails(
// android: AndroidNotificationDetails(
// notificationChannelId,
// notificationChannelName,
// icon: 'ic_bg_service_small',
// ongoing: true,
// ),
// ),
// );
});
});
}
@ -211,14 +227,7 @@ Future<bool> onIosBackground(ServiceInstance service) async {
Future<void> initializeService(FlutterBackgroundService bgService, bool useNotifications) async {
if (useNotifications) {
const AndroidNotificationChannel channel = AndroidNotificationChannel(
notificationChannelId,
notificationChannelName,
description: notificationChannelDescription,
importance: Importance.low,
);
final FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin =
FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin =
FlutterLocalNotificationsPlugin();
if (Platform.isIOS || Platform.isAndroid) {
@ -230,13 +239,17 @@ Future<void> initializeService(FlutterBackgroundService bgService, bool useNotif
);
}
await flutterLocalNotificationsPlugin
.resolvePlatformSpecificImplementation<AndroidFlutterLocalNotificationsPlugin>()
?.createNotificationChannel(channel);
flutterLocalNotificationsPlugin
.resolvePlatformSpecificImplementation<AndroidFlutterLocalNotificationsPlugin>()
?.requestNotificationsPermission();
for (int i = 0; i < 10; i++) {
AndroidNotificationChannel channel = AndroidNotificationChannel(
"${notificationChannelId}_$i",
"${notificationChannelName}_$i",
description: notificationChannelDescription,
importance: Importance.low,
);
await flutterLocalNotificationsPlugin
.resolvePlatformSpecificImplementation<AndroidFlutterLocalNotificationsPlugin>()
?.createNotificationChannel(channel);
}
setNotificationStandby(flutterLocalNotificationsPlugin);
}
@ -273,10 +286,13 @@ Future<void> initializeService(FlutterBackgroundService bgService, bool useNotif
class BackgroundTasks {
FlutterBackgroundService bgService = FlutterBackgroundService();
FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin =
FlutterLocalNotificationsPlugin();
void updateServiceState(bool foreground, bool useNotifications) async {
if (foreground) {
bgService.invoke('stopService');
await Future.delayed(const Duration(seconds: 2));
initializeService(bgService, useNotifications);
} else {
bgService.invoke("setBackground");
@ -313,10 +329,15 @@ class BackgroundTasks {
return;
}
final SyncMode syncMode = settingsStore.currentSyncMode;
final bool syncAll = settingsStore.currentSyncAll;
if (settingsStore.showSyncNotification) {
flutterLocalNotificationsPlugin
.resolvePlatformSpecificImplementation<AndroidFlutterLocalNotificationsPlugin>()
?.requestNotificationsPermission();
}
if (syncMode.type == SyncType.disabled || !FeatureFlag.isBackgroundSyncEnabled) {
bgService.invoke('stopService');
return;

View file

@ -132,6 +132,7 @@ class RootState extends State<Root> with WidgetsBindingObserver {
@override
void didChangeAppLifecycleState(AppLifecycleState state) {
final syncingWalletTypes = [WalletType.litecoin, WalletType.monero, WalletType.bitcoin];
switch (state) {
case AppLifecycleState.paused:
if (isQrScannerShown) {
@ -142,7 +143,7 @@ class RootState extends State<Root> with WidgetsBindingObserver {
setState(() => _setInactive(true));
}
if (widget.appStore.wallet?.type == WalletType.litecoin) {
if (syncingWalletTypes.contains(widget.appStore.wallet?.type)) {
widget.appStore.wallet?.stopSync();
}
@ -172,7 +173,7 @@ class RootState extends State<Root> with WidgetsBindingObserver {
return;
}
wasInBackground = false;
if (widget.appStore.wallet?.type == WalletType.litecoin) {
if (syncingWalletTypes.contains(widget.appStore.wallet?.type)) {
// wait a few seconds before starting the sync make sure the background service is fully exited:
Future.delayed(const Duration(seconds: 3), () {
widget.appStore.wallet?.startSync();
@ -180,13 +181,15 @@ class RootState extends State<Root> with WidgetsBindingObserver {
}
break;
case AppLifecycleState.paused:
getIt.get<BackgroundTasks>().updateServiceState(false, showNotifications);
// TODO: experimental: maybe should uncomment this:
// getIt.get<BackgroundTasks>().updateServiceState(false, showNotifications);
case AppLifecycleState.inactive:
case AppLifecycleState.detached:
default:
// if we enter any state other than resumed start a timer for 30 seconds
// after which we'll consider the app to be in the background
_stateTimer?.cancel();
// TODO: bump this to > 30 seconds when testing is done:
_stateTimer = Timer(const Duration(seconds: 10), () async {
wasInBackground = true;
getIt.get<BackgroundTasks>().updateServiceState(false, showNotifications);

View file

@ -78,6 +78,34 @@ class ConnectionSyncPage extends BasePage {
// }
});
}),
Observer(builder: (context) {
return SettingsSwitcherCell(
title: "T: show sync% in notification",
value: dashboardViewModel.showSyncNotification,
onValueChange: (BuildContext _, bool isEnabled) async {
dashboardViewModel.setShowSyncNotification(isEnabled);
// if (!isEnabled) {
// final bool confirmation = await showPopUp<bool>(
// context: context,
// builder: (BuildContext context) {
// return AlertWithTwoActions(
// alertTitle: S.of(context).warning,
// alertContent: S.of(context).disable_fee_api_warning,
// rightButtonText: S.of(context).confirm,
// leftButtonText: S.of(context).cancel,
// actionRightButton: () => Navigator.of(context).pop(true),
// actionLeftButton: () => Navigator.of(context).pop(false));
// }) ??
// false;
// if (confirmation) {
// _privacySettingsViewModel.setUseMempoolFeeAPI(isEnabled);
// }
// return;
// }
},
);
}),
Observer(builder: (context) {
return SettingsSwitcherCell(
title: S.current.sync_all_wallets,
@ -106,7 +134,8 @@ class ConnectionSyncPage extends BasePage {
},
),
if (isWalletConnectCompatibleChain(dashboardViewModel.wallet.type) &&
!dashboardViewModel.wallet.isHardwareWallet) ...[ // ToDo: Remove this line once WalletConnect is implemented
!dashboardViewModel.wallet.isHardwareWallet) ...[
// ToDo: Remove this line once WalletConnect is implemented
WalletConnectTile(
onTap: () => Navigator.of(context).pushNamed(Routes.walletConnectConnectionsListing),
),

View file

@ -714,6 +714,12 @@ abstract class DashboardViewModelBase with Store {
@computed
bool get syncAll => settingsStore.currentSyncAll;
@action
void setShowSyncNotification(bool value) => settingsStore.showSyncNotification = value;
@computed
bool get showSyncNotification => settingsStore.showSyncNotification;
@action
void setSyncAll(bool value) => settingsStore.currentSyncAll = value;