Skip to content

Commit 9ab3f5f

Browse files
committed
msglist: Retrieve topic from failed-to-send messages
Fixes: #1441
1 parent ff8a941 commit 9ab3f5f

File tree

3 files changed

+36
-19
lines changed

3 files changed

+36
-19
lines changed

lib/widgets/compose_box.dart

-17
Original file line numberDiff line numberDiff line change
@@ -1141,15 +1141,8 @@ class _SendButtonState extends State<_SendButton> {
11411141
final content = controller.content.textNormalized;
11421142

11431143
controller.content.clear();
1144-
// The following `stoppedComposing` call is currently redundant,
1145-
// because clearing input sends a "typing stopped" notice.
1146-
// It will be necessary once we resolve #720.
1147-
store.typingNotifier.stoppedComposing();
11481144

11491145
try {
1150-
// TODO(#720) clear content input only on success response;
1151-
// while waiting, put input(s) and send button into a disabled
1152-
// "working on it" state (letting input text be selected for copying).
11531146
await store.sendMessage(destination: widget.getDestination(), content: content);
11541147
} on ApiRequestException catch (e) {
11551148
if (!mounted) return;
@@ -1241,7 +1234,6 @@ class _ComposeBoxContainer extends StatelessWidget {
12411234
border: Border(top: BorderSide(color: designVariables.borderBar)),
12421235
boxShadow: ComposeBoxTheme.of(context).boxShadow,
12431236
),
1244-
// TODO(#720) try a Stack for the overlaid linear progress indicator
12451237
child: Material(
12461238
color: designVariables.composeBoxBg,
12471239
child: Column(
@@ -1476,10 +1468,6 @@ class _ErrorBanner extends _Banner {
14761468

14771469
@override
14781470
Widget? buildTrailing(context) {
1479-
// TODO(#720) "x" button goes here.
1480-
// 24px square with 8px touchable padding in all directions?
1481-
// and `bool get padEnd => false`; see Figma:
1482-
// https://www.figma.com/design/1JTNtYo9memgW7vV6d0ygq/Zulip-Mobile?node-id=4031-17029&m=dev
14831471
return null;
14841472
}
14851473
}
@@ -1610,11 +1598,6 @@ class _ComposeBoxState extends State<ComposeBox> with PerAccountStoreAwareStateM
16101598
}
16111599
}
16121600

1613-
// TODO(#720) dismissable message-send error, maybe something like:
1614-
// if (controller.sendMessageError.value != null) {
1615-
// errorBanner = _ErrorBanner(label:
1616-
// ZulipLocalizations.of(context).errorSendMessageTimeout);
1617-
// }
16181601
return _ComposeBoxContainer(body: body, banner: null);
16191602
}
16201603
}

lib/widgets/message_list.dart

+7-1
Original file line numberDiff line numberDiff line change
@@ -1479,7 +1479,6 @@ class OutboxMessageWithPossibleSender extends StatelessWidget {
14791479

14801480
final MessageListOutboxMessageItem item;
14811481

1482-
// TODO should we restore the topic as well?
14831482
void _handlePress(BuildContext context) {
14841483
final content = item.message.content.endsWith('\n')
14851484
? item.message.content : '${item.message.content}\n';
@@ -1491,6 +1490,13 @@ class OutboxMessageWithPossibleSender extends StatelessWidget {
14911490
composeBoxController.contentFocusNode.requestFocus();
14921491
}
14931492

1493+
if (composeBoxController case StreamComposeBoxController(:final topic)) {
1494+
final conversation = item.message.conversation;
1495+
if (conversation is StreamConversation) {
1496+
topic.setTopic(conversation.topic);
1497+
}
1498+
}
1499+
14941500
final store = PerAccountStoreWidget.of(context);
14951501
assert(store.outboxMessages.containsKey(item.message.localMessageId));
14961502
store.removeOutboxMessage(item.message.localMessageId);

test/widgets/message_list_test.dart

+29-1
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import 'package:zulip/api/model/events.dart';
1111
import 'package:zulip/api/model/initial_snapshot.dart';
1212
import 'package:zulip/api/model/model.dart';
1313
import 'package:zulip/api/model/narrow.dart';
14+
import 'package:zulip/api/route/channels.dart';
1415
import 'package:zulip/api/route/messages.dart';
1516
import 'package:zulip/model/actions.dart';
1617
import 'package:zulip/model/localizations.dart';
@@ -1359,6 +1360,8 @@ void main() {
13591360
final stream = eg.stream();
13601361
const content = 'outbox message content';
13611362

1363+
final topicInputFinder = find.byWidgetPredicate(
1364+
(widget) => widget is TextField && widget.controller is ComposeTopicController);
13621365
final contentInputFinder = find.byWidgetPredicate(
13631366
(widget) => widget is TextField && widget.controller is ComposeContentController);
13641367

@@ -1409,7 +1412,32 @@ void main() {
14091412
localMessageId: store.outboxMessages.keys.single));
14101413
});
14111414

1412-
testWidgets('failed to send message, retrieve the content to compose box', (tester) async {
1415+
testWidgets('in channel narrow, failed to send message, retrieve both topic and content to compose box', (tester) async {
1416+
await setupMessageListPage(tester,
1417+
narrow: ChannelNarrow(stream.streamId), streams: [stream],
1418+
messages: []);
1419+
1420+
connection.prepare(json: GetStreamTopicsResult(topics: []).toJson());
1421+
await tester.enterText(topicInputFinder, 'test topic');
1422+
await sendMessageAndFail(tester);
1423+
1424+
final controller = tester.state<ComposeBoxState>(find.byType(ComposeBox)).controller;
1425+
controller as StreamComposeBoxController;
1426+
await tester.enterText(topicInputFinder, 'different topic');
1427+
check(controller.content).text.isNotNull().isEmpty();
1428+
1429+
// Tap the message. This should put its content back into the compose box
1430+
// and remove it.
1431+
await tester.tap(outboxMessageFinder);
1432+
await tester.pump();
1433+
check(outboxMessageFinder).findsNothing();
1434+
check(controller.topic).text.equals('test topic');
1435+
check(controller.content).text.equals('$content\n\n');
1436+
1437+
await tester.pump(kLocalEchoDebounceDuration);
1438+
});
1439+
1440+
testWidgets('in topic narrow, failed to send message, retrieve the content to compose box', (tester) async {
14131441
await setupMessageListPage(tester,
14141442
narrow: eg.topicNarrow(stream.streamId, 'topic'), streams: [stream],
14151443
messages: []);

0 commit comments

Comments
 (0)