Skip to content

Commit ac6c750

Browse files
committed
msglist [nfc]: Move _buildAppBar to a widget-like class
Conceptually this should be a widget, but can't quite be, for the reasons explained in the comment. Still we can organize the code in nearly the same way as if it were a widget.
1 parent 30989af commit ac6c750

File tree

1 file changed

+82
-70
lines changed

1 file changed

+82
-70
lines changed

lib/widgets/message_list.dart

Lines changed: 82 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -281,75 +281,6 @@ class _MessageListPageState extends State<MessageListPage> implements MessageLis
281281
});
282282
}
283283

284-
AppBar _buildAppBar(BuildContext context) {
285-
final store = PerAccountStoreWidget.of(context);
286-
final messageListTheme = MessageListTheme.of(context);
287-
final zulipLocalizations = ZulipLocalizations.of(context);
288-
289-
final Color? appBarBackgroundColor;
290-
bool removeAppBarBottomBorder = false;
291-
switch(narrow) {
292-
case CombinedFeedNarrow():
293-
case MentionsNarrow():
294-
case StarredMessagesNarrow():
295-
case KeywordSearchNarrow():
296-
appBarBackgroundColor = null; // i.e., inherit
297-
298-
case ChannelNarrow(:final streamId):
299-
case TopicNarrow(:final streamId):
300-
final subscription = store.subscriptions[streamId];
301-
appBarBackgroundColor =
302-
colorSwatchFor(context, subscription).barBackground;
303-
// All recipient headers will match this color; remove distracting line
304-
// (but are recipient headers even needed for topic narrows?)
305-
removeAppBarBottomBorder = true;
306-
307-
case DmNarrow():
308-
appBarBackgroundColor = messageListTheme.dmRecipientHeaderBg;
309-
// All recipient headers will match this color; remove distracting line
310-
// (but are recipient headers even needed?)
311-
removeAppBarBottomBorder = true;
312-
}
313-
314-
List<Widget> actions = [];
315-
switch (narrow) {
316-
case CombinedFeedNarrow():
317-
case MentionsNarrow():
318-
case StarredMessagesNarrow():
319-
case KeywordSearchNarrow():
320-
case DmNarrow():
321-
break;
322-
case ChannelNarrow(:final streamId):
323-
actions.add(_TopicListButton(streamId: streamId));
324-
case TopicNarrow(:final streamId):
325-
actions.add(IconButton(
326-
icon: const Icon(ZulipIcons.message_feed),
327-
tooltip: zulipLocalizations.channelFeedButtonTooltip,
328-
onPressed: () => Navigator.push(context,
329-
MessageListPage.buildRoute(context: context,
330-
narrow: ChannelNarrow(streamId)))));
331-
actions.add(_TopicListButton(streamId: streamId));
332-
}
333-
334-
return ZulipAppBar(
335-
centerTitle: switch (narrow) {
336-
CombinedFeedNarrow() || ChannelNarrow()
337-
|| TopicNarrow() || DmNarrow()
338-
|| MentionsNarrow() || StarredMessagesNarrow()
339-
=> null,
340-
KeywordSearchNarrow()
341-
=> false,
342-
},
343-
buildTitle: (willCenterTitle) =>
344-
MessageListAppBarTitle(narrow: narrow, willCenterTitle: willCenterTitle),
345-
actions: actions,
346-
backgroundColor: appBarBackgroundColor,
347-
shape: removeAppBarBottomBorder
348-
? const Border()
349-
: null, // i.e., inherit
350-
);
351-
}
352-
353284
@override
354285
Widget build(BuildContext context) {
355286
final Anchor initAnchor;
@@ -364,7 +295,7 @@ class _MessageListPageState extends State<MessageListPage> implements MessageLis
364295
}
365296

366297
Widget result = Scaffold(
367-
appBar: _buildAppBar(context),
298+
appBar: _MessageListAppBar.build(context, narrow: narrow),
368299
// TODO question for Vlad: for a stream view, should we set the Scaffold's
369300
// [backgroundColor] based on stream color, as in this frame:
370301
// https://www.figma.com/file/1JTNtYo9memgW7vV6d0ygq/Zulip-Mobile?node-id=132%3A9684&mode=dev
@@ -439,6 +370,87 @@ class _RevealedMutedMessagesProvider extends InheritedNotifier<RevealedMutedMess
439370
RevealedMutedMessagesState get state => notifier!;
440371
}
441372

