Skip to content

Commit f297a65

Browse files
committed
msglist: Retrieve topic from failed-to-send messages
1 parent 33ad24c commit f297a65

File tree

2 files changed

+61
-2
lines changed

2 files changed

+61
-2
lines changed

lib/widgets/message_list.dart

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

14811481
final MessageListOutboxMessageItem item;
14821482

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

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

test/widgets/message_list_test.dart

+54-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,57 @@ 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, '');
1427+
check(controller.content).text.isNotNull().isEmpty();
1428+
1429+
// Tap the message. This should put its topic and content back into
1430+
// the compose box 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 channel narrow, failed to send message, retrieve only content to compose box if topic input is non-vacuous', (tester) async {
1441+
await setupMessageListPage(tester,
1442+
narrow: ChannelNarrow(stream.streamId), streams: [stream],
1443+
messages: []);
1444+
1445+
connection.prepare(json: GetStreamTopicsResult(topics: []).toJson());
1446+
await tester.enterText(topicInputFinder, 'test topic');
1447+
await sendMessageAndFail(tester);
1448+
1449+
final controller = tester.state<ComposeBoxState>(find.byType(ComposeBox)).controller;
1450+
controller as StreamComposeBoxController;
1451+
await tester.enterText(topicInputFinder, 'different topic');
1452+
check(controller.content).text.isNotNull().isEmpty();
1453+
1454+
// Tap the message. This should put its content back into the compose box
1455+
// and remove it.
1456+
await tester.tap(outboxMessageFinder);
1457+
await tester.pump();
1458+
check(outboxMessageFinder).findsNothing();
1459+
check(controller.topic).text.equals('different topic');
1460+
check(controller.content).text.equals('$content\n\n');
1461+
1462+
await tester.pump(kLocalEchoDebounceDuration);
1463+
});
1464+
1465+
testWidgets('in topic narrow, failed to send message, retrieve the content to compose box', (tester) async {
14131466
await setupMessageListPage(tester,
14141467
narrow: eg.topicNarrow(stream.streamId, 'topic'), streams: [stream],
14151468
messages: []);

0 commit comments

Comments
 (0)