Skip to content

Commit 794544c

Browse files
committed
msglist [nfc]: Provide MessageListPageState via an inherited widget
Soon we'll want to access some state in the build method of a leafward widget, for muted-users. So, follow the TODO on MessageListPage.ancestorOf.
1 parent 96bfe26 commit 794544c

File tree

1 file changed

+35
-10
lines changed

1 file changed

+35
-10
lines changed

lib/widgets/message_list.dart

Lines changed: 35 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)