373+
// Conceptually this should be a widget class. But it needs to be a
374+
// PreferredSizeWidget, with the `preferredSize` that the underlying AppBar
375+
// will have... and there's currently no good way to get that value short of
376+
// constructing the whole AppBar widget with all its properties.
377+
// So this has to be built eagerly by its parent's build method,
378+
// making it a build function rather than a widget. Discussion:
379+
// https://github.com/zulip/zulip-flutter/pull/1662#discussion_r2183471883
380+
// Still we can organize it on a class, with the name the widget would have.
381+
// TODO(upstream): AppBar should expose a bit more API so that it's possible
382+
// to customize by composition in a reasonable way.
383+
abstract class _MessageListAppBar {
384+
static AppBar build(BuildContext context, {required Narrow narrow}) {
385+
final store = PerAccountStoreWidget.of(context);
386+
final messageListTheme = MessageListTheme.of(context);
387+
final zulipLocalizations = ZulipLocalizations.of(context);
388+
389+
final Color? appBarBackgroundColor;
390+
bool removeAppBarBottomBorder = false;
391+
switch(narrow) {
392+
case CombinedFeedNarrow():
393+
case MentionsNarrow():
394+
case StarredMessagesNarrow():
395+
case KeywordSearchNarrow():
396+
appBarBackgroundColor = null; // i.e., inherit
397+
398+
case ChannelNarrow(:final streamId):
399+
case TopicNarrow(:final streamId):
400+
final subscription = store.subscriptions[streamId];
401+
appBarBackgroundColor =
402+
colorSwatchFor(context, subscription).barBackground;
403+
// All recipient headers will match this color; remove distracting line
404+
// (but are recipient headers even needed for topic narrows?)
405+
removeAppBarBottomBorder = true;
406+
407+
case DmNarrow():
408+
appBarBackgroundColor = messageListTheme.dmRecipientHeaderBg;
409+
// All recipient headers will match this color; remove distracting line
410+
// (but are recipient headers even needed?)
411+
removeAppBarBottomBorder = true;
412+
}
413+
414+
List<Widget> actions = [];
415+
switch (narrow) {
416+
case CombinedFeedNarrow():
417+
case MentionsNarrow():
418+
case StarredMessagesNarrow():
419+
case KeywordSearchNarrow():
420+
case DmNarrow():
421+
break;
422+
case ChannelNarrow(:final streamId):
423+
actions.add(_TopicListButton(streamId: streamId));
424+
case TopicNarrow(:final streamId):
425+
actions.add(IconButton(
426+
icon: const Icon(ZulipIcons.message_feed),
427+
tooltip: zulipLocalizations.channelFeedButtonTooltip,
428+
onPressed: () => Navigator.push(context,
429+
MessageListPage.buildRoute(context: context,
430+
narrow: ChannelNarrow(streamId)))));
431+
actions.add(_TopicListButton(streamId: streamId));
432+
}
433+
434+
return ZulipAppBar(
435+
centerTitle: switch (narrow) {
436+
CombinedFeedNarrow() || ChannelNarrow()
437+
|| TopicNarrow() || DmNarrow()
438+
|| MentionsNarrow() || StarredMessagesNarrow()
439+
=> null,
440+
KeywordSearchNarrow()
441+
=> false,
442+
},
443+
buildTitle: (willCenterTitle) =>
444+
MessageListAppBarTitle(narrow: narrow, willCenterTitle: willCenterTitle),
445+
actions: actions,
446+
backgroundColor: appBarBackgroundColor,
447+
shape: removeAppBarBottomBorder
448+
? const Border()
449+
: null, // i.e., inherit
450+
);
451+
}
452+
}
453+
442454
class _TopicListButton extends StatelessWidget {
443455
const _TopicListButton({required this.streamId});
444456

0 commit comments

Comments
 (0)