diff --git a/lib/widgets/message_list.dart b/lib/widgets/message_list.dart index 14c33ad5fd..c894ec531b 100644 --- a/lib/widgets/message_list.dart +++ b/lib/widgets/message_list.dart @@ -1259,6 +1259,7 @@ class StreamMessageRecipientHeader extends StatelessWidget { ?? zulipLocalizations.unknownChannelName; // TODO(log) streamWidget = GestureDetector( + behavior: HitTestBehavior.opaque, onTap: () => Navigator.push(context, MessageListPage.buildRoute(context: context, narrow: ChannelNarrow(streamId))), diff --git a/test/widgets/message_list_test.dart b/test/widgets/message_list_test.dart index f048bf437d..44689d6fe5 100644 --- a/test/widgets/message_list_test.dart +++ b/test/widgets/message_list_test.dart @@ -2023,4 +2023,107 @@ void main() { ..status.equals(AnimationStatus.dismissed); }); }); + + group('recipient header navigation in multi-channel narrows', () { + late List> pushedRoutes; + + final channel = eg.stream(); + const testTopic = 'testTopic'; + final message = eg.streamMessage(stream: channel, topic: testTopic); + + final recipientHeaderFinder = find.byType(StreamMessageRecipientHeader); + late Rect recipientHeaderRect; + + Future prepare(WidgetTester tester) async { + pushedRoutes = []; + final navObserver = TestNavigatorObserver() + ..onPushed = (route, prevRoute) => pushedRoutes.add(route); + + await setupMessageListPage(tester, + narrow: const CombinedFeedNarrow(), + streams: [channel], + subscriptions: [eg.subscription(channel)], + messages: [message], + navObservers: [navObserver]); + + assert(pushedRoutes.length == 1); + pushedRoutes.clear(); + + recipientHeaderRect = tester.getRect(recipientHeaderFinder); + } + + // Regression test for: https://github.com/zulip/zulip-flutter/issues/1179 + testWidgets("navigates to ChannelNarrow when tapping above or below channel name in recipient header", (tester) async { + await prepare(tester); + + final channelNameFinder = find.descendant( + of: recipientHeaderFinder, + matching: find.text(channel.name)); + final channelNameRect = tester.getRect(channelNameFinder); + + connection.prepare(json: eg.newestGetMessagesResult( + foundOldest: true, messages: [message]).toJson()); + // Tap just right below the top of recipient header, above and outside of + // its channel name component. + await tester.tapAt(Offset( + channelNameRect.center.dx, recipientHeaderRect.top + 1)); + await tester.pump(); + check(pushedRoutes).single.isA().page.isA() + .initNarrow.equals(ChannelNarrow(channel.streamId)); + await tester.pumpAndSettle(); + + // Navigate back to original page and clear routes. + await tester.pageBack(); + await tester.pumpAndSettle(); + pushedRoutes.clear(); + + connection.prepare(json: eg.newestGetMessagesResult( + foundOldest: true, messages: [message]).toJson()); + // Tap just above the bottom of recipient header, below and outside of + // its channel name component. + await tester.tapAt(Offset( + channelNameRect.center.dx, recipientHeaderRect.bottom - 1)); + await tester.pump(); + check(pushedRoutes).single.isA().page.isA() + .initNarrow.equals(ChannelNarrow(channel.streamId)); + await tester.pumpAndSettle(); + }); + + // Regression test for: https://github.com/zulip/zulip-flutter/issues/1179 + testWidgets("navigates to TopicNarrow when tapping above or below topic name in recipient header", (tester) async { + await prepare(tester); + + final topicNameFinder = find.descendant( + of: recipientHeaderFinder, + matching: find.text(testTopic)); + final topicNameRect = tester.getRect(topicNameFinder); + + connection.prepare(json: eg.newestGetMessagesResult( + foundOldest: true, messages: [message]).toJson()); + // Tap just right below the top of recipient header, above and outside of + // its topic name component. + await tester.tapAt(Offset( + topicNameRect.center.dx, recipientHeaderRect.top + 1)); + await tester.pump(); + check(pushedRoutes).single.isA().page.isA() + .initNarrow.equals(TopicNarrow(channel.streamId, message.topic)); + await tester.pumpAndSettle(); + + // Navigate back to original page and clear routes. + await tester.pageBack(); + await tester.pumpAndSettle(); + pushedRoutes.clear(); + + connection.prepare(json: eg.newestGetMessagesResult( + foundOldest: true, messages: [message]).toJson()); + // Tap just above the bottom of recipient header, below and outside of + // its topic name component. + await tester.tapAt(Offset( + topicNameRect.center.dx, recipientHeaderRect.bottom - 1)); + await tester.pump(); + check(pushedRoutes).single.isA().page.isA() + .initNarrow.equals(TopicNarrow(channel.streamId, message.topic)); + await tester.pumpAndSettle(); + }); + }); }