diff --git a/assets/l10n/en.json b/assets/l10n/en.json index 38a9598..6240441 100644 --- a/assets/l10n/en.json +++ b/assets/l10n/en.json @@ -780,6 +780,7 @@ "목록 · 영상 옆 · 영상 위에 나오는 광고 영역을 감춥니다": "Hides ad areas in lists · next to · on top of videos", "목록 보기": "View list", "목록에서 빼기": "Remove from list", + "목록에서 빼기 (파일은 그대로)": "Remove from list (file is kept)", "목록에서 제거": "Remove from list", "목록에서 지우기 (파일은 그대로)": "Remove from list (files stay)", "목록을 모두 비울까요?": "Clear the whole list?", diff --git a/assets/l10n/ja.json b/assets/l10n/ja.json index 885a2b6..503dc7b 100644 --- a/assets/l10n/ja.json +++ b/assets/l10n/ja.json @@ -780,6 +780,7 @@ "목록 · 영상 옆 · 영상 위에 나오는 광고 영역을 감춥니다": "リスト・動画の横・動画の上に出る広告エリアを隠します", "목록 보기": "リストを見る", "목록에서 빼기": "リストから外す", + "목록에서 빼기 (파일은 그대로)": "リストから外す (ファイルはそのまま)", "목록에서 제거": "リストから削除", "목록에서 지우기 (파일은 그대로)": "リストから削除 (ファイルはそのまま)", "목록을 모두 비울까요?": "一覧をすべて空にしますか?", diff --git a/assets/l10n/zh-Hans.json b/assets/l10n/zh-Hans.json index 30142d6..8fa689b 100644 --- a/assets/l10n/zh-Hans.json +++ b/assets/l10n/zh-Hans.json @@ -780,6 +780,7 @@ "목록 · 영상 옆 · 영상 위에 나오는 광고 영역을 감춥니다": "隐藏列表 · 视频旁 · 视频上方出现的广告区域", "목록 보기": "查看列表", "목록에서 빼기": "从列表中移除", + "목록에서 빼기 (파일은 그대로)": "从列表中移除 (保留文件)", "목록에서 제거": "从列表中移除", "목록에서 지우기 (파일은 그대로)": "从列表中删除 (文件保留)", "목록을 모두 비울까요?": "清空整个列表吗?", diff --git a/lib/ui/home_page.dart b/lib/ui/home_page.dart index 918caed..de60a2b 100644 --- a/lib/ui/home_page.dart +++ b/lib/ui/home_page.dart @@ -2,6 +2,7 @@ import 'dart:async'; import 'dart:io'; import 'package:flutter/material.dart'; +import 'package:flutter/services.dart' show HapticFeedback; import '../app/app_controller.dart'; import '../app/bookmarks_controller.dart'; @@ -686,7 +687,7 @@ class _VideoTile extends StatelessWidget { item('search', Icons.travel_explore, tr('인터넷 자막 찾기'), enabled: !busy), item('subtitle', Icons.subtitles_outlined, tr('자막 파일 추가'), enabled: !busy), const PopupMenuDivider(), - item('remove', Icons.close, tr('삭제 (목록에서 제거)'), enabled: !busy), + item('remove', Icons.close, tr('목록에서 빼기 (파일은 그대로)'), enabled: !busy), ], ); if (pick == null || !context.mounted) return; @@ -734,7 +735,13 @@ class _VideoTile extends StatelessWidget { Widget build(BuildContext context) { final isSel = c.selected == v; final subs = v.subtitles.where((s) => s.enabled).length; - return InkWell( + // 51: 터치 화면에서는 길게 누르면 오른쪽 클릭과 같은 메뉴 (누른 자리에) + return GestureDetector( + onLongPressStart: (d) { + HapticFeedback.selectionClick(); + _menu(context, d.globalPosition); + }, + child: InkWell( // 한 번: 보기 · 두 번: 재생 · 세 번 이상: 이동 폴더로 옮기기 onTap: () => _tapped(context), // 오른쪽 클릭: 이 동영상으로 할 수 있는 일 @@ -805,7 +812,7 @@ class _VideoTile extends StatelessWidget { ], ), ), - ); + )); } } diff --git a/test/scale_menu_test.dart b/test/scale_menu_test.dart index 92ffc57..b3bee38 100644 --- a/test/scale_menu_test.dart +++ b/test/scale_menu_test.dart @@ -106,7 +106,7 @@ void main() { await tester.tapAt(tester.getCenter(find.text('둘째.mp4').first), buttons: kSecondaryButton); await tester.pumpAndSettle(); expect(c.selected, c.videos[1]); - for (final label in ['대상 폴더 열기', '자막 파일 추가', '삭제 (목록에서 제거)']) { + for (final label in ['대상 폴더 열기', '자막 파일 추가', '목록에서 빼기 (파일은 그대로)']) { expect(find.text(label), findsWidgets, reason: label); } await tester.tap(find.text('대상 폴더 열기')); @@ -116,11 +116,34 @@ void main() { // 삭제 await tester.tapAt(tester.getCenter(find.text('둘째.mp4').first), buttons: kSecondaryButton); await tester.pumpAndSettle(); - await tester.tap(find.text('삭제 (목록에서 제거)')); + await tester.tap(find.text('목록에서 빼기 (파일은 그대로)')); await tester.pumpAndSettle(); expect([for (final v in c.videos) v.fileName], ['첫째.mp4']); }); + testWidgets('51: 터치 화면 - 동영상 줄을 길게 누르면 오른쪽 클릭과 같은 메뉴 (그 줄이 선택됨)', (tester) async { + tester.view.physicalSize = const Size(1500, 900); + tester.view.devicePixelRatio = 1; + addTearDown(tester.view.reset); + final c = AppController(PlatformServices(mediaTool: ProcessMediaTool('x', 'y'), storage: DesktopStorageService())); + c.videos.addAll([VideoItem(r'D:\v\첫째.mp4'), VideoItem(r'D:\v\둘째.mp4')]); + c.selected = c.videos.first; + await tester.pumpWidget(MaterialApp(home: HomePage(c: c))); + await tester.longPress(find.text('둘째.mp4').first); + await tester.pumpAndSettle(); + expect(c.selected, c.videos[1]); + for (final label in ['대상 폴더 열기', '자막 파일 추가', '목록에서 빼기 (파일은 그대로)']) { + expect(find.text(label), findsWidgets, reason: label); + } + // 한 번 누르기는 그대로 (메뉴 없이 보기) + await tester.tapAt(const Offset(5, 5)); + await tester.pumpAndSettle(); + await tester.tap(find.text('첫째.mp4').first); + await tester.pump(const Duration(milliseconds: 600)); + expect(c.selected, c.videos.first); + expect(find.text('대상 폴더 열기'), findsNothing); + }); + testWidgets('MKV 화면 위쪽 막대: 창이 좁아도 넘치지 않고 설정 · 종료 버튼이 창 안에 있다', (tester) async { addTearDown(tester.view.reset); final dir = Directory.systemTemp.createTempSync('jj_bar_');