From 493b0804946ef1e6b6786478ce87c1d9cd6c9058 Mon Sep 17 00:00:00 2001 From: Felipe Bueno Date: Tue, 11 Jun 2024 22:08:13 -0300 Subject: [PATCH] 1.3.4+40: Fix "Navigating to or from a comment item is causing the PostPage to rebuild, loosing the state" --- lib/views/pages/post/post_page.dart | 112 +++++++++++++++++----------- pubspec.yaml | 2 +- 2 files changed, 69 insertions(+), 45 deletions(-) diff --git a/lib/views/pages/post/post_page.dart b/lib/views/pages/post/post_page.dart index 1da6e2f..81ee93f 100644 --- a/lib/views/pages/post/post_page.dart +++ b/lib/views/pages/post/post_page.dart @@ -19,64 +19,88 @@ class PostPage extends StatefulWidget { } class _PostPageState extends State { + Future? _postFuture; + Post? _post; + bool _isInitialized = false; + + @override + void didChangeDependencies() { + super.didChangeDependencies(); + + // Fetch route arguments only once + // Fix https://github.com/felipebueno/stacker_news/issues/18 + // TODO: Apply the fix on all pages and widgets that are using ModdalRoute + if (!_isInitialized) { + final post = ModalRoute.of(context)?.settings.arguments as Post; + _post = post; + _postFuture = _fetchPostDetails(post.id ?? ''); + _isInitialized = true; + } + } + Future _fetchPostDetails(String id) async { return await locator().fetchPostDetails(id); } @override Widget build(BuildContext context) { - final post = ModalRoute.of(context)?.settings.arguments as Post; - return GenericPageScaffold( - title: post.pageTitle ?? '#${post.id}', - body: FutureBuilder( - future: _fetchPostDetails(post.id ?? ''), - builder: (context, snapshot) { - if (snapshot.connectionState == ConnectionState.waiting || - !snapshot.hasData) { - return const Center(child: CircularProgressIndicator()); - } - - if (snapshot.hasError) { - final err = snapshot.error.toString(); - Utils.showError(err); + title: _post == null ? 'Loading...' : _post!.pageTitle ?? '#${_post!.id}', + body: _post == null + ? const Center(child: CircularProgressIndicator()) + : FutureBuilder( + future: _postFuture, + builder: (context, snapshot) { + if (snapshot.connectionState == ConnectionState.waiting || + !snapshot.hasData) { + return const Center(child: CircularProgressIndicator()); + } - return PostListError(err); - } + if (snapshot.hasError) { + final err = snapshot.error.toString(); + Utils.showError(err); - final item = snapshot.data as Post; + return PostListError(err); + } - final comments = item.comments ?? []; + final item = snapshot.data as Post; + final comments = item.comments ?? []; - return RefreshIndicator( - onRefresh: () async { - setState(() {}); - }, - child: ListView.separated( - itemBuilder: (context, index) { - if (index == 0) { - return Column( - crossAxisAlignment: CrossAxisAlignment.end, - children: [ - PostItem(item, isCommentsPage: true), - ReplyField( - item, - onCommentCreated: () { - setState(() {}); - }, - ), - ], - ); - } + return RefreshIndicator( + onRefresh: () async { + setState(() { + _postFuture = _fetchPostDetails(_post!.id ?? ''); + }); + }, + child: ListView.separated( + addAutomaticKeepAlives: true, + itemBuilder: (context, index) { + if (index == 0) { + return Column( + crossAxisAlignment: CrossAxisAlignment.end, + children: [ + PostItem(item, isCommentsPage: true), + ReplyField( + item, + onCommentCreated: () { + setState(() { + _postFuture = + _fetchPostDetails(_post!.id ?? ''); + }); + }, + ), + ], + ); + } - return CommentItem(comments[index - 1]); + return CommentItem(comments[index - 1]); + }, + separatorBuilder: (context, index) => const Divider(), + itemCount: comments.length + 1, + ), + ); }, - separatorBuilder: (context, index) => const Divider(), - itemCount: comments.length + 1, ), - ); - }, - ), ); } } diff --git a/pubspec.yaml b/pubspec.yaml index 2143dc4..1f4c18c 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -11,7 +11,7 @@ description: A new Flutter project. # In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion. # Read more about iOS versioning at # https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html -version: 1.3.3+39 +version: 1.3.4+40 environment: sdk: ">=3.4.0 <4.0.0"