Merge branch 'xplore_p3' into next
commit
fefe972937
|
|
@ -76,6 +76,7 @@
|
|||
"1/2 · AI 그림으로 다듬는 중": "1/2 · Refining with AI image",
|
||||
"10초 뒤로 (←)": "Back 10 seconds (←)",
|
||||
"10초 앞으로 (→)": "Forward 10 seconds (→)",
|
||||
"16진": "Hex",
|
||||
"16진 보기 · {0}": "Hex view · {0}",
|
||||
"1배 (선명하게)": "1× (sharpen)",
|
||||
"1분 안": "under 1 min",
|
||||
|
|
@ -2592,6 +2593,7 @@
|
|||
"폴더 복사 · 이동 방법": "Folder copy · move method",
|
||||
"폴더 삭제: {0} (안의 {1}개 포함)": "Folder deleted: {0} (including {1} inside)",
|
||||
"폴더 선택": "Choose folder",
|
||||
"폴더 속성": "Folder properties",
|
||||
"폴더 속성 · {0}": "Folder properties · {0}",
|
||||
"폴더 수정": "Edit folder",
|
||||
"폴더 안 파일 크기의 합을 목록에 보입니다. 큰 폴더 · NAS 는 읽는 데 오래 걸릴 수 있습니다. 길게 누르기 [폴더 크기 계산] 은 늘 됩니다": "Shows the total size of the files inside each folder. Large folders or a NAS can take a while to read. Long-press [Calculate folder size] always works",
|
||||
|
|
@ -2688,6 +2690,7 @@
|
|||
"해상도 올리기 모델을 받아야 합니다. 어느 것을 받을까요?": "An upscaling model is needed. Which one should be downloaded?",
|
||||
"해상도를 올리지 못했습니다": "Couldn't upscale",
|
||||
"해상도를 올린 그림 저장 폴더": "Folder for upscaled images",
|
||||
"해시 (MD5 · SHA-256)": "Hash (MD5 · SHA-256)",
|
||||
"해시 · {0}": "Hash · {0}",
|
||||
"해제": "Unset",
|
||||
"허용": "Allow",
|
||||
|
|
|
|||
|
|
@ -76,6 +76,7 @@
|
|||
"1/2 · AI 그림으로 다듬는 중": "1/2 · AI 画像で整え中",
|
||||
"10초 뒤로 (←)": "10秒戻る(←)",
|
||||
"10초 앞으로 (→)": "10秒進む(→)",
|
||||
"16진": "16進",
|
||||
"16진 보기 · {0}": "16進表示 · {0}",
|
||||
"1배 (선명하게)": "1倍 (くっきり)",
|
||||
"1분 안": "1 分以内",
|
||||
|
|
@ -2592,6 +2593,7 @@
|
|||
"폴더 복사 · 이동 방법": "フォルダーのコピー · 移動方法",
|
||||
"폴더 삭제: {0} (안의 {1}개 포함)": "フォルダーを削除: {0}(中の {1}個を含む)",
|
||||
"폴더 선택": "フォルダーを選択",
|
||||
"폴더 속성": "フォルダーのプロパティ",
|
||||
"폴더 속성 · {0}": "フォルダーのプロパティ · {0}",
|
||||
"폴더 수정": "フォルダーを編集",
|
||||
"폴더 안 파일 크기의 합을 목록에 보입니다. 큰 폴더 · NAS 는 읽는 데 오래 걸릴 수 있습니다. 길게 누르기 [폴더 크기 계산] 은 늘 됩니다": "フォルダー内のファイルサイズの合計を一覧に表示します。大きなフォルダー・NAS は読み込みに時間がかかることがあります。長押しの [フォルダーサイズを計算] はいつでも使えます",
|
||||
|
|
@ -2688,6 +2690,7 @@
|
|||
"해상도 올리기 모델을 받아야 합니다. 어느 것을 받을까요?": "解像度アップのモデルが必要です。どれをダウンロードしますか?",
|
||||
"해상도를 올리지 못했습니다": "高解像度化できませんでした",
|
||||
"해상도를 올린 그림 저장 폴더": "高解像度化した画像の保存フォルダー",
|
||||
"해시 (MD5 · SHA-256)": "ハッシュ (MD5 · SHA-256)",
|
||||
"해시 · {0}": "ハッシュ · {0}",
|
||||
"해제": "解除",
|
||||
"허용": "許可",
|
||||
|
|
|
|||
|
|
@ -76,6 +76,7 @@
|
|||
"1/2 · AI 그림으로 다듬는 중": "1/2 · 正在用 AI 图片优化",
|
||||
"10초 뒤로 (←)": "后退 10 秒(←)",
|
||||
"10초 앞으로 (→)": "前进 10 秒(→)",
|
||||
"16진": "十六进制",
|
||||
"16진 보기 · {0}": "十六进制查看 · {0}",
|
||||
"1배 (선명하게)": "1倍 (锐化)",
|
||||
"1분 안": "1 分钟以内",
|
||||
|
|
@ -2592,6 +2593,7 @@
|
|||
"폴더 복사 · 이동 방법": "文件夹复制 · 移动方式",
|
||||
"폴더 삭제: {0} (안의 {1}개 포함)": "已删除文件夹: {0}(含其中 {1} 个)",
|
||||
"폴더 선택": "选择文件夹",
|
||||
"폴더 속성": "文件夹属性",
|
||||
"폴더 속성 · {0}": "文件夹属性 · {0}",
|
||||
"폴더 수정": "编辑文件夹",
|
||||
"폴더 안 파일 크기의 합을 목록에 보입니다. 큰 폴더 · NAS 는 읽는 데 오래 걸릴 수 있습니다. 길게 누르기 [폴더 크기 계산] 은 늘 됩니다": "在列表中显示文件夹内文件大小的总和。大型文件夹或 NAS 可能需要较长时间读取。长按 [计算文件夹大小] 始终可用",
|
||||
|
|
@ -2688,6 +2690,7 @@
|
|||
"해상도 올리기 모델을 받아야 합니다. 어느 것을 받을까요?": "需要放大模型。要下载哪一个?",
|
||||
"해상도를 올리지 못했습니다": "无法提高分辨率",
|
||||
"해상도를 올린 그림 저장 폴더": "提高分辨率后图片的保存文件夹",
|
||||
"해시 (MD5 · SHA-256)": "哈希 (MD5 · SHA-256)",
|
||||
"해시 · {0}": "哈希 · {0}",
|
||||
"해제": "解除",
|
||||
"허용": "允许",
|
||||
|
|
|
|||
|
|
@ -53,6 +53,7 @@ import '../l10n/tr.dart';
|
|||
import 'explorer_bookmarks.dart';
|
||||
import 'explorer_search.dart';
|
||||
import 'quick_look.dart';
|
||||
import 'file_tools.dart' show showFileHash, showFolderProperties;
|
||||
import 'explorer_drag.dart';
|
||||
import 'archive_ui.dart';
|
||||
import 'explorer_grid.dart';
|
||||
|
|
@ -1814,6 +1815,9 @@ class _ExplorerPageState extends State<ExplorerPage> {
|
|||
if (e.isDir && !dav && !widget.rsync) ('wifiShare', Icons.wifi_tethering, tr('Wi-Fi 로 공유')),
|
||||
// 80: 이 폴더 크기를 지금 계산 (설정이 "안 함" 이어도)
|
||||
if (e.isDir) ('folderSize', Icons.data_usage, _sizes.busy(e.path) ? tr('폴더 크기 계산 멈추기') : tr('폴더 크기 계산')),
|
||||
// X-plore P3: 폴더 속성 (안의 파일 · 폴더 수 · 크기 · 만든 · 바뀐 때) · 파일 해시 (MD5 · SHA-256) - 이 기기의 것만 (원격은 다 받아야 해서 뺌)
|
||||
if (e.isDir && !dav) ('props', Icons.fact_check_outlined, tr('폴더 속성')),
|
||||
if (!e.isDir && !dav) ('hash', Icons.tag, tr('해시 (MD5 · SHA-256)')),
|
||||
if (e.isDir && dual) ('openOther', Icons.vertical_split_outlined, tr('다른 창에서 열기')),
|
||||
if (e.isDir) ('playFolder', Icons.play_circle_outline, tr('이 폴더의 동영상 재생')),
|
||||
// X-plore 비교 g: 그림 · 동영상을 썸네일 격자로
|
||||
|
|
@ -1924,6 +1928,10 @@ class _ExplorerPageState extends State<ExplorerPage> {
|
|||
pane.focused = made;
|
||||
pane.changed();
|
||||
}
|
||||
case 'props':
|
||||
await showFolderProperties(context, e.path);
|
||||
case 'hash':
|
||||
await showFileHash(context, e.path);
|
||||
case 'folderSize':
|
||||
if (_sizes.busy(e.path)) {
|
||||
_sizes.cancel(e.path);
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ import '../core/models.dart';
|
|||
import '../core/playlist.dart' show isAudioFile, isVideoFile;
|
||||
import '../core/vfs.dart';
|
||||
import '../l10n/tr.dart';
|
||||
import 'file_tools.dart' show HexViewerPage;
|
||||
import 'theme.dart';
|
||||
|
||||
/// 81: 빠른 보기에서 글로 보는 확장자
|
||||
|
|
@ -209,6 +210,12 @@ class _QuickLookState extends State<QuickLook> {
|
|||
]),
|
||||
),
|
||||
actions: [
|
||||
// X-plore P3: 16진 보기 (이 기기의 파일만 - 앞부분부터 나눠 읽기)
|
||||
if (!e.isDir && !isDav(e.path))
|
||||
TextButton(
|
||||
onPressed: () => Navigator.of(context).push(MaterialPageRoute<void>(builder: (_) => HexViewerPage(path: e.path))),
|
||||
child: Text(tr('16진')),
|
||||
),
|
||||
TextButton(onPressed: () => Navigator.pop(context), child: Text(tr('닫기'))),
|
||||
FilledButton(
|
||||
onPressed: () {
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@ import 'package:jj_mkvmaker/services/platform_services.dart';
|
|||
import 'package:jj_mkvmaker/core/file_ops.dart' show formatSize;
|
||||
import 'package:jj_mkvmaker/ui/explorer_page.dart';
|
||||
import 'package:jj_mkvmaker/ui/explorer_search.dart';
|
||||
import 'package:jj_mkvmaker/ui/file_tools.dart' show HexViewerPage;
|
||||
import 'package:jj_mkvmaker/ui/quick_look.dart';
|
||||
import 'package:jj_mkvmaker/ui/explorer_drag.dart';
|
||||
import 'package:jj_mkvmaker/ui/explorer_grid.dart';
|
||||
|
|
@ -163,6 +164,38 @@ void main() {
|
|||
await tester.pump(const Duration(seconds: 2));
|
||||
});
|
||||
|
||||
testWidgets('X-plore P3: 길게 누르기 [해시] (MD5 · SHA-256) · 폴더 [폴더 속성] · 빠른 보기 [16진]', (tester) async {
|
||||
await open(tester);
|
||||
// 해시: doc.txt = "hello"
|
||||
await tester.longPress(find.text('doc.txt'));
|
||||
await calm(tester);
|
||||
await act(tester, () => tester.tap(find.text('해시 (MD5 · SHA-256)')));
|
||||
await settle(tester, () => find.textContaining('2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824').evaluate().isNotEmpty);
|
||||
expect(find.textContaining('5d41402abc4b2a76b9719d911017c592'), findsOneWidget, reason: 'MD5');
|
||||
await act(tester, () => tester.tap(find.text('닫기').last));
|
||||
await calm(tester);
|
||||
// 폴더 속성: sub 안에 inner.txt 하나
|
||||
await tester.longPress(find.text('sub'));
|
||||
await calm(tester);
|
||||
await act(tester, () => tester.tap(find.text('폴더 속성')));
|
||||
await settle(tester, () => find.text('파일 1개 · 폴더 0개').evaluate().isNotEmpty);
|
||||
await act(tester, () => tester.tap(find.text('닫기').last));
|
||||
await calm(tester);
|
||||
// 빠른 보기 → [16진]
|
||||
await tester.longPress(find.text('doc.txt'));
|
||||
await calm(tester);
|
||||
await act(tester, () => tester.tap(find.text('미리 보기')));
|
||||
await settle(tester, () => find.text('16진').evaluate().isNotEmpty);
|
||||
await act(tester, () => tester.tap(find.text('16진')));
|
||||
await settle(tester, () => find.byType(HexViewerPage).evaluate().isNotEmpty);
|
||||
expect(find.byType(HexViewerPage), findsOneWidget);
|
||||
// 16진 보기가 앞부분을 다 읽어 파일을 놓을 때까지 (실제 시간) 기다린 뒤 닫는다 - 열린 파일이 남으면 시험 폴더를 못 지운다
|
||||
await tester.runAsync(() => Future<void>.delayed(const Duration(milliseconds: 300)));
|
||||
await tester.pump();
|
||||
await act(tester, () => tester.pageBack());
|
||||
await calm(tester);
|
||||
});
|
||||
|
||||
testWidgets('X-plore b: 가운데 버튼 길게 누르기 = 짝 동작 - [복사] 길게 = 이동 창 · [삭제] 길게 = 영구 삭제 창', (tester) async {
|
||||
await open(tester);
|
||||
await act(tester, () => tester.tap(find.text('doc.txt')));
|
||||
|
|
|
|||
Loading…
Reference in New Issue