WIP 266 폰 세로 MKV 화면: DNS 닿지 않음 줄을 한 줄로 (글 줄임 · 길게 누르면 전체 · 버튼 같은 줄) - 세부 정보의 자막 버튼이 밀려나지 않게 (검토 대기)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>묶음6
parent
1c6b008332
commit
f596ef7253
|
|
@ -103,7 +103,7 @@ class HomePage extends StatelessWidget {
|
||||||
),
|
),
|
||||||
const Divider(height: 1),
|
const Divider(height: 1),
|
||||||
// 249: DNS 서버에 닿지 않는 동안 작업 기록 위에 (아래 안내를 놓쳐도 MKV 화면에서 보고 바꿀 수 있게)
|
// 249: DNS 서버에 닿지 않는 동안 작업 기록 위에 (아래 안내를 놓쳐도 MKV 화면에서 보고 바꿀 수 있게)
|
||||||
Padding(padding: const EdgeInsets.symmetric(horizontal: 12), child: DnsFailureLine(c: c)),
|
Padding(padding: const EdgeInsets.symmetric(horizontal: 12), child: DnsFailureLine(c: c, compact: isCompact(context))),
|
||||||
if (c.settings.showLog)
|
if (c.settings.showLog)
|
||||||
SizedBox(
|
SizedBox(
|
||||||
// 화면이 낮은 기기 (휴대폰 가로) 에서 목록 · 자세히 보기를 가리지 않도록 화면 높이에 맞춘다.
|
// 화면이 낮은 기기 (휴대폰 가로) 에서 목록 · 자세히 보기를 가리지 않도록 화면 높이에 맞춘다.
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,11 @@ import 'tor_page.dart' show showTorNotice;
|
||||||
/// 서버가 다시 답하거나 DNS 설정을 바꾸면 사라진다.
|
/// 서버가 다시 답하거나 DNS 설정을 바꾸면 사라진다.
|
||||||
class DnsFailureLine extends StatelessWidget {
|
class DnsFailureLine extends StatelessWidget {
|
||||||
final AppController c;
|
final AppController c;
|
||||||
const DnsFailureLine({super.key, required this.c});
|
|
||||||
|
/// 266: 좁은 화면 (폰 세로) - 한 줄 (글은 줄임, 길게 누르면 전체 · 버튼은 같은 줄). 두 줄이면 위의 세부 정보 칸이 줄어
|
||||||
|
/// [AI 자막 만들기] · [인터넷 자막 찾기] 가 칸 밖으로 밀렸다
|
||||||
|
final bool compact;
|
||||||
|
const DnsFailureLine({super.key, required this.c, this.compact = false});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) => ValueListenableBuilder<DnsFailure?>(
|
Widget build(BuildContext context) => ValueListenableBuilder<DnsFailure?>(
|
||||||
|
|
@ -27,12 +31,33 @@ class DnsFailureLine extends StatelessWidget {
|
||||||
builder: (context, f, _) {
|
builder: (context, f, _) {
|
||||||
if (f == null) return const SizedBox.shrink();
|
if (f == null) return const SizedBox.shrink();
|
||||||
String two(int x) => x.toString().padLeft(2, '0');
|
String two(int x) => x.toString().padLeft(2, '0');
|
||||||
|
final text = trf('DNS 서버 ({0}) 에 닿지 않음 ({1}부터)', [f.server, '${two(f.at.hour)}:${two(f.at.minute)}']);
|
||||||
|
if (compact) {
|
||||||
|
return SizedBox(
|
||||||
|
height: 36,
|
||||||
|
child: Row(children: [
|
||||||
|
const Icon(Icons.warning_amber_rounded, size: 16, color: Colors.orange),
|
||||||
|
const SizedBox(width: 6),
|
||||||
|
Expanded(
|
||||||
|
child: Tooltip(
|
||||||
|
message: text,
|
||||||
|
child: Text(text, maxLines: 1, overflow: TextOverflow.ellipsis, style: const TextStyle(fontSize: 12, color: Colors.orange)),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
TextButton(
|
||||||
|
style: TextButton.styleFrom(
|
||||||
|
visualDensity: VisualDensity.compact, padding: const EdgeInsets.symmetric(horizontal: 8), minimumSize: const Size(0, 36)),
|
||||||
|
onPressed: () => c.updateSettings((x) => x.dnsMode = 'system'),
|
||||||
|
child: Text(tr('시스템 DNS 로 바꾸기'), style: const TextStyle(fontSize: 13)),
|
||||||
|
),
|
||||||
|
]),
|
||||||
|
);
|
||||||
|
}
|
||||||
return Padding(
|
return Padding(
|
||||||
padding: const EdgeInsets.symmetric(vertical: 4),
|
padding: const EdgeInsets.symmetric(vertical: 4),
|
||||||
child: Wrap(spacing: 8, crossAxisAlignment: WrapCrossAlignment.center, children: [
|
child: Wrap(spacing: 8, crossAxisAlignment: WrapCrossAlignment.center, children: [
|
||||||
const Icon(Icons.warning_amber_rounded, size: 18, color: Colors.orange),
|
const Icon(Icons.warning_amber_rounded, size: 18, color: Colors.orange),
|
||||||
Text(trf('DNS 서버 ({0}) 에 닿지 않음 ({1}부터)', [f.server, '${two(f.at.hour)}:${two(f.at.minute)}']),
|
Text(text, style: const TextStyle(fontSize: 12, color: Colors.orange)),
|
||||||
style: const TextStyle(fontSize: 12, color: Colors.orange)),
|
|
||||||
TextButton(
|
TextButton(
|
||||||
onPressed: () => c.updateSettings((x) => x.dnsMode = 'system'),
|
onPressed: () => c.updateSettings((x) => x.dnsMode = 'system'),
|
||||||
child: Text(tr('시스템 DNS 로 바꾸기')),
|
child: Text(tr('시스템 DNS 로 바꾸기')),
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_test/flutter_test.dart';
|
import 'package:flutter_test/flutter_test.dart';
|
||||||
import 'package:jj_mkvmaker/app/app_controller.dart';
|
import 'package:jj_mkvmaker/app/app_controller.dart';
|
||||||
|
import 'package:jj_mkvmaker/app/net_guard.dart';
|
||||||
import 'package:jj_mkvmaker/app/settings.dart';
|
import 'package:jj_mkvmaker/app/settings.dart';
|
||||||
import 'package:jj_mkvmaker/core/models.dart';
|
import 'package:jj_mkvmaker/core/models.dart';
|
||||||
import 'package:jj_mkvmaker/platform/windows/desktop_storage_service.dart';
|
import 'package:jj_mkvmaker/platform/windows/desktop_storage_service.dart';
|
||||||
|
|
@ -10,8 +11,8 @@ import 'package:jj_mkvmaker/ui/home_page.dart';
|
||||||
|
|
||||||
/// 261: 폰 세로 (노트 10+ 412×869) 의 MKV 세부 정보 - "감지한 언어" 줄이 생겨도 [AI 자막 만들기] 가 밀려 가려지지 않는다
|
/// 261: 폰 세로 (노트 10+ 412×869) 의 MKV 세부 정보 - "감지한 언어" 줄이 생겨도 [AI 자막 만들기] 가 밀려 가려지지 않는다
|
||||||
void main() {
|
void main() {
|
||||||
for (final detected in [false, true]) {
|
for (final (detected, dns) in [(false, false), (true, false), (true, true)]) {
|
||||||
testWidgets('261: 폰 세로 · 작업 기록 켬 · 감지한 언어 ${detected ? '있음' : '없음'} - [AI 자막 만들기] 가 스크롤 없이 보인다', (tester) async {
|
testWidgets('261 · 266: 폰 세로 · 작업 기록 켬 · 감지한 언어 ${detected ? '있음' : '없음'}${dns ? ' · DNS 닿지 않음 줄' : ''} - [AI 자막 만들기] 가 스크롤 없이 보인다', (tester) async {
|
||||||
tester.view.physicalSize = const Size(412, 869);
|
tester.view.physicalSize = const Size(412, 869);
|
||||||
tester.view.devicePixelRatio = 1;
|
tester.view.devicePixelRatio = 1;
|
||||||
addTearDown(tester.view.reset);
|
addTearDown(tester.view.reset);
|
||||||
|
|
@ -27,6 +28,11 @@ void main() {
|
||||||
c.videos.add(VideoItem('D:/v/아주 긴 이름의 동영상 파일 $i.mp4'));
|
c.videos.add(VideoItem('D:/v/아주 긴 이름의 동영상 파일 $i.mp4'));
|
||||||
}
|
}
|
||||||
c.selected = c.videos.first..aiDetected = detected ? 'en' : null;
|
c.selected = c.videos.first..aiDetected = detected ? 'en' : null;
|
||||||
|
// 266: DNS 가 닿지 않는 동안 작업 기록 위의 줄 (936 노트 10+ 에서 두 줄이 되어 버튼을 밀어냄)
|
||||||
|
if (dns) {
|
||||||
|
NetGuard.instance.failure.value = DnsFailure('192.0.2.1', '답이 없습니다', DateTime(2026, 10, 12, 8, 42));
|
||||||
|
addTearDown(() => NetGuard.instance.failure.value = null);
|
||||||
|
}
|
||||||
await tester.pumpWidget(MaterialApp(home: HomePage(c: c)));
|
await tester.pumpWidget(MaterialApp(home: HomePage(c: c)));
|
||||||
await tester.pump();
|
await tester.pump();
|
||||||
expect(tester.takeException(), isNull);
|
expect(tester.takeException(), isNull);
|
||||||
|
|
@ -36,6 +42,12 @@ void main() {
|
||||||
final view = tester.getRect(find.ancestor(of: ai, matching: find.byType(Scrollable)).first);
|
final view = tester.getRect(find.ancestor(of: ai, matching: find.byType(Scrollable)).first);
|
||||||
final button = tester.getRect(ai);
|
final button = tester.getRect(ai);
|
||||||
expect(button.bottom, lessThanOrEqualTo(view.bottom), reason: '버튼 $button · 세부 정보 칸 $view');
|
expect(button.bottom, lessThanOrEqualTo(view.bottom), reason: '버튼 $button · 세부 정보 칸 $view');
|
||||||
|
if (dns) {
|
||||||
|
// 한 줄 · 버튼도 그 줄에
|
||||||
|
final line = tester.getRect(find.text('DNS 서버 (192.0.2.1) 에 닿지 않음 (08:42부터)'));
|
||||||
|
final sys = tester.getRect(find.text('시스템 DNS 로 바꾸기'));
|
||||||
|
expect((sys.center.dy - line.center.dy).abs(), lessThan(4), reason: '버튼이 같은 줄');
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue