@@ -1099,12 +1099,37 @@ class _ComposeBoxLayout extends StatelessWidget {
1099
1099
}
1100
1100
}
1101
1101
1102
- abstract class ComposeBoxController <T extends StatefulWidget > extends State <T > {
1103
- ComposeTopicController ? get topicController;
1104
- ComposeContentController get contentController;
1105
- FocusNode get contentFocusNode;
1102
+ sealed class ComposeBoxController {
1103
+ ComposeContentController get contentController => _contentController;
1104
+ final _contentController = ComposeContentController ();
1105
+
1106
+ FocusNode get contentFocusNode => _contentFocusNode;
1107
+ final _contentFocusNode = FocusNode ();
1108
+
1109
+ @mustCallSuper
1110
+ void dispose () {
1111
+ _contentController.dispose ();
1112
+ _contentFocusNode.dispose ();
1113
+ }
1106
1114
}
1107
1115
1116
+ class StreamComposeBoxController extends ComposeBoxController {
1117
+ ComposeTopicController get topicController => _topicController;
1118
+ final _topicController = ComposeTopicController ();
1119
+
1120
+ FocusNode get topicFocusNode => _topicFocusNode;
1121
+ final _topicFocusNode = FocusNode ();
1122
+
1123
+ @override
1124
+ void dispose () {
1125
+ _topicController.dispose ();
1126
+ _topicFocusNode.dispose ();
1127
+ super .dispose ();
1128
+ }
1129
+ }
1130
+
1131
+ class FixedDestinationComposeBoxController extends ComposeBoxController {}
1132
+
1108
1133
/// A compose box for use in a channel narrow.
1109
1134
///
1110
1135
/// This offers a text input for the topic to send to,
@@ -1119,50 +1144,42 @@ class _StreamComposeBox extends StatefulWidget {
1119
1144
State <_StreamComposeBox > createState () => _StreamComposeBoxState ();
1120
1145
}
1121
1146
1122
- class _StreamComposeBoxState extends State <_StreamComposeBox > implements ComposeBoxController <_StreamComposeBox > {
1123
- @override ComposeTopicController get topicController => _topicController;
1124
- final _topicController = ComposeTopicController ();
1125
-
1126
- @override ComposeContentController get contentController => _contentController;
1127
- final _contentController = ComposeContentController ();
1128
-
1129
- @override FocusNode get contentFocusNode => _contentFocusNode;
1130
- final _contentFocusNode = FocusNode ();
1131
-
1132
- FocusNode get topicFocusNode => _topicFocusNode;
1133
- final _topicFocusNode = FocusNode ();
1147
+ class _StreamComposeBoxState extends State <_StreamComposeBox > {
1148
+ StreamComposeBoxController get controller => _controller;
1149
+ final _controller = StreamComposeBoxController ();
1134
1150
1135
1151
@override
1136
1152
void dispose () {
1137
- _topicController.dispose ();
1138
- _contentController.dispose ();
1139
- _contentFocusNode.dispose ();
1140
- _topicFocusNode.dispose ();
1153
+ _controller.dispose ();
1141
1154
super .dispose ();
1142
1155
}
1143
1156
1144
1157
@override
1145
1158
Widget build (BuildContext context) {
1159
+ final StreamComposeBoxController (
1160
+ : topicController, : contentController, : topicFocusNode, : contentFocusNode,
1161
+ ) = controller;
1162
+
1146
1163
return _ComposeBoxLayout (
1147
- contentController: _contentController ,
1148
- contentFocusNode: _contentFocusNode ,
1164
+ contentController: contentController ,
1165
+ contentFocusNode: contentFocusNode ,
1149
1166
topicInput: _TopicInput (
1150
1167
streamId: widget.narrow.streamId,
1151
- controller: _topicController ,
1168
+ controller: topicController ,
1152
1169
focusNode: topicFocusNode,
1153
- contentFocusNode: _contentFocusNode ,
1170
+ contentFocusNode: contentFocusNode ,
1154
1171
),
1155
1172
contentInput: _StreamContentInput (
1156
1173
narrow: widget.narrow,
1157
- topicController: _topicController ,
1158
- controller: _contentController ,
1159
- focusNode: _contentFocusNode ,
1174
+ topicController: topicController ,
1175
+ controller: contentController ,
1176
+ focusNode: contentFocusNode ,
1160
1177
),
1161
1178
sendButton: _SendButton (
1162
- topicController: _topicController ,
1163
- contentController: _contentController ,
1179
+ topicController: topicController ,
1180
+ contentController: contentController ,
1164
1181
getDestination: () => StreamDestination (
1165
- widget.narrow.streamId, _topicController .textNormalized),
1182
+ widget.narrow.streamId, topicController .textNormalized),
1166
1183
));
1167
1184
}
1168
1185
}
@@ -1197,46 +1214,43 @@ class _FixedDestinationComposeBox extends StatefulWidget {
1197
1214
State <_FixedDestinationComposeBox > createState () => _FixedDestinationComposeBoxState ();
1198
1215
}
1199
1216
1200
- class _FixedDestinationComposeBoxState extends State <_FixedDestinationComposeBox > implements ComposeBoxController <_FixedDestinationComposeBox > {
1201
- @override ComposeTopicController ? get topicController => null ;
1202
-
1203
- @override ComposeContentController get contentController => _contentController;
1204
- final _contentController = ComposeContentController ();
1205
-
1206
- @override FocusNode get contentFocusNode => _contentFocusNode;
1207
- final _contentFocusNode = FocusNode ();
1217
+ class _FixedDestinationComposeBoxState extends State <_FixedDestinationComposeBox > {
1218
+ FixedDestinationComposeBoxController get controller => _controller;
1219
+ final _controller = FixedDestinationComposeBoxController ();
1208
1220
1209
1221
@override
1210
1222
void dispose () {
1211
- _contentController.dispose ();
1212
- _contentFocusNode.dispose ();
1223
+ _controller.dispose ();
1213
1224
super .dispose ();
1214
1225
}
1215
1226
1216
1227
@override
1217
1228
Widget build (BuildContext context) {
1229
+ final FixedDestinationComposeBoxController (
1230
+ : contentController, : contentFocusNode,
1231
+ ) = controller;
1232
+
1218
1233
return _ComposeBoxLayout (
1219
- contentController: _contentController ,
1220
- contentFocusNode: _contentFocusNode ,
1234
+ contentController: contentController ,
1235
+ contentFocusNode: contentFocusNode ,
1221
1236
topicInput: null ,
1222
1237
contentInput: _FixedDestinationContentInput (
1223
1238
narrow: widget.narrow,
1224
- controller: _contentController ,
1225
- focusNode: _contentFocusNode ,
1239
+ controller: contentController ,
1240
+ focusNode: contentFocusNode ,
1226
1241
),
1227
1242
sendButton: _SendButton (
1228
1243
topicController: null ,
1229
- contentController: _contentController ,
1244
+ contentController: contentController ,
1230
1245
getDestination: () => widget.narrow.destination,
1231
1246
));
1232
1247
}
1233
1248
}
1234
1249
1235
- class ComposeBox extends StatelessWidget {
1236
- ComposeBox ({super .key, this .controllerKey, required this .narrow})
1250
+ class ComposeBox extends StatefulWidget {
1251
+ ComposeBox ({super .key, required this .narrow})
1237
1252
: assert (ComposeBox .hasComposeBox (narrow));
1238
1253
1239
- final GlobalKey <ComposeBoxController >? controllerKey;
1240
1254
final Narrow narrow;
1241
1255
1242
1256
static bool hasComposeBox (Narrow narrow) {
@@ -1253,10 +1267,30 @@ class ComposeBox extends StatelessWidget {
1253
1267
}
1254
1268
}
1255
1269
1270
+ @override
1271
+ State <ComposeBox > createState () => _ComposeBoxState ();
1272
+ }
1273
+
1274
+ /// The interface for the state of a [ComposeBox] .
1275
+ abstract class ComposeBoxState extends State <ComposeBox > {
1276
+ ComposeBoxController ? get controller;
1277
+ }
1278
+
1279
+ class _ComposeBoxState extends State <ComposeBox > implements ComposeBoxState {
1280
+ @override ComposeBoxController ? get controller {
1281
+ final forStream = _streamComposeBoxControllerKey.currentState? .controller;
1282
+ final forFixedDestination = _fixedDestinationComposeBoxControllerKey.currentState? .controller;
1283
+ assert (forStream == null || forFixedDestination == null );
1284
+ // Both can be null (error-banner case).
1285
+ return forStream ?? forFixedDestination;
1286
+ }
1287
+ final _streamComposeBoxControllerKey = GlobalKey <_StreamComposeBoxState >();
1288
+ final _fixedDestinationComposeBoxControllerKey = GlobalKey <_FixedDestinationComposeBoxState >();
1289
+
1256
1290
Widget ? _errorBanner (BuildContext context) {
1257
1291
final store = PerAccountStoreWidget .of (context);
1258
1292
final selfUser = store.users[store.selfUserId]! ;
1259
- switch (narrow) {
1293
+ switch (widget. narrow) {
1260
1294
case ChannelNarrow (: final streamId):
1261
1295
case TopicNarrow (: final streamId):
1262
1296
final channel = store.streams[streamId];
@@ -1287,14 +1321,16 @@ class ComposeBox extends StatelessWidget {
1287
1321
return _ComposeBoxContainer (child: errorBanner);
1288
1322
}
1289
1323
1290
- final narrow = this .narrow;
1324
+ final narrow = widget .narrow;
1291
1325
switch (narrow) {
1292
1326
case ChannelNarrow ():
1293
- return _StreamComposeBox (key: controllerKey , narrow: narrow);
1327
+ return _StreamComposeBox (key: _streamComposeBoxControllerKey , narrow: narrow);
1294
1328
case TopicNarrow ():
1295
- return _FixedDestinationComposeBox (key: controllerKey, narrow: narrow);
1329
+ return _FixedDestinationComposeBox (key: _fixedDestinationComposeBoxControllerKey,
1330
+ narrow: narrow);
1296
1331
case DmNarrow ():
1297
- return _FixedDestinationComposeBox (key: controllerKey, narrow: narrow);
1332
+ return _FixedDestinationComposeBox (key: _fixedDestinationComposeBoxControllerKey,
1333
+ narrow: narrow);
1298
1334
case CombinedFeedNarrow ():
1299
1335
case MentionsNarrow ():
1300
1336
case StarredMessagesNarrow ():
0 commit comments