diff --git a/assets/l10n/en.json b/assets/l10n/en.json index 24551ee..0d6782b 100644 --- a/assets/l10n/en.json +++ b/assets/l10n/en.json @@ -681,7 +681,6 @@ "⚠ 동기화 멈춤 {0}개 · 원본 확인 필요": "⚠ {0} sync stopped · check the source", "⚠ 지난 실행이 정상적으로 끝나지 않았습니다 (시작 {0}, 마지막 확인 {1}). 그 전의 기록은 Logs 폴더의 app.log 에 있습니다.": "⚠ The last run did not end normally (started {0}, last check {1}). Earlier records are in app.log in the Logs folder.", "⚠ 평문 FTP (암호화 안 됨)": "⚠ Plain FTP (not encrypted)", - "⚠ 평문 FTP 는 아이디 · 비밀번호 · 파일이 암호화되지 않은 채 오갑니다. 같은 망의 다른 사람이 볼 수 있습니다. 서버가 FTPS 를 못 할 때만, 믿을 수 있는 집 안 망에서만 쓰세요.": "⚠ With plain FTP, your user name, password and files travel unencrypted. Others on the same network can see them. Use it only when the server can't do FTPS, and only on a trusted home network.", "가로 16:9": "Landscape 16:9", "가로 고정": "Landscape only", "가로 고정 · 세로 고정, 또는 자동 (기기를 돌리는 대로, 기기의 자동 회전 설정을 따름)": "Lock landscape · lock portrait, or auto (follows how you hold the device and its auto-rotate setting)", @@ -2933,6 +2932,8 @@ "편집 목록에 추가": "Add to the edit list", "편집 목록에 추가 (MKV 만들기 대상)": "Add to the edit list (Make MKV target)", "펼친 폴더를 다시 누르면 접기": "Tap an open folder again to collapse", + "평문 FTP 는 아이디 · 비밀번호 · 파일이 암호화되지 않은 채 오갑니다. 같은 망의 다른 사람이 볼 수 있습니다. 서버가 FTPS 를 못 할 때만, 믿을 수 있는 집 안 망에서만 쓰세요.": "With plain FTP, your user name, password and files travel unencrypted. Others on the same network can see them. Use it only when the server can't do FTPS, and only on a trusted home network.", + "평문 FTP: 암호화 안 됨": "Plain FTP: not encrypted", "평일 9~18시": "Weekdays 9-18", "포르투갈어": "Portuguese", "포트": "Port", diff --git a/assets/l10n/ja.json b/assets/l10n/ja.json index cc21c8f..49d787d 100644 --- a/assets/l10n/ja.json +++ b/assets/l10n/ja.json @@ -681,7 +681,6 @@ "⚠ 동기화 멈춤 {0}개 · 원본 확인 필요": "⚠ 同期停止 {0} 件・元を確認してください", "⚠ 지난 실행이 정상적으로 끝나지 않았습니다 (시작 {0}, 마지막 확인 {1}). 그 전의 기록은 Logs 폴더의 app.log 에 있습니다.": "⚠ 前回の実行が正常に終了しませんでした(開始 {0}、最終確認 {1})。それ以前の記録は Logs フォルダーの app.log にあります。", "⚠ 평문 FTP (암호화 안 됨)": "⚠ 平文 FTP (暗号化なし)", - "⚠ 평문 FTP 는 아이디 · 비밀번호 · 파일이 암호화되지 않은 채 오갑니다. 같은 망의 다른 사람이 볼 수 있습니다. 서버가 FTPS 를 못 할 때만, 믿을 수 있는 집 안 망에서만 쓰세요.": "⚠ 平文 FTP ではユーザー名 · パスワード · ファイルが暗号化されずにやり取りされます。同じネットワークの他人に見られる可能性があります。サーバーが FTPS に対応していないときだけ、信頼できる家庭内ネットワークでのみ使ってください。", "가로 16:9": "横 16:9", "가로 고정": "横向き固定", "가로 고정 · 세로 고정, 또는 자동 (기기를 돌리는 대로, 기기의 자동 회전 설정을 따름)": "横向き固定・縦向き固定、または自動(端末の向きに合わせ、端末の自動回転設定に従う)", @@ -2933,6 +2932,8 @@ "편집 목록에 추가": "編集リストに追加", "편집 목록에 추가 (MKV 만들기 대상)": "編集リストに追加(MKV 作成の対象)", "펼친 폴더를 다시 누르면 접기": "開いたフォルダーをもう一度押すと閉じる", + "평문 FTP 는 아이디 · 비밀번호 · 파일이 암호화되지 않은 채 오갑니다. 같은 망의 다른 사람이 볼 수 있습니다. 서버가 FTPS 를 못 할 때만, 믿을 수 있는 집 안 망에서만 쓰세요.": "平文 FTP ではユーザー名 · パスワード · ファイルが暗号化されずにやり取りされます。同じネットワークの他人に見られる可能性があります。サーバーが FTPS に対応していないときだけ、信頼できる家庭内ネットワークでのみ使ってください。", + "평문 FTP: 암호화 안 됨": "平文 FTP: 暗号化なし", "평일 9~18시": "平日 9~18 時", "포르투갈어": "ポルトガル語", "포트": "ポート", diff --git a/assets/l10n/zh-Hans.json b/assets/l10n/zh-Hans.json index 2946ffe..50f1979 100644 --- a/assets/l10n/zh-Hans.json +++ b/assets/l10n/zh-Hans.json @@ -681,7 +681,6 @@ "⚠ 동기화 멈춤 {0}개 · 원본 확인 필요": "⚠ {0} 个同步已停止 · 请检查源", "⚠ 지난 실행이 정상적으로 끝나지 않았습니다 (시작 {0}, 마지막 확인 {1}). 그 전의 기록은 Logs 폴더의 app.log 에 있습니다.": "⚠ 上次运行未正常结束(开始 {0},最后检查 {1})。之前的记录在 Logs 文件夹的 app.log 中。", "⚠ 평문 FTP (암호화 안 됨)": "⚠ 明文 FTP (未加密)", - "⚠ 평문 FTP 는 아이디 · 비밀번호 · 파일이 암호화되지 않은 채 오갑니다. 같은 망의 다른 사람이 볼 수 있습니다. 서버가 FTPS 를 못 할 때만, 믿을 수 있는 집 안 망에서만 쓰세요.": "⚠ 明文 FTP 会以未加密方式传输用户名、密码和文件,同一网络中的其他人可能看到。仅在服务器不支持 FTPS 时、并且只在可信的家庭网络中使用。", "가로 16:9": "横屏 16:9", "가로 고정": "固定横屏", "가로 고정 · 세로 고정, 또는 자동 (기기를 돌리는 대로, 기기의 자동 회전 설정을 따름)": "锁定横屏 · 锁定竖屏,或自动(随设备方向旋转,遵循设备的自动旋转设置)", @@ -2933,6 +2932,8 @@ "편집 목록에 추가": "加入编辑列表", "편집 목록에 추가 (MKV 만들기 대상)": "加入编辑列表(制作 MKV 的对象)", "펼친 폴더를 다시 누르면 접기": "再次点按已展开的文件夹可折叠", + "평문 FTP 는 아이디 · 비밀번호 · 파일이 암호화되지 않은 채 오갑니다. 같은 망의 다른 사람이 볼 수 있습니다. 서버가 FTPS 를 못 할 때만, 믿을 수 있는 집 안 망에서만 쓰세요.": "明文 FTP 会以未加密方式传输用户名、密码和文件,同一网络中的其他人可能看到。仅在服务器不支持 FTPS 时、并且只在可信的家庭网络中使用。", + "평문 FTP: 암호화 안 됨": "明文 FTP: 未加密", "평일 9~18시": "工作日 9~18 点", "포르투갈어": "葡萄牙语", "포트": "端口", diff --git a/integration_test/notice_places_shot_test.dart b/integration_test/notice_places_shot_test.dart index a25c587..7e4b389 100644 --- a/integration_test/notice_places_shot_test.dart +++ b/integration_test/notice_places_shot_test.dart @@ -24,6 +24,8 @@ import 'package:path/path.dart' as p; /// 동영상 자세히의 오류 상자 · AI 서비스 추가 창의 경고. 412 · 960. 모으기 전 판과 뒤 판을 같은 이름으로 찍어 견준다 (JJ_SHOT_DIR) void main() { IntegrationTestWidgetsFlutterBinding.ensureInitialized(); + // 글 칸 커서가 깜빡여 캡처가 실행마다 달라지지 않게 (시험 쪽에서만 - 관리자 10/24) + EditableText.debugDeterministicCursor = true; final out = Platform.environment['JJ_SHOT_DIR'] ?? p.join(Directory.systemTemp.path, 'jj_shots_notice'); for (final (w, h) in [(412, 900), (960, 600)]) { diff --git a/integration_test/windows_check_shot_test.dart b/integration_test/windows_check_shot_test.dart index 0dd9eae..7881d67 100644 --- a/integration_test/windows_check_shot_test.dart +++ b/integration_test/windows_check_shot_test.dart @@ -11,6 +11,7 @@ import 'package:jj_mkvmaker/app/master_lock.dart'; import 'package:jj_mkvmaker/platform/windows/recycle_bin.dart'; import 'package:jj_mkvmaker/services/image_ai.dart'; import 'package:jj_mkvmaker/services/platform_services.dart'; +import 'package:jj_mkvmaker/services/system_usage.dart'; import 'package:jj_mkvmaker/services/secret_store.dart'; import 'package:jj_mkvmaker/ui/ai_image_page.dart'; import 'package:jj_mkvmaker/ui/explorer_page.dart'; @@ -28,6 +29,8 @@ import 'support/temp_dir.dart'; /// 시험 폴더 · 메모리 저장소만 쓴다 (사용자 설정 · 비밀번호는 건드리지 않음). 휴지통에 넣은 시험 항목은 끝에 $I 로 골라 지운다. void main() { IntegrationTestWidgetsFlutterBinding.ensureInitialized(); + // 글 칸 커서가 깜빡여 캡처가 실행마다 달라지지 않게 (시험 쪽에서만 - 관리자 10/24) + EditableText.debugDeterministicCursor = true; // ⑦ 밝은 화면 캡처: JJ_SHOT_THEME=light (JJ_SHOT_DIR 를 따로 두어 어두운 것과 견줌) if (Platform.environment['JJ_SHOT_THEME'] == 'light') JjColors.use(Brightness.light); final out = Platform.environment['JJ_SHOT_DIR'] ?? p.join(Directory.systemTemp.path, 'jj_shots'); @@ -68,7 +71,27 @@ void main() { await settle(t); } - AppController controller() => AppController(PlatformServices.create()); + /// 실제 조립에서 위 막대의 CPU · 메모리 값만 고정 (실행마다 이 PC 의 실제 CPU % 가 달라 캡처가 흔들렸다 - 시험 쪽에서만) + AppController controller() { + final r = PlatformServices.create(); + return AppController(PlatformServices( + mediaTool: r.mediaTool, + storage: r.storage, + createPlayer: r.createPlayer, + createMediaPlayer: r.createMediaPlayer, + createRecognizer: r.createRecognizer, + createTranslator: r.createTranslator, + createDownloadBackends: r.createDownloadBackends, + createSubtitleProviders: r.createSubtitleProviders, + createUpscaler: r.createUpscaler, + findLanSmb: r.findLanSmb, + updater: r.updater, + usage: r.usage == null ? null : const _FixedUsage(), + models: r.models, + shell: r.shell, + platform: r.platform, + )); + } /// 그 글이 화면에 나올 때까지 (목록을 다시 읽는 중일 수 있어) 기다렸다가 누른다 Future tapText(WidgetTester t, String text) async { @@ -309,3 +332,12 @@ Future _purgeRecycled(String dir, {required DateTime since}) async { } return n; } + +/// 늘 같은 값을 내는 사용량 원천 (CPU 5% · 메모리 31%) - 캡처가 실행마다 같게 +class _FixedUsage implements SystemUsage { + const _FixedUsage(); + @override + UsageSample? read() => const UsageSample(cpu: 0.05, memUsed: 31, memTotal: 100); + @override + (int, int)? disk(String path) => null; +} diff --git a/integration_test/windows_ftp_shot_test.dart b/integration_test/windows_ftp_shot_test.dart index 3f1cba2..c457bed 100644 --- a/integration_test/windows_ftp_shot_test.dart +++ b/integration_test/windows_ftp_shot_test.dart @@ -19,6 +19,8 @@ import 'package:path/path.dart' as p; /// 크기 412 · 960, 언어 ko · en · ja. 설정은 메모리에만. 실행: flutter test integration_test\windows_ftp_shot_test.dart -d windows void main() { IntegrationTestWidgetsFlutterBinding.ensureInitialized(); + // 글 칸 커서가 깜빡여 캡처가 실행마다 달라지지 않게 (시험 쪽에서만 - 관리자 10/24) + EditableText.debugDeterministicCursor = true; final out = Platform.environment['JJ_SHOT_DIR'] ?? p.join(Directory.systemTemp.path, 'jj_shots_ftp'); for (final lang in ['ko', 'en', 'ja']) { for (final (w, h) in [(412, 900), (960, 600)]) { @@ -52,7 +54,8 @@ void main() { } Future shot(String name) async { - await settle(3); + // 창이 뜰 때 잠깐 보인 스크롤 막대가 다 사라진 뒤에 찍는다 (실행마다 사라지는 중간에 찍혀 960 캡처가 흔들렸다) + await settle(25); final b = shotKey.currentContext!.findRenderObject()! as RenderRepaintBoundary; final img = await t.runAsync(() => b.toImage()); final bytes = await t.runAsync(() => img!.toByteData(format: ui.ImageByteFormat.png)); diff --git a/lib/ui/ftp_settings.dart b/lib/ui/ftp_settings.dart index 66e9d48..4ca4c17 100644 --- a/lib/ui/ftp_settings.dart +++ b/lib/ui/ftp_settings.dart @@ -244,7 +244,7 @@ Future editFtpServer(BuildContext context, AppController c, {FtpServ ]), ), if (security == 'none') - NoticeBand(icon: Icons.lock_open, color: JjColors.danger, margin: EdgeInsets.zero, title: tr('⚠ 평문 FTP 는 아이디 · 비밀번호 · 파일이 암호화되지 않은 채 오갑니다. 같은 망의 다른 사람이 볼 수 있습니다. 서버가 FTPS 를 못 할 때만, 믿을 수 있는 집 안 망에서만 쓰세요.')), + NoticeBand(icon: Icons.lock_open, color: JjColors.danger, margin: EdgeInsets.zero, title: tr('평문 FTP: 암호화 안 됨'), body: tr('평문 FTP 는 아이디 · 비밀번호 · 파일이 암호화되지 않은 채 오갑니다. 같은 망의 다른 사람이 볼 수 있습니다. 서버가 FTPS 를 못 할 때만, 믿을 수 있는 집 안 망에서만 쓰세요.')), TextField(controller: user, decoration: InputDecoration(labelText: tr('아이디 (비우면 익명)'))), TextField( controller: pass, diff --git a/lib/ui/home/video_detail.dart b/lib/ui/home/video_detail.dart index 3e504e5..f033b78 100644 --- a/lib/ui/home/video_detail.dart +++ b/lib/ui/home/video_detail.dart @@ -180,7 +180,7 @@ class VideoDetailPane extends StatelessWidget { ], if (v.message != null) ...[ const SizedBox(height: 12), - NoticeBand(icon: Icons.error_outline, color: JjColors.danger, margin: EdgeInsets.zero, title: v.message!, selectable: true), + NoticeBand(icon: Icons.error_outline, color: JjColors.danger, margin: EdgeInsets.zero, title: tr('실패'), body: v.message!, selectable: true), ], if (!compact) ...[ const SizedBox(height: 24),