File tree 7 files changed +52
-6
lines changed
7 files changed +52
-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.
@@ -997,15 +1000,20 @@ class _SendButtonState extends State<_SendButton> {
997
1000
widget.controller._enabled.value = false ;
998
1001
999
1002
try {
1000
- await store.sendMessage (destination: widget.getDestination (), content: content);
1003
+ await store
1004
+ .sendMessage (destination: widget.getDestination (), content: content)
1005
+ .timeout (kSendMessageTimeout);
1001
1006
widget.controller.content.clear ();
1002
- } on ApiRequestException catch (e) {
1007
+ } catch (e) {
1003
1008
if (! mounted) return ;
1004
1009
final zulipLocalizations = ZulipLocalizations .of (context);
1005
- final message = switch (e) {
1006
- ZulipApiException () => zulipLocalizations.errorServerMessage (e.message),
1007
- _ => e.message,
1008
- };
1010
+ String message;
1011
+ switch (e) {
1012
+ case ZulipApiException (): message = zulipLocalizations.errorServerMessage (e.message);
1013
+ case ApiRequestException (): message = e.message;
1014
+ case TimeoutException (): message = zulipLocalizations.errorSendMessageTimeout;
1015
+ default : rethrow ;
1016
+ }
1009
1017
showErrorDialog (context: context,
1010
1018
title: zulipLocalizations.errorMessageNotSent,
1011
1019
message: message);
Original file line number Diff line number Diff line change @@ -480,6 +480,25 @@ void main() {
480
480
check (find.byType (LinearProgressIndicator )).findsNothing ();
481
481
});
482
482
483
+ testWidgets ('fail after timeout' , (tester) async {
484
+ const longDelay = Duration (hours: 1 );
485
+ assert (longDelay > kSendMessageTimeout);
486
+ await setupAndTapSend (tester, prepareResponse: (_) {
487
+ connection.prepare (
488
+ httpStatus: 400 ,
489
+ json: {'result' : 'error' , 'code' : 'BAD_REQUEST' },
490
+ delay: longDelay);
491
+ });
492
+
493
+ await tester.pump (kSendMessageTimeout);
494
+ final zulipLocalizations = GlobalLocalizations .zulipLocalizations;
495
+ await tester.tap (find.byWidget (checkErrorDialog (tester,
496
+ expectedTitle: zulipLocalizations.errorMessageNotSent,
497
+ expectedMessage: zulipLocalizations.errorSendMessageTimeout)));
498
+
499
+ await tester.pump (longDelay);
500
+ });
501
+
483
502
testWidgets ('ZulipApiException' , (tester) async {
484
503
await setupAndTapSend (tester, prepareResponse: (message) {
485
504
connection.prepare (
You can’t perform that action at this time.
0 commit comments