@@ -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+
442454class _TopicListButton extends StatelessWidget {
443455 const _TopicListButton ({required this .streamId});
444456
0 commit comments