이동 카드 저장 창은 '이 이동을' · '받는 쪽이 더 새것이면 건너뛰기' 를 Rsync 탭에도 (233)
- 233 (버그): 이동 카드인데 '이 복사를' 로 묻던 것 - 관리자 지시: 229 설정이 Rsync 화면 · 모니터링에서도 쓰이므로 Rsync 설정 탭에서도 같은 스위치 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>묶음5
parent
4cad606fe1
commit
5a0bc0ec50
|
|
@ -1480,6 +1480,7 @@
|
||||||
"이 언어 지우기": "Remove this language",
|
"이 언어 지우기": "Remove this language",
|
||||||
"이 위치 (네트워크 드라이브 · 네트워크 공유 · USB 메모리 등) 에는 휴지통이 없어 바로 지워집니다.": "This location (network drive, network share, USB memory etc.) has no Recycle Bin, so items are deleted right away.",
|
"이 위치 (네트워크 드라이브 · 네트워크 공유 · USB 메모리 등) 에는 휴지통이 없어 바로 지워집니다.": "This location (network drive, network share, USB memory etc.) has no Recycle Bin, so items are deleted right away.",
|
||||||
"이 이동 버튼 지우기": "Delete this move button",
|
"이 이동 버튼 지우기": "Delete this move button",
|
||||||
|
"이 이동을 다시 할 때 이 옵션을 씁니다. 지금 새 옵션으로 실행할까요?": "These options will be used the next time this move runs. Run it now with the new options?",
|
||||||
"이 파일에 맞는 자막 우선 (영상 해시)": "Prefer subtitles that match this file (video hash)",
|
"이 파일에 맞는 자막 우선 (영상 해시)": "Prefer subtitles that match this file (video hash)",
|
||||||
"이 파일용": "For this file",
|
"이 파일용": "For this file",
|
||||||
"이 파일을 열 수 있는 앱이 없습니다.": "No app can open this file.",
|
"이 파일을 열 수 있는 앱이 없습니다.": "No app can open this file.",
|
||||||
|
|
@ -1767,6 +1768,7 @@
|
||||||
"지금 것만 취소 (다음 것부터 이어서)": "Cancel only the current one (continue with the next)",
|
"지금 것만 취소 (다음 것부터 이어서)": "Cancel only the current one (continue with the next)",
|
||||||
"지금 것만 취소: {0}": "Cancelled only the current one: {0}",
|
"지금 것만 취소: {0}": "Cancelled only the current one: {0}",
|
||||||
"지금 도는 복사는 앞의 옵션으로 돌고 있습니다. 멈추고 새 옵션으로 다시 실행할까요?": "The running copy uses the previous options. Stop it and run again with the new options?",
|
"지금 도는 복사는 앞의 옵션으로 돌고 있습니다. 멈추고 새 옵션으로 다시 실행할까요?": "The running copy uses the previous options. Stop it and run again with the new options?",
|
||||||
|
"지금 도는 이동은 앞의 옵션으로 돌고 있습니다. 멈추고 새 옵션으로 다시 실행할까요?": "The running move is using the previous options. Stop it and run again with the new options?",
|
||||||
"지금 마스터 (또는 최상) 비밀번호": "Current master (or top) password",
|
"지금 마스터 (또는 최상) 비밀번호": "Current master (or top) password",
|
||||||
"지금 맞추기": "Sync now",
|
"지금 맞추기": "Sync now",
|
||||||
"지금 맞추는 중입니다. 끝난 뒤에 하세요.": "Syncing right now. Try again when it finishes.",
|
"지금 맞추는 중입니다. 끝난 뒤에 하세요.": "Syncing right now. Try again when it finishes.",
|
||||||
|
|
|
||||||
|
|
@ -1480,6 +1480,7 @@
|
||||||
"이 언어 지우기": "この言語を削除",
|
"이 언어 지우기": "この言語を削除",
|
||||||
"이 위치 (네트워크 드라이브 · 네트워크 공유 · USB 메모리 등) 에는 휴지통이 없어 바로 지워집니다.": "この場所 (ネットワークドライブ・ネットワーク共有・USB メモリなど) にはごみ箱がないため、すぐに削除されます。",
|
"이 위치 (네트워크 드라이브 · 네트워크 공유 · USB 메모리 등) 에는 휴지통이 없어 바로 지워집니다.": "この場所 (ネットワークドライブ・ネットワーク共有・USB メモリなど) にはごみ箱がないため、すぐに削除されます。",
|
||||||
"이 이동 버튼 지우기": "この移動ボタンを削除",
|
"이 이동 버튼 지우기": "この移動ボタンを削除",
|
||||||
|
"이 이동을 다시 할 때 이 옵션을 씁니다. 지금 새 옵션으로 실행할까요?": "この移動を次に行うときにこのオプションを使います。今すぐ新しいオプションで実行しますか?",
|
||||||
"이 파일에 맞는 자막 우선 (영상 해시)": "このファイルに合う字幕を優先(動画ハッシュ)",
|
"이 파일에 맞는 자막 우선 (영상 해시)": "このファイルに合う字幕を優先(動画ハッシュ)",
|
||||||
"이 파일용": "このファイル用",
|
"이 파일용": "このファイル用",
|
||||||
"이 파일을 열 수 있는 앱이 없습니다.": "このファイルを開けるアプリがありません。",
|
"이 파일을 열 수 있는 앱이 없습니다.": "このファイルを開けるアプリがありません。",
|
||||||
|
|
@ -1767,6 +1768,7 @@
|
||||||
"지금 것만 취소 (다음 것부터 이어서)": "今のものだけ取り消し (次から続ける)",
|
"지금 것만 취소 (다음 것부터 이어서)": "今のものだけ取り消し (次から続ける)",
|
||||||
"지금 것만 취소: {0}": "今のものだけ取り消し: {0}",
|
"지금 것만 취소: {0}": "今のものだけ取り消し: {0}",
|
||||||
"지금 도는 복사는 앞의 옵션으로 돌고 있습니다. 멈추고 새 옵션으로 다시 실행할까요?": "実行中のコピーは前のオプションで動いています。止めて新しいオプションで再実行しますか?",
|
"지금 도는 복사는 앞의 옵션으로 돌고 있습니다. 멈추고 새 옵션으로 다시 실행할까요?": "実行中のコピーは前のオプションで動いています。止めて新しいオプションで再実行しますか?",
|
||||||
|
"지금 도는 이동은 앞의 옵션으로 돌고 있습니다. 멈추고 새 옵션으로 다시 실행할까요?": "実行中の移動は前のオプションで動いています。止めて新しいオプションでやり直しますか?",
|
||||||
"지금 마스터 (또는 최상) 비밀번호": "現在のマスター (または最上位) パスワード",
|
"지금 마스터 (또는 최상) 비밀번호": "現在のマスター (または最上位) パスワード",
|
||||||
"지금 맞추기": "今すぐ同期",
|
"지금 맞추기": "今すぐ同期",
|
||||||
"지금 맞추는 중입니다. 끝난 뒤에 하세요.": "同期中です。終わってから行ってください。",
|
"지금 맞추는 중입니다. 끝난 뒤에 하세요.": "同期中です。終わってから行ってください。",
|
||||||
|
|
|
||||||
|
|
@ -1480,6 +1480,7 @@
|
||||||
"이 언어 지우기": "删除此语言",
|
"이 언어 지우기": "删除此语言",
|
||||||
"이 위치 (네트워크 드라이브 · 네트워크 공유 · USB 메모리 등) 에는 휴지통이 없어 바로 지워집니다.": "此位置 (网络驱动器 · 网络共享 · U 盘等) 没有回收站,会直接删除。",
|
"이 위치 (네트워크 드라이브 · 네트워크 공유 · USB 메모리 등) 에는 휴지통이 없어 바로 지워집니다.": "此位置 (网络驱动器 · 网络共享 · U 盘等) 没有回收站,会直接删除。",
|
||||||
"이 이동 버튼 지우기": "删除此移动按钮",
|
"이 이동 버튼 지우기": "删除此移动按钮",
|
||||||
|
"이 이동을 다시 할 때 이 옵션을 씁니다. 지금 새 옵션으로 실행할까요?": "下次执行此移动时将使用这些选项。现在用新选项执行吗?",
|
||||||
"이 파일에 맞는 자막 우선 (영상 해시)": "优先匹配此文件的字幕(视频哈希)",
|
"이 파일에 맞는 자막 우선 (영상 해시)": "优先匹配此文件的字幕(视频哈希)",
|
||||||
"이 파일용": "适用于此文件",
|
"이 파일용": "适用于此文件",
|
||||||
"이 파일을 열 수 있는 앱이 없습니다.": "没有可以打开此文件的应用。",
|
"이 파일을 열 수 있는 앱이 없습니다.": "没有可以打开此文件的应用。",
|
||||||
|
|
@ -1767,6 +1768,7 @@
|
||||||
"지금 것만 취소 (다음 것부터 이어서)": "仅取消当前项(从下一个继续)",
|
"지금 것만 취소 (다음 것부터 이어서)": "仅取消当前项(从下一个继续)",
|
||||||
"지금 것만 취소: {0}": "仅取消当前项:{0}",
|
"지금 것만 취소: {0}": "仅取消当前项:{0}",
|
||||||
"지금 도는 복사는 앞의 옵션으로 돌고 있습니다. 멈추고 새 옵션으로 다시 실행할까요?": "正在运行的复制使用的是之前的选项。停止并用新选项重新运行吗?",
|
"지금 도는 복사는 앞의 옵션으로 돌고 있습니다. 멈추고 새 옵션으로 다시 실행할까요?": "正在运行的复制使用的是之前的选项。停止并用新选项重新运行吗?",
|
||||||
|
"지금 도는 이동은 앞의 옵션으로 돌고 있습니다. 멈추고 새 옵션으로 다시 실행할까요?": "正在进行的移动使用的是之前的选项。要停止并用新选项重新执行吗?",
|
||||||
"지금 마스터 (또는 최상) 비밀번호": "当前主密码 (或最高密码)",
|
"지금 마스터 (또는 최상) 비밀번호": "当前主密码 (或最高密码)",
|
||||||
"지금 맞추기": "立即同步",
|
"지금 맞추기": "立即同步",
|
||||||
"지금 맞추는 중입니다. 끝난 뒤에 하세요.": "正在同步。请等结束后再进行。",
|
"지금 맞추는 중입니다. 끝난 뒤에 하세요.": "正在同步。请等结束后再进行。",
|
||||||
|
|
|
||||||
|
|
@ -151,13 +151,7 @@ class _CopySyncSettingsState extends State<CopySyncSettings> {
|
||||||
onChanged: (v) => c.updateSettings((x) => x.copyConflict = v ?? 'ask'),
|
onChanged: (v) => c.updateSettings((x) => x.copyConflict = v ?? 'ask'),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
// 229: 폴더 안의 것을 맞출 때 (모니터링의 현재 방식 · WebDAV) - rsync 의 -u 와 같다
|
_skipNewerTile(),
|
||||||
SwitchListTile(
|
|
||||||
value: s.copySkipNewer,
|
|
||||||
onChanged: (v) => c.updateSettings((x) => x.copySkipNewer = v),
|
|
||||||
title: Text(tr('받는 쪽이 더 새것이면 건너뛰기')),
|
|
||||||
subtitle: Text(tr('현재 방식 · robocopy · WebDAV 로 복사 · 이동할 때 (rsync 의 -u, robocopy 의 /XO 와 같음). 건너뛴 파일은 이동이라도 원본에 남깁니다')),
|
|
||||||
),
|
|
||||||
SettingTile(
|
SettingTile(
|
||||||
title: Text(tr('속도 제한 (KB/s)')),
|
title: Text(tr('속도 제한 (KB/s)')),
|
||||||
subtitle: Text(tr('0 = 제한 없음. 모든 방법에 적용: rsync --bwlimit, 현재 방식은 앱이 조절, robocopy 는 /IPG 로 비슷하게. '
|
subtitle: Text(tr('0 = 제한 없음. 모든 방법에 적용: rsync --bwlimit, 현재 방식은 앱이 조절, robocopy 는 /IPG 로 비슷하게. '
|
||||||
|
|
@ -178,6 +172,14 @@ class _CopySyncSettingsState extends State<CopySyncSettings> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Rsync 화면: rsync 옵션 · rsync 가져오기 · 실시간 동기화 (lsync)
|
/// Rsync 화면: rsync 옵션 · rsync 가져오기 · 실시간 동기화 (lsync)
|
||||||
|
/// 229: 받는 쪽이 더 새것이면 건너뛰기 - 파일 탐색기 · Rsync 탭 두 곳에 같은 설정 (Rsync 화면 · 모니터링에서도 쓰여 찾기 쉽게)
|
||||||
|
Widget _skipNewerTile() => SwitchListTile(
|
||||||
|
value: c.settings.copySkipNewer,
|
||||||
|
onChanged: (v) => c.updateSettings((x) => x.copySkipNewer = v),
|
||||||
|
title: Text(tr('받는 쪽이 더 새것이면 건너뛰기')),
|
||||||
|
subtitle: Text(tr('현재 방식 · robocopy · WebDAV 로 복사 · 이동할 때 (rsync 의 -u, robocopy 의 /XO 와 같음). 건너뛴 파일은 이동이라도 원본에 남깁니다')),
|
||||||
|
);
|
||||||
|
|
||||||
Widget _rsyncPart() {
|
Widget _rsyncPart() {
|
||||||
final s = c.settings;
|
final s = c.settings;
|
||||||
final desk = Platform.isWindows;
|
final desk = Platform.isWindows;
|
||||||
|
|
@ -186,6 +188,7 @@ class _CopySyncSettingsState extends State<CopySyncSettings> {
|
||||||
_options(tr('rsync 옵션'), tr('예: -avPog (보관 · 자세히 · 진행 · 소유자 · 그룹). 속도 제한은 파일 탐색기의 속도 제한을 함께 씀. '
|
_options(tr('rsync 옵션'), tr('예: -avPog (보관 · 자세히 · 진행 · 소유자 · 그룹). 속도 제한은 파일 탐색기의 속도 제한을 함께 씀. '
|
||||||
'새로 맞추는 폴더 쌍에 씁니다 - 이미 실행한 쌍은 기억한 옵션을 쓰며 모니터링 > 복사 · rsync 에서 따로 고칩니다'),
|
'새로 맞추는 폴더 쌍에 씁니다 - 이미 실행한 쌍은 기억한 옵션을 쓰며 모니터링 > 복사 · rsync 에서 따로 고칩니다'),
|
||||||
s.rsyncOptions, defaultRsyncOptions, (x, v) => x.rsyncOptions = v),
|
s.rsyncOptions, defaultRsyncOptions, (x, v) => x.rsyncOptions = v),
|
||||||
|
_skipNewerTile(),
|
||||||
SettingTile(
|
SettingTile(
|
||||||
title: Text(tr('rsync 가져오기')),
|
title: Text(tr('rsync 가져오기')),
|
||||||
subtitle: Text(_checking
|
subtitle: Text(_checking
|
||||||
|
|
|
||||||
|
|
@ -435,8 +435,13 @@ class _CopyCardState extends State<_CopyCard> {
|
||||||
scrollable: true,
|
scrollable: true,
|
||||||
title: Text(tr('옵션을 저장했습니다')),
|
title: Text(tr('옵션을 저장했습니다')),
|
||||||
content: Text(running
|
content: Text(running
|
||||||
? tr('지금 도는 복사는 앞의 옵션으로 돌고 있습니다. 멈추고 새 옵션으로 다시 실행할까요?')
|
// 233: 이동 카드는 "이동" 으로
|
||||||
: tr('이 복사를 다시 할 때 이 옵션을 씁니다. 지금 새 옵션으로 실행할까요?')),
|
? (t.move
|
||||||
|
? tr('지금 도는 이동은 앞의 옵션으로 돌고 있습니다. 멈추고 새 옵션으로 다시 실행할까요?')
|
||||||
|
: tr('지금 도는 복사는 앞의 옵션으로 돌고 있습니다. 멈추고 새 옵션으로 다시 실행할까요?'))
|
||||||
|
: (t.move
|
||||||
|
? tr('이 이동을 다시 할 때 이 옵션을 씁니다. 지금 새 옵션으로 실행할까요?')
|
||||||
|
: tr('이 복사를 다시 할 때 이 옵션을 씁니다. 지금 새 옵션으로 실행할까요?'))),
|
||||||
actions: [
|
actions: [
|
||||||
TextButton(onPressed: () => Navigator.pop(ctx, false), child: Text(tr('현재 유지'))),
|
TextButton(onPressed: () => Navigator.pop(ctx, false), child: Text(tr('현재 유지'))),
|
||||||
FilledButton(onPressed: () => Navigator.pop(ctx, true), child: Text(tr('설정 반영 후 실행'))),
|
FilledButton(onPressed: () => Navigator.pop(ctx, true), child: Text(tr('설정 반영 후 실행'))),
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,7 @@ import 'package:jj_mkvmaker/core/cron_window.dart';
|
||||||
import 'package:jj_mkvmaker/platform/windows/desktop_storage_service.dart';
|
import 'package:jj_mkvmaker/platform/windows/desktop_storage_service.dart';
|
||||||
import 'package:jj_mkvmaker/platform/windows/process_media_tool.dart';
|
import 'package:jj_mkvmaker/platform/windows/process_media_tool.dart';
|
||||||
import 'package:jj_mkvmaker/services/platform_services.dart';
|
import 'package:jj_mkvmaker/services/platform_services.dart';
|
||||||
|
import 'package:jj_mkvmaker/ui/copy_sync_settings.dart' show CopySyncSettings;
|
||||||
import 'package:jj_mkvmaker/ui/monitor_page.dart';
|
import 'package:jj_mkvmaker/ui/monitor_page.dart';
|
||||||
import 'package:path/path.dart' as p;
|
import 'package:path/path.dart' as p;
|
||||||
|
|
||||||
|
|
@ -300,6 +301,7 @@ void main() {
|
||||||
await tester.tap(find.text('저장'));
|
await tester.tap(find.text('저장'));
|
||||||
await tester.pumpAndSettle();
|
await tester.pumpAndSettle();
|
||||||
expect(find.text('옵션을 저장했습니다'), findsOneWidget);
|
expect(find.text('옵션을 저장했습니다'), findsOneWidget);
|
||||||
|
expect(find.text('이 복사를 다시 할 때 이 옵션을 씁니다. 지금 새 옵션으로 실행할까요?'), findsOneWidget);
|
||||||
expect(find.text('설정 반영 후 실행'), findsOneWidget);
|
expect(find.text('설정 반영 후 실행'), findsOneWidget);
|
||||||
await tester.tap(find.text('현재 유지'));
|
await tester.tap(find.text('현재 유지'));
|
||||||
await tester.pumpAndSettle();
|
await tester.pumpAndSettle();
|
||||||
|
|
@ -313,4 +315,30 @@ void main() {
|
||||||
expect(find.text('지금 맞추기'), findsOneWidget);
|
expect(find.text('지금 맞추기'), findsOneWidget);
|
||||||
expect(find.text('복사 · rsync 로 이동'), findsOneWidget);
|
expect(find.text('복사 · rsync 로 이동'), findsOneWidget);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
testWidgets('233: 이동 카드의 저장 창은 "이 이동을" · 229 설정은 Rsync 탭에도 있다', (tester) async {
|
||||||
|
final tmp = Directory.systemTemp.createTempSync('jj_mon233_');
|
||||||
|
addTearDown(() => tmp.deleteSync(recursive: true));
|
||||||
|
final c = AppController(PlatformServices(mediaTool: ProcessMediaTool('x', 'y'), storage: DesktopStorageService()));
|
||||||
|
c.settings.copyTasks = [CopyTask(id: '1', sources: [tmp.path], dest: p.join(tmp.path, '..'), move: true, method: 'builtin')];
|
||||||
|
tester.view.physicalSize = const Size(1500, 1000);
|
||||||
|
tester.view.devicePixelRatio = 1;
|
||||||
|
addTearDown(tester.view.reset);
|
||||||
|
await tester.pumpWidget(MaterialApp(home: MonitorPage(c: c)));
|
||||||
|
await tester.pump();
|
||||||
|
await tester.enterText(find.widgetWithText(TextField, '속도 제한'), '500');
|
||||||
|
await tester.pump();
|
||||||
|
await tester.tap(find.text('저장'));
|
||||||
|
await tester.pumpAndSettle();
|
||||||
|
expect(find.text('이 이동을 다시 할 때 이 옵션을 씁니다. 지금 새 옵션으로 실행할까요?'), findsOneWidget);
|
||||||
|
await tester.tap(find.text('현재 유지'));
|
||||||
|
await tester.pumpAndSettle();
|
||||||
|
// Rsync 탭의 설정에도 같은 스위치
|
||||||
|
await tester.pumpWidget(MaterialApp(home: Scaffold(body: SingleChildScrollView(child: CopySyncSettings(c: c, rsync: true)))));
|
||||||
|
await tester.pump();
|
||||||
|
expect(find.text('받는 쪽이 더 새것이면 건너뛰기'), findsOneWidget);
|
||||||
|
await tester.tap(find.text('받는 쪽이 더 새것이면 건너뛰기'));
|
||||||
|
await tester.pump();
|
||||||
|
expect(c.settings.copySkipNewer, isFalse);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue