Skip to content

fix: Refactor Starred Messages to use useInfiniteQuery for non-blockin…#39238

Open
iramsk02 wants to merge 1 commit intoRocketChat:developfrom
iramsk02:fix/refactor-starred-messages-infinite-query
Open

fix: Refactor Starred Messages to use useInfiniteQuery for non-blockin…#39238
iramsk02 wants to merge 1 commit intoRocketChat:developfrom
iramsk02:fix/refactor-starred-messages-infinite-query

Conversation

@iramsk02
Copy link

@iramsk02 iramsk02 commented Mar 2, 2026

refactor: Use useInfiniteQuery for non-blocking Starred Messages pagination

Proposed changes

Refactored the Starred Messages tab to use @tanstack/react-query's useInfiniteQuery for non-blocking, streamed pagination.
The big picture:
Previously, opening the Starred Messages sidebar triggered a sequential await loop (waterfall) that fetched every single page of starred messages before rendering any results. This blocked the UI and caused significant delays for users with many starred items.
Technical context:

  • Updated the shared MessageListTab.tsx component to handle both standard UseQueryResult and UseInfiniteQueryResult using type narrowing (Array.isArray).
  • Implemented data "flattening" in the shared component so Virtuoso can still render a single continuous list while supporting background fetching.
  • Integrated endReached callback in Virtuoso to trigger the fetchNextPage streaming automatically.
  • Fixed a bug where the sidebar's "Close" button functionality was accidentally overwritten during manual edits.

Issue(s)

Relates to performance goals for the Activity Hub project. #39237.

Steps to test or reproduce

  1. Go to any room and star ~30-50 messages.
  2. Open the "Starred Messages" sidebar.
  3. Observe that the list loads the first 25 messages immediately without staying in an elongated loading state.
  4. Scroll to the bottom and verify (via Network Tab) that a new request with offset=25 is triggered.
  5. Click the "X" close button to ensure the sidebar still closes correctly.

For testing, the offset is 2
https://github.com/user-attachments/assets/4f3c2baa-b783-4aaf-be83-c4a112343077

Summary by CodeRabbit

  • New Features

    • Infinite-scroll support for message lists with automatic incremental loading when reaching the end.
  • Improvements

    • Improved rendering of paginated message data by flattening pages for smoother display and better performance with large lists.
    • Starred messages now load via paginated requests, reducing initial load and improving responsiveness during navigation.

@iramsk02 iramsk02 requested a review from a team as a code owner March 2, 2026 07:03
@dionisio-bot
Copy link
Contributor

dionisio-bot bot commented Mar 2, 2026

Looks like this PR is not ready to merge, because of the following issues:

  • This PR is missing the 'stat: QA assured' label
  • This PR is missing the required milestone or project

Please fix the issues and try again

If you have any trouble, please check the PR guidelines

@changeset-bot
Copy link

changeset-bot bot commented Mar 2, 2026

⚠️ No Changeset found

Latest commit: 322ddd1

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

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Mar 2, 2026

Walkthrough

Message list contextual components were updated to support paginated infinite queries: MessageListTab accepts either standard or infinite query results, flattens paginated data into a memoized messages array and exposes an end-reached handler; StarredMessagesTab was migrated from useQuery to useInfiniteQuery with page-based fetching.

Changes

