Skip to content

Conversation

Copy link

Copilot AI commented Aug 31, 2025

Problem

When a user deletes messages from a conversation, the unread message counters for other users are not updated to reflect that some of their unread messages have been deleted. This causes incorrect unread counts to be displayed in the UI.

Scenario:

  1. User A sends messages 1, 2, 3, 4, 5 to User B
  2. User B reads messages 1, 2 (readID = 2, unread count = 3)
  3. User A deletes messages 3, 4 (soft delete)
  4. User B should now have only 1 unread message (message 5), but the counter still shows 3

This affects both online users and users who come back online later, and applies to both soft deletes and hard deletes.

Root Cause

The handleNoteBroadcast function calculates unread counts using simple arithmetic (pud.readID - msg.Note.SeqId) without considering that some messages in the range may have been deleted. The replyDelMsg function successfully deletes messages but doesn't update unread counters for affected users.

Solution

Added logic to update unread counters when messages are deleted:

  1. Helper function calculateUnreadInRanges: Efficiently calculates how many unread messages fall within given deletion ranges using intersection logic. Uses linear search to find the first relevant range (where rangeEnd > readID) and then iterates to sum up unread messages in the deleted ranges.

  2. Enhanced replyDelMsg: After successful deletion, iterates through all users with read permissions and decreases their unread count by the number of unread messages that were deleted. This applies to:

    • Hard deletes: Updates unread counters for all users since hard deletes remove messages for everyone
    • Soft deletes: Updates unread counters for other users (not the deleting user)
  3. Minimal performance impact: Only runs during message deletion operations (rare events), not during normal read operations.

Technical Details

  • Updates unread counters for both hard and soft deletes
  • Uses existing usersUpdateUnread infrastructure for consistency
  • Preserves all existing functionality and API compatibility
  • Zero impact on read notification performance

Testing

  • Added comprehensive unit tests for calculateUnreadInRanges covering edge cases
  • Added integration test TestReplyDelMsgUpdatesUnreadCounters for soft delete scenario
  • Added integration test TestReplyDelMsgHardDelete for hard delete scenario
  • All existing tests continue to pass

Example calculation:

// User has readID=5, lastID=10 (unread messages: 6,7,8,9,10)
// Delete range [7,9) removes messages 7,8
// Result: 2 unread messages removed from count
ranges := []types.Range{{Low: 7, Hi: 9}}
deleted := calculateUnreadInRanges(5, 10, ranges) // Returns 2

Fixes #898


✨ Let Copilot coding agent set things up for you — coding agent works faster and does higher quality work when set up for your repo.

Copilot AI changed the title [WIP] Propose a solution to this bug: @tinode/chat/issues/898 Fix unread message counter not accounting for deleted messages Aug 31, 2025
Copilot AI requested a review from or-else August 31, 2025 13:05
Copilot finished work on behalf of or-else August 31, 2025 13:05
@or-else or-else changed the base branch from master to devel November 6, 2025 13:06
@or-else or-else marked this pull request as ready for review November 6, 2025 13:17
@or-else
Copy link
Contributor

or-else commented Nov 6, 2025

@copilot Please inplement fixes according to code review.

Copy link
Author

Copilot AI commented Nov 6, 2025

@copilot Please inplement fixes according to code review.

All fixes implemented in dd3d3c9:

  • Removed .gitignore
  • Optimized calculateUnreadInRanges with binary search
  • Added hard delete test case

Copilot AI requested a review from or-else November 6, 2025 13:25
Copilot finished work on behalf of or-else November 6, 2025 13:25
Copilot AI requested a review from or-else November 6, 2025 13:37
Copilot finished work on behalf of or-else November 6, 2025 13:37
Copy link
Contributor

@or-else or-else left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@copilot Still weak, but OK, I'll clean it up later.

@or-else or-else merged commit b7d7868 into devel Nov 6, 2025
@or-else or-else deleted the copilot/fix-f4f37f1f-efcc-4cb4-9ff7-148964e37222 branch November 6, 2025 13:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

In-app unread message counter does not account for deleted messages

2 participants