52 복사 · 이동 진행 막대: 화면을 떠났다 돌아와도 다시 보이고, 끝나면 받는 폴더를 새로 읽음
- 화면을 열 때 CopyCenter 에서 아직 도는 작업을 찾아 진행 막대를 다시 붙이고, 끝나면 받는 · 원본 폴더를 새로 읽은 뒤 내린다 (.jjpart 가 남아 보이지 않게) - 시험: 속도 제한으로 오래 걸리는 복사 도중 화면을 없앴다가 다시 열기 (수정 전 코드에서는 실패) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>묶음3
parent
f01fe96151
commit
1c919ce8c6
|
|
@ -285,6 +285,13 @@ class _ExplorerPageState extends State<ExplorerPage> {
|
||||||
}
|
}
|
||||||
if (!mounted) return;
|
if (!mounted) return;
|
||||||
setState(() => _ready = true);
|
setState(() => _ready = true);
|
||||||
|
// 52: 다른 화면에 다녀와도 아직 도는 복사 · 이동의 진행 막대를 다시 보이고, 끝나면 그 폴더들을 새로 읽는다
|
||||||
|
final center = CopyCenter.peekOf(c);
|
||||||
|
if (center != null) {
|
||||||
|
for (final job in center.jobs.values.where((j) => !j.finished)) {
|
||||||
|
_adoptJob(job);
|
||||||
|
}
|
||||||
|
}
|
||||||
// 165: 드라이브 종류 · 연결은 드라이브마다 따로 뒤에서 (느린 드라이브가 있어도 다른 드라이브 · 창은 바로)
|
// 165: 드라이브 종류 · 연결은 드라이브마다 따로 뒤에서 (느린 드라이브가 있어도 다른 드라이브 · 창은 바로)
|
||||||
if (Platform.isWindows) {
|
if (Platform.isWindows) {
|
||||||
for (final (path, _) in _local) {
|
for (final (path, _) in _local) {
|
||||||
|
|
@ -1446,6 +1453,21 @@ class _ExplorerPageState extends State<ExplorerPage> {
|
||||||
/// (Rsync 화면의 ⇄ 는 둘이 함께)
|
/// (Rsync 화면의 ⇄ 는 둘이 함께)
|
||||||
List<TransferJob> _jobs = const [];
|
List<TransferJob> _jobs = const [];
|
||||||
|
|
||||||
|
/// 52: 이 화면을 떠난 사이에 시작된 (또는 앞의 화면이 시작한) 작업을 다시 보이고, 끝나면 새로 읽고 막대를 내린다
|
||||||
|
void _adoptJob(TransferJob job) {
|
||||||
|
if (_jobs.contains(job)) return;
|
||||||
|
setState(() => _jobs = [..._jobs, job]);
|
||||||
|
unawaited(job.done.then((_) async {
|
||||||
|
if (!mounted) return;
|
||||||
|
await _refreshAll([job.dest, ...job.sources.map(vDirname)]);
|
||||||
|
for (final x in _panes) {
|
||||||
|
x.changed();
|
||||||
|
}
|
||||||
|
await Future<void>.delayed(const Duration(milliseconds: 1200));
|
||||||
|
if (mounted && _jobs.contains(job)) setState(() => _jobs = [for (final j in _jobs) if (j != job) j]);
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
/// 한쪽이라도 WebDAV 면 rsync 대신 앱이 직접 맞춘다 (rsync 는 WebDAV 를 모름)
|
/// 한쪽이라도 WebDAV 면 rsync 대신 앱이 직접 맞춘다 (rsync 는 WebDAV 를 모름)
|
||||||
bool _viaDav(Iterable<String> paths) => paths.any(isDav);
|
bool _viaDav(Iterable<String> paths) => paths.any(isDav);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -105,6 +105,33 @@ void main() {
|
||||||
expect(Directory(p.join(right, 'left')).existsSync(), isFalse);
|
expect(Directory(p.join(right, 'left')).existsSync(), isFalse);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
testWidgets('52: 복사 중에 화면을 떠났다 돌아와도 진행 막대가 다시 보이고, 끝나면 받는 폴더를 새로 읽는다 (.jjpart 가 남아 보이지 않음)', (tester) async {
|
||||||
|
File(p.join(left, 'big.bin')).writeAsBytesSync(List.filled(150 * 1024, 3));
|
||||||
|
c.settings.copyBandwidthKBps = 60; // 약 2.5초 걸리게
|
||||||
|
tester.view.physicalSize = const Size(1600, 900);
|
||||||
|
tester.view.devicePixelRatio = 1;
|
||||||
|
addTearDown(tester.view.reset);
|
||||||
|
await tester.runAsync(() => tester.pumpWidget(MaterialApp(home: ExplorerPage(c: c))));
|
||||||
|
await settle(tester, () => find.text('big.bin').evaluate().isNotEmpty);
|
||||||
|
await tester.runAsync(() => tester.tap(find.text('big.bin')));
|
||||||
|
await settle(tester, () => false, rounds: 10);
|
||||||
|
await tester.runAsync(() => tester.tap(find.text('복사').first));
|
||||||
|
await tester.pump();
|
||||||
|
await tester.runAsync(() => tester.tap(find.widgetWithText(FilledButton, '복사')));
|
||||||
|
await settle(tester, () => find.byType(LinearProgressIndicator).evaluate().isNotEmpty);
|
||||||
|
// 다른 화면으로 (탐색기 화면이 없어짐) → 돌아옴
|
||||||
|
await tester.runAsync(() => tester.pumpWidget(const MaterialApp(home: Scaffold(body: Text('다른 화면')))));
|
||||||
|
await tester.pump();
|
||||||
|
await tester.runAsync(() => tester.pumpWidget(MaterialApp(home: ExplorerPage(c: c))));
|
||||||
|
await settle(tester, () => find.byType(LinearProgressIndicator).evaluate().isNotEmpty, rounds: 30);
|
||||||
|
expect(find.byType(LinearProgressIndicator), findsWidgets, reason: '돌아와도 진행 막대');
|
||||||
|
// 끝나면 오른쪽 창에 big.bin 이 보이고 .jjpart 는 없다
|
||||||
|
await settle(tester, () => File(p.join(right, 'big.bin')).existsSync() && find.text('big.bin').evaluate().length >= 2,
|
||||||
|
rounds: 300);
|
||||||
|
expect(find.text('big.bin'), findsNWidgets(2));
|
||||||
|
expect(find.textContaining('.jjpart'), findsNothing);
|
||||||
|
});
|
||||||
|
|
||||||
testWidgets('48: 건너뛰기를 고르면 그대로 두고 건너뛴 것을 알린다', (tester) async {
|
testWidgets('48: 건너뛰기를 고르면 그대로 두고 건너뛴 것을 알린다', (tester) async {
|
||||||
await startCopy(tester);
|
await startCopy(tester);
|
||||||
await tester.tap(find.text('건너뛰기'));
|
await tester.tap(find.text('건너뛰기'));
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue