Skip to content

Commit 084cb2f

Browse files
PIG208chrisbobbe
authored andcommitted
nav [nfc]: Extract some *PageBody widgets
These are extracted because we will later make them accessible as bottom tabs on the HomePage. Among those bottom tabs, the "Users" page (not yet implemented) and MessageListPage are skipped. These are out-of-scope of as now. See Figma for the available tabs: https://www.figma.com/design/1JTNtYo9memgW7vV6d0ygq/Zulip-Mobile?node-id=3307-50151&node-type=frame&t=hGZtzX2QTLse81un-0 Signed-off-by: Zixuan James Li <[email protected]>
1 parent f46187a commit 084cb2f

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)