Cohort / File(s) Summary
Contextual bar message list components
apps/meteor/client/views/room/contextualBar/MessageListTab.tsx, apps/meteor/client/views/room/contextualBar/StarredMessagesTab.tsx
Refactored to support useInfiniteQuery. MessageListTab now accepts `UseQueryResult<IMessage[]>

Sequence Diagram(s)

sequenceDiagram
  participant User as User
  participant UI as MessageListTab (Virtuoso)
  participant Q as ReactQuery (useInfiniteQuery)
  participant API as Server API
  User->>UI: scrolls to end
  UI->>Q: call fetchNextPage()
  Q->>API: GET /messages?offset=pageParam&count=25
  API-->>Q: { messages: [...], total: N }
  Q-->>UI: new page appended (pages -> flattened messages)
  UI->>User: render additional messages
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the primary objective: refactoring Starred Messages to use useInfiniteQuery for non-blocking pagination, matching the main changes across both modified files.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@iramsk02 iramsk02 changed the title fix:Refactor Starred Messages to use useInfiniteQuery for non-blockin… fix: Refactor Starred Messages to use useInfiniteQuery for non-blockin… Mar 2, 2026
@coderabbitai coderabbitai bot added the type: feature Pull requests that introduces new feature label Mar 2, 2026
Copy link
Contributor

@cubic-dev-ai cubic-dev-ai bot left a comment

Choose a reason for hiding this comment

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

No issues found across 2 files


Since this is your first cubic review, here's how it works:

  • cubic automatically reviews your code and comments on bugs and improvements
  • Teach cubic by replying to its comments. cubic learns from your replies and gets better over time
  • Add one-off context when rerunning by tagging @cubic-dev-ai with guidance or docs links (including llms.txt)
  • Ask questions if you need clarification on any suggestion

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🧹 Nitpick comments (1)
apps/meteor/client/views/room/contextualBar/MessageListTab.tsx (1)

35-47: Replace any with typed page structure to ensure type safety in message flattening.

Line 35 uses UseInfiniteQueryResult<any> and line 46 uses page: any, which allows non-array objects into the messages array. Introduce a concrete page type that matches your query structure:

♻️ Proposed typed flattening
+type InfiniteMessagePage = IMessage[] | { items?: IMessage[]; messages?: IMessage[] };
+
 type MessageListTabProps = {
 	iconName: IconName;
 	title: ReactNode;
 	emptyResultMessage: string;
 	context: MessageActionContext;
-	queryResult: UseQueryResult<IMessage[]> | UseInfiniteQueryResult<any>;
+	queryResult: UseQueryResult<IMessage[]> | UseInfiniteQueryResult<InfiniteMessagePage>;
 };
@@
-		return queryResult.data.pages.flatMap((page: any) => page.items || page.messages || page);
+		return queryResult.data.pages.flatMap((page) => {
+			if (Array.isArray(page)) {
+				return page;
+			}
+			return page.items ?? page.messages ?? [];
+		});
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@apps/meteor/client/views/room/contextualBar/MessageListTab.tsx` around lines
35 - 47, The messages flattening uses untyped infinite-query pages so non-array
values can leak into messages; define a concrete page type (e.g., interface
InfiniteMessagesPage { items?: IMessage[]; messages?: IMessage[]; data?:
IMessage[] } or similar to match your API) and replace
UseInfiniteQueryResult<any> with UseInfiniteQueryResult<InfiniteMessagesPage> in
MessageListTabProps, then update the useMemo to type the page parameter as
InfiniteMessagesPage when doing queryResult.data.pages.flatMap to ensure the
fallback expressions (items/messages/data) are strongly typed and only
IMessage[] are returned by MessageListTab's messages variable.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@apps/meteor/client/views/room/contextualBar/MessageListTab.tsx`:
- Around line 58-62: The handleEndReached handler should avoid firing duplicate
page loads by checking the queryResult.isFetchingNextPage flag before calling
queryResult.fetchNextPage; update the handleEndReached callback (the function
named handleEndReached that currently checks 'fetchNextPage' in queryResult and
queryResult.hasNextPage) to return early if queryResult.isFetchingNextPage is
true, and when invoking queryResult.fetchNextPage call it without awaiting
(marking the Promise as intentionally unawaited, e.g., void
queryResult.fetchNextPage()) so concurrent fetches are prevented.

In `@apps/meteor/client/views/room/contextualBar/StarredMessagesTab.tsx`:
- Line 21: In StarredMessagesTab
(apps/meteor/client/views/room/contextualBar/StarredMessagesTab.tsx) remove the
inline implementation comment "// Map and normalize messages for THIS page only"
from inside the component/handler where messages are being mapped; do not
replace it with another implementation-style comment—if documentation is needed,
move it to a top-level JSDoc or commit message instead.

---

Nitpick comments:
In `@apps/meteor/client/views/room/contextualBar/MessageListTab.tsx`:
- Around line 35-47: The messages flattening uses untyped infinite-query pages
so non-array values can leak into messages; define a concrete page type (e.g.,
interface InfiniteMessagesPage { items?: IMessage[]; messages?: IMessage[];
data?: IMessage[] } or similar to match your API) and replace
UseInfiniteQueryResult<any> with UseInfiniteQueryResult<InfiniteMessagesPage> in
MessageListTabProps, then update the useMemo to type the page parameter as
InfiniteMessagesPage when doing queryResult.data.pages.flatMap to ensure the
fallback expressions (items/messages/data) are strongly typed and only
IMessage[] are returned by MessageListTab's messages variable.

ℹ️ Review info

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 3c30636 and b044f15.

📒 Files selected for processing (2)
  • apps/meteor/client/views/room/contextualBar/MessageListTab.tsx
  • apps/meteor/client/views/room/contextualBar/StarredMessagesTab.tsx
📜 Review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: cubic · AI code reviewer
🧰 Additional context used
📓 Path-based instructions (1)
**/*.{ts,tsx,js}

📄 CodeRabbit inference engine (.cursor/rules/playwright.mdc)

**/*.{ts,tsx,js}: Write concise, technical TypeScript/JavaScript with accurate typing in Playwright tests
Avoid code comments in the implementation

Files:

  • apps/meteor/client/views/room/contextualBar/MessageListTab.tsx
  • apps/meteor/client/views/room/contextualBar/StarredMessagesTab.tsx
🧠 Learnings (4)
📓 Common learnings
Learnt from: ggazzo
Repo: RocketChat/Rocket.Chat PR: 35995
File: apps/meteor/app/api/server/v1/rooms.ts:1107-1112
Timestamp: 2026-02-23T17:53:18.785Z
Learning: In Rocket.Chat PR reviews, maintain strict scope boundaries—when a PR is focused on a specific endpoint (e.g., rooms.favorite), avoid reviewing or suggesting changes to other endpoints that were incidentally refactored (e.g., rooms.invite) unless explicitly requested by maintainers.
Learnt from: juliajforesti
Repo: RocketChat/Rocket.Chat PR: 38493
File: apps/meteor/tests/e2e/page-objects/fragments/home-content.ts:60-82
Timestamp: 2026-02-24T19:36:55.089Z
Learning: In RocketChat/Rocket.Chat e2e tests (apps/meteor/tests/e2e/page-objects/fragments/home-content.ts), thread message preview listitems do not have aria-roledescription="message", so lastThreadMessagePreview locator cannot be scoped to messageListItems (which filters for aria-roledescription="message"). It should remain scoped to page.getByRole('listitem') or mainMessageList.getByRole('listitem').
📚 Learning: 2026-02-24T19:36:55.089Z
Learnt from: juliajforesti
Repo: RocketChat/Rocket.Chat PR: 38493
File: apps/meteor/tests/e2e/page-objects/fragments/home-content.ts:60-82
Timestamp: 2026-02-24T19:36:55.089Z
Learning: In RocketChat/Rocket.Chat e2e tests (apps/meteor/tests/e2e/page-objects/fragments/home-content.ts), thread message preview listitems do not have aria-roledescription="message", so lastThreadMessagePreview locator cannot be scoped to messageListItems (which filters for aria-roledescription="message"). It should remain scoped to page.getByRole('listitem') or mainMessageList.getByRole('listitem').

Applied to files:

  • apps/meteor/client/views/room/contextualBar/MessageListTab.tsx
📚 Learning: 2025-12-02T22:23:49.593Z
Learnt from: d-gubert
Repo: RocketChat/Rocket.Chat PR: 37654
File: apps/meteor/client/hooks/useAppSlashCommands.ts:32-38
Timestamp: 2025-12-02T22:23:49.593Z
Learning: In apps/meteor/client/hooks/useAppSlashCommands.ts, the `data?.forEach((command) => slashCommands.add(command))` call during render is intentional. The query is configured with `structuralSharing: false` to prevent React Query from keeping stable data references, and `slashCommands.add` is idempotent, so executing on every render is acceptable and ensures the command registry stays current.

Applied to files:

  • apps/meteor/client/views/room/contextualBar/MessageListTab.tsx
  • apps/meteor/client/views/room/contextualBar/StarredMessagesTab.tsx
📚 Learning: 2026-02-25T20:10:16.987Z
Learnt from: ahmed-n-abdeltwab
Repo: RocketChat/Rocket.Chat PR: 38913
File: packages/ddp-client/src/legacy/types/SDKLegacy.ts:34-34
Timestamp: 2026-02-25T20:10:16.987Z
Learning: In the RocketChat/Rocket.Chat monorepo, packages/ddp-client and apps/meteor do not use TypeScript project references. Module augmentations in apps/meteor (e.g., declare module 'rocket.chat/rest-typings') are not visible when compiling packages/ddp-client in isolation, which is why legacy SDK methods that depend on OperationResult types for OpenAPI-migrated endpoints must remain commented out.

Applied to files:

  • apps/meteor/client/views/room/contextualBar/MessageListTab.tsx
🧬 Code graph analysis (2)
apps/meteor/client/views/room/contextualBar/MessageListTab.tsx (1)
packages/ui-contexts/src/index.ts (2)
  • useUserPreference (86-86)
  • useRoomToolbox (62-62)
apps/meteor/client/views/room/contextualBar/StarredMessagesTab.tsx (1)
apps/meteor/client/lib/queryKeys.ts (1)
  • roomsQueryKeys (13-38)
🔇 Additional comments (2)
apps/meteor/client/views/room/contextualBar/StarredMessagesTab.tsx (1)

16-34: Good infinite pagination flow.

The useInfiniteQuery setup (paged queryFn, initialPageParam, and getNextPageParam) is clean and aligns with the non-blocking loading objective.

apps/meteor/client/views/room/contextualBar/MessageListTab.tsx (1)

54-56: Close button callback wiring looks correct.

This callback cleanly delegates to closeTab and restores the expected contextual bar close behavior.

@iramsk02 iramsk02 force-pushed the fix/refactor-starred-messages-infinite-query branch from b044f15 to 884acab Compare March 2, 2026 12:52
@coderabbitai coderabbitai bot added type: bug and removed type: feature Pull requests that introduces new feature labels Mar 2, 2026
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (1)
apps/meteor/client/views/room/contextualBar/MessageListTab.tsx (1)

35-47: Tighten infinite-query typing and page flattening.

Lines 35 and 46 rely on any and || page, which can leak non-message objects into messages. The only infinite-query consumer (StarredMessagesTab) returns { messages, total }, but the fallback || page could pass the entire page object (including metadata) if the structure diverges. Prefer explicit page typing and null-coalescing (??) over short-circuit operators.

Proposed refactor
-type MessageListTabProps = {
+type InfiniteMessagesPage = { messages: IMessage[]; total: number } | { items: IMessage[]; itemCount: number };
+
+type MessageListTabProps = {
 	iconName: IconName;
 	title: ReactNode;
 	emptyResultMessage: string;
 	context: MessageActionContext;
-	queryResult: UseQueryResult<IMessage[]> | UseInfiniteQueryResult<any>;
+	queryResult: UseQueryResult<IMessage[]> | UseInfiniteQueryResult<InfiniteMessagesPage>;
 };
@@
-		return queryResult.data.pages.flatMap((page: any) => page.items || page.messages || page);
+		return queryResult.data.pages.flatMap((page) => {
+			if (Array.isArray(page)) {
+				return page;
+			}
+			return (page.items ?? page.messages ?? []) as IMessage[];
+		});
 	}, [queryResult.data]);
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@apps/meteor/client/views/room/contextualBar/MessageListTab.tsx` around lines
35 - 47, The messages useMemo in MessageListTab accepts a loosely typed
queryResult and flattens pages with "any" and a fallback "|| page", which can
leak non-message objects; tighten the typing by specifying
UseInfiniteQueryResult<{ messages: IMessage[]; total?: number }> (or the exact
page shape used by StarredMessagesTab) instead of any, and change the flatten
logic in the useMemo to explicitly pick known arrays and use null-coalescing
(e.g., page.messages ?? page.items ?? []) when building messages; update the
MessageListTabProps queryResult type and the useMemo flattening to rely on these
explicit types and null-coalescing so only IMessage[] elements are returned.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@apps/meteor/client/views/room/contextualBar/StarredMessagesTab.tsx`:
- Line 19: The pagination call in StarredMessagesTab uses a test page size
(getStarredMessages({ roomId: room._id, offset, count: 2 })) which should be
replaced with the normal page size constant or value to avoid excessive
requests; update the call in the StarredMessagesTab component to use the shared
page-size constant (or 25) instead of hardcoded 2, ensuring any imports or
references to the constant (e.g., PAGE_SIZE or USERS_PER_PAGE) are
added/adjusted accordingly.

---

Nitpick comments:
In `@apps/meteor/client/views/room/contextualBar/MessageListTab.tsx`:
- Around line 35-47: The messages useMemo in MessageListTab accepts a loosely
typed queryResult and flattens pages with "any" and a fallback "|| page", which
can leak non-message objects; tighten the typing by specifying
UseInfiniteQueryResult<{ messages: IMessage[]; total?: number }> (or the exact
page shape used by StarredMessagesTab) instead of any, and change the flatten
logic in the useMemo to explicitly pick known arrays and use null-coalescing
(e.g., page.messages ?? page.items ?? []) when building messages; update the
MessageListTabProps queryResult type and the useMemo flattening to rely on these
explicit types and null-coalescing so only IMessage[] elements are returned.

ℹ️ Review info

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between b044f15 and 884acab.

📒 Files selected for processing (2)
  • apps/meteor/client/views/room/contextualBar/MessageListTab.tsx
  • apps/meteor/client/views/room/contextualBar/StarredMessagesTab.tsx
📜 Review details
🧰 Additional context used
📓 Path-based instructions (1)
**/*.{ts,tsx,js}

📄 CodeRabbit inference engine (.cursor/rules/playwright.mdc)

**/*.{ts,tsx,js}: Write concise, technical TypeScript/JavaScript with accurate typing in Playwright tests
Avoid code comments in the implementation

Files:

  • apps/meteor/client/views/room/contextualBar/StarredMessagesTab.tsx
  • apps/meteor/client/views/room/contextualBar/MessageListTab.tsx
🧠 Learnings (9)
📓 Common learnings
Learnt from: ggazzo
Repo: RocketChat/Rocket.Chat PR: 35995
File: apps/meteor/app/api/server/v1/rooms.ts:1107-1112
Timestamp: 2026-02-23T17:53:18.785Z
Learning: In Rocket.Chat PR reviews, maintain strict scope boundaries—when a PR is focused on a specific endpoint (e.g., rooms.favorite), avoid reviewing or suggesting changes to other endpoints that were incidentally refactored (e.g., rooms.invite) unless explicitly requested by maintainers.
Learnt from: juliajforesti
Repo: RocketChat/Rocket.Chat PR: 38493
File: apps/meteor/tests/e2e/page-objects/fragments/home-content.ts:60-82
Timestamp: 2026-02-24T19:36:55.089Z
Learning: In RocketChat/Rocket.Chat e2e tests (apps/meteor/tests/e2e/page-objects/fragments/home-content.ts), thread message preview listitems do not have aria-roledescription="message", so lastThreadMessagePreview locator cannot be scoped to messageListItems (which filters for aria-roledescription="message"). It should remain scoped to page.getByRole('listitem') or mainMessageList.getByRole('listitem').
📚 Learning: 2025-12-02T22:23:49.593Z
Learnt from: d-gubert
Repo: RocketChat/Rocket.Chat PR: 37654
File: apps/meteor/client/hooks/useAppSlashCommands.ts:32-38
Timestamp: 2025-12-02T22:23:49.593Z
Learning: In apps/meteor/client/hooks/useAppSlashCommands.ts, the `data?.forEach((command) => slashCommands.add(command))` call during render is intentional. The query is configured with `structuralSharing: false` to prevent React Query from keeping stable data references, and `slashCommands.add` is idempotent, so executing on every render is acceptable and ensures the command registry stays current.

