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);