Skip to content

Conversation

@abhinavkrin
Copy link
Member

@abhinavkrin abhinavkrin commented Jun 30, 2025

Proposed changes (including videos or screenshots)

When you create a brand-new channel and immediately reply to your own message in a thread, the unread-messages banner was showing up even though you hadn’t missed anything. This happened because the baseline timestamp (lastMessageDate) stayed undefined until an off-screen message was detected, so every reply looked like “new” content. Now, on first load—when the message count goes from zero to some number—we set lastMessageDate to the newest message’s timestamp, giving the unread-count logic a proper anchor and preventing self-sent thread replies from ever triggering the banner.

Issue(s)

Steps to test or reproduce

Further comments

CORE-1214

…reation

Signed-off-by: Abhinav Kumar <abhinav@avitechlab.com>
@abhinavkrin abhinavkrin requested a review from a team as a code owner June 30, 2025 16:48
@dionisio-bot
Copy link
Contributor

dionisio-bot bot commented Jun 30, 2025

Looks like this PR is ready to merge! 🎉
If you have any trouble, please check the PR guidelines

@changeset-bot
Copy link

changeset-bot bot commented Jun 30, 2025

⚠️ No Changeset found

Latest commit: 18d7420

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

return;
}
setMessageJumpQueryStringParameter(message?._id);
chat.readStateManager.markAsRead();
Copy link
Member Author

@abhinavkrin abhinavkrin Jun 30, 2025

Choose a reason for hiding this comment

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

This seemed to be a fix for me. While clicking on the banner, It would take me to message. But when page is refreshed, the banner would reapper.

@github-actions
Copy link
Contributor

github-actions bot commented Jun 30, 2025

PR Preview Action v1.6.1

🚀 View preview at
https://RocketChat.github.io/Rocket.Chat/pr-preview/pr-36331/

Built to branch gh-pages at 2025-07-01 19:49 UTC.
Preview will be ready when the GitHub Pages deployment is complete.

Signed-off-by: Abhinav Kumar <abhinav@avitechlab.com>
@codecov
Copy link

codecov bot commented Jun 30, 2025

Codecov Report

Attention: Patch coverage is 0% with 1 line in your changes missing coverage. Please review.

Project coverage is 64.54%. Comparing base (a14410b) to head (8340250).

Additional details and impacted files

Impacted file tree graph

@@                Coverage Diff                @@
##           release-7.8.0   #36331      +/-   ##
=================================================
- Coverage          64.55%   64.54%   -0.01%     
=================================================
  Files               3147     3147              
  Lines             104629   104629              
  Branches           19766    19766              
=================================================
- Hits               67544    67538       -6     
- Misses             34401    34406       +5     
- Partials            2684     2685       +1     
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

jessicaschelly
jessicaschelly previously approved these changes Jun 30, 2025
Copy link
Member

@MartinSchoeler MartinSchoeler left a comment

Choose a reason for hiding this comment

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

Do we know the root cause of the issue (in what PR the bug was introduced)? Here it seems we are only patching the symptom, not actually fixing the root cause of the issue.
I think we can dive a little deeper and come up with a more elegant solution.

[getMessage, setUnreadCount],
);

useEffect(() => {
Copy link
Member

Choose a reason for hiding this comment

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

Could we find an alternative to this use effect? As it is, this is going to run every time the messagesCount prop changes (basically on every message). It seems costly for an operation that only needs to happen when the room is initialized.

Copy link
Member Author

Choose a reason for hiding this comment

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

Actually this will run only once. In first run, the lastMessageDate will be set and there is a check to return early when lastMessageDate is set.

Copy link
Member Author

Choose a reason for hiding this comment

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

Also, this is not expensive tasks. It is used only at one or two places all over the client. Plus it only runs once and loops around few messages. Next runs, it returns early. I dont think it is expensive.

(a, b) => b.ts.getTime() - a.ts.getTime(),
);
if (newest) {
setLastMessageDate(newest.ts);
Copy link
Member

Choose a reason for hiding this comment

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

We should avoid changing the value of a state that is in the dependency list

Copy link
Member Author

Choose a reason for hiding this comment

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

same.

@Al2Tul2 Al2Tul2 added this to the 7.8.0 milestone Jul 1, 2025
@abhinavkrin
Copy link
Member Author

Do we know the root cause of the issue (in what PR the bug was introduced)? Here it seems we are only patching the symptom, not actually fixing the root cause of the issue. I think we can dive a little deeper and come up with a more elegant solution.

  1. The root cause is as explained, we are using the last message which is hidden behind the scroll or near the scroll to calculate the lastMessageDate. But when a room is new, there arent a lot of messages so that a message is behind the scroll or near to it. This made lastMessageDate undefined.
  2. Earlier the count code was:
const count = Messages.find({
			rid: room._id,
			ts: { $lte: lastMessageDate, $gt: subscription?.ls },
		}).count();

This will always return nothing sinc lastMessageDate is undefined.
But now the code is

const count = filterMessages(
			(record) =>
				record.rid === room._id &&
				record.ts.getTime() <= (lastMessageDate?.getTime() ?? Infinity) &&
				record.ts.getTime() > (subscription?.ls?.getTime() ?? -Infinity),
		).length;

This will always return a number > 0 if lastMessageDate is undefined.
So this code change made the already existing bug to appear now.

@MartinSchoeler
Copy link
Member

const count = filterMessages(
			(record) =>
				record.rid === room._id &&
				record.ts.getTime() <= (lastMessageDate?.getTime() ?? Infinity) &&
				record.ts.getTime() > (subscription?.ls?.getTime() ?? -Infinity),
		).length;

I think we could fix the issue here, add an exception before we filter the messages since when the lastMessage is undefined, the filter does nothing (since infinity will always be larger).

just by doing

const count = filterMessages(
			(record) =>
				record.rid === room._id && !!lastMessageDate &&
				record.ts.getTime() <= lastMessageDate?.getTime() &&
				record.ts.getTime() > (subscription?.ls?.getTime() ?? -Infinity),
		).length;

the issue seems to go away (just an example, need testing), so I think we don't need another useEffect, just to adjust the existing one

Also it seems that this issue was introduced in #36158

@abhinavkrin
Copy link
Member Author

const count = filterMessages(
			(record) =>
				record.rid === room._id &&
				record.ts.getTime() <= (lastMessageDate?.getTime() ?? Infinity) &&
				record.ts.getTime() > (subscription?.ls?.getTime() ?? -Infinity),
		).length;

I think we could fix the issue here, add an exception before we filter the messages since when the lastMessage is undefined, the filter does nothing (since infinity will always be larger).

just by doing

const count = filterMessages(
			(record) =>
				record.rid === room._id && !!lastMessageDate &&
				record.ts.getTime() <= lastMessageDate?.getTime() &&
				record.ts.getTime() > (subscription?.ls?.getTime() ?? -Infinity),
		).length;

the issue seems to go away (just an example, need testing), so I think we don't need another useEffect, just to adjust the existing one

Also it seems that this issue was introduced in #36158

Yes it will go back to the previous behavior. But still the issue with how we calculate lastMessageDate will remain same. It will be undefined for new rooms. Since there wont be enough messages which will cause a message to go invisible. And hence unread message banner might not show for new rooms.

Signed-off-by: Abhinav Kumar <abhinav@avitechlab.com>
@MartinSchoeler
Copy link
Member

Behavior matches version 7.7.0

@MartinSchoeler MartinSchoeler added the stat: QA assured Means it has been tested and approved by a company insider label Jul 1, 2025
@dionisio-bot dionisio-bot bot added the stat: ready to merge PR tested and approved waiting for merge label Jul 1, 2025
@ggazzo ggazzo merged commit a20ca2c into release-7.8.0 Jul 2, 2025
9 of 10 checks passed
@ggazzo ggazzo deleted the regression/unread-banner-thread branch July 2, 2025 04:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

stat: QA assured Means it has been tested and approved by a company insider stat: ready to merge PR tested and approved waiting for merge

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants