From 91246ee3280818661770ca10fe82dd11e6d49c09 Mon Sep 17 00:00:00 2001 From: loveucifer Date: Mon, 28 Jul 2025 19:21:44 +0530 Subject: [PATCH 1/2] fix for : Don't show "Mark as unread from here" button in unsubscribed channels #1641 --- lib/widgets/action_sheet.dart | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/widgets/action_sheet.dart b/lib/widgets/action_sheet.dart index 6b280df6ee..de99117309 100644 --- a/lib/widgets/action_sheet.dart +++ b/lib/widgets/action_sheet.dart @@ -606,7 +606,8 @@ void showMessageActionSheet({required BuildContext context, required Message mes final isMessageRead = message.flags.contains(MessageFlag.read); final markAsUnreadSupported = store.zulipFeatureLevel >= 155; // TODO(server-6) - final showMarkAsUnreadButton = markAsUnreadSupported && isMessageRead; + final showMarkAsUnreadButton = markAsUnreadSupported && isMessageRead && + (message is! StreamMessage || store.subscriptions[message.streamId] != null); final isSenderMuted = store.isUserMuted(message.senderId); From f4fdacd09b49ab41b359282969fcd2187567bc9d Mon Sep 17 00:00:00 2001 From: loveucifer Date: Wed, 30 Jul 2025 16:07:42 +0530 Subject: [PATCH 2/2] actions: Omit 'Mark as unread' for messages in unsubscribed streams. earlier, the 'Mark as unread' button was displayed for any read message even if they were unsubscribed . This pr change adds a condition that should only show the button for direct messages or for stream messages where the subscription exists. The corresponding test is added to verify this new behavior which uses the `setupToMessageActionSheet` helper, dismissing the action sheet and also firing the `SubscriptionRemoveEvent`, and then re-opening the sheet to confirm that the button is now not present there --- lib/widgets/action_sheet.dart | 2 +- test/widgets/action_sheet_test.dart | 33 ++++++++++++++++++++++++++++- 2 files changed, 33 insertions(+), 2 deletions(-) diff --git a/lib/widgets/action_sheet.dart b/lib/widgets/action_sheet.dart index de99117309..f0fa51fad3 100644 --- a/lib/widgets/action_sheet.dart +++ b/lib/widgets/action_sheet.dart @@ -607,7 +607,7 @@ void showMessageActionSheet({required BuildContext context, required Message mes final isMessageRead = message.flags.contains(MessageFlag.read); final markAsUnreadSupported = store.zulipFeatureLevel >= 155; // TODO(server-6) final showMarkAsUnreadButton = markAsUnreadSupported && isMessageRead && - (message is! StreamMessage || store.subscriptions[message.streamId] != null); + (message is! StreamMessage || store.subscriptions[message.streamId] != null); final isSenderMuted = store.isUserMuted(message.senderId); diff --git a/test/widgets/action_sheet_test.dart b/test/widgets/action_sheet_test.dart index 631856efde..8cd9521553 100644 --- a/test/widgets/action_sheet_test.dart +++ b/test/widgets/action_sheet_test.dart @@ -1341,6 +1341,38 @@ void main() { check(find.byIcon(Icons.mark_chat_unread_outlined).evaluate()).single; }); + testWidgets('not visible if message is in unsubscribed stream', (tester) async { + // Setup with a read message, so the button is potentially visible. + final readMessage = eg.streamMessage(flags: [MessageFlag.read]); + + // this will use the common helper function . + // This will subscribe to the stream and open the action sheet . + await setupToMessageActionSheet(tester, + message: readMessage, narrow: TopicNarrow.ofMessage(readMessage)); + + // Initially, the button should be visible because the helper subscribes to the stream. + check(find.byIcon(Icons.mark_chat_unread_outlined).evaluate()).single; + + // Close the action sheet + await tester.tapAt(const Offset(0, 0)); // Tap outside to dismiss it + await tester.pumpAndSettle(); + + // Now, we will fire an event to unsubscribe from the stream. + await store.handleEvent(SubscriptionRemoveEvent( + id: 999, // dummy event ID + streamIds: [readMessage.streamId])); + + // this will Process the state change + await tester.pump(); + + // Open the action sheet again after unsubscribing from the stream + await tester.longPress(find.byType(MessageContent), warnIfMissed: false); + await tester.pump(const Duration(milliseconds: 250)); + + // After the rebuild, the button should be gone. + check(find.byIcon(Icons.mark_chat_unread_outlined).evaluate()).isEmpty(); + }); + group('onPressed', () { testWidgets('smoke test', (tester) async { final message = eg.streamMessage(flags: [MessageFlag.read]); @@ -1547,7 +1579,6 @@ void main() { of: find.byWidget(snackbar.content), matching: find.text(zulipLocalizations.successMessageTextCopied))); }); - testWidgets('request has an error', (tester) async { final message = eg.streamMessage(); await setupToMessageActionSheet(tester, message: message, narrow: TopicNarrow.ofMessage(message));