From 4187cf2d2a976a71a6ae6852a545a9d50dbfb2d8 Mon Sep 17 00:00:00 2001 From: chaos-zhu Date: Sat, 23 May 2026 21:05:29 +0800 Subject: [PATCH] =?UTF-8?q?feat(mobile):=20SFTP=20=E5=8D=95=E5=87=BB?= =?UTF-8?q?=E6=96=87=E4=BB=B6=E8=BF=9B=E5=85=A5=E6=96=87=E6=9C=AC=E7=BC=96?= =?UTF-8?q?=E8=BE=91=E5=99=A8=EF=BC=8C=E5=88=86=E6=94=AF=E4=B8=89=E7=B1=BB?= =?UTF-8?q?=E5=BC=82=E5=B8=B8=20toast?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- mobile/lib/features/shell/sftp_tab.dart | 46 +++++++++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/mobile/lib/features/shell/sftp_tab.dart b/mobile/lib/features/shell/sftp_tab.dart index aaf8e36..3bc0405 100644 --- a/mobile/lib/features/shell/sftp_tab.dart +++ b/mobile/lib/features/shell/sftp_tab.dart @@ -14,6 +14,8 @@ import '../../state/api_providers.dart'; import '../../state/auth_notifier.dart'; import '../../state/host_list_notifier.dart'; import '../../state/terminal_providers.dart'; +import 'editor/editor_text_sniffer.dart'; +import 'editor/text_editor_page.dart'; import 'sftp_session_manager.dart'; class SftpTab extends ConsumerStatefulWidget { @@ -213,6 +215,8 @@ class _SftpConnectedView extends StatelessWidget { manager.openPath( manager.entryPath(session, entry), ); + } else { + _openInEditor(context, manager, session, entry); } }, onLongPress: () { @@ -244,6 +248,48 @@ class _SftpConnectedView extends StatelessWidget { ); } + Future _openInEditor( + BuildContext context, + SftpSessionManager manager, + SftpSessionState session, + SftpFileEntry entry, + ) async { + final l = AppLocalizations.of(context); + final remotePath = manager.entryPath(session, entry); + try { + final bytes = await manager.readTextFile(remotePath); + if (!context.mounted) return; + final sniff = sniffAndDecode(bytes); + await Navigator.of(context).push( + MaterialPageRoute( + builder: (_) => TextEditorPage( + manager: manager, + remotePath: remotePath, + fileName: entry.name, + initialText: sniff.text, + malformedUtf8: sniff.malformedUtf8, + totalBytes: bytes.length, + ), + ), + ); + if (!context.mounted) return; + await manager.refreshActive(); + } on SftpFileTooLargeException { + if (!context.mounted) return; + ScaffoldMessenger.of(context) + .showSnackBar(SnackBar(content: Text(l.tr('editor.tooLarge')))); + } on SftpBinaryFileException { + if (!context.mounted) return; + ScaffoldMessenger.of(context) + .showSnackBar(SnackBar(content: Text(l.tr('editor.binary')))); + } catch (error) { + if (!context.mounted) return; + ScaffoldMessenger.of(context).showSnackBar( + SnackBar(content: Text(l.trf('editor.readFailed', [error.toString()]))), + ); + } + } + void _showFileActionSheet( BuildContext context, SftpSessionState session,