import 'package:flutter/material.dart'; import '../../app/app_controller.dart'; import '../../core/vfs.dart'; import '../../core/wifi_share.dart' show WifiShare; import '../../l10n/tr.dart'; import '../storage_page.dart'; import '../theme.dart'; import '../wifi_share_page.dart'; import 'delete_flow.dart'; import 'explorer_controller.dart'; import 'explorer_pane.dart'; import 'transfer_flow.dart'; /// 약속 (E5d-6): 탐색기에서 여는 도구 - 저장 공간 분석 (87: 고른 것을 탐색기에서 그 자리로, 지우기 · 이동은 탐색기의 흐름으로, /// 원격은 오래 걸린다고 먼저 묻는다) · Wi-Fi 공유 (89: 이 기기의 폴더만, 켜져 있으면 그 공유). 위의 [Wi-Fi 공유 중] 줄은 [WifiShareBar] class ExplorerTools { ExplorerTools(this.ctl, this.deletes, this.transfers); final ExplorerController ctl; final ExplorerDeleteFlow deletes; final ExplorerTransfers transfers; /// 87: 저장 공간 분석 → 고른 것을 탐색기에서 그 자리로 (지우기는 탐색기의 지우기로만). /// WebDAV 는 직접 시킬 때만 (이 메뉴) 하고, 서버에서 모두 읽어 오래 걸린다고 먼저 알린다 Future openStorage(BuildContext context, ExplorerPane pane, String dir) async { ctl ..active = ctl.panes.indexOf(pane) ..update(); if (isDav(dir)) { final ok = await showDialog( context: context, builder: (ctx) => AlertDialog( title: Text(tr('저장 공간 분석')), content: Text(tr('WebDAV · SFTP 는 서버에서 안의 것을 모두 읽어 오래 걸릴 수 있습니다. 분석할까요?')), actions: [ TextButton(onPressed: () => Navigator.pop(ctx, false), child: Text(tr('취소'))), FilledButton(onPressed: () => Navigator.pop(ctx, true), child: Text(tr('분석'))), ], ), ); if (ok != true || !context.mounted) return; } // X-plore 비교 5-1 ⑤ (관리자 지시 10/21): 분석 화면에서도 이 탐색기의 지우기 (확인 · 휴지통) · 이동 (붙여넣기로) final path = await StorageAnalysisPage.open(context, dir, onDelete: (paths) async { await deletes.run(context, pane, paths); return [for (final x in paths) if (!await vExists(x)) x]; }, onCut: (paths) => transfers.toClipboard(paths, move: true)); if (path == null || !context.mounted) return; final isDir = await vIsDir(path); await ctl.goTo(pane, isDir ? path : vDirname(path), fresh: true); pane.focused = path; pane.changed(); ctl.host.reveal(pane, path); } /// 89: Wi-Fi 공유 화면 (이미 켜져 있으면 그 공유를 보인다). 이 기기의 폴더만 - WebDAV 등 원격은 알림 Future openWifiShare(BuildContext context, String dir) async { final on = WifiShare.instance; if (on == null && isDav(dir)) { ctl.host.snack(tr('Wi-Fi 공유는 이 기기의 폴더만 할 수 있습니다')); return; } await WifiSharePage.open(context, ctl.c, on?.root ?? dir); } } /// 89: 탐색기 위의 [Wi-Fi 공유 중] 줄 - 누르면 공유 화면, [끄기] class WifiShareBar extends StatelessWidget { const WifiShareBar({super.key, required this.c, required this.share}); final AppController c; final WifiShare share; // 화면을 닫아도 켜져 있음을 늘 보이게 (사용자가 모르게 열려 있지 않게) @override Widget build(BuildContext context) { final s = share; final left = s.endsAt?.difference(DateTime.now()); return Material( color: JjColors.panelHigh, child: InkWell( onTap: () => WifiSharePage.open(context, c, s.root), child: Padding( padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 6), child: Row(children: [ Icon(Icons.wifi_tethering, size: 18, color: JjColors.success), const SizedBox(width: 6), Expanded( child: Text( left == null ? trf('Wi-Fi 공유 중 · 코드 {0} · {1}', [s.code, s.root]) : trf('Wi-Fi 공유 중 · 코드 {0} · {1}분 남음 · {2}', [s.code, (left.inSeconds / 60).ceil().clamp(0, 9999), s.root]), maxLines: 1, overflow: TextOverflow.ellipsis, style: const TextStyle(fontSize: 12)), ), TextButton(onPressed: () => s.stop(), child: Text(tr('끄기'))), ]), ), ), ); } }