Skip to content

Commit 493b080

Browse files
committed
1.3.4+40: Fix "Navigating to or from a comment item is causing the PostPage to rebuild, loosing the state"
1 parent fe318cd commit 493b080

File tree

2 files changed

+69
-45
lines changed

2 files changed

+69
-45
lines changed

lib/views/pages/post/post_page.dart

Lines changed: 68 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -19,64 +19,88 @@ class PostPage extends StatefulWidget {
1919
}
2020

2121
class _PostPageState extends State<PostPage> {
22+
Future<Post>? _postFuture;
23+
Post? _post;
24+
bool _isInitialized = false;
25+
26+
@override
27+
void didChangeDependencies() {
28+
super.didChangeDependencies();
29+
30+
// Fetch route arguments only once
31+
// Fix https://github.com/felipebueno/stacker_news/issues/18
32+
// TODO: Apply the fix on all pages and widgets that are using ModdalRoute
33+
if (!_isInitialized) {
34+
final post = ModalRoute.of(context)?.settings.arguments as Post;
35+
_post = post;
36+
_postFuture = _fetchPostDetails(post.id ?? '');
37+
_isInitialized = true;
38+
}
39+
}
40+
2241
Future<Post> _fetchPostDetails(String id) async {
2342
return await locator<SNApiClient>().fetchPostDetails(id);
2443
}
2544

2645
@override
2746
Widget build(BuildContext context) {
28-
final post = ModalRoute.of(context)?.settings.arguments as Post;
29-
3047
return GenericPageScaffold(
31-
title: post.pageTitle ?? '#${post.id}',
32-
body: FutureBuilder(
33-
future: _fetchPostDetails(post.id ?? ''),
34-
builder: (context, snapshot) {
35-
if (snapshot.connectionState == ConnectionState.waiting ||
36-
!snapshot.hasData) {
37-
return const Center(child: CircularProgressIndicator());
38-
}
39-
40-
if (snapshot.hasError) {
41-
final err = snapshot.error.toString();
42-
Utils.showError(err);
48+
title: _post == null ? 'Loading...' : _post!.pageTitle ?? '#${_post!.id}',
49+
body: _post == null
50+
? const Center(child: CircularProgressIndicator())
51+
: FutureBuilder(
52+
future: _postFuture,
53+
builder: (context, snapshot) {
54+
if (snapshot.connectionState == ConnectionState.waiting ||
55+
!snapshot.hasData) {
56+
return const Center(child: CircularProgressIndicator());
57+
}
4358

44-
return PostListError(err);
45-
}
59+
if (snapshot.hasError) {
60+
final err = snapshot.error.toString();
61+
Utils.showError(err);
4662

47-
final item = snapshot.data as Post;
63+
return PostListError(err);
64+
}
4865

49-
final comments = item.comments ?? [];
66+
final item = snapshot.data as Post;
67+
final comments = item.comments ?? [];
5068

51-
return RefreshIndicator(
52-
onRefresh: () async {
53-
setState(() {});
54-
},
55-
child: ListView.separated(
56-
itemBuilder: (context, index) {
57-
if (index == 0) {
58-
return Column(
59-
crossAxisAlignment: CrossAxisAlignment.end,
60-
children: [
61-
PostItem(item, isCommentsPage: true),
62-
ReplyField(
63-
item,
64-
onCommentCreated: () {
65-
setState(() {});
66-
},
67-
),
68-
],
69-
);
70-
}
69+
return RefreshIndicator(
70+
onRefresh: () async {
71+
setState(() {
72+
_postFuture = _fetchPostDetails(_post!.id ?? '');
73+
});
74+
},
75+
child: ListView.separated(
76+
addAutomaticKeepAlives: true,
77+
itemBuilder: (context, index) {
78+
if (index == 0) {
79+
return Column(
80+
crossAxisAlignment: CrossAxisAlignment.end,
81+
children: [
82+
PostItem(item, isCommentsPage: true),
83+
ReplyField(
84+
item,
85+
onCommentCreated: () {
86+
setState(() {
87+
_postFuture =
88+
_fetchPostDetails(_post!.id ?? '');
89+
});
90+
},
91+
),
92+
],
93+
);
94+
}
7195

72-
return CommentItem(comments[index - 1]);
96+
return CommentItem(comments[index - 1]);
97+
},
98+
separatorBuilder: (context, index) => const Divider(),
99+
itemCount: comments.length + 1,
100+
),
101+
);
73102
},
74-
separatorBuilder: (context, index) => const Divider(),
75-
itemCount: comments.length + 1,
76103
),
77-
);
78-
},
79-
),
80104
);
81105
}
82106
}

pubspec.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ description: A new Flutter project.
1111
# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion.
1212
# Read more about iOS versioning at
1313
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
14-
version: 1.3.3+39
14+
version: 1.3.4+40
1515

1616
environment:
1717
sdk: ">=3.4.0 <4.0.0"

0 commit comments

Comments
 (0)