Prompt on close for connected local node
This commit is contained in:
+39
-3
@@ -4,10 +4,12 @@ import 'dart:io';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_localizations/flutter_localizations.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:path/path.dart' as p;
|
||||
import 'package:window_manager/window_manager.dart';
|
||||
|
||||
import 'domain/models.dart';
|
||||
import 'package:salvium_wallet/l10n/app_localizations.dart';
|
||||
import 'services/app_paths.dart';
|
||||
import 'services/local_node_service.dart';
|
||||
import 'state/providers.dart';
|
||||
import 'state/wallet_controller.dart';
|
||||
@@ -42,6 +44,17 @@ class _PeyaAppState extends ConsumerState<PeyaApp> with WindowListener {
|
||||
bool _desktopCloseHookInitialized = false;
|
||||
bool _handlingWindowClose = false;
|
||||
|
||||
Future<void> _logCloseDebug(String message) async {
|
||||
try {
|
||||
final file = File(p.join((await AppPaths.appSupportDir()).path, 'close-debug.log'));
|
||||
await file.parent.create(recursive: true);
|
||||
await file.writeAsString(
|
||||
'[${DateTime.now().toIso8601String()}] $message\n',
|
||||
mode: FileMode.writeOnlyAppend,
|
||||
);
|
||||
} catch (_) {}
|
||||
}
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
@@ -112,32 +125,45 @@ class _PeyaAppState extends ConsumerState<PeyaApp> with WindowListener {
|
||||
Future<void> _initDesktopCloseHook() async {
|
||||
if (_desktopCloseHookInitialized ||
|
||||
!(Platform.isLinux || Platform.isWindows)) {
|
||||
await _logCloseDebug(
|
||||
'initDesktopCloseHook skipped: initialized=$_desktopCloseHookInitialized platform=${Platform.operatingSystem}',
|
||||
);
|
||||
return;
|
||||
}
|
||||
await windowManager.ensureInitialized();
|
||||
windowManager.addListener(this);
|
||||
await windowManager.setPreventClose(true);
|
||||
final preventClose = await windowManager.isPreventClose();
|
||||
_desktopCloseHookInitialized = true;
|
||||
await _logCloseDebug(
|
||||
'initDesktopCloseHook ready: platform=${Platform.operatingSystem} preventClose=$preventClose',
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
void onWindowClose() {
|
||||
unawaited(_logCloseDebug('onWindowClose fired'));
|
||||
unawaited(_handleNativeWindowClose());
|
||||
}
|
||||
|
||||
Future<void> _handleNativeWindowClose() async {
|
||||
if (_handlingWindowClose) {
|
||||
await _logCloseDebug('handleNativeWindowClose skipped: already handling');
|
||||
return;
|
||||
}
|
||||
_handlingWindowClose = true;
|
||||
try {
|
||||
await _logCloseDebug('handleNativeWindowClose entered');
|
||||
final shouldClose = await _handleAppCloseRequest();
|
||||
await _logCloseDebug('handleNativeWindowClose decision: shouldClose=$shouldClose');
|
||||
if (!shouldClose) {
|
||||
return;
|
||||
}
|
||||
await windowManager.setPreventClose(false);
|
||||
await _logCloseDebug('handleNativeWindowClose destroying window');
|
||||
await windowManager.destroy();
|
||||
} finally {
|
||||
await _logCloseDebug('handleNativeWindowClose finished');
|
||||
_handlingWindowClose = false;
|
||||
}
|
||||
}
|
||||
@@ -290,15 +316,21 @@ class _PeyaAppState extends ConsumerState<PeyaApp> with WindowListener {
|
||||
final config = ref.read(appConfigControllerProvider);
|
||||
final localNodeService = ref.read(localNodeServiceProvider);
|
||||
final shouldPromptForLocalNode = config.nodeConfig.mode == NodeMode.local &&
|
||||
await localNodeService.isRunning(
|
||||
config: LocalNodeConfig(extraArgs: config.localNodeArgs),
|
||||
);
|
||||
((await localNodeService.isRunning(
|
||||
config: LocalNodeConfig(extraArgs: config.localNodeArgs),
|
||||
)) ||
|
||||
(await ref.read(walletRepositoryProvider).isConnected()));
|
||||
await _logCloseDebug(
|
||||
'handleAppCloseRequest: mode=${config.nodeConfig.mode} prompt=$shouldPromptForLocalNode mounted=$mounted',
|
||||
);
|
||||
var shouldStopLocalNode = false;
|
||||
if (shouldPromptForLocalNode) {
|
||||
final l10n = AppLocalizations.of(context);
|
||||
if (l10n == null || !mounted) {
|
||||
await _logCloseDebug('handleAppCloseRequest aborted: l10n null or not mounted');
|
||||
return false;
|
||||
}
|
||||
await _logCloseDebug('handleAppCloseRequest showing dialog');
|
||||
final decision = await showDialog<bool?>(
|
||||
context: context,
|
||||
builder: (dialogContext) {
|
||||
@@ -323,12 +355,15 @@ class _PeyaAppState extends ConsumerState<PeyaApp> with WindowListener {
|
||||
},
|
||||
);
|
||||
if (decision == null) {
|
||||
await _logCloseDebug('handleAppCloseRequest dialog cancelled');
|
||||
return false;
|
||||
}
|
||||
shouldStopLocalNode = decision;
|
||||
await _logCloseDebug('handleAppCloseRequest dialog decision: stopNode=$shouldStopLocalNode');
|
||||
}
|
||||
if (shouldStopLocalNode) {
|
||||
final stopped = await localNodeService.stop();
|
||||
await _logCloseDebug('handleAppCloseRequest stop result: $stopped');
|
||||
if (!stopped) {
|
||||
if (mounted) {
|
||||
final l10n = AppLocalizations.of(context);
|
||||
@@ -344,6 +379,7 @@ class _PeyaAppState extends ConsumerState<PeyaApp> with WindowListener {
|
||||
}
|
||||
}
|
||||
await ref.read(walletRepositoryProvider).closeWallet();
|
||||
await _logCloseDebug('handleAppCloseRequest wallet closed');
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user