Skip to content

Commit 19999f4

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 fda6f48 commit 19999f4

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
@@ -819,12 +819,18 @@ class _ComposeBoxLayout extends StatelessWidget {
819819
])))); }
820820
}
821821

822+
abstract class ComposeBoxController<T extends StatefulWidget> extends State<T> {
823+
ComposeTopicController? get topicController;
824+
ComposeContentController get contentController;
825+
FocusNode get contentFocusNode;
826+
}
827+
822828
/// A compose box for use in a stream narrow.
823829
///
824830
/// This offers a text input for the topic to send to,
825831
/// in addition to a text input for the message content.
826832
class _StreamComposeBox extends StatefulWidget {
827-
const _StreamComposeBox({required this.narrow});
833+
const _StreamComposeBox({super.key, required this.narrow});
828834

829835
/// The narrow on view in the message list.
830836
final StreamNarrow narrow;
@@ -833,9 +839,14 @@ class _StreamComposeBox extends StatefulWidget {
833839
State<_StreamComposeBox> createState() => _StreamComposeBoxState();
834840
}
835841

836-
class _StreamComposeBoxState extends State<_StreamComposeBox> {
842+
class _StreamComposeBoxState extends State<_StreamComposeBox> implements ComposeBoxController<_StreamComposeBox> {
843+
@override ComposeTopicController get topicController => _topicController;
837844
final _topicController = ComposeTopicController();
845+
846+
@override ComposeContentController get contentController => _contentController;
838847
final _contentController = ComposeContentController();
848+
849+
@override FocusNode get contentFocusNode => _contentFocusNode;
839850
final _contentFocusNode = FocusNode();
840851

841852
@override
@@ -874,16 +885,21 @@ class _StreamComposeBoxState extends State<_StreamComposeBox> {
874885
}
875886

876887
class _FixedDestinationComposeBox extends StatefulWidget {
877-
const _FixedDestinationComposeBox({required this.narrow});
888+
const _FixedDestinationComposeBox({super.key, required this.narrow});
878889

879890
final SendableNarrow narrow;
880891

881892
@override
882893
State<_FixedDestinationComposeBox> createState() => _FixedDestinationComposeBoxState();
883894
}
884895

885-
class _FixedDestinationComposeBoxState extends State<_FixedDestinationComposeBox> {
896+
class _FixedDestinationComposeBoxState extends State<_FixedDestinationComposeBox> implements ComposeBoxController<_FixedDestinationComposeBox> {
897+
@override ComposeTopicController? get topicController => null;
898+
899+
@override ComposeContentController get contentController => _contentController;
886900
final _contentController = ComposeContentController();
901+
902+
@override FocusNode get contentFocusNode => _contentFocusNode;
887903
final _contentFocusNode = FocusNode();
888904

889905
@override
@@ -913,19 +929,20 @@ class _FixedDestinationComposeBoxState extends State<_FixedDestinationComposeBox
913929
}
914930

915931
class ComposeBox extends StatelessWidget {
916-
const ComposeBox({super.key, required this.narrow});
932+
const ComposeBox({super.key, this.controllerKey, required this.narrow});
917933

934+
final GlobalKey<ComposeBoxController>? controllerKey;
918935
final Narrow narrow;
919936

920937
@override
921938
Widget build(BuildContext context) {
922939
final narrow = this.narrow;
923940
if (narrow is StreamNarrow) {
924-
return _StreamComposeBox(narrow: narrow);
941+
return _StreamComposeBox(key: controllerKey, narrow: narrow);
925942
} else if (narrow is TopicNarrow) {
926-
return _FixedDestinationComposeBox(narrow: narrow);
943+
return _FixedDestinationComposeBox(key: controllerKey, narrow: narrow);
927944
} else if (narrow is DmNarrow) {
928-
return _FixedDestinationComposeBox(narrow: narrow);
945+
return _FixedDestinationComposeBox(key: controllerKey, narrow: narrow);
929946
} else if (narrow is AllMessagesNarrow) {
930947
return const SizedBox.shrink();
931948
} 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)