File tree 7 files changed +53
-6
lines changed
7 files changed +53
-6
lines changed Original file line number Diff line number Diff line change 169
169
"@errorQuotationFailed": {
170
170
"description": "Error message when quoting a message failed."
171
171
},
172
+ "errorSendMessageTimeout": "Message isn’t sent. Check your connection.",
173
+ "@errorSendMessageTimeout": {
174
+ "description": "Error message when failed to send a message due to timeout."
175
+ },
172
176
"errorServerMessage": "The server said:\n\n{message}",
173
177
"@errorServerMessage": {
174
178
"description": "Error message that quotes an error from the server.",
Original file line number Diff line number Diff line change @@ -325,6 +325,12 @@ abstract class ZulipLocalizations {
325
325
/// **'Quotation failed'**
326
326
String get errorQuotationFailed;
327
327
328
+ /// Error message when failed to send a message due to timeout.
329
+ ///
330
+ /// In en, this message translates to:
331
+ /// **'Message isn’t sent. Check your connection.'**
332
+ String get errorSendMessageTimeout;
333
+
328
334
/// Error message that quotes an error from the server.
329
335
///
330
336
/// In en, this message translates to:
Original file line number Diff line number Diff line change @@ -144,6 +144,9 @@ class ZulipLocalizationsAr extends ZulipLocalizations {
144
144
@override
145
145
String get errorQuotationFailed => 'Quotation failed' ;
146
146
147
+ @override
148
+ String get errorSendMessageTimeout => 'Message isn’t sent. Check your connection.' ;
149
+
147
150
@override
148
151
String errorServerMessage (String message) {
149
152
return 'The server said:\n\n $message ' ;
Original file line number Diff line number Diff line change @@ -144,6 +144,9 @@ class ZulipLocalizationsEn extends ZulipLocalizations {
144
144
@override
145
145
String get errorQuotationFailed => 'Quotation failed' ;
146
146
147
+ @override
148
+ String get errorSendMessageTimeout => 'Message isn’t sent. Check your connection.' ;
149
+
147
150
@override
148
151
String errorServerMessage (String message) {
149
152
return 'The server said:\n\n $message ' ;
Original file line number Diff line number Diff line change @@ -144,6 +144,9 @@ class ZulipLocalizationsJa extends ZulipLocalizations {
144
144
@override
145
145
String get errorQuotationFailed => 'Quotation failed' ;
146
146
147
+ @override
148
+ String get errorSendMessageTimeout => 'Message isn’t sent. Check your connection.' ;
149
+
147
150
@override
148
151
String errorServerMessage (String message) {
149
152
return 'The server said:\n\n $message ' ;
Original file line number Diff line number Diff line change
1
+ import 'dart:async' ;
1
2
import 'dart:math' ;
2
3
3
4
import 'package:app_settings/app_settings.dart' ;
@@ -22,6 +23,8 @@ import 'store.dart';
22
23
import 'text.dart' ;
23
24
import 'theme.dart' ;
24
25
26
+ const Duration kSendMessageTimeout = Duration (seconds: 5 );
27
+
25
28
const double _composeButtonSize = 44 ;
26
29
27
30
/// A [TextEditingController] for use in the compose box.
@@ -1046,15 +1049,21 @@ class _SendButtonState extends State<_SendButton> {
1046
1049
widget.enabled.value = false ;
1047
1050
1048
1051
try {
1049
- await store.sendMessage (destination: widget.getDestination (), content: content);
1052
+ await store
1053
+ .sendMessage (destination: widget.getDestination (), content: content)
1054
+ .timeout (kSendMessageTimeout);
1050
1055
widget.contentController.clear ();
1051
- } on ApiRequestException catch (e) {
1056
+ } catch (e) {
1052
1057
if (! mounted) return ;
1058
+
1053
1059
final zulipLocalizations = ZulipLocalizations .of (context);
1054
- final message = switch (e) {
1055
- ZulipApiException () => zulipLocalizations.errorServerMessage (e.message),
1056
- _ => e.message,
1057
- };
1060
+ String message;
1061
+ switch (e) {
1062
+ case ZulipApiException (): message = zulipLocalizations.errorServerMessage (e.message);
1063
+ case ApiRequestException (): message = e.message;
1064
+ case TimeoutException (): message = zulipLocalizations.errorSendMessageTimeout;
1065
+ default : rethrow ;
1066
+ }
1058
1067
showErrorDialog (context: context,
1059
1068
title: zulipLocalizations.errorMessageNotSent,
1060
1069
message: message);
Original file line number Diff line number Diff line change @@ -476,6 +476,25 @@ void main() {
476
476
check (composeBoxController.contentController.text).equals (oldText);
477
477
});
478
478
479
+ testWidgets ('fail after timeout' , (tester) async {
480
+ const longDelay = Duration (hours: 1 );
481
+ assert (longDelay > kSendMessageTimeout);
482
+ await setupAndTapSend (tester, prepareResponse: (_) {
483
+ connection.prepare (
484
+ httpStatus: 400 ,
485
+ json: {'result' : 'error' , 'code' : 'BAD_REQUEST' },
486
+ delay: longDelay);
487
+ });
488
+
489
+ await tester.pump (kSendMessageTimeout);
490
+ final zulipLocalizations = GlobalLocalizations .zulipLocalizations;
491
+ await tester.tap (find.byWidget (checkErrorDialog (tester,
492
+ expectedTitle: zulipLocalizations.errorMessageNotSent,
493
+ expectedMessage: zulipLocalizations.errorSendMessageTimeout)));
494
+
495
+ await tester.pump (longDelay);
496
+ });
497
+
479
498
testWidgets ('ZulipApiException' , (tester) async {
480
499
await setupAndTapSend (tester, prepareResponse: (message) {
481
500
connection.prepare (
You can’t perform that action at this time.
0 commit comments