Skip to content

Commit c56963e

Browse files
committed
compose box: On failed message send, show error dialog
Fixes: zulip#815
1 parent 3f65665 commit c56963e

File tree

2 files changed

+38
-2
lines changed

2 files changed

+38
-2
lines changed

lib/widgets/compose_box.dart

+19-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,7 +736,23 @@ 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);
739+
740+
try {
741+
// TODO(#720) put input(s) and send button into a disabled "working on it"
742+
// state (allowing input text to be selected for copying).
743+
await store.sendMessage(destination: widget.getDestination(), content: content);
744+
} on ApiRequestException catch (e) {
745+
if (!mounted) return;
746+
final zulipLocalizations = ZulipLocalizations.of(context);
747+
final message = switch (e) {
748+
ZulipApiException() => zulipLocalizations.errorServerMessage(e.message),
749+
_ => e.message,
750+
};
751+
showErrorDialog(context: context,
752+
title: zulipLocalizations.errorMessageNotSent,
753+
message: message);
754+
return;
755+
}
739756

740757
widget.contentController.clear();
741758
}

test/widgets/compose_box_test.dart

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

2021
void main() {
2122
TestZulipBinding.ensureInitialized();
@@ -225,5 +226,23 @@ void main() {
225226
final errorDialogs = tester.widgetList(find.byType(AlertDialog));
226227
check(errorDialogs).isEmpty();
227228
});
229+
230+
testWidgets('ZulipApiException', (tester) async {
231+
await setupAndTapSend(tester, prepareResponse: (message) {
232+
connection.prepare(
233+
httpStatus: 400,
234+
json: {
235+
'result': 'error',
236+
'code': 'BAD_REQUEST',
237+
'msg': 'You do not have permission to initiate direct message conversations.',
238+
});
239+
});
240+
final zulipLocalizations = GlobalLocalizations.zulipLocalizations;
241+
await tester.tap(find.byWidget(checkErrorDialog(tester,
242+
expectedTitle: zulipLocalizations.errorMessageNotSent,
243+
expectedMessage: zulipLocalizations.errorServerMessage(
244+
'You do not have permission to initiate direct message conversations.'),
245+
)));
246+
});
228247
});
229248
}

0 commit comments

Comments
 (0)