feat: term session mgr (#846)

This commit is contained in:
lollipopkit🏳️‍⚧️
2025-08-12 23:43:42 +08:00
committed by GitHub
parent 584af5423a
commit 9b01da5a23
39 changed files with 1275 additions and 55 deletions

View File

@@ -61,6 +61,11 @@ extension _Init on SSHPageState {
_listen(session.stdout);
_listen(session.stderr);
// Hold the session for external control (disconnect)
_session = session;
// Mark status connected for notifications / live activities
TermSessionManager.updateStatus(_sessionId, TermSessionStatus.connected);
for (final snippet in SnippetProvider.snippets.value) {
if (snippet.autoRunOn?.contains(widget.args.spi.id) == true) {
snippet.runInTerm(_terminal, widget.args.spi);
@@ -85,6 +90,7 @@ extension _Init on SSHPageState {
context.pop();
}
widget.args.onSessionEnd?.call();
TermSessionManager.remove(_sessionId);
}
void _listen(Stream<Uint8List>? stream) {
@@ -122,6 +128,7 @@ extension _Init on SSHPageState {
_discontinuityTimer?.cancel();
if (!mounted) return;
_writeLn('\n\nConnection lost\r\n');
TermSessionManager.updateStatus(_sessionId, TermSessionStatus.disconnected);
context.showRoundDialog(
title: libL10n.attention,
child: Text('${l10n.disconnected}\n${l10n.goBackQ}'),
@@ -139,3 +146,17 @@ extension _Init on SSHPageState {
_terminal.write('$p0\r\n');
}
}
extension on SSHPageState {
void _disconnectFromNotification() {
// Mark as disconnected in session manager for immediate UI/notification feedback
TermSessionManager.updateStatus(_sessionId, TermSessionStatus.disconnected);
// Try to close the running SSH session, if any
try {
_session?.close();
} catch (e, stackTrace) {
Loggers.app.warning('Error closing SSH session: $e\n$stackTrace');
}
}
}

View File

@@ -21,6 +21,7 @@ import 'package:server_box/data/provider/snippet.dart';
import 'package:server_box/data/provider/virtual_keyboard.dart';
import 'package:server_box/data/res/store.dart';
import 'package:server_box/data/res/terminal.dart';
import 'package:server_box/data/ssh/session_manager.dart';
import 'package:server_box/view/page/storage/sftp.dart';
import 'package:wakelock_plus/wakelock_plus.dart';
@@ -81,10 +82,13 @@ class SSHPageState extends State<SSHPage>
bool _isDark = false;
Timer? _virtKeyLongPressTimer;
late SSHClient? _client = widget.args.spi.server?.value.client;
SSHSession? _session;
Timer? _discontinuityTimer;
/// Used for (de)activate the wake lock and forground service
static var _sshConnCount = 0;
late final String _sessionId = ShortId.generate();
late final int _sessionStartMs = DateTime.now().millisecondsSinceEpoch;
@override
void dispose() {
@@ -101,6 +105,9 @@ class SSHPageState extends State<SSHPage>
}
}
// Remove session entry
TermSessionManager.remove(_sessionId);
super.dispose();
}
@@ -117,6 +124,16 @@ class SSHPageState extends State<SSHPage>
MethodChans.startService();
}
}
// Add session entry (for Android notifications & iOS Live Activities)
TermSessionManager.add(
id: _sessionId,
spi: widget.args.spi,
startTimeMs: _sessionStartMs,
disconnect: _disconnectFromNotification,
status: TermSessionStatus.connecting,
);
TermSessionManager.setActive(_sessionId, hasTerminal: true);
}
@override