Applied to files:

  • apps/meteor/client/views/room/contextualBar/StarredMessagesTab.tsx
  • apps/meteor/client/views/room/contextualBar/MessageListTab.tsx
📚 Learning: 2025-11-24T17:08:17.065Z
Learnt from: CR
Repo: RocketChat/Rocket.Chat PR: 0
File: .cursor/rules/playwright.mdc:0-0
Timestamp: 2025-11-24T17:08:17.065Z
Learning: Applies to **/*.{ts,tsx,js} : Avoid code comments in the implementation

Applied to files:

  • apps/meteor/client/views/room/contextualBar/StarredMessagesTab.tsx
📚 Learning: 2026-01-17T01:51:47.764Z
Learnt from: tassoevan
Repo: RocketChat/Rocket.Chat PR: 38219
File: packages/core-typings/src/cloud/Announcement.ts:5-6
Timestamp: 2026-01-17T01:51:47.764Z
Learning: In packages/core-typings/src/cloud/Announcement.ts, the AnnouncementSchema.createdBy field intentionally overrides IBannerSchema.createdBy (object with _id and optional username) with a string enum ['cloud', 'system'] to match existing runtime behavior. This is documented as technical debt with a FIXME comment at apps/meteor/app/cloud/server/functions/syncWorkspace/handleCommsSync.ts:53 and should not be flagged as an error until the runtime behavior is corrected.

Applied to files:

  • apps/meteor/client/views/room/contextualBar/StarredMessagesTab.tsx
📚 Learning: 2026-02-24T19:36:55.089Z
Learnt from: juliajforesti
Repo: RocketChat/Rocket.Chat PR: 38493
File: apps/meteor/tests/e2e/page-objects/fragments/home-content.ts:60-82
Timestamp: 2026-02-24T19:36:55.089Z
Learning: In RocketChat/Rocket.Chat e2e tests (apps/meteor/tests/e2e/page-objects/fragments/home-content.ts), thread message preview listitems do not have aria-roledescription="message", so lastThreadMessagePreview locator cannot be scoped to messageListItems (which filters for aria-roledescription="message"). It should remain scoped to page.getByRole('listitem') or mainMessageList.getByRole('listitem').

Applied to files:

  • apps/meteor/client/views/room/contextualBar/StarredMessagesTab.tsx
  • apps/meteor/client/views/room/contextualBar/MessageListTab.tsx
📚 Learning: 2026-02-24T19:09:09.561Z
Learnt from: ahmed-n-abdeltwab
Repo: RocketChat/Rocket.Chat PR: 38974
File: apps/meteor/app/api/server/v1/im.ts:220-221
Timestamp: 2026-02-24T19:09:09.561Z
Learning: In RocketChat/Rocket.Chat OpenAPI migration PRs for apps/meteor/app/api/server/v1 endpoints, maintainers prefer to avoid any logic changes; style-only cleanups (like removing inline comments) may be deferred to follow-ups to keep scope tight.

Applied to files:

  • apps/meteor/client/views/room/contextualBar/StarredMessagesTab.tsx
📚 Learning: 2025-11-10T19:06:20.146Z
Learnt from: MartinSchoeler
Repo: RocketChat/Rocket.Chat PR: 37408
File: apps/meteor/client/views/admin/ABAC/useRoomAttributeOptions.tsx:53-69
Timestamp: 2025-11-10T19:06:20.146Z
Learning: In the Rocket.Chat repository, do not provide suggestions or recommendations about code sections marked with TODO comments. The maintainers have already identified these as future work and external reviewers lack the full context about implementation plans and timing.

Applied to files:

  • apps/meteor/client/views/room/contextualBar/StarredMessagesTab.tsx
📚 Learning: 2026-02-25T20:10:16.987Z
Learnt from: ahmed-n-abdeltwab
Repo: RocketChat/Rocket.Chat PR: 38913
File: packages/ddp-client/src/legacy/types/SDKLegacy.ts:34-34
Timestamp: 2026-02-25T20:10:16.987Z
Learning: In the RocketChat/Rocket.Chat monorepo, packages/ddp-client and apps/meteor do not use TypeScript project references. Module augmentations in apps/meteor (e.g., declare module 'rocket.chat/rest-typings') are not visible when compiling packages/ddp-client in isolation, which is why legacy SDK methods that depend on OperationResult types for OpenAPI-migrated endpoints must remain commented out.

Applied to files:

  • apps/meteor/client/views/room/contextualBar/StarredMessagesTab.tsx
📚 Learning: 2026-02-24T19:16:35.307Z
Learnt from: sampaiodiego
Repo: RocketChat/Rocket.Chat PR: 39003
File: apps/meteor/client/lib/chats/flows/sendMessage.ts:39-45
Timestamp: 2026-02-24T19:16:35.307Z
Learning: In apps/meteor/client/lib/chats/flows/sendMessage.ts, when sdk.call('sendMessage', ...) throws an error, the message is intentionally left with temp: true (not deleted or cleaned up) to support a future retry UI feature. This allows users to retry sending failed messages rather than losing them.

Applied to files:

  • apps/meteor/client/views/room/contextualBar/StarredMessagesTab.tsx
🧬 Code graph analysis (1)
apps/meteor/client/views/room/contextualBar/MessageListTab.tsx (3)
packages/ui-contexts/src/index.ts (2)
  • useUserPreference (86-86)
  • useRoomToolbox (62-62)
packages/ui-contexts/src/hooks/useRoomToolbox.ts (1)
  • useRoomToolbox (6-6)
packages/ui-client/src/components/Contextualbar/index.ts (1)
  • ContextualbarEmptyContent (34-34)
🔇 Additional comments (1)
apps/meteor/client/views/room/contextualBar/MessageListTab.tsx (1)

58-62: Nice guard for boundary-triggered pagination.

Line 59’s !queryResult.isFetchingNextPage check plus void queryResult.fetchNextPage() is the right non-blocking pattern here.

@iramsk02 iramsk02 force-pushed the fix/refactor-starred-messages-infinite-query branch from 884acab to 322ddd1 Compare March 2, 2026 13:54
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

🧹 Nitpick comments (2)
apps/meteor/client/views/room/contextualBar/StarredMessagesTab.tsx (1)

21-21: Remove stray whitespace line.

This line appears to be leftover from the removed inline comment. Consider removing the empty whitespace.

Suggested fix
 		const result = await getStarredMessages({ roomId: room._id, offset, count: 25 });
-
-			
+
 			const messages = await Promise.all(
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@apps/meteor/client/views/room/contextualBar/StarredMessagesTab.tsx` at line
21, In the StarredMessagesTab.tsx component remove the stray empty whitespace
line left from a removed inline comment (the blank line near the top of the
StarredMessagesTab component file); simply delete that empty line so there are
no unnecessary blank lines at the start of the file and ensure the surrounding
imports/exports (e.g., the StarredMessagesTab component declaration/export)
remain intact.
apps/meteor/client/views/room/contextualBar/MessageListTab.tsx (1)

35-35: Consider adding a more specific type for UseInfiniteQueryResult.

Using any here loses type safety for paginated data. Consider defining a page shape type to improve inference and catch potential mismatches:

type MessagePage = { messages: IMessage[]; total: number };
queryResult: UseQueryResult<IMessage[]> | UseInfiniteQueryResult<InfiniteData<MessagePage>>;

This is optional since the current approach works and the memoized derivation handles the shape defensively.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@apps/meteor/client/views/room/contextualBar/MessageListTab.tsx` at line 35,
The union type for queryResult currently uses UseInfiniteQueryResult<any>, which
loses type safety; define a specific page shape (e.g., MessagePage with
messages: IMessage[] and total: number) and replace the any with
UseInfiniteQueryResult<InfiniteData<MessagePage>> (or
UseInfiniteQueryResult<MessagePage> depending on your imports) so paginated
results are strongly typed; update the type of queryResult accordingly and
adjust any downstream uses that assume the page shape to use the new
MessagePage/InfiniteData structure.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@apps/meteor/client/views/room/contextualBar/MessageListTab.tsx`:
- Line 35: The union type for queryResult currently uses
UseInfiniteQueryResult<any>, which loses type safety; define a specific page
shape (e.g., MessagePage with messages: IMessage[] and total: number) and
replace the any with UseInfiniteQueryResult<InfiniteData<MessagePage>> (or
UseInfiniteQueryResult<MessagePage> depending on your imports) so paginated
results are strongly typed; update the type of queryResult accordingly and
adjust any downstream uses that assume the page shape to use the new
MessagePage/InfiniteData structure.

In `@apps/meteor/client/views/room/contextualBar/StarredMessagesTab.tsx`:
- Line 21: In the StarredMessagesTab.tsx component remove the stray empty
whitespace line left from a removed inline comment (the blank line near the top
of the StarredMessagesTab component file); simply delete that empty line so
there are no unnecessary blank lines at the start of the file and ensure the
surrounding imports/exports (e.g., the StarredMessagesTab component
declaration/export) remain intact.

ℹ️ Review info

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 884acab and 322ddd1.

📒 Files selected for processing (2)
  • apps/meteor/client/views/room/contextualBar/MessageListTab.tsx
  • apps/meteor/client/views/room/contextualBar/StarredMessagesTab.tsx
📜 Review details
🧰 Additional context used
📓 Path-based instructions (1)
**/*.{ts,tsx,js}

