@@ -1002,10 +1002,12 @@ class _SendButtonState extends State<_SendButton> {
1002
1002
widget.controller._enabled.value = false ;
1003
1003
1004
1004
try {
1005
+ throw TimeoutException ('asd' );
1005
1006
await store
1006
1007
.sendMessage (destination: widget.getDestination (), content: content)
1007
1008
.timeout (kSendMessageTimeout);
1008
1009
widget.controller.content.clear ();
1010
+ widget.controller._sendMessageError.value = null ;
1009
1011
} catch (e) {
1010
1012
if (! mounted) return ;
1011
1013
final zulipLocalizations = ZulipLocalizations .of (context);
@@ -1016,9 +1018,7 @@ class _SendButtonState extends State<_SendButton> {
1016
1018
case TimeoutException (): message = zulipLocalizations.errorSendMessageTimeout;
1017
1019
default : rethrow ;
1018
1020
}
1019
- showErrorDialog (context: context,
1020
- title: zulipLocalizations.errorMessageNotSent,
1021
- message: message);
1021
+ widget.controller._sendMessageError.value = message;
1022
1022
return ;
1023
1023
} finally {
1024
1024
widget.controller._enabled.value = true ;
@@ -1246,11 +1246,15 @@ sealed class ComposeBoxController {
1246
1246
bool get enabled => _enabled.value;
1247
1247
final ValueNotifier <bool > _enabled = ValueNotifier <bool >(true );
1248
1248
1249
+ String ? get sendMessageError => _sendMessageError.value;
1250
+ final ValueNotifier <String ?> _sendMessageError = ValueNotifier <String ?>(null );
1251
+
1249
1252
@mustCallSuper
1250
1253
void dispose () {
1251
1254
content.dispose ();
1252
1255
contentFocusNode.dispose ();
1253
1256
_enabled.dispose ();
1257
+ _sendMessageError.dispose ();
1254
1258
}
1255
1259
}
1256
1260
@@ -1269,13 +1273,15 @@ class StreamComposeBoxController extends ComposeBoxController {
1269
1273
class FixedDestinationComposeBoxController extends ComposeBoxController {}
1270
1274
1271
1275
class _ErrorBanner extends StatelessWidget {
1272
- const _ErrorBanner ({required this .label});
1276
+ const _ErrorBanner ({required this .label, this .onDismiss });
1273
1277
1274
1278
final String label;
1279
+ final void Function ()? onDismiss;
1275
1280
1276
1281
@override
1277
1282
Widget build (BuildContext context) {
1278
1283
final designVariables = DesignVariables .of (context);
1284
+ final iconButtonTheme = IconButtonTheme .of (context);
1279
1285
final labelTextStyle = TextStyle (
1280
1286
fontSize: 17 ,
1281
1287
height: 22 / 17 ,
@@ -1297,8 +1303,16 @@ class _ErrorBanner extends StatelessWidget {
1297
1303
child: Text (style: labelTextStyle,
1298
1304
label))),
1299
1305
const SizedBox (width: 8 ),
1300
- // TODO(#720) "x" button goes here.
1301
- // 24px square with 8px touchable padding in all directions?
1306
+ if (onDismiss != null )
1307
+ IconButton (
1308
+ icon: Icon (
1309
+ ZulipIcons .remove, color: designVariables.btnLabelAttLowIntDanger),
1310
+ style: iconButtonTheme.style! .copyWith (
1311
+ overlayColor: const WidgetStatePropertyAll (Colors .transparent),
1312
+ splashFactory: NoSplash .splashFactory,
1313
+ shape: const WidgetStatePropertyAll (ContinuousRectangleBorder (
1314
+ borderRadius: BorderRadius .all (Radius .circular (4 ))))),
1315
+ onPressed: onDismiss),
1302
1316
])));
1303
1317
}
1304
1318
}
@@ -1385,6 +1399,21 @@ class _ComposeBoxState extends State<ComposeBox> implements ComposeBoxState {
1385
1399
return null ;
1386
1400
}
1387
1401
1402
+ Widget _sendMessageErrorErrorBanner (BuildContext context) {
1403
+ final designVariables = DesignVariables .of (context);
1404
+ return ValueListenableBuilder (
1405
+ valueListenable: controller._sendMessageError,
1406
+ builder: (context, sendMessageError, child) {
1407
+ if (sendMessageError == null ) return const SizedBox .shrink ();
1408
+ return _ErrorBanner (
1409
+ label: sendMessageError,
1410
+ onDismiss: () => controller._sendMessageError.value = null );
1411
+ },
1412
+ child: IconButton (icon: Icon (ZulipIcons .remove,
1413
+ color: designVariables.btnLabelAttLowIntDanger),
1414
+ onPressed: () => controller._sendMessageError.value = null ));
1415
+ }
1416
+
1388
1417
@override
1389
1418
Widget build (BuildContext context) {
1390
1419
final Widget ? body;
@@ -1406,11 +1435,7 @@ class _ComposeBoxState extends State<ComposeBox> implements ComposeBoxState {
1406
1435
}
1407
1436
}
1408
1437
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 );
1438
+ return _ComposeBoxContainer (
1439
+ body: body, errorBanner: _sendMessageErrorErrorBanner (context));
1415
1440
}
1416
1441
}
0 commit comments