diff --git a/lib/ui/pages/landing_page/landing_page.dart b/lib/ui/pages/landing_page/landing_page.dart index 1c0ac34a..59860bfd 100644 --- a/lib/ui/pages/landing_page/landing_page.dart +++ b/lib/ui/pages/landing_page/landing_page.dart @@ -39,6 +39,8 @@ class _LandingPageState extends ConsumerState { late ProjectDatabase database; late IFileService fileService; late IImageService imageService; + Future>? _projectsFuture; + ProjectDatabase? _projectsLoadedFrom; @override void initState() { @@ -96,9 +98,15 @@ class _LandingPageState extends ConsumerState { return database.projectDAO.getProjects(); } + void _refreshProjectsFuture() { + _projectsFuture = _getProjects(); + } + Future _navigateToPocketPaint() async { await Navigator.pushNamed(context, '/PocketPaint'); - if (mounted){setState(() {});} + if (mounted) { + setState(_refreshProjectsFuture); + } } Future _loadProject(IOHandler ioHandler, Project project) async { @@ -141,7 +149,13 @@ class _LandingPageState extends ConsumerState { final db = ref.watch(ProjectDatabase.provider); db.when( - data: (value) => database = value, + data: (value) { + database = value; + if (!identical(_projectsLoadedFrom, value)) { + _projectsLoadedFrom = value; + _refreshProjectsFuture(); + } + }, error: (err, stacktrace) => ToastUtils.showShortToast(message: 'Error: $err'), loading: () {}, @@ -158,7 +172,7 @@ class _LandingPageState extends ConsumerState { actions: const [MainOverflowMenu()], ), body: FutureBuilder( - future: _getProjects(), + future: _projectsFuture, builder: (BuildContext context, AsyncSnapshot> snapshot) { if (snapshot.connectionState == ConnectionState.done && snapshot.hasData) { diff --git a/test/widget/landing_page/landing_page_test.dart b/test/widget/landing_page/landing_page_test.dart index 68c5f244..07442f32 100644 --- a/test/widget/landing_page/landing_page_test.dart +++ b/test/widget/landing_page/landing_page_test.dart @@ -1,3 +1,4 @@ +import 'dart:async'; import 'dart:io'; import 'dart:ui' as ui; @@ -738,4 +739,28 @@ void main() { expect(find.byType(CircularProgressIndicator), findsOneWidget); }, ); + + testWidgets( + 'Should reuse the projects future across rebuilds while the list is loading', + (tester) async { + final projectsCompleter = Completer>(); + when(database.projectDAO).thenReturn(dao); + when(dao.getProjects()).thenAnswer((_) => projectsCompleter.future); + + await tester.pumpWidget(sut); + await tester.pump(); + + expect(find.byType(CircularProgressIndicator), findsWidgets); + + await tester.pump(); + await tester.pump(const Duration(milliseconds: 16)); + + expect(find.byType(CircularProgressIndicator), findsWidgets); + + projectsCompleter.complete([]); + await tester.pumpAndSettle(); + + verify(dao.getProjects()).called(1); + }, + ); }