@@ -151,13 +151,17 @@ class MessageListPage extends StatefulWidget {
151
151
152
152
/// The [MessageListPageState] above this context in the tree.
153
153
///
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.
158
160
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' );
161
165
return state! ;
162
166
}
163
167
@@ -240,9 +244,7 @@ class _MessageListPageState extends State<MessageListPage> implements MessageLis
240
244
actions.add (_TopicListButton (streamId: streamId));
241
245
}
242
246
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 (
246
248
appBar: ZulipAppBar (
247
249
buildTitle: (willCenterTitle) =>
248
250
MessageListAppBarTitle (narrow: narrow, willCenterTitle: willCenterTitle),
@@ -283,7 +285,30 @@ class _MessageListPageState extends State<MessageListPage> implements MessageLis
283
285
))),
284
286
if (ComposeBox .hasComposeBox (narrow))
285
287
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 ;
287
312
}
288
313
}
289
314
0 commit comments