Skip to content

Commit 13e8b01

Browse files
committed
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 cacb49e commit 13e8b01

File tree

2 files changed

+39
-9
lines changed

2 files changed

+39
-9
lines changed

lib/widgets/compose_box.dart

+25-8
Original file line numberDiff line numberDiff line change
@@ -845,12 +845,18 @@ class _ComposeBoxLayout extends StatelessWidget {
845845
])))); }
846846
}
847847

848+
abstract class ComposeBoxController<T extends StatefulWidget> extends State<T> {
849+
ComposeTopicController? get topicController;
850+
ComposeContentController get contentController;
851+
FocusNode get contentFocusNode;
852+
}
853+
848854
/// A compose box for use in a stream narrow.
849855
///
850856
/// This offers a text input for the topic to send to,
851857
/// in addition to a text input for the message content.
852858
class _StreamComposeBox extends StatefulWidget {
853-
const _StreamComposeBox({required this.narrow});
859+
const _StreamComposeBox({super.key, required this.narrow});
854860

855861
/// The narrow on view in the message list.
856862
final StreamNarrow narrow;
@@ -859,9 +865,14 @@ class _StreamComposeBox extends StatefulWidget {
859865
State<_StreamComposeBox> createState() => _StreamComposeBoxState();
860866
}
861867

862-
class _StreamComposeBoxState extends State<_StreamComposeBox> {
868+
class _StreamComposeBoxState extends State<_StreamComposeBox> implements ComposeBoxController<_StreamComposeBox> {
869+
@override ComposeTopicController get topicController => _topicController;
863870
final _topicController = ComposeTopicController();
871+
872+
@override ComposeContentController get contentController => _contentController;
864873
final _contentController = ComposeContentController();
874+
875+
@override FocusNode get contentFocusNode => _contentFocusNode;
865876
final _contentFocusNode = FocusNode();
866877

867878
@override
@@ -900,16 +911,21 @@ class _StreamComposeBoxState extends State<_StreamComposeBox> {
900911
}
901912

902913
class _FixedDestinationComposeBox extends StatefulWidget {
903-
const _FixedDestinationComposeBox({required this.narrow});
914+
const _FixedDestinationComposeBox({super.key, required this.narrow});
904915

905916
final SendableNarrow narrow;
906917

907918
@override
908919
State<_FixedDestinationComposeBox> createState() => _FixedDestinationComposeBoxState();
909920
}
910921

911-
class _FixedDestinationComposeBoxState extends State<_FixedDestinationComposeBox> {
922+
class _FixedDestinationComposeBoxState extends State<_FixedDestinationComposeBox> implements ComposeBoxController<_FixedDestinationComposeBox> {
923+
@override ComposeTopicController? get topicController => null;
924+
925+
@override ComposeContentController get contentController => _contentController;
912926
final _contentController = ComposeContentController();
927+
928+
@override FocusNode get contentFocusNode => _contentFocusNode;
913929
final _contentFocusNode = FocusNode();
914930

915931
@override
@@ -939,19 +955,20 @@ class _FixedDestinationComposeBoxState extends State<_FixedDestinationComposeBox
939955
}
940956

941957
class ComposeBox extends StatelessWidget {
942-
const ComposeBox({super.key, required this.narrow});
958+
const ComposeBox({super.key, this.controllerKey, required this.narrow});
943959

960+
final GlobalKey<ComposeBoxController>? controllerKey;
944961
final Narrow narrow;
945962

946963
@override
947964
Widget build(BuildContext context) {
948965
final narrow = this.narrow;
949966
if (narrow is StreamNarrow) {
950-
return _StreamComposeBox(narrow: narrow);
967+
return _StreamComposeBox(key: controllerKey, narrow: narrow);
951968
} else if (narrow is TopicNarrow) {
952-
return _FixedDestinationComposeBox(narrow: narrow);
969+
return _FixedDestinationComposeBox(key: controllerKey, narrow: narrow);
953970
} else if (narrow is DmNarrow) {
954-
return _FixedDestinationComposeBox(narrow: narrow);
971+
return _FixedDestinationComposeBox(key: controllerKey, narrow: narrow);
955972
} else if (narrow is AllMessagesNarrow) {
956973
return const SizedBox.shrink();
957974
} else {

lib/widgets/message_list.dart

+14-1
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,19 @@ class MessageListPage extends StatefulWidget {
2929
}
3030

3131
class MessageListPageState extends State<MessageListPage> {
32+
GlobalKey<ComposeBoxController> get composeBoxKey => _composeBoxKey;
33+
final GlobalKey<ComposeBoxController> _composeBoxKey = GlobalKey();
34+
35+
/// A [ComposeBoxController], if this [MessageListPage] offers a compose box.
36+
///
37+
/// Uses the inefficient [BuildContext.findAncestorStateOfType];
38+
/// don't call this in a build method.
39+
static ComposeBoxController? composeBoxControllerOf(BuildContext context) {
40+
final messageListPageState = context.findAncestorStateOfType<MessageListPageState>();
41+
assert(messageListPageState != null, 'No MessageListPageState ancestor');
42+
return messageListPageState!.composeBoxKey.currentState;
43+
}
44+
3245
@override
3346
Widget build(BuildContext context) {
3447
return Scaffold(
@@ -48,7 +61,7 @@ class MessageListPageState extends State<MessageListPage> {
4861
child: Expanded(
4962
child: MessageList(narrow: widget.narrow))),
5063

51-
ComposeBox(narrow: widget.narrow),
64+
ComposeBox(controllerKey: _composeBoxKey, narrow: widget.narrow),
5265
]))));
5366
}
5467
}

0 commit comments

Comments
 (0)