From 037ddf502a6d05d95ff25adf06dd92a697e41ca0 Mon Sep 17 00:00:00 2001 From: RyuJongJin <266630912+RyuJongJin@users.noreply.github.com> Date: Mon, 12 Oct 2026 00:35:11 +0900 Subject: [PATCH] =?UTF-8?q?=ED=83=90=EC=83=89=EA=B8=B0:=20=EC=95=B1?= =?UTF-8?q?=EC=9C=BC=EB=A1=9C=20=EB=8F=8C=EC=95=84=EC=98=A4=EB=A9=B4=20?= =?UTF-8?q?=EB=B3=B4=EC=9D=B4=EB=8A=94=20=ED=8F=B4=EB=8D=94=EB=A5=BC=20?= =?UTF-8?q?=EB=8B=A4=EC=8B=9C=20=EC=9D=BD=EA=B8=B0=20(232)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 버그 (기기 확인): 다른 앱에서 바꾸고 돌아와도 예전 목록이 남았다 - 돌아올 때 [새로 고침] 과 같게 (WebDAV 는 빼고 - 관리자 판단 승인) Co-Authored-By: Claude Opus 5.5 --- lib/ui/explorer_page.dart | 40 +++++++++++++++++++++++++--------- test/explorer_steady_test.dart | 26 ++++++++++++++++++++++ 2 files changed, 56 insertions(+), 10 deletions(-) diff --git a/lib/ui/explorer_page.dart b/lib/ui/explorer_page.dart index 8e17a52..c0665dd 100644 --- a/lib/ui/explorer_page.dart +++ b/lib/ui/explorer_page.dart @@ -313,9 +313,36 @@ class _ExplorerPageState extends State { for (final pane in _panes) { pane.addListener(_onPane); } + _resumeReload = AppLifecycleListener(onResume: () => unawaited(_reloadOpen(localOnly: true))); _init(); } + /// 232: 앱으로 돌아오면 (다른 앱 · 탐색기에서 파일을 바꾸고 오면) 보이는 폴더를 다시 읽는다 + late final AppLifecycleListener _resumeReload; + bool _reloading = false; + + /// 열려 있는 (보이는) 폴더를 두 창 모두 다시 읽는다 - [새로 고침] (183) 과 같다. + /// [localOnly]: 돌아올 때는 WebDAV 폴더는 빼고 (네트워크가 아직 안 붙었을 때 오류가 뜨지 않게 - [새로 고침] 으로는 읽음) + Future _reloadOpen({bool localOnly = false}) async { + if (_reloading) return; + _reloading = true; + try { + // 180: 목록을 먼저 비우지 않고 새로 읽은 것으로 바꾼다 (비우면 목록이 사라졌다 생겨 스크롤 · 자리가 바뀐다) + for (final x in _panes) { + final open = {...x.expanded, x.current}; + for (final d in open) { + if (!mounted) return; + if (localOnly && isDav(d)) continue; + await _load(x, d, force: true); + } + x.cache.removeWhere((k, _) => !open.contains(k)); + x.changed(); + } + } finally { + _reloading = false; + } + } + @override void dispose() { if (widget.rsync) { @@ -328,6 +355,7 @@ class _ExplorerPageState extends State { pane.dispose(); } if (_allFiles != null) _life.dispose(); + _resumeReload.dispose(); super.dispose(); } @@ -1372,16 +1400,8 @@ class _ExplorerPageState extends State { case ExplorerButton.both: await _runRsync(right: true, left: true); case ExplorerButton.refresh: - // 183: 두 창 모두 (밖에서 지운 파일이 다른 창에 남지 않게). - // 180: 목록을 먼저 비우지 않고 새로 읽은 것으로 바꾼다 (비우면 목록이 사라졌다 생겨 스크롤 · 자리가 바뀐다) - for (final x in _panes) { - final open = {...x.expanded, x.current}; - for (final d in open) { - await _load(x, d, force: true); - } - x.cache.removeWhere((k, _) => !open.contains(k)); - x.changed(); - } + // 183: 두 창 모두 (밖에서 지운 파일이 다른 창에 남지 않게) + await _reloadOpen(); case ExplorerButton.play: final t = _targets(pane); final videos = t.where((x) => !vIsDirSync(x) && isVideoFile(x)).toList(); diff --git a/test/explorer_steady_test.dart b/test/explorer_steady_test.dart index 984fdf9..eb925b6 100644 --- a/test/explorer_steady_test.dart +++ b/test/explorer_steady_test.dart @@ -156,6 +156,32 @@ void main() { await settle(tester, () => find.text('f03.txt').evaluate().isEmpty); expect(find.text('f03.txt'), findsNothing); }); + + testWidgets('232: 앱으로 돌아오면 보이는 폴더를 다시 읽는다 (다른 앱에서 지우고 · 만든 것이 바로 보이게)', (tester) async { + c.settings + ..explorerLayout = 'dual' + ..explorerPaths = [left, left]; + tester.view.physicalSize = const Size(1280, 800); + tester.view.devicePixelRatio = 1; + addTearDown(tester.view.reset); + await tester.runAsync(() => tester.pumpWidget(MaterialApp(home: ExplorerPage(c: c)))); + await settle(tester, () => find.text('f03.txt').evaluate().length == 2); + // 다른 앱으로 갔다가 (그사이 밖에서 지우고 만듦) + tester.binding.handleAppLifecycleStateChanged(AppLifecycleState.inactive); + tester.binding.handleAppLifecycleStateChanged(AppLifecycleState.hidden); + await tester.runAsync(() async { + await File(p.join(left, 'f03.txt')).delete(); + await File(p.join(left, '0_made_outside.txt')).writeAsString('m'); // 맨 위에 보이게 (목록이 길다) + }); + await settle(tester, () => false, rounds: 5); + expect(find.text('f03.txt'), findsNWidgets(2), reason: '돌아오기 전에는 그대로'); + // 돌아옴 + tester.binding.handleAppLifecycleStateChanged(AppLifecycleState.inactive); + tester.binding.handleAppLifecycleStateChanged(AppLifecycleState.resumed); + await settle(tester, () => find.text('f03.txt').evaluate().isEmpty && find.text('0_made_outside.txt').evaluate().length == 2); + expect(find.text('f03.txt'), findsNothing); + expect(find.text('0_made_outside.txt'), findsNWidgets(2)); + }); } Finder markOf(String name) => find.descendant(