@@ -151,13 +151,17 @@ class MessageListPage extends StatefulWidget {
151151
152152 /// The [MessageListPageState] above this context in the tree.
153153 ///
154- /// Uses the inefficient [BuildContext.findAncestorStateOfType] ;
155- /// don't call this in a build method.
156- // If we do find ourselves wanting this in a build method, it won't be hard
157- // to enable that: we'd just need to add an [InheritedWidget] here.
154+ /// Uses the efficient [BuildContext.dependOnInheritedWidgetOfExactType] ,
155+ /// so this may be called in a build method.
156+ ///
157+ /// Because this uses [BuildContext.dependOnInheritedWidgetOfExactType] ,
158+ /// it creates a dependency, and [context] will rebuild when the underlying
159+ /// [State.setState] is called.
158160 static MessageListPageState ancestorOf (BuildContext context) {
159- final state = context.findAncestorStateOfType <_MessageListPageState >();
160- assert (state != null , 'No MessageListPage ancestor' );
161+ final state = context
162+ .dependOnInheritedWidgetOfExactType <_MessageListPageInheritedWidget >()
163+ ? .state;
164+ assert (state != null , 'No _MessageListPageInheritedWidget ancestor' );
161165 return state! ;
162166 }
163167
@@ -240,9 +244,7 @@ class _MessageListPageState extends State<MessageListPage> implements MessageLis
240244 actions.add (_TopicListButton (streamId: streamId));
241245 }
242246
243- // Insert a PageRoot here, to provide a context that can be used for
244- // MessageListPage.ancestorOf.
245- return PageRoot (child: Scaffold (
247+ Widget result = Scaffold (
246248 appBar: ZulipAppBar (
247249 buildTitle: (willCenterTitle) =>
248250 MessageListAppBarTitle (narrow: narrow, willCenterTitle: willCenterTitle),
@@ -283,7 +285,30 @@ class _MessageListPageState extends State<MessageListPage> implements MessageLis
283285 ))),
284286 if (ComposeBox .hasComposeBox (narrow))
285287 ComposeBox (key: _composeBoxKey, narrow: narrow)
286- ]))));
288+ ])));
289+
290+ // Insert a PageRoot here (under _MessageListPageInheritedWidget),
291+ // to provide a context that can be used for MessageListPage.ancestorOf.
292+ result = PageRoot (child: result);
293+
294+ return _MessageListPageInheritedWidget (this , child: result);
295+ }
296+ }
297+
298+ /// An [InheritedWidget] to provide [MessageListPageState] to leafward widgets.
299+ class _MessageListPageInheritedWidget extends InheritedWidget {
300+ const _MessageListPageInheritedWidget (
301+ this .state, {
302+ required super .child,
303+ });
304+
305+ final MessageListPageState state;
306+
307+ @override
308+ bool updateShouldNotify (covariant _MessageListPageInheritedWidget oldWidget) {
309+ // Ensure that dependent elements using [MessageListPage.ancestorOf]
310+ // always rebuild when _MessageListPageState.setState is called.
311+ return true ;
287312 }
288313}
289314
0 commit comments