Skip to content

Commit 0276637

Browse files
chrisbobbegnprice
authored andcommitted
compose: Give MessageListPageState access to topic/content controllers
Then, widgets that have MessageListPageState in their ancestry will be able to set the topic and content inputs as part of managing a quote-and-reply interaction.
1 parent 16950fa commit 0276637

File tree

2 files changed

+38
-9
lines changed

2 files changed

+38
-9
lines changed

lib/widgets/compose_box.dart

+25-8
Original file line numberDiff line numberDiff line change
@@ -851,12 +851,18 @@ class _ComposeBoxLayout extends StatelessWidget {
851851
])))); }
852852
}
853853

854+
abstract class ComposeBoxController<T extends StatefulWidget> extends State<T> {
855+
ComposeTopicController? get topicController;
856+
ComposeContentController get contentController;
857+
FocusNode get contentFocusNode;
858+
}
859+
854860
/// A compose box for use in a stream narrow.
855861
///
856862
/// This offers a text input for the topic to send to,
857863
/// in addition to a text input for the message content.
858864
class _StreamComposeBox extends StatefulWidget {
859-
const _StreamComposeBox({required this.narrow});
865+
const _StreamComposeBox({super.key, required this.narrow});
860866

861867
/// The narrow on view in the message list.
862868
final StreamNarrow narrow;
@@ -865,9 +871,14 @@ class _StreamComposeBox extends StatefulWidget {
865871
State<_StreamComposeBox> createState() => _StreamComposeBoxState();
866872
}
867873

868-
class _StreamComposeBoxState extends State<_StreamComposeBox> {
874+
class _StreamComposeBoxState extends State<_StreamComposeBox> implements ComposeBoxController<_StreamComposeBox> {
875+
@override ComposeTopicController get topicController => _topicController;
869876
final _topicController = ComposeTopicController();
877+
878+
@override ComposeContentController get contentController => _contentController;
870879
final _contentController = ComposeContentController();
880+
881+
@override FocusNode get contentFocusNode => _contentFocusNode;
871882
final _contentFocusNode = FocusNode();
872883

873884
@override
@@ -906,16 +917,21 @@ class _StreamComposeBoxState extends State<_StreamComposeBox> {
906917
}
907918

908919
class _FixedDestinationComposeBox extends StatefulWidget {
909-
const _FixedDestinationComposeBox({required this.narrow});
920+
const _FixedDestinationComposeBox({super.key, required this.narrow});
910921

911922
final SendableNarrow narrow;
912923

913924
@override
914925
State<_FixedDestinationComposeBox> createState() => _FixedDestinationComposeBoxState();
915926
}
916927

917-
class _FixedDestinationComposeBoxState extends State<_FixedDestinationComposeBox> {
928+
class _FixedDestinationComposeBoxState extends State<_FixedDestinationComposeBox> implements ComposeBoxController<_FixedDestinationComposeBox> {
929+
@override ComposeTopicController? get topicController => null;
930+
931+
@override ComposeContentController get contentController => _contentController;
918932
final _contentController = ComposeContentController();
933+
934+
@override FocusNode get contentFocusNode => _contentFocusNode;
919935
final _contentFocusNode = FocusNode();
920936

921937
@override
@@ -945,19 +961,20 @@ class _FixedDestinationComposeBoxState extends State<_FixedDestinationComposeBox
945961
}
946962

947963
class ComposeBox extends StatelessWidget {
948-
const ComposeBox({super.key, required this.narrow});
964+
const ComposeBox({super.key, this.controllerKey, required this.narrow});
949965

966+
final GlobalKey<ComposeBoxController>? controllerKey;
950967
final Narrow narrow;
951968

952969
@override
953970
Widget build(BuildContext context) {
954971
final narrow = this.narrow;
955972
if (narrow is StreamNarrow) {
956-
return _StreamComposeBox(narrow: narrow);
973+
return _StreamComposeBox(key: controllerKey, narrow: narrow);
957974
} else if (narrow is TopicNarrow) {
958-
return _FixedDestinationComposeBox(narrow: narrow);
975+
return _FixedDestinationComposeBox(key: controllerKey, narrow: narrow);
959976
} else if (narrow is DmNarrow) {
960-
return _FixedDestinationComposeBox(narrow: narrow);
977+
return _FixedDestinationComposeBox(key: controllerKey, narrow: narrow);
961978
} else if (narrow is AllMessagesNarrow) {
962979
return const SizedBox.shrink();
963980
} else {

lib/widgets/message_list.dart

+13-1
Original file line numberDiff line numberDiff line change
@@ -22,13 +22,25 @@ class MessageListPage extends StatefulWidget {
2222
builder: (context) => MessageListPage(narrow: narrow));
2323
}
2424

25+
/// A [ComposeBoxController], if this [MessageListPage] offers a compose box.
26+
///
27+
/// Uses the inefficient [BuildContext.findAncestorStateOfType];
28+
/// don't call this in a build method.
29+
static ComposeBoxController? composeBoxControllerOf(BuildContext context) {
30+
final messageListPageState = context.findAncestorStateOfType<_MessageListPageState>();
31+
assert(messageListPageState != null, 'No MessageListPage ancestor');
32+
return messageListPageState!._composeBoxKey.currentState;
33+
}
34+
2535
final Narrow narrow;
2636

2737
@override
2838
State<MessageListPage> createState() => _MessageListPageState();
2939
}
3040

3141
class _MessageListPageState extends State<MessageListPage> {
42+
final GlobalKey<ComposeBoxController> _composeBoxKey = GlobalKey();
43+
3244
@override
3345
Widget build(BuildContext context) {
3446
return Scaffold(
@@ -48,7 +60,7 @@ class _MessageListPageState extends State<MessageListPage> {
4860
child: Expanded(
4961
child: MessageList(narrow: widget.narrow))),
5062

51-
ComposeBox(narrow: widget.narrow),
63+
ComposeBox(controllerKey: _composeBoxKey, narrow: widget.narrow),
5264
]))));
5365
}
5466
}

0 commit comments

Comments
 (0)