@@ -1269,13 +1269,15 @@ class StreamComposeBoxController extends ComposeBoxController {
1269
1269
class FixedDestinationComposeBoxController extends ComposeBoxController {}
1270
1270
1271
1271
class _ErrorBanner extends StatelessWidget {
1272
- const _ErrorBanner ({required this .label});
1272
+ const _ErrorBanner ({required this .label, this .onDismiss });
1273
1273
1274
1274
final String label;
1275
+ final void Function ()? onDismiss;
1275
1276
1276
1277
@override
1277
1278
Widget build (BuildContext context) {
1278
1279
final designVariables = DesignVariables .of (context);
1280
+ final iconButtonTheme = IconButtonTheme .of (context);
1279
1281
final labelTextStyle = TextStyle (
1280
1282
fontSize: 17 ,
1281
1283
height: 22 / 17 ,
@@ -1297,8 +1299,14 @@ class _ErrorBanner extends StatelessWidget {
1297
1299
child: Text (style: labelTextStyle,
1298
1300
label))),
1299
1301
const SizedBox (width: 8 ),
1300
- // TODO(#720) "x" button goes here.
1301
- // 24px square with 8px touchable padding in all directions?
1302
+ if (onDismiss != null )
1303
+ IconButton (
1304
+ icon: Icon (
1305
+ ZulipIcons .remove, color: designVariables.btnLabelAttLowIntDanger),
1306
+ style: iconButtonTheme.style! .copyWith (
1307
+ shape: const WidgetStatePropertyAll (ContinuousRectangleBorder (
1308
+ borderRadius: BorderRadius .all (Radius .circular (4 ))))),
1309
+ onPressed: onDismiss),
1302
1310
])));
1303
1311
}
1304
1312
}
@@ -1358,7 +1366,7 @@ class _ComposeBoxState extends State<ComposeBox> implements ComposeBoxState {
1358
1366
super .dispose ();
1359
1367
}
1360
1368
1361
- Widget ? _errorBanner (BuildContext context) {
1369
+ Widget ? _canPostInNarrowErrorBanner (BuildContext context) {
1362
1370
final store = PerAccountStoreWidget .of (context);
1363
1371
final selfUser = store.users[store.selfUserId]! ;
1364
1372
switch (widget.narrow) {
@@ -1385,13 +1393,28 @@ class _ComposeBoxState extends State<ComposeBox> implements ComposeBoxState {
1385
1393
return null ;
1386
1394
}
1387
1395
1396
+ Widget _sendMessageErrorErrorBanner (BuildContext context) {
1397
+ final designVariables = DesignVariables .of (context);
1398
+ return ValueListenableBuilder (
1399
+ valueListenable: controller._sendMessageError,
1400
+ builder: (context, sendMessageError, child) {
1401
+ if (sendMessageError == null ) return const SizedBox .shrink ();
1402
+ return _ErrorBanner (
1403
+ label: sendMessageError,
1404
+ onDismiss: () => controller._sendMessageError.value = null );
1405
+ },
1406
+ child: IconButton (icon: Icon (ZulipIcons .remove,
1407
+ color: designVariables.btnLabelAttLowIntDanger),
1408
+ onPressed: () => controller._sendMessageError.value = null ));
1409
+ }
1410
+
1388
1411
@override
1389
1412
Widget build (BuildContext context) {
1390
1413
final Widget ? body;
1391
1414
1392
- final errorBanner = _errorBanner (context);
1393
- if (errorBanner != null ) {
1394
- return _ComposeBoxContainer (body: null , errorBanner: errorBanner );
1415
+ final canPostInNarrowErrorBanner = _canPostInNarrowErrorBanner (context);
1416
+ if (canPostInNarrowErrorBanner != null ) {
1417
+ return _ComposeBoxContainer (body: null , errorBanner: canPostInNarrowErrorBanner );
1395
1418
}
1396
1419
1397
1420
final narrow = widget.narrow;
@@ -1406,11 +1429,7 @@ class _ComposeBoxState extends State<ComposeBox> implements ComposeBoxState {
1406
1429
}
1407
1430
}
1408
1431
1409
- // TODO(#720) dismissable message-send error, maybe something like:
1410
- // if (controller.sendMessageError.value != null) {
1411
- // errorBanner = _ErrorBanner(label:
1412
- // ZulipLocalizations.of(context).errorSendMessageTimeout);
1413
- // }
1414
- return _ComposeBoxContainer (body: body, errorBanner: null );
1432
+ return _ComposeBoxContainer (
1433
+ body: body, errorBanner: _sendMessageErrorErrorBanner (context));
1415
1434
}
1416
1435
}
0 commit comments