폰 세로 MKV 위 막대 진행: "2/3 · 37%" 짧은 꼴 · 폭을 미리 잡아 [+ 동영상 추가] 를 가리지 않게
a4 의 934 기기 확인 · 관리자 지시 (10/12): 폰 세로에서 진행이 "37%" 만 보여 몇 번째인지 몰랐고, 동영상 추가 [+] 를 반쯤 가렸다. 위 막대는 작업이 시작될 때 재는데 그때는 진행률이 없어 글이 없다가, 나중에 글이 생기며 잰 폭보다 넓어졌다. - 아이콘만 보이는 좁은 꼴에서 여러 개면 "n/전체 · %" · 폭은 늘 같게 (여러 개 72 · 하나 36). - 여러 개를 만드는지가 바뀌면 위 막대를 다시 잰다. - 시험: 폰 세로 411×800, 3개 만드는 중 진행률이 생긴 뒤에도 "n/3 · 37%" · [+] 의 보이는 부분과 겹치지 않음. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>통합
parent
031e8d3f84
commit
1be9f58248
|
|
@ -416,7 +416,8 @@ class _TopBar extends StatelessWidget {
|
|||
|
||||
return AppTopBar(
|
||||
// 242: 작업 중 (진행 표시 · 취소) 이 생기거나 없어지면 다시 잰다
|
||||
key: ValueKey(('mkvTopBar', c.busy)),
|
||||
// (여러 개를 만드는지에 따라 진행 표시 폭이 달라 그때도 다시 잰다)
|
||||
key: ValueKey(('mkvTopBar', c.busy, c.batchTotal > 1)),
|
||||
// 242: 오른쪽 묶음 때문에 왼쪽 (동영상 추가 · AI) 이 아이콘 하나보다 좁아지면 두 줄
|
||||
minMiddleWidth: 56,
|
||||
// 모든 화면 공통: [JJ 홈] [MKV 화면] [뒤로] [다운로드 목록]
|
||||
|
|
|
|||
|
|
@ -419,10 +419,24 @@ class JobIndicator extends StatelessWidget {
|
|||
value: p == null || p == 0 ? null : p,
|
||||
),
|
||||
),
|
||||
// 좁아서 아이콘만일 때도 진행률은 보이게
|
||||
if (iconOnly && p != null) ...[
|
||||
// 좁아서 아이콘만일 때도 진행률은 보이게. 여러 개면 짧은 꼴 "2/3 · 37%" (폰 세로에서 "MKV 3개 중 2번째" 가 잘렸다).
|
||||
// 폭은 늘 같게 잡아 둔다 - 위 막대는 작업이 시작될 때 재는데, 그때는 진행률이 없어 글이 없다가 나중에 생기면
|
||||
// 잰 폭보다 넓어져 왼쪽의 [+ 동영상 추가] 를 가렸다 (a4 934, 폰 세로)
|
||||
if (iconOnly) ...[
|
||||
const SizedBox(width: 4),
|
||||
Text('${(p * 100).round()}%', style: const TextStyle(fontSize: 12, color: JjColors.accent)),
|
||||
SizedBox(
|
||||
width: c.batchTotal > 1 ? 72 : 36,
|
||||
child: Text(
|
||||
[
|
||||
if (c.batchTotal > 1) '${c.batchStarted}/${c.batchTotal}',
|
||||
if (p != null) '${(p * 100).round()}%',
|
||||
].join(' · '),
|
||||
maxLines: 1,
|
||||
softWrap: false,
|
||||
overflow: TextOverflow.fade,
|
||||
style: const TextStyle(fontSize: 12, color: JjColors.accent),
|
||||
),
|
||||
),
|
||||
],
|
||||
if (!iconOnly) const SizedBox(width: 6),
|
||||
if (!iconOnly)
|
||||
|
|
|
|||
|
|
@ -755,4 +755,52 @@ void main() {
|
|||
await tester.runAsync(() => building);
|
||||
await tester.pump();
|
||||
});
|
||||
|
||||
testWidgets('폰 세로 (노트 10+ 약 411×800): 여러 개를 만드는 동안 위 막대 진행은 "n/3 · 37%" 짧은 꼴 · [+ 동영상 추가] 를 가리지 않는다', (tester) async {
|
||||
tester.view.physicalSize = const Size(411, 800);
|
||||
tester.view.devicePixelRatio = 1;
|
||||
addTearDown(tester.view.reset);
|
||||
final tool = _HoldTool();
|
||||
final dir = Directory.systemTemp.createTempSync('jj_batch_portrait_');
|
||||
addTearDown(() => dir.deleteSync(recursive: true));
|
||||
final files = [for (final n in ['a', 'b', 'c']) (File(p.join(dir.path, '$n.mp4'))..writeAsBytesSync([0])).path];
|
||||
final c = AppController(PlatformServices(mediaTool: tool, storage: DesktopStorageService()));
|
||||
late Future<void> building;
|
||||
await tester.runAsync(() async {
|
||||
await c.init();
|
||||
await c.addVideos(files);
|
||||
c.selected = c.videos.first;
|
||||
building = c.buildVideos([...c.videos]);
|
||||
for (var i = 0; i < 200 && tool.runs.isEmpty; i++) {
|
||||
await Future<void>.delayed(const Duration(milliseconds: 10));
|
||||
}
|
||||
});
|
||||
expect(c.busy, isTrue);
|
||||
expect(c.batchTotal, 3);
|
||||
await tester.pumpWidget(MaterialApp(home: HomePage(c: c)));
|
||||
await tester.pump();
|
||||
await tester.pump();
|
||||
// 위 막대를 잰 뒤에 진행률이 생긴다 (예전에는 이때 글이 넓어져 [+] 를 가렸다)
|
||||
for (final v in c.videos.where((v) => v.status == JobStatus.running)) {
|
||||
v.progress = 0.37;
|
||||
}
|
||||
await c.updateSettings((_) {});
|
||||
await tester.pump();
|
||||
expect(tester.takeException(), isNull);
|
||||
final prog = find.textContaining(RegExp(r'^\d+/3 · 37%$'));
|
||||
expect(prog, findsOneWidget);
|
||||
final add = find.byTooltip(Platform.isAndroid ? '동영상 추가' : '동영상 추가 (탐색기에서 끌어다 놓아도 됩니다)');
|
||||
expect(add, findsWidgets);
|
||||
final r = tester.getRect(prog);
|
||||
// [+] 는 옆으로 미는 줄 안에 있어 끝이 잘려 보일 수 있다 - 실제로 보이는 부분 (밀기 줄 안쪽) 이 진행 글과 겹치지 않아야 한다
|
||||
for (final e in add.evaluate()) {
|
||||
final a = tester.getRect(find.byWidget(e.widget).first);
|
||||
final view = tester.getRect(find.ancestor(of: find.byWidget(e.widget).first, matching: find.byType(Scrollable)).first);
|
||||
final seen = a.intersect(view);
|
||||
expect(seen.width > 0 && seen.overlaps(r), isFalse, reason: '[+] 의 보이는 부분 $seen 이 진행 글 $r 와 겹침');
|
||||
}
|
||||
c.cancel();
|
||||
await tester.runAsync(() => building);
|
||||
await tester.pump();
|
||||
});
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue