AI 해상도 올리기 비교 화면: 저장하지 않고 닫으면 묻기 (160)
닫으면 올린 그림이 지워지므로 [닫기] · 뒤로 키 · 뒤로 몸짓 모두 "저장하지 않고 닫을까요?" ([취소] · [저장하지 않고 닫기] · [저장]). 위쪽 [저장] 은 묻지 않는다. 시험하려고 UpscaleCompareView 로 공개. upscale_compare_test. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>묶음4
parent
06b6169ad8
commit
bf72557fc3
|
|
@ -1266,6 +1266,7 @@
|
|||
"올린 것": "Upscaled",
|
||||
"올린 것 (AI)": "Upscaled (AI)",
|
||||
"올린 것으로 계속 보기": "Keep viewing the upscaled one",
|
||||
"올린 그림은 지워집니다. 다시 보려면 해상도 올리기를 다시 해야 합니다.": "The upscaled image will be deleted. To see it again you will need to upscale again.",
|
||||
"올린 이 {0}": "Uploaded by {0}",
|
||||
"옮겼습니다.": "moved.",
|
||||
"옮기기": "Move",
|
||||
|
|
@ -1593,6 +1594,8 @@
|
|||
"저장하고 실행": "Save and run",
|
||||
"저장하는 중": "Saving",
|
||||
"저장하지 못했습니다: {0}": "Could not save: {0}",
|
||||
"저장하지 않고 닫기": "Close without saving",
|
||||
"저장하지 않고 닫을까요?": "Close without saving?",
|
||||
"저장하지 않은 변경": "Unsaved changes",
|
||||
"저장한 뒤": "After saving",
|
||||
"저장했습니다": "Saved",
|
||||
|
|
|
|||
|
|
@ -1266,6 +1266,7 @@
|
|||
"올린 것": "高解像度化後",
|
||||
"올린 것 (AI)": "高解像度化後 (AI)",
|
||||
"올린 것으로 계속 보기": "高解像度化した画像で表示を続ける",
|
||||
"올린 그림은 지워집니다. 다시 보려면 해상도 올리기를 다시 해야 합니다.": "高解像度化した画像は削除されます。もう一度見るには高解像度化をやり直す必要があります。",
|
||||
"올린 이 {0}": "投稿者 {0}",
|
||||
"옮겼습니다.": "移動しました。",
|
||||
"옮기기": "移動",
|
||||
|
|
@ -1593,6 +1594,8 @@
|
|||
"저장하고 실행": "保存して実行",
|
||||
"저장하는 중": "保存中",
|
||||
"저장하지 못했습니다: {0}": "保存できませんでした: {0}",
|
||||
"저장하지 않고 닫기": "保存せずに閉じる",
|
||||
"저장하지 않고 닫을까요?": "保存せずに閉じますか?",
|
||||
"저장하지 않은 변경": "未保存の変更",
|
||||
"저장한 뒤": "保存後",
|
||||
"저장했습니다": "保存しました",
|
||||
|
|
|
|||
|
|
@ -1266,6 +1266,7 @@
|
|||
"올린 것": "提高后",
|
||||
"올린 것 (AI)": "提高后 (AI)",
|
||||
"올린 것으로 계속 보기": "继续查看提高后的图片",
|
||||
"올린 그림은 지워집니다. 다시 보려면 해상도 올리기를 다시 해야 합니다.": "提升后的图片将被删除。要再次查看需要重新提升分辨率。",
|
||||
"올린 이 {0}": "上传者 {0}",
|
||||
"옮겼습니다.": "已移动。",
|
||||
"옮기기": "移动",
|
||||
|
|
@ -1593,6 +1594,8 @@
|
|||
"저장하고 실행": "保存并执行",
|
||||
"저장하는 중": "正在保存",
|
||||
"저장하지 못했습니다: {0}": "无法保存: {0}",
|
||||
"저장하지 않고 닫기": "不保存并关闭",
|
||||
"저장하지 않고 닫을까요?": "不保存就关闭吗?",
|
||||
"저장하지 않은 변경": "未保存的更改",
|
||||
"저장한 뒤": "保存后",
|
||||
"저장했습니다": "已保存",
|
||||
|
|
|
|||
|
|
@ -260,7 +260,7 @@ Future<String?> upscaleOne(BuildContext context, AppController c, {required Stri
|
|||
try {
|
||||
final save = await Navigator.of(context).push<bool>(MaterialPageRoute(
|
||||
fullscreenDialog: true,
|
||||
builder: (_) => _CompareView(original: input, upscaled: four!, title: p.basename(nameFrom)),
|
||||
builder: (_) => UpscaleCompareView(original: input, upscaled: four!, title: p.basename(nameFrom)),
|
||||
));
|
||||
if (save != true || !context.mounted) return null;
|
||||
final saved = await saveUpscaled(four, source: nameFrom, original: input, o: upscaleOptionsOf(c, outDir: outDir));
|
||||
|
|
@ -353,18 +353,18 @@ Future<void> upscaleAll(BuildContext context, AppController c, ReaderSource src)
|
|||
));
|
||||
}
|
||||
|
||||
/// 원본 / 올린 것을 바꿔 보며 비교 (확대해서 볼 수 있음)
|
||||
class _CompareView extends StatefulWidget {
|
||||
const _CompareView({required this.original, required this.upscaled, required this.title});
|
||||
/// 원본 / 올린 것을 바꿔 보며 비교 (확대해서 볼 수 있음). [저장] 이면 true, 저장하지 않고 닫으면 false
|
||||
class UpscaleCompareView extends StatefulWidget {
|
||||
const UpscaleCompareView({super.key, required this.original, required this.upscaled, required this.title});
|
||||
final String original;
|
||||
final String upscaled;
|
||||
final String title;
|
||||
|
||||
@override
|
||||
State<_CompareView> createState() => _CompareViewState();
|
||||
State<UpscaleCompareView> createState() => UpscaleCompareViewState();
|
||||
}
|
||||
|
||||
class _CompareViewState extends State<_CompareView> {
|
||||
class UpscaleCompareViewState extends State<UpscaleCompareView> {
|
||||
bool _up = true;
|
||||
final _zoom = TransformationController();
|
||||
|
||||
|
|
@ -374,12 +374,44 @@ class _CompareViewState extends State<_CompareView> {
|
|||
super.dispose();
|
||||
}
|
||||
|
||||
/// 160: 저장하지 않고 닫으면 올린 그림이 지워지므로 묻는다 (닫기 버튼 · 뒤로 키 · 뒤로 몸짓)
|
||||
Future<void> _close() async {
|
||||
final r = await showDialog<String>(
|
||||
context: context,
|
||||
builder: (ctx) => AlertDialog(
|
||||
title: Text(tr('저장하지 않고 닫을까요?')),
|
||||
content: Text(tr('올린 그림은 지워집니다. 다시 보려면 해상도 올리기를 다시 해야 합니다.')),
|
||||
actions: [
|
||||
TextButton(onPressed: () => Navigator.pop(ctx), child: Text(tr('취소'))),
|
||||
TextButton(onPressed: () => Navigator.pop(ctx, 'discard'), child: Text(tr('저장하지 않고 닫기'))),
|
||||
FilledButton.icon(
|
||||
onPressed: () => Navigator.pop(ctx, 'save'),
|
||||
icon: const Icon(Icons.save_outlined, size: 18),
|
||||
label: Text(tr('저장')),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
if (!mounted || r == null) return;
|
||||
Navigator.pop(context, r == 'save');
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return PopScope(
|
||||
canPop: false,
|
||||
onPopInvokedWithResult: (didPop, _) {
|
||||
if (!didPop) _close();
|
||||
},
|
||||
child: _page(context),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _page(BuildContext context) {
|
||||
return Scaffold(
|
||||
backgroundColor: Colors.black,
|
||||
appBar: AppBar(
|
||||
leading: IconButton(tooltip: tr('닫기'), icon: const Icon(Icons.close), onPressed: () => Navigator.pop(context, false)),
|
||||
leading: IconButton(tooltip: tr('닫기'), icon: const Icon(Icons.close), onPressed: _close),
|
||||
title: Text(widget.title, maxLines: 1, overflow: TextOverflow.ellipsis),
|
||||
actions: [
|
||||
SegmentedButton<bool>(
|
||||
|
|
|
|||
|
|
@ -0,0 +1,67 @@
|
|||
import 'dart:io';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:image/image.dart' as img;
|
||||
import 'package:jj_mkvmaker/ui/ai_upscale_ui.dart';
|
||||
import 'package:path/path.dart' as p;
|
||||
|
||||
/// 160: 비교 화면을 저장하지 않고 닫으면 (올린 그림이 지워지므로) 묻는다 - 닫기 버튼 · 뒤로 키
|
||||
void main() {
|
||||
late Directory dir;
|
||||
late String a, b;
|
||||
setUp(() {
|
||||
dir = Directory.systemTemp.createTempSync('jj_cmp_');
|
||||
a = p.join(dir.path, 'a.png');
|
||||
b = p.join(dir.path, 'b.png');
|
||||
File(a).writeAsBytesSync(img.encodePng(img.Image(width: 4, height: 4)));
|
||||
File(b).writeAsBytesSync(img.encodePng(img.Image(width: 16, height: 16)));
|
||||
});
|
||||
tearDown(() => dir.deleteSync(recursive: true));
|
||||
|
||||
Future<Future<bool?>> open(WidgetTester tester) async {
|
||||
late NavigatorState nav;
|
||||
await tester.pumpWidget(MaterialApp(home: Builder(builder: (context) {
|
||||
nav = Navigator.of(context);
|
||||
return const SizedBox();
|
||||
})));
|
||||
final r = nav.push<bool>(MaterialPageRoute(builder: (_) => UpscaleCompareView(original: a, upscaled: b, title: 't')));
|
||||
await tester.pumpAndSettle();
|
||||
return r;
|
||||
}
|
||||
|
||||
testWidgets('[닫기] → 묻기: [취소] 면 그대로 · [저장하지 않고 닫기] 면 false', (tester) async {
|
||||
final r = await open(tester);
|
||||
await tester.tap(find.byTooltip('닫기'));
|
||||
await tester.pumpAndSettle();
|
||||
expect(find.text('저장하지 않고 닫을까요?'), findsOneWidget);
|
||||
await tester.tap(find.text('취소'));
|
||||
await tester.pumpAndSettle();
|
||||
expect(find.byType(UpscaleCompareView), findsOneWidget, reason: '닫지 않음');
|
||||
await tester.tap(find.byTooltip('닫기'));
|
||||
await tester.pumpAndSettle();
|
||||
await tester.tap(find.text('저장하지 않고 닫기'));
|
||||
await tester.pumpAndSettle();
|
||||
expect(find.byType(UpscaleCompareView), findsNothing);
|
||||
expect(await r, isFalse);
|
||||
});
|
||||
|
||||
testWidgets('뒤로 키도 묻고, 묻는 창의 [저장] 이면 true', (tester) async {
|
||||
final r = await open(tester);
|
||||
await tester.binding.handlePopRoute();
|
||||
await tester.pumpAndSettle();
|
||||
expect(find.text('저장하지 않고 닫을까요?'), findsOneWidget);
|
||||
expect(find.byType(UpscaleCompareView), findsOneWidget);
|
||||
await tester.tap(find.descendant(of: find.byType(AlertDialog), matching: find.widgetWithText(FilledButton, '저장')));
|
||||
await tester.pumpAndSettle();
|
||||
expect(await r, isTrue);
|
||||
});
|
||||
|
||||
testWidgets('위쪽 [저장] 은 묻지 않고 바로 true', (tester) async {
|
||||
final r = await open(tester);
|
||||
await tester.tap(find.widgetWithText(FilledButton, '저장'));
|
||||
await tester.pumpAndSettle();
|
||||
expect(find.text('저장하지 않고 닫을까요?'), findsNothing);
|
||||
expect(await r, isTrue);
|
||||
});
|
||||
}
|
||||
Loading…
Reference in New Issue