105 lines
4.4 KiB
Dart
105 lines
4.4 KiB
Dart
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<void> openStorage(BuildContext context, ExplorerPane pane, String dir) async {
|
|
ctl
|
|
..active = ctl.panes.indexOf(pane)
|
|
..update();
|
|
if (isDav(dir)) {
|
|
final ok = await showDialog<bool>(
|
|
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<void> 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('끄기'))),
|
|
]),
|
|
),
|
|
),
|
|
);
|
|
}
|
|
}
|