Skip to content

Commit 48671b2

Browse files
committed
nav [nfc]: Extract *PageBody widgets
Signed-off-by: Zixuan James Li <[email protected]>
1 parent 152a0e7 commit 48671b2

File tree

3 files changed

+96
-71
lines changed

3 files changed

+96
-71
lines changed

lib/widgets/inbox.dart

Lines changed: 33 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ import 'text.dart';
1414
import 'theme.dart';
1515
import 'unread_count_badge.dart';
1616

17-
class InboxPage extends StatefulWidget {
17+
class InboxPage extends StatelessWidget {
1818
const InboxPage({super.key});
1919

2020
static Route<void> buildRoute({int? accountId, BuildContext? context}) {
@@ -23,10 +23,21 @@ class InboxPage extends StatefulWidget {
2323
}
2424

2525
@override
26-
State<InboxPage> createState() => _InboxPageState();
26+
Widget build(BuildContext context) {
27+
return Scaffold(
28+
appBar: ZulipAppBar(title: const Text('Inbox')),
29+
body: const InboxPageBody());
30+
}
31+
}
32+
33+
class InboxPageBody extends StatefulWidget {
34+
const InboxPageBody({super.key});
35+
36+
@override
37+
State<InboxPageBody> createState() => _InboxPageState();
2738
}
2839

29-
class _InboxPageState extends State<InboxPage> with PerAccountStoreAwareStateMixin<InboxPage> {
40+
class _InboxPageState extends State<InboxPageBody> with PerAccountStoreAwareStateMixin<InboxPageBody> {
3041
Unreads? unreadsModel;
3142
RecentDmConversationsView? recentDmConversationsModel;
3243

@@ -160,27 +171,25 @@ class _InboxPageState extends State<InboxPage> with PerAccountStoreAwareStateMix
160171
sections.add(_StreamSectionData(streamId, countInStream, streamHasMention, topicItems));
161172
}
162173

163-
return Scaffold(
164-
appBar: ZulipAppBar(title: const Text('Inbox')),
165-
body: SafeArea(
166-
// Don't pad the bottom here; we want the list content to do that.
167-
bottom: false,
168-
child: StickyHeaderListView.builder(
169-
itemCount: sections.length,
170-
itemBuilder: (context, index) {
171-
final section = sections[index];
172-
switch (section) {
173-
case _AllDmsSectionData():
174-
return _AllDmsSection(
175-
data: section,
176-
collapsed: allDmsCollapsed,
177-
pageState: this,
178-
);
179-
case _StreamSectionData(:var streamId):
180-
final collapsed = collapsedStreamIds.contains(streamId);
181-
return _StreamSection(data: section, collapsed: collapsed, pageState: this);
182-
}
183-
})));
174+
return SafeArea(
175+
// Don't pad the bottom here; we want the list content to do that.
176+
bottom: false,
177+
child: StickyHeaderListView.builder(
178+
itemCount: sections.length,
179+
itemBuilder: (context, index) {
180+
final section = sections[index];
181+
switch (section) {
182+
case _AllDmsSectionData():
183+
return _AllDmsSection(
184+
data: section,
185+
collapsed: allDmsCollapsed,
186+
pageState: this,
187+
);
188+
case _StreamSectionData(:var streamId):
189+
final collapsed = collapsedStreamIds.contains(streamId);
190+
return _StreamSection(data: section, collapsed: collapsed, pageState: this);
191+
}
192+
}));
184193
}
185194
}
186195

lib/widgets/recent_dm_conversations.dart

Lines changed: 28 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ import 'store.dart';
1313
import 'theme.dart';
1414
import 'unread_count_badge.dart';
1515

16-
class RecentDmConversationsPage extends StatefulWidget {
16+
class RecentDmConversationsPage extends StatelessWidget {
1717
const RecentDmConversationsPage({super.key});
1818

1919
static Route<void> buildRoute({int? accountId, BuildContext? context}) {
@@ -22,10 +22,23 @@ class RecentDmConversationsPage extends StatefulWidget {
2222
}
2323

2424
@override
25-
State<RecentDmConversationsPage> createState() => _RecentDmConversationsPageState();
25+
Widget build(BuildContext context) {
26+
final zulipLocalizations = ZulipLocalizations.of(context);
27+
return Scaffold(
28+
appBar: ZulipAppBar(
29+
title: Text(zulipLocalizations.recentDmConversationsPageTitle)),
30+
body: const RecentDmConversationsPageBody());
31+
}
32+
}
33+
34+
class RecentDmConversationsPageBody extends StatefulWidget {
35+
const RecentDmConversationsPageBody({super.key});
36+
37+
@override
38+
State<RecentDmConversationsPageBody> createState() => _RecentDmConversationsPageBodyState();
2639
}
2740

28-
class _RecentDmConversationsPageState extends State<RecentDmConversationsPage> with PerAccountStoreAwareStateMixin<RecentDmConversationsPage> {
41+
class _RecentDmConversationsPageBodyState extends State<RecentDmConversationsPageBody> with PerAccountStoreAwareStateMixin<RecentDmConversationsPageBody> {
2942
RecentDmConversationsView? model;
3043
Unreads? unreadsModel;
3144

@@ -56,24 +69,19 @@ class _RecentDmConversationsPageState extends State<RecentDmConversationsPage> w
5669

5770
@override
5871
Widget build(BuildContext context) {
59-
final zulipLocalizations = ZulipLocalizations.of(context);
6072
final sorted = model!.sorted;
61-
return Scaffold(
62-
appBar: ZulipAppBar(
63-
title: Text(zulipLocalizations.recentDmConversationsPageTitle)),
64-
body: SafeArea(
65-
// Don't pad the bottom here; we want the list content to do that.
66-
bottom: false,
67-
child: ListView.builder(
68-
itemCount: sorted.length,
69-
itemBuilder: (context, index) {
70-
final narrow = sorted[index];
71-
return RecentDmConversationsItem(
72-
narrow: narrow,
73-
unreadCount: unreadsModel!.countInDmNarrow(narrow),
74-
);
75-
}),
76-
));
73+
return SafeArea(
74+
// Don't pad the bottom here; we want the list content to do that.
75+
bottom: false,
76+
child: ListView.builder(
77+
itemCount: sorted.length,
78+
itemBuilder: (context, index) {
79+
final narrow = sorted[index];
80+
return RecentDmConversationsItem(
81+
narrow: narrow,
82+
unreadCount: unreadsModel!.countInDmNarrow(narrow),
83+
);
84+
}));
7785
}
7886
}
7987

lib/widgets/subscription_list.dart

Lines changed: 35 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ import 'theme.dart';
1313
import 'unread_count_badge.dart';
1414

1515
/// Scrollable listing of subscribed streams.
16-
class SubscriptionListPage extends StatefulWidget {
16+
class SubscriptionListPage extends StatelessWidget {
1717
const SubscriptionListPage({super.key});
1818

1919
static Route<void> buildRoute({int? accountId, BuildContext? context}) {
@@ -22,10 +22,21 @@ class SubscriptionListPage extends StatefulWidget {
2222
}
2323

2424
@override
25-
State<SubscriptionListPage> createState() => _SubscriptionListPageState();
25+
Widget build(BuildContext context) {
26+
return Scaffold(
27+
appBar: ZulipAppBar(title: const Text("Channels")),
28+
body: const SubscriptionListPageBody());
29+
}
30+
}
31+
32+
class SubscriptionListPageBody extends StatefulWidget {
33+
const SubscriptionListPageBody({super.key});
34+
35+
@override
36+
State<SubscriptionListPageBody> createState() => _SubscriptionListPageBodyState();
2637
}
2738

28-
class _SubscriptionListPageState extends State<SubscriptionListPage> with PerAccountStoreAwareStateMixin<SubscriptionListPage> {
39+
class _SubscriptionListPageBodyState extends State<SubscriptionListPageBody> with PerAccountStoreAwareStateMixin<SubscriptionListPageBody> {
2940
Unreads? unreadsModel;
3041

3142
@override
@@ -89,30 +100,27 @@ class _SubscriptionListPageState extends State<SubscriptionListPage> with PerAcc
89100
_sortSubs(pinned);
90101
_sortSubs(unpinned);
91102

92-
return Scaffold(
93-
appBar: ZulipAppBar(title: const Text("Channels")),
94-
body: SafeArea(
95-
// Don't pad the bottom here; we want the list content to do that.
96-
bottom: false,
97-
child: CustomScrollView(
98-
slivers: [
99-
if (pinned.isEmpty && unpinned.isEmpty)
100-
const _NoSubscriptionsItem(),
101-
if (pinned.isNotEmpty) ...[
102-
const _SubscriptionListHeader(label: "Pinned"),
103-
_SubscriptionList(unreadsModel: unreadsModel, subscriptions: pinned),
104-
],
105-
if (unpinned.isNotEmpty) ...[
106-
const _SubscriptionListHeader(label: "Unpinned"),
107-
_SubscriptionList(unreadsModel: unreadsModel, subscriptions: unpinned),
108-
],
109-
110-
// TODO(#188): add button leading to "All Streams" page with ability to subscribe
111-
112-
// This ensures last item in scrollable can settle in an unobstructed area.
113-
const SliverSafeArea(sliver: SliverToBoxAdapter(child: SizedBox.shrink())),
114-
]),
115-
));
103+
return SafeArea(
104+
// Don't pad the bottom here; we want the list content to do that.
105+
bottom: false,
106+
child: CustomScrollView(
107+
slivers: [
108+
if (pinned.isEmpty && unpinned.isEmpty)
109+
const _NoSubscriptionsItem(),
110+
if (pinned.isNotEmpty) ...[
111+
const _SubscriptionListHeader(label: "Pinned"),
112+
_SubscriptionList(unreadsModel: unreadsModel, subscriptions: pinned),
113+
],
114+
if (unpinned.isNotEmpty) ...[
115+
const _SubscriptionListHeader(label: "Unpinned"),
116+
_SubscriptionList(unreadsModel: unreadsModel, subscriptions: unpinned),
117+
],
118+
119+
// TODO(#188): add button leading to "All Streams" page with ability to subscribe
120+
121+
// This ensures last item in scrollable can settle in an unobstructed area.
122+
const SliverSafeArea(sliver: SliverToBoxAdapter(child: SizedBox.shrink())),
123+
]));
116124
}
117125
}
118126

0 commit comments

Comments
 (0)