Skip to content

Commit 3256d1a

Browse files
committed
compose box: On failed message send, show error dialog
Fixes: #815
1 parent 81e2c9d commit 3256d1a

File tree

2 files changed

+39
-2
lines changed

2 files changed

+39
-2
lines changed

lib/widgets/compose_box.dart

+20-2
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import 'package:flutter/services.dart';
55
import 'package:flutter_gen/gen_l10n/zulip_localizations.dart';
66
import 'package:image_picker/image_picker.dart';
77

8+
import '../api/exception.dart';
89
import '../api/model/model.dart';
910
import '../api/route/messages.dart';
1011
import '../model/compose.dart';
@@ -716,7 +717,7 @@ class _SendButtonState extends State<_SendButton> {
716717
|| widget.contentController.hasValidationErrors.value;
717718
}
718719

719-
void _send() {
720+
void _send() async {
720721
if (_hasValidationErrors) {
721722
final zulipLocalizations = ZulipLocalizations.of(context);
722723
List<String> validationErrorMessages = [
@@ -735,9 +736,26 @@ class _SendButtonState extends State<_SendButton> {
735736

736737
final store = PerAccountStoreWidget.of(context);
737738
final content = widget.contentController.textNormalized;
738-
store.sendMessage(destination: widget.getDestination(), content: content);
739739

740740
widget.contentController.clear();
741+
742+
try {
743+
// TODO(#720) clear content input only on success response;
744+
// while waiting, put input(s) and send button into a disabled
745+
// "working on it" state (letting input text be selected for copying).
746+
await store.sendMessage(destination: widget.getDestination(), content: content);
747+
} on ApiRequestException catch (e) {
748+
if (!mounted) return;
749+
final zulipLocalizations = ZulipLocalizations.of(context);
750+
final message = switch (e) {
751+
ZulipApiException() => zulipLocalizations.errorServerMessage(e.message),
752+
_ => e.message,
753+
};
754+
showErrorDialog(context: context,
755+
title: zulipLocalizations.errorMessageNotSent,
756+
message: message);
757+
return;
758+
}
741759
}
742760

743761
@override

test/widgets/compose_box_test.dart

+19
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import '../example_data.dart' as eg;
1515
import '../flutter_checks.dart';
1616
import '../model/binding.dart';
1717
import '../stdlib_checks.dart';
18+
import 'dialog_checks.dart';
1819

1920
void main() {
2021
TestZulipBinding.ensureInitialized();
@@ -218,5 +219,23 @@ void main() {
218219
final errorDialogs = tester.widgetList(find.byType(AlertDialog));
219220
check(errorDialogs).isEmpty();
220221
});
222+
223+
testWidgets('ZulipApiException', (tester) async {
224+
await setupAndTapSend(tester, prepareResponse: (message) {
225+
connection.prepare(
226+
httpStatus: 400,
227+
json: {
228+
'result': 'error',
229+
'code': 'BAD_REQUEST',
230+
'msg': 'You do not have permission to initiate direct message conversations.',
231+
});
232+
});
233+
final zulipLocalizations = GlobalLocalizations.zulipLocalizations;
234+
await tester.tap(find.byWidget(checkErrorDialog(tester,
235+
expectedTitle: zulipLocalizations.errorMessageNotSent,
236+
expectedMessage: zulipLocalizations.errorServerMessage(
237+
'You do not have permission to initiate direct message conversations.'),
238+
)));
239+
});
221240
});
222241
}

0 commit comments

Comments
 (0)