📄 CodeRabbit inference engine (.cursor/rules/playwright.mdc)

**/*.{ts,tsx,js}: Write concise, technical TypeScript/JavaScript with accurate typing in Playwright tests
Avoid code comments in the implementation

Files:

  • apps/meteor/client/views/room/contextualBar/StarredMessagesTab.tsx
  • apps/meteor/client/views/room/contextualBar/MessageListTab.tsx
🧠 Learnings (11)
📓 Common learnings
Learnt from: ggazzo
Repo: RocketChat/Rocket.Chat PR: 35995
File: apps/meteor/app/api/server/v1/rooms.ts:1107-1112
Timestamp: 2026-02-23T17:53:18.785Z
Learning: In Rocket.Chat PR reviews, maintain strict scope boundaries—when a PR is focused on a specific endpoint (e.g., rooms.favorite), avoid reviewing or suggesting changes to other endpoints that were incidentally refactored (e.g., rooms.invite) unless explicitly requested by maintainers.
Learnt from: juliajforesti
Repo: RocketChat/Rocket.Chat PR: 38493
File: apps/meteor/tests/e2e/page-objects/fragments/home-content.ts:60-82
Timestamp: 2026-02-24T19:36:55.089Z
Learning: In RocketChat/Rocket.Chat e2e tests (apps/meteor/tests/e2e/page-objects/fragments/home-content.ts), thread message preview listitems do not have aria-roledescription="message", so lastThreadMessagePreview locator cannot be scoped to messageListItems (which filters for aria-roledescription="message"). It should remain scoped to page.getByRole('listitem') or mainMessageList.getByRole('listitem').
📚 Learning: 2025-12-02T22:23:49.593Z
Learnt from: d-gubert
Repo: RocketChat/Rocket.Chat PR: 37654
File: apps/meteor/client/hooks/useAppSlashCommands.ts:32-38
Timestamp: 2025-12-02T22:23:49.593Z
Learning: In apps/meteor/client/hooks/useAppSlashCommands.ts, the `data?.forEach((command) => slashCommands.add(command))` call during render is intentional. The query is configured with `structuralSharing: false` to prevent React Query from keeping stable data references, and `slashCommands.add` is idempotent, so executing on every render is acceptable and ensures the command registry stays current.

Applied to files:

  • apps/meteor/client/views/room/contextualBar/StarredMessagesTab.tsx
  • apps/meteor/client/views/room/contextualBar/MessageListTab.tsx
📚 Learning: 2025-11-24T17:08:17.065Z
Learnt from: CR
Repo: RocketChat/Rocket.Chat PR: 0
File: .cursor/rules/playwright.mdc:0-0
Timestamp: 2025-11-24T17:08:17.065Z
Learning: Applies to **/*.{ts,tsx,js} : Avoid code comments in the implementation

Applied to files:

  • apps/meteor/client/views/room/contextualBar/StarredMessagesTab.tsx
📚 Learning: 2026-01-17T01:51:47.764Z
Learnt from: tassoevan
Repo: RocketChat/Rocket.Chat PR: 38219
File: packages/core-typings/src/cloud/Announcement.ts:5-6
Timestamp: 2026-01-17T01:51:47.764Z
Learning: In packages/core-typings/src/cloud/Announcement.ts, the AnnouncementSchema.createdBy field intentionally overrides IBannerSchema.createdBy (object with _id and optional username) with a string enum ['cloud', 'system'] to match existing runtime behavior. This is documented as technical debt with a FIXME comment at apps/meteor/app/cloud/server/functions/syncWorkspace/handleCommsSync.ts:53 and should not be flagged as an error until the runtime behavior is corrected.

Applied to files:

  • apps/meteor/client/views/room/contextualBar/StarredMessagesTab.tsx
📚 Learning: 2026-02-24T19:09:09.561Z
Learnt from: ahmed-n-abdeltwab
Repo: RocketChat/Rocket.Chat PR: 38974
File: apps/meteor/app/api/server/v1/im.ts:220-221
Timestamp: 2026-02-24T19:09:09.561Z
Learning: In RocketChat/Rocket.Chat OpenAPI migration PRs for apps/meteor/app/api/server/v1 endpoints, maintainers prefer to avoid any logic changes; style-only cleanups (like removing inline comments) may be deferred to follow-ups to keep scope tight.

Applied to files:

  • apps/meteor/client/views/room/contextualBar/StarredMessagesTab.tsx
📚 Learning: 2026-02-24T19:36:55.089Z
Learnt from: juliajforesti
Repo: RocketChat/Rocket.Chat PR: 38493
File: apps/meteor/tests/e2e/page-objects/fragments/home-content.ts:60-82
Timestamp: 2026-02-24T19:36:55.089Z
Learning: In RocketChat/Rocket.Chat e2e tests (apps/meteor/tests/e2e/page-objects/fragments/home-content.ts), thread message preview listitems do not have aria-roledescription="message", so lastThreadMessagePreview locator cannot be scoped to messageListItems (which filters for aria-roledescription="message"). It should remain scoped to page.getByRole('listitem') or mainMessageList.getByRole('listitem').

Applied to files:

  • apps/meteor/client/views/room/contextualBar/StarredMessagesTab.tsx
  • apps/meteor/client/views/room/contextualBar/MessageListTab.tsx
📚 Learning: 2025-11-10T19:06:20.146Z
Learnt from: MartinSchoeler
Repo: RocketChat/Rocket.Chat PR: 37408
File: apps/meteor/client/views/admin/ABAC/useRoomAttributeOptions.tsx:53-69
Timestamp: 2025-11-10T19:06:20.146Z
Learning: In the Rocket.Chat repository, do not provide suggestions or recommendations about code sections marked with TODO comments. The maintainers have already identified these as future work and external reviewers lack the full context about implementation plans and timing.

Applied to files:

  • apps/meteor/client/views/room/contextualBar/StarredMessagesTab.tsx
📚 Learning: 2026-02-25T20:10:16.987Z
Learnt from: ahmed-n-abdeltwab
Repo: RocketChat/Rocket.Chat PR: 38913
File: packages/ddp-client/src/legacy/types/SDKLegacy.ts:34-34
Timestamp: 2026-02-25T20:10:16.987Z
Learning: In the RocketChat/Rocket.Chat monorepo, packages/ddp-client and apps/meteor do not use TypeScript project references. Module augmentations in apps/meteor (e.g., declare module 'rocket.chat/rest-typings') are not visible when compiling packages/ddp-client in isolation, which is why legacy SDK methods that depend on OperationResult types for OpenAPI-migrated endpoints must remain commented out.

Applied to files:

  • apps/meteor/client/views/room/contextualBar/StarredMessagesTab.tsx
  • apps/meteor/client/views/room/contextualBar/MessageListTab.tsx
📚 Learning: 2026-02-24T19:16:35.307Z
Learnt from: sampaiodiego
Repo: RocketChat/Rocket.Chat PR: 39003
File: apps/meteor/client/lib/chats/flows/sendMessage.ts:39-45
Timestamp: 2026-02-24T19:16:35.307Z
Learning: In apps/meteor/client/lib/chats/flows/sendMessage.ts, when sdk.call('sendMessage', ...) throws an error, the message is intentionally left with temp: true (not deleted or cleaned up) to support a future retry UI feature. This allows users to retry sending failed messages rather than losing them.

Applied to files:

  • apps/meteor/client/views/room/contextualBar/StarredMessagesTab.tsx
📚 Learning: 2025-11-19T18:20:07.720Z
Learnt from: gabriellsh
Repo: RocketChat/Rocket.Chat PR: 37419
File: packages/i18n/src/locales/en.i18n.json:918-921
Timestamp: 2025-11-19T18:20:07.720Z
Learning: Repo: RocketChat/Rocket.Chat — i18n/formatting
Learning: This repository uses a custom message formatting parser in UI blocks/messages; do not assume standard Markdown rules. For keys like Call_ended_bold, Call_not_answered_bold, Call_failed_bold, and Call_transferred_bold in packages/i18n/src/locales/en.i18n.json, retain the existing single-asterisk emphasis unless maintainers request otherwise.

Applied to files:

  • apps/meteor/client/views/room/contextualBar/StarredMessagesTab.tsx
📚 Learning: 2025-11-24T17:08:17.065Z
Learnt from: CR
Repo: RocketChat/Rocket.Chat PR: 0
File: .cursor/rules/playwright.mdc:0-0
Timestamp: 2025-11-24T17:08:17.065Z
Learning: Applies to apps/meteor/tests/e2e/**/*.{ts,spec.ts} : Follow Page Object Model pattern consistently in Playwright tests

Applied to files:

  • apps/meteor/client/views/room/contextualBar/StarredMessagesTab.tsx
🧬 Code graph analysis (1)
apps/meteor/client/views/room/contextualBar/StarredMessagesTab.tsx (2)
apps/meteor/client/lib/queryKeys.ts (1)
  • roomsQueryKeys (13-38)
packages/livechat/src/lib/room.js (1)
  • messages (258-258)
🔇 Additional comments (5)
apps/meteor/client/views/room/contextualBar/StarredMessagesTab.tsx (2)

18-28: LGTM! Clean infinite query implementation.

The pagination logic is correct: pageParam as offset, proper page size (25), and getNextPageParam correctly sums loaded messages to compute the next offset. The message processing pipeline with Promise.all handles async normalization appropriately.


30-34: LGTM! Correct pagination boundary logic.

The getNextPageParam implementation properly accumulates loaded message counts across all pages and returns undefined when all items are fetched, which correctly signals to React Query that no more pages exist.

apps/meteor/client/views/room/contextualBar/MessageListTab.tsx (3)

39-47: LGTM! Well-structured type narrowing.

The memoized derivation correctly handles both query result shapes: direct array for UseQueryResult and flattened pages for UseInfiniteQueryResult. The Array.isArray check is a clean runtime type guard.


58-62: LGTM! Proper infinite scroll guard implemented.

The isFetchingNextPage check prevents duplicate fetch calls when endReached fires multiple times at the scroll boundary. The void prefix correctly marks the promise as intentionally unawaited.


88-94: LGTM! Clean Virtuoso integration.

The endReached callback is properly wired, and the itemContent correctly references the derived messages array for both current and previous message lookups, ensuring consistent behavior between standard and infinite query modes.

@iramsk02
Copy link
Author

iramsk02 commented Mar 2, 2026

@dougfabris Can you check this out??

@KevLehman KevLehman added the valid A valid contribution where maintainers will review based on priority label Mar 2, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

type: bug valid A valid contribution where maintainers will review based on priority

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants