From f34cbe5a69c90e116ebbdd80e6f852cd0e0582b9 Mon Sep 17 00:00:00 2001 From: RyuJongJin <266630912+RyuJongJin@users.noreply.github.com> Date: Fri, 9 Oct 2026 18:27:25 +0900 Subject: [PATCH] =?UTF-8?q?P0=20=EB=B3=B4=EC=B6=A9:=20=EB=90=98=EB=8F=8C?= =?UTF-8?q?=EB=A6=AC=EA=B8=B0=EC=9D=98=20AI=20=EB=AA=A8=EB=8D=B8=20?= =?UTF-8?q?=EB=B3=B5=EC=82=AC=20=EC=B2=B4=ED=81=AC=EB=8A=94=20[=EC=A0=80?= =?UTF-8?q?=EC=9E=A5=ED=95=98=EA=B3=A0=20=EA=B3=84=EC=86=8D]=20=EB=95=8C?= =?UTF-8?q?=EB=A7=8C=20=EC=84=A4=EC=A0=95=EC=97=90=20([=EC=B7=A8=EC=86=8C]?= =?UTF-8?q?=20=ED=95=98=EB=A9=B4=20=EA=B7=B8=EB=8C=80=EB=A1=9C,=20?= =?UTF-8?q?=EA=B1=B4=EB=93=9C=EB=A6=AC=EC=A7=80=20=EC=95=8A=EC=9C=BC?= =?UTF-8?q?=EB=A9=B4=20=EC=9E=90=EB=8F=99=20=EC=9C=A0=EC=A7=80)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Opus 5.5 --- lib/ui/update_dialog.dart | 13 +++++++++---- test/update_ui_test.dart | 19 +++++++++++++++---- 2 files changed, 24 insertions(+), 8 deletions(-) diff --git a/lib/ui/update_dialog.dart b/lib/ui/update_dialog.dart index 136879a..9983e6e 100644 --- a/lib/ui/update_dialog.dart +++ b/lib/ui/update_dialog.dart @@ -457,6 +457,7 @@ Future _androidRollback(BuildContext context, AppController c, Updater up, final free = (await diskSpace(probe))?.$1; final setting = c.settings.rollbackKeepModels; var keep = modelSize > 0 && (setting == 'on' || (setting == '' && free != null && free >= modelSize * 2)); + var keepTouched = false; // 옮겨 둔 모델을 되살리는 기능은 이 판 다음부터 들어 있다 (설정 되살리기는 v2026.10.08_001 부터) final targetRestoresModels = compareVersions(r.version, '2026.10.09_001') > 0; final targetRestoresSettings = compareVersions(r.version, '2026.10.08_001') >= 0; @@ -499,10 +500,11 @@ Future _androidRollback(BuildContext context, AppController c, Updater up, CheckboxListTile( contentPadding: EdgeInsets.zero, value: keep, - onChanged: (v) { - setInner(() => keep = v ?? false); - c.updateSettings((x) => x.rollbackKeepModels = keep ? 'on' : 'off'); - }, + // 고른 것은 [저장하고 계속] 을 누를 때만 설정에 남긴다 ([취소] 하면 그대로) + onChanged: (v) => setInner(() { + keep = v ?? false; + keepTouched = true; + }), title: Text(trf('받은 AI 모델 ({0}) 을 Download/JJ_MKVMaker 에 복사해 두었다가 다시 설치한 뒤 되살리기 (잠시 {0} 더 필요)', [size])), subtitle: Text([ if (free != null) trf('남은 공간 {0}', [gbText(free)]), @@ -525,6 +527,9 @@ Future _androidRollback(BuildContext context, AppController c, Updater up, ), ); if (ok != true || !context.mounted) return; + // 체크를 바꿨으면 이제 설정에 (자동이던 것은 건드리지 않으면 자동 그대로) + if (keepTouched) await c.updateSettings((x) => x.rollbackKeepModels = keep ? 'on' : 'off'); + if (!context.mounted) return; // 사라지는 것이 있으니 한 번 더 (비밀번호 · 로그인은 늘 사라진다) final sure = await showDialog( context: context, diff --git a/test/update_ui_test.dart b/test/update_ui_test.dart index 41ae948..f2a00bc 100644 --- a/test/update_ui_test.dart +++ b/test/update_ui_test.dart @@ -268,7 +268,7 @@ void main() { expect(up.calls, ['download 1.0.0', 'uninstall']); }); - testWidgets('P0 Android: 받은 AI 모델을 복사해 두기 (기본: 남은 공간이 2배 이상이면 켬) · 끄면 "다시 받아야" · 설정에 기억', (tester) async { + testWidgets('P0 Android: 받은 AI 모델을 복사해 두기 (기본: 남은 공간이 2배 이상이면 켬) · 끄면 "다시 받아야" · [저장하고 계속] 때만 설정에 기억', (tester) async { up.installsInPlace = true; up.downloaded = (File(p.join(data.path, 'dl.apk'))..writeAsStringSync('apk')).path; File(p.join(data.path, 'ai', 'models', 'esrgan.pth')) @@ -292,13 +292,24 @@ void main() { await tester.tap(find.byType(Checkbox)); await tester.pumpAndSettle(); expect(find.textContaining('다시 받아야 합니다 (약 3MB)'), findsOneWidget); - expect(c.settings.rollbackKeepModels, 'off'); - // 다시 켜고 진행 → 공용 폴더에 모델 사본과 목록 + // 체크를 바꿔도 [취소] 하면 설정은 그대로 (자동) + await tester.tap(find.text('취소')); + await tester.pumpAndSettle(); + expect(c.settings.rollbackKeepModels, ''); + await openPicker(tester); + await tester.tap(find.text('v1.0.0').first); + await tester.pumpAndSettle(); + await tester.tap(find.text('이 버전으로 되돌리기')); + await settleIo(tester, until: () => find.text('저장하고 계속').evaluate().isNotEmpty); + // 끄고 다시 켠 뒤 [저장하고 계속] 을 누를 때 설정에 → 공용 폴더에 모델 사본과 목록 await tester.tap(find.byType(Checkbox)); await tester.pumpAndSettle(); - expect(c.settings.rollbackKeepModels, 'on'); + await tester.tap(find.byType(Checkbox)); + await tester.pumpAndSettle(); + expect(c.settings.rollbackKeepModels, ''); await tester.tap(find.text('저장하고 계속')); await tester.pumpAndSettle(); + expect(c.settings.rollbackKeepModels, 'on'); await tester.tap(find.text('되돌리기 계속')); await settleIo(tester, until: () => find.text('저장했습니다').evaluate().isNotEmpty); expect(find.text('저장했습니다'), findsOneWidget);