Skip to content

Commit a724bf2

Browse files
home [nfc]: Factor bottom nav into its own widget
Co-authored-by: chrisbobbe <[email protected]>
1 parent 16cb62a commit a724bf2

File tree

1 file changed

+57
-46
lines changed

1 file changed

+57
-46
lines changed

lib/widgets/home.dart

Lines changed: 57 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -87,31 +87,54 @@ class _HomePageState extends State<HomePage> {
8787

8888
@override
8989
Widget build(BuildContext context) {
90-
final zulipLocalizations = ZulipLocalizations.of(context);
91-
9290
const pageBodies = [
9391
(_HomePageTab.inbox, InboxPageBody()),
9492
(_HomePageTab.channels, SubscriptionListPageBody()),
9593
// TODO(#1094): Users
9694
(_HomePageTab.directMessages, RecentDmConversationsPageBody()),
9795
];
9896

99-
_NavigationBarButton button({
100-
required _HomePageTab tab,
101-
required IconData icon,
102-
required String label})
103-
{
104-
return _NavigationBarButton(icon: icon,
105-
label: label,
106-
selected: _tab.value == tab,
107-
onPressed: () {
108-
_tab.value = tab;
109-
});
110-
}
97+
return Scaffold(
98+
appBar: ZulipAppBar(titleSpacing: 16,
99+
title: Text(_currentTabTitle)),
100+
body: Stack(
101+
children: [
102+
for (final (tab, body) in pageBodies)
103+
// TODO(#535): Decide if we find it helpful to use something like
104+
// [SemanticsProperties.namesRoute] to structure this UI better
105+
// for screen-reader software.
106+
Offstage(offstage: tab != _tab.value, child: body),
107+
]),
108+
bottomNavigationBar: _BottomNavBar(tabNotifier: _tab));
109+
}
110+
}
111+
112+
class _BottomNavBar extends StatelessWidget {
113+
const _BottomNavBar({required this.tabNotifier});
114+
115+
final ValueNotifier<_HomePageTab> tabNotifier;
116+
117+
_NavigationBarButton _button({
118+
required _HomePageTab tab,
119+
required IconData icon,
120+
required String label})
121+
{
122+
return _NavigationBarButton(icon: icon,
123+
label: label,
124+
selected: tabNotifier.value == tab,
125+
onPressed: () {
126+
tabNotifier.value = tab;
127+
});
128+
}
129+
130+
@override
131+
Widget build(BuildContext context) {
132+
final designVariables = DesignVariables.of(context);
133+
final zulipLocalizations = ZulipLocalizations.of(context);
111134

112135
// TODO(a11y): add tooltips for these buttons
113136
final navigationBarButtons = [
114-
button(tab: _HomePageTab.inbox,
137+
_button(tab: _HomePageTab.inbox,
115138
icon: ZulipIcons.inbox,
116139
label: zulipLocalizations.inboxPageTitle),
117140
_NavigationBarButton(icon: ZulipIcons.message_feed,
@@ -120,47 +143,35 @@ class _HomePageState extends State<HomePage> {
120143
onPressed: () => Navigator.push(context,
121144
MessageListPage.buildRoute(context: context,
122145
narrow: const CombinedFeedNarrow()))),
123-
button(tab: _HomePageTab.channels,
146+
_button(tab: _HomePageTab.channels,
124147
icon: ZulipIcons.hash_italic,
125148
label: zulipLocalizations.channelsPageTitle),
126149
// TODO(#1094): Users
127-
button(tab: _HomePageTab.directMessages,
150+
_button(tab: _HomePageTab.directMessages,
128151
icon: ZulipIcons.two_person,
129152
label: zulipLocalizations.recentDmConversationsPageTitle),
130153
_NavigationBarButton(icon: ZulipIcons.menu,
131154
label: zulipLocalizations.navBarMenuLabel,
132155
selected: false,
133-
onPressed: () => _showMainMenu(context, tabNotifier: _tab)),
156+
onPressed: () => _showMainMenu(context, tabNotifier: tabNotifier)),
134157
];
135158

136-
final designVariables = DesignVariables.of(context);
137-
return Scaffold(
138-
appBar: ZulipAppBar(titleSpacing: 16,
139-
title: Text(_currentTabTitle)),
140-
body: Stack(
141-
children: [
142-
for (final (tab, body) in pageBodies)
143-
// TODO(#535): Decide if we find it helpful to use something like
144-
// [SemanticsProperties.namesRoute] to structure this UI better
145-
// for screen-reader software.
146-
Offstage(offstage: tab != _tab.value, child: body),
147-
]),
148-
bottomNavigationBar: DecoratedBox(
149-
decoration: BoxDecoration(
150-
border: Border(top: BorderSide(color: designVariables.borderBar)),
151-
color: designVariables.bgBotBar),
152-
child: SafeArea(
153-
child: Center(
154-
heightFactor: 1,
155-
child: ConstrainedBox(
156-
// TODO(design): determine a suitable max width for bottom nav bar
157-
constraints: const BoxConstraints(maxWidth: 600, minHeight: 48),
158-
child: Row(
159-
crossAxisAlignment: CrossAxisAlignment.start,
160-
children: [
161-
for (final navigationBarButton in navigationBarButtons)
162-
Expanded(child: navigationBarButton),
163-
]))))));
159+
return DecoratedBox(
160+
decoration: BoxDecoration(
161+
border: Border(top: BorderSide(color: designVariables.borderBar)),
162+
color: designVariables.bgBotBar),
163+
child: SafeArea(
164+
child: Center(
165+
heightFactor: 1,
166+
child: ConstrainedBox(
167+
// TODO(design): determine a suitable max width for bottom nav bar
168+
constraints: const BoxConstraints(maxWidth: 600, minHeight: 48),
169+
child: Row(
170+
crossAxisAlignment: CrossAxisAlignment.start,
171+
children: [
172+
for (final navigationBarButton in navigationBarButtons)
173+
Expanded(child: navigationBarButton),
174+
])))));
164175
}
165176
}
166177

0 commit comments

Comments
 (0)