@@ -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
+ }
1114
+ }
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
+ }
1106
1129
}
1107
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,49 +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 ();
1153
+ _controller.dispose ();
1140
1154
super .dispose ();
1141
1155
}
1142
1156
1143
1157
@override
1144
1158
Widget build (BuildContext context) {
1159
+ final StreamComposeBoxController (
1160
+ : topicController, : contentController, : topicFocusNode, : contentFocusNode,
1161
+ ) = controller;
1162
+
1145
1163
return _ComposeBoxLayout (
1146
- contentController: _contentController ,
1147
- contentFocusNode: _contentFocusNode ,
1164
+ contentController: contentController ,
1165
+ contentFocusNode: contentFocusNode ,
1148
1166
topicInput: _TopicInput (
1149
1167
streamId: widget.narrow.streamId,
1150
- controller: _topicController ,
1168
+ controller: topicController ,
1151
1169
focusNode: topicFocusNode,
1152
- contentFocusNode: _contentFocusNode ,
1170
+ contentFocusNode: contentFocusNode ,
1153
1171
),
1154
1172
contentInput: _StreamContentInput (
1155
1173
narrow: widget.narrow,
1156
- topicController: _topicController ,
1157
- controller: _contentController ,
1158
- focusNode: _contentFocusNode ,
1174
+ topicController: topicController ,
1175
+ controller: contentController ,
1176
+ focusNode: contentFocusNode ,
1159
1177
),
1160
1178
sendButton: _SendButton (
1161
- topicController: _topicController ,
1162
- contentController: _contentController ,
1179
+ topicController: topicController ,
1180
+ contentController: contentController ,
1163
1181
getDestination: () => StreamDestination (
1164
- widget.narrow.streamId, _topicController .textNormalized),
1182
+ widget.narrow.streamId, topicController .textNormalized),
1165
1183
));
1166
1184
}
1167
1185
}
@@ -1196,46 +1214,43 @@ class _FixedDestinationComposeBox extends StatefulWidget {
1196
1214
State <_FixedDestinationComposeBox > createState () => _FixedDestinationComposeBoxState ();
1197
1215
}
1198
1216
1199
- class _FixedDestinationComposeBoxState extends State <_FixedDestinationComposeBox > implements ComposeBoxController <_FixedDestinationComposeBox > {
1200
- @override ComposeTopicController ? get topicController => null ;
1201
-
1202
- @override ComposeContentController get contentController => _contentController;
1203
- final _contentController = ComposeContentController ();
1204
-
1205
- @override FocusNode get contentFocusNode => _contentFocusNode;
1206
- final _contentFocusNode = FocusNode ();
1217
+ class _FixedDestinationComposeBoxState extends State <_FixedDestinationComposeBox > {
1218
+ FixedDestinationComposeBoxController get controller => _controller;
1219
+ final _controller = FixedDestinationComposeBoxController ();
1207
1220
1208
1221
@override
1209
1222
void dispose () {
1210
- _contentController.dispose ();
1211
- _contentFocusNode.dispose ();
1223
+ _controller.dispose ();
1212
1224
super .dispose ();
1213
1225
}
1214
1226
1215
1227
@override
1216
1228
Widget build (BuildContext context) {
1229
+ final FixedDestinationComposeBoxController (
1230
+ : contentController, : contentFocusNode,
1231
+ ) = controller;
1232
+
1217
1233
return _ComposeBoxLayout (
1218
- contentController: _contentController ,
1219
- contentFocusNode: _contentFocusNode ,
1234
+ contentController: contentController ,
1235
+ contentFocusNode: contentFocusNode ,
1220
1236
topicInput: null ,
1221
1237
contentInput: _FixedDestinationContentInput (
1222
1238
narrow: widget.narrow,
1223
- controller: _contentController ,
1224
- focusNode: _contentFocusNode ,
1239
+ controller: contentController ,
1240
+ focusNode: contentFocusNode ,
1225
1241
),
1226
1242
sendButton: _SendButton (
1227
1243
topicController: null ,
1228
- contentController: _contentController ,
1244
+ contentController: contentController ,
1229
1245
getDestination: () => widget.narrow.destination,
1230
1246
));
1231
1247
}
1232
1248
}
1233
1249
1234
- class ComposeBox extends StatelessWidget {
1235
- ComposeBox ({super .key, this .controllerKey, required this .narrow})
1250
+ class ComposeBox extends StatefulWidget {
1251
+ ComposeBox ({super .key, required this .narrow})
1236
1252
: assert (ComposeBox .hasComposeBox (narrow));
1237
1253
1238
- final GlobalKey <ComposeBoxController >? controllerKey;
1239
1254
final Narrow narrow;
1240
1255
1241
1256
static bool hasComposeBox (Narrow narrow) {
@@ -1252,10 +1267,30 @@ class ComposeBox extends StatelessWidget {
1252
1267
}
1253
1268
}
1254
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
+
1255
1290
Widget ? _errorBanner (BuildContext context) {
1256
1291
final store = PerAccountStoreWidget .of (context);
1257
1292
final selfUser = store.users[store.selfUserId]! ;
1258
- switch (narrow) {
1293
+ switch (widget. narrow) {
1259
1294
case ChannelNarrow (: final streamId):
1260
1295
case TopicNarrow (: final streamId):
1261
1296
final channel = store.streams[streamId];
@@ -1286,14 +1321,16 @@ class ComposeBox extends StatelessWidget {
1286
1321
return _ComposeBoxContainer (child: errorBanner);
1287
1322
}
1288
1323
1289
- final narrow = this .narrow;
1324
+ final narrow = widget .narrow;
1290
1325
switch (narrow) {
1291
1326
case ChannelNarrow ():
1292
- return _StreamComposeBox (key: controllerKey , narrow: narrow);
1327
+ return _StreamComposeBox (key: _streamComposeBoxControllerKey , narrow: narrow);
1293
1328
case TopicNarrow ():
1294
- return _FixedDestinationComposeBox (key: controllerKey, narrow: narrow);
1329
+ return _FixedDestinationComposeBox (key: _fixedDestinationComposeBoxControllerKey,
1330
+ narrow: narrow);
1295
1331
case DmNarrow ():
1296
- return _FixedDestinationComposeBox (key: controllerKey, narrow: narrow);
1332
+ return _FixedDestinationComposeBox (key: _fixedDestinationComposeBoxControllerKey,
1333
+ narrow: narrow);
1297
1334
case CombinedFeedNarrow ():
1298
1335
case MentionsNarrow ():
1299
1336
case StarredMessagesNarrow ():
0 commit comments