import 'dart:io'; import 'package:flutter/widgets.dart'; import '../core/vfs.dart'; import '../l10n/tr.dart'; /// 화면에 보일 경로 (67): Android 는 "내장 저장소 › Download › 폴더", WebDAV 는 "☁ 서버 › 폴더", Windows 는 "D: › 폴더" String friendlyPath(String path) { if (isDav(path)) { final d = DavPath.parse(path); return ['${d.mark} ${d.serverLabel}', ...d.rel.split('/').where((s) => s.isNotEmpty)].join(' › '); } if (Platform.isAndroid || path.startsWith('/storage/')) { final m = RegExp(r'^/storage/(emulated/\d+|[^/]+)(/.*)?$').firstMatch(path); if (m != null) { final root = m[1]!.startsWith('emulated/') ? tr('내장 저장소') : tr('SD 카드'); return [root, ...(m[2] ?? '').split('/').where((s) => s.isNotEmpty)].join(' › '); } } final parts = path.split(RegExp(r'[\\/]')).where((s) => s.isNotEmpty).toList(); return parts.isEmpty ? path : parts.join(' › '); } /// 짧게: 끝의 [keep] 단계만 (앞은 "…"). 쌍이 여러 개여도 무엇이 무엇인지 보이게 (67) String shortPath(String path, {int keep = 3}) { final parts = friendlyPath(path).split(' › '); return parts.length <= keep ? parts.join(' › ') : ['…', ...parts.sublist(parts.length - keep)].join(' › '); } /// [text] 를 [style] 로 한 줄에 그렸을 때의 폭 double textWidth(BuildContext context, String text, TextStyle style) { final tp = TextPainter( text: TextSpan(text: text, style: DefaultTextStyle.of(context).style.merge(style)), textDirection: Directionality.of(context), textScaler: MediaQuery.textScalerOf(context), maxLines: 1) ..layout(); final w = tp.width; tp.dispose(); return w; } /// [text] 가 [maxWidth] 를 넘으면 가운데를 "…" 로 줄인다 (앞 · 끝이 보이게 - 412 캡처 10/18, 갈 곳 막대) String middleEllipsis(BuildContext context, String text, TextStyle style, double maxWidth) { if (maxWidth <= 0) return '…'; if (textWidth(context, text, style) <= maxWidth) return text; var lo = 0, hi = text.length; String cut(int n) => '${text.substring(0, (n + 1) ~/ 2)}…${text.substring(text.length - n ~/ 2)}'; while (lo < hi) { final mid = (lo + hi + 1) ~/ 2; if (textWidth(context, cut(mid), style) <= maxWidth) { lo = mid; } else { hi = mid - 1; } } return lo == 0 ? '…' : cut(lo); }