Skip to content

Conversation

@Kushagra2024-code
Copy link

Fix: “Mark as read?” Dialog Now Acknowledges Muted Messages (Fixes #2030)
Background

Issue #2030 reports a confusing behavior in the “Mark as read?” confirmation dialog:

The dialog only showed the count of visible (unmuted) unread messages.

But confirming the action marked all unread messages as read — including those hidden due to:

muted streams

muted topics

muted DMs

This mismatch caused confusion, especially in CombinedFeedNarrow, where users often have thousands of muted unreads that are not shown in the UI.

Example expected behavior from the issue:

No muted unreads:
→ “26 messages will be marked as read.”

With muted unreads:
→ “10026 messages will be marked as read, including 10000 muted messages.”

This PR implements exactly that.

What This PR Does

  1. Adds Full Unread Counting (including muted) to the Unreads Model

📁 lib/model/unreads.dart

New public method:

countInNarrowIncludingMuted(Narrow narrow)

Helper methods:

_countInCombinedFeedNarrowIncludingMuted()

_countInChannelNarrowIncludingMuted(int streamId)

_countInMentionsNarrowIncludingMuted()

These return total unread messages, regardless of mute status.

They complement the existing:

countInNarrow() → counts only unmuted messages (visible in UI)

This fulfills the requirement from the issue:

“The Unreads model will need to offer unread counts that include all unreads in a given narrow.”

  1. Adds New Localization Strings

📁 assets/l10n/app_en.arb

New strings:

markAsReadConfirmationDialogMessage
→ used when no muted messages are present.

markAsReadConfirmationDialogMessageWithMuted
→ used when some messages are muted.

markAsReadConfirmationDialogConfirmButton
→ “Mark as read”

Ran flutter gen-l10n to update generated localization code.

  1. Updates MarkAsReadWidget to Show Accurate Confirmation Dialog

📁 lib/widgets/message_list.dart

Enhanced _handlePress():

Get visible unread count (old behavior)

Get total unread count, including muted (new)

Compute muted count = total − visible

Select dialog message based on presence of muted messages

Ask for explicit user confirmation

Only proceed with mark-as-read after confirmation

This fully aligns with the user expectation outlined in the issue.

  1. Adds Comprehensive Tests for All Narrow Types

📁 test/model/unreads_test.dart

New test group:

countInNarrowIncludingMuted

Covers:

CombinedFeedNarrow
→ includes muted topics, streams, and DMs

ChannelNarrow / StreamNarrow
→ includes muted topics

TopicNarrow
→ unchanged (no subtopic muting exists)

MentionsNarrow
→ mentions are included even if muted

Each test compares:

countInNarrow() (visible only)

countInNarrowIncludingMuted() (total)

to confirm muted messages are correctly counted.

Result: Clear, Transparent Confirmation UI

The user now sees exactly what will happen before marking messages as read.

Example outcomes:

When all are visible
“26 messages will be marked as read.”

When muted messages exist
“10026 messages will be marked as read, including 10000 muted messages.”

This eliminates confusion and improves trust in the action — especially in the interleaved CombinedFeedNarrow view, where muted messages frequently accumulate in large quantities.

Related Issues

Issue #2030 — This PR fixes it.

Related conceptual issue: #2031
“Mark as read?” dialog should acknowledge uncertainty when unreads are extremely high.

Files Changed

lib/model/unreads.dart

lib/widgets/message_list.dart

assets/l10n/app_en.arb

test/model/unreads_test.dart

Currently, when marking messages as read, the confirmation dialog shows only the count of visible (unmuted) messages, but the action marks both visible and muted messages as read. This is confusing as the displayed count doesn't match what actually happens. This commit adds a confirmation dialog that shows: - Simple count when no muted messages: "26 messages will be marked as read." - Detailed breakdown when muted messages exist: "10026 messages will be marked as read, including 10000 muted messages." Implementation: - Added countInNarrowIncludingMuted() method in Unreads model to count all unreads (muted + unmuted) in a narrow - Added helper methods for different narrow types (combined feed, channel, mentions) - Added localization strings for dialog messages - Modified MarkAsReadWidget to show confirmation dialog before marking messages as read - Added comprehensive tests for the new counting functionality Fixes: zulip#1858
@chrisbobbe
Copy link
Collaborator

There is a lot of text to read in that PR description. Did you use ChatGPT or another LLM to write it? If so, we'd much rather see whatever prompt you used, instead of the LLM output — the LLM fundamentally doesn't add any information that wasn't there already, and the prompt should be a lot shorter and so less work to read.

There's also no need to repeat information that's there in the diffs, like the names of files you touched and identifiers you added there.

In general, this PR description reads like it might if you had an LLM write it for you. That generally won't produce something that meets our standards for communicating clearly. I recommend reading our AI use policy and guidelines:
https://zulip.readthedocs.io/en/latest/contributing/contributing.html#ai-use-policy-and-guidelines

@gnprice
Copy link
Member

gnprice commented Dec 13, 2025

Closing because it doesn't look likely that this PR will become something that's a good use of our time to review.

This issue #2030 isn't marked with "help wanted", because we don't expect it to be accessible to a new contributor. See this other section of our contributing guide (same page Chris linked above, and linked repeatedly in our README):

Can I work on an issue that’s not marked as “help wanted”? The entire purpose of the “help wanted” label is to indicate which issues are open for contribution, so the answer is generally “no”. Please feel free to ask if you have a merged PR in a closely related part of the codebase, and the issue has a clear product spec, and no obvious blockers. Otherwise, asking to claim an issue without a “help wanted” label clutters up comment threads, and wastes maintainer time.

@Kushagra2024-code if you would like to contribute to Zulip, please read our contributing guide, including the AI policy. A future PR will need to communicate much more clearly than this one, as Chris pointed out above, in addition to following our guidelines on choosing and claiming an issue.

@gnprice gnprice closed this Dec 13, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

3 participants