import 'package:flutter/material.dart'; import '../../core/ftp.dart' show FtpRegistry; import '../../core/sftp.dart' show SftpRegistry; import '../../core/smb.dart' show SmbRegistry; import '../../core/vfs.dart'; import '../../core/webdav.dart' show DavRegistry; import '../ftp_settings.dart'; import '../sftp_settings.dart'; import '../smb_settings.dart'; import '../webdav_settings.dart'; import 'explorer_controller.dart'; import 'explorer_pane.dart'; import 'path_dialog.dart'; /// 약속 (E5d-3): 창에서 네트워크 서버 추가 · 고치기 · 경로 입력 흐름. 서버 설정 창은 webdav · sftp · ftp · smb_settings 가, /// 경로 확인은 [PathDialog] 가 하고, 여기는 그 결과로 창을 옮길 뿐이다. /// - [root] 가 null 이면 새 서버, 아니면 그 탭의 서버를 고친다. 저장하면 그 서버의 읽어 둔 목록 (· 호스트 키 · 인증서 오류) 을 /// 모든 창에서 버리고 [pane] 을 그 서버로 옮긴다. 취소하면 아무것도 바꾸지 않는다. /// - 부를 때마다 [pane] 을 지금 창으로. 창이 닫힌 뒤 (Host 가 살아 있지 않음) 에는 옮기지 않는다. class ExplorerServers { ExplorerServers(this.ctl); final ExplorerController ctl; void _activate(ExplorerPane pane) { ctl.active = ctl.panes.indexOf(pane); ctl.update(); } /// 경로를 직접 넣어 가기 (37). 146 · 37-2: 없는 폴더면 창을 닫지 않고 칸 아래에 알린다 (고쳐서 다시 넣을 수 있게) Future enterPath(BuildContext context, ExplorerPane pane, {required bool android}) async { _activate(pane); final path = await showDialog(context: context, builder: (_) => PathDialog(initial: pane.current, android: android)); if (path == null || !ctl.host.alive || !context.mounted) return; // 179: SMB 를 넣었다가 [WebDAV 서버 추가] 를 누름 if (path == PathDialog.addDav) return editDav(context, pane, null); // 88: Android 에서 smb:// · \\서버\공유 를 넣고 [SMB 서버 추가] if (path.startsWith(PathDialog.addSmb)) return editSmb(context, pane, null, from: path.substring(PathDialog.addSmb.length)); await ctl.goTo(pane, path, fresh: true); } /// WebDAV 서버 추가 (없으면 [root] 는 null) · 고치기 (탭 길게 누르기). 저장하면 그 서버로 간다. Future editDav(BuildContext context, ExplorerPane pane, String? root) async { _activate(pane); final old = root == null ? null : DavRegistry.server(DavPath.parse(root).server); final saved = await editDavServer(context, ctl.c, old: old); if (saved == null || !ctl.host.alive) return; for (final x in ctl.panes) { x.cache.removeWhere((k, _) => isDav(k) && DavPath.parse(k).server == saved.id); } await ctl.goTo(pane, '$davScheme${saved.id}/'); } /// 88: SFTP 서버 추가 (없으면 [root] 는 null) · 고치기 (탭 길게 누르기). 저장하면 그 서버로 간다. Future editSftp(BuildContext context, ExplorerPane pane, String? root) async { _activate(pane); final old = root == null ? null : SftpRegistry.server(DavPath.parse(root).server); final saved = await editSftpServer(context, ctl.c, old: old); if (saved == null || !ctl.host.alive) return; for (final x in ctl.panes) { x.cache.removeWhere((k, _) => isSftp(k) && DavPath.parse(k).server == saved.id); x.hostKeyErrors.removeWhere((k, _) => isSftp(k) && DavPath.parse(k).server == saved.id); } await ctl.goTo(pane, '$sftpScheme${saved.id}/'); } /// l: FTP 서버 추가 (없으면 [root] 는 null) · 고치기 (탭 길게 누르기). 저장하면 그 서버로 간다. Future editFtp(BuildContext context, ExplorerPane pane, String? root) async { _activate(pane); final old = root == null ? null : FtpRegistry.server(DavPath.parse(root).server); final saved = await editFtpServer(context, ctl.c, old: old); if (saved == null || !ctl.host.alive) return; for (final x in ctl.panes) { x.cache.removeWhere((k, _) => isFtp(k) && DavPath.parse(k).server == saved.id); x.certErrors.removeWhere((k, _) => isFtp(k) && DavPath.parse(k).server == saved.id); } await ctl.goTo(pane, '$ftpScheme${saved.id}/'); } /// 88: SMB 서버 추가 (없으면 [root] 는 null, [from] 은 경로 입력에 넣은 주소) · 고치기 (탭 길게 누르기). 저장하면 그 서버로 간다. Future editSmb(BuildContext context, ExplorerPane pane, String? root, {String? from}) async { _activate(pane); final old = root == null ? null : SmbRegistry.server(DavPath.parse(root).server); final saved = await editSmbServer(context, ctl.c, old: old, from: from); if (saved == null || !ctl.host.alive) return; for (final x in ctl.panes) { x.cache.removeWhere((k, _) => isSmb(k) && DavPath.parse(k).server == saved.id); } await ctl.goTo(pane, '$smbScheme${saved.id}/'); } }