Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: functionality to view unread messages and mark messages as read. #2353

Open
wants to merge 40 commits into
base: develop-postgres
Choose a base branch
from

Conversation

disha1202
Copy link

@disha1202 disha1202 commented Oct 25, 2024

What kind of change does this PR introduce?

Issue Number:

Fixes #2352

Did you add tests for your changes?

Snapshots/Videos:

If relevant, did you update the documentation?

Summary

Does this PR introduce a breaking change?

Other information

Have you read the contributing guide?

Summary by CodeRabbit

  • New Features

    • Enhanced chat functionality with new options to create chats and group chats.
    • Added ability to reply to messages in chat rooms.
    • Introduced tracking for unseen messages for better user engagement.
  • Bug Fixes

    • Improved localization support for various UI elements across multiple languages.
  • Tests

    • Expanded test coverage for chat functionalities, including unseen message tracking and message read states.
  • Style

    • Updated styles for improved layout and visual hierarchy in the ContactCard component.

Copy link

coderabbitai bot commented Oct 25, 2024

Walkthrough

The changes in this pull request involve updates to translation files for multiple languages, enhancing chat functionalities by adding new keys for user interactions. Additionally, the GraphQL schema and related components have been modified to support marking messages as read and managing unseen messages. The updates include the removal of certain mutations and the introduction of new ones, along with adjustments to the component logic for improved user experience and internationalization.

Changes

File Change Summary
public/locales/en/translation.json Added keys in userChat (create, newChat, newGroupChat) and userChatRoom (reply).
public/locales/fr/translation.json Added keys in userChat (add, create, newGroupChat) and userChatRoom (reply).
public/locales/hi/translation.json Added keys in userChat (add, create, newChat, newGroupChat) and userChatRoom (reply).
public/locales/sp/translation.json Added keys in userChat (add, create, newChat, newGroupChat) and userChatRoom (reply).
public/locales/zh/translation.json Added keys in userChat (add, create, newChat, newGroupChat) and userChatRoom (reply).
schema.graphql Removed type field from ChatMessage, modified sendMessageToChat, removed sendMessageToDirectChat and sendMessageToGroupChat, added markChatMessagesAsRead.
src/GraphQl/Mutations/OrganizationMutations.ts Removed CREATE_GROUP_CHAT, CREATE_DIRECT_CHAT, added MARK_CHAT_MESSAGES_AS_READ, updated MESSAGE_SENT_TO_CHAT.
src/GraphQl/Mutations/mutations.ts Removed export of CREATE_DIRECT_CHAT.
src/GraphQl/Queries/PlugInQueries.ts Added unseenMessagesByUsers field to CHAT_BY_ID and CHATS_LIST.
src/components/UserPortal/ChatRoom/ChatRoom.tsx Added MARK_CHAT_MESSAGES_AS_READ mutation, updated chat type, and modified useEffect for marking messages as read.
src/components/UserPortal/ContactCard/ContactCard.module.css Updated styles for .contactNameContainer, added .lastMessage and .unseenMessagesCount.
src/components/UserPortal/ContactCard/ContactCard.test.tsx Added properties unseenMessages and lastMessage to props.
src/components/UserPortal/ContactCard/ContactCard.tsx Added properties unseenMessages and lastMessage to props interface, updated rendering logic.
src/components/UserPortal/CreateDirectChat/CreateDirectChat.test.tsx Updated mocks to include MARK_CHAT_MESSAGES_AS_READ.
src/components/UserPortal/CreateDirectChat/CreateDirectChat.tsx Removed CREATE_DIRECT_CHAT, updated chatsListRefetch type.
src/components/UserPortal/CreateGroupChat/CreateGroupChat.test.tsx Added mock responses for MARK_CHAT_MESSAGES_AS_READ.
src/components/UserPortal/CreateGroupChat/CreateGroupChat.tsx Updated chatsListRefetch type, localized button text.
src/screens/UserPortal/Chat/Chat.test.tsx Added mock responses for MARK_CHAT_MESSAGES_AS_READ, updated test names.
src/screens/UserPortal/Chat/Chat.tsx Added markChatMessagesAsRead mutation, updated types and interfaces for better structure.

Assessment against linked issues

Objective Addressed Explanation
Add feature to view unread messages and mark messages as read in chat (#2352)

Possibly related PRs

Suggested labels

no-pr-activity

Suggested reviewers

  • DMills27
  • palisadoes

Poem

🐇 In the chat where messages flow,
New keys added, watch them grow!
Unseen counts and replies in sight,
Mark them read, make chats feel right!
With translations bright and clear,
Let's chat away, spread the cheer!


Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link

Our Pull Request Approval Process

We have these basic policies to make the approval process smoother for our volunteer team.

Testing Your Code

Please make sure your code passes all tests. Our test code coverage system will fail if these conditions occur:

  1. The overall code coverage drops below the target threshold of the repository
  2. Any file in the pull request has code coverage levels below the repository threshold
  3. Merge conflicts

The process helps maintain the overall reliability of the code base and is a prerequisite for getting your PR approved. Assigned reviewers regularly review the PR queue and tend to focus on PRs that are passing.

Reviewers

Do not assign reviewers. Our Queue Monitors will review your PR and assign them.
When your PR has been assigned reviewers contact them to get your code reviewed and approved via:

  1. comments in this PR or
  2. our slack channel

Reviewing Your Code

Your reviewer(s) will have the following roles:

  1. arbitrators of future discussions with other contributors about the validity of your changes
  2. point of contact for evaluating the validity of your work
  3. person who verifies matching issues by others that should be closed.
  4. person who gives general guidance in fixing your tests

CONTRIBUTING.md

Read our CONTRIBUTING.md file. Most importantly:

  1. PRs with issues not assigned to you will be closed by the reviewer
  2. Fix the first comment in the PR so that each issue listed automatically closes

Other

  1. 🎯 Please be considerate of our volunteers' time. Contacting the person who assigned the reviewers is not advised unless they ask for your input. Do not @ the person who did the assignment otherwise.
  2. Read the CONTRIBUTING.md file make

Copy link

codecov bot commented Oct 25, 2024

Codecov Report

Attention: Patch coverage is 82.35294% with 3 lines in your changes missing coverage. Please review.

Project coverage is 97.85%. Comparing base (6393648) to head (da51531).
Report is 45 commits behind head on develop.

Files with missing lines Patch % Lines
src/components/UserPortal/ChatRoom/ChatRoom.tsx 57.14% 3 Missing ⚠️
Additional details and impacted files
@@             Coverage Diff             @@
##           develop    #2353      +/-   ##
===========================================
- Coverage    97.98%   97.85%   -0.13%     
===========================================
  Files          244      244              
  Lines         6949     6960      +11     
  Branches      2009     2011       +2     
===========================================
+ Hits          6809     6811       +2     
- Misses         130      139       +9     
  Partials        10       10              

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

Copy link

@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: 24

🧹 Outside diff range and nitpick comments (11)
src/components/UserPortal/ContactCard/ContactCard.tsx (1)

Line range hint 17-33: Update JSDoc documentation to include new props.

The component's documentation is outdated and missing the new props. Please update it to include:

  • unseenMessages: Number of unread messages
  • lastMessage: The most recent message in the conversation
 * @param  selectedContact - The ID of the currently selected contact.
 * @param  setSelectedContact - Function to set the ID of the selected contact.
-* @param  setSelectedContactName - Function to set the name of the selected contact.
+* @param  unseenMessages - Number of unread messages in the conversation
+* @param  lastMessage - The most recent message in the conversation
+* @param  isGroup - Boolean indicating if the contact represents a group
src/GraphQl/Queries/PlugInQueries.ts (1)

151-151: Update JSDoc comments to include the new field.

The queries' documentation should be updated to include information about the unseenMessagesByUsers field for better maintainability and developer experience.

Add the new field to the @returns section of both query documentations:

 * @returns The list of direct chats associated with the user, including details such as ID, creator, messages, organization, and participating users.
+ *          The `unseenMessagesByUsers` field tracks messages that haven't been read by users.
 */

Also applies to: 191-191

src/GraphQl/Mutations/OrganizationMutations.ts (1)

80-86: Add JSDoc documentation for consistency.

Consider adding JSDoc documentation to match the style of other mutations in this file, describing the parameters and return value.

+/**
+ * GraphQL mutation to mark all messages in a chat as read for a specific user.
+ *
+ * @param chatId - The ID of the chat containing the messages
+ * @param userId - The ID of the user marking messages as read
+ * @returns The updated chat message object
+ */
 export const MARK_CHAT_MESSAGES_AS_READ = gql`
src/components/UserPortal/CreateDirectChat/CreateDirectChat.tsx (1)

195-195: Consider translating other hardcoded strings.

While it's good that the "Add" button text is now translated, there are other hardcoded strings in the component that should also use the translation system for consistency:

Apply similar changes to these hardcoded strings:

- <Modal.Title>{'Chat'}</Modal.Title>
+ <Modal.Title>{t('chat')}</Modal.Title>

- placeholder="searchFullName"
+ placeholder={t('searchFullName')}

- <StyledTableCell>#</StyledTableCell>
- <StyledTableCell align="center">{'user'}</StyledTableCell>
- <StyledTableCell align="center">{'Chat'}</StyledTableCell>
+ <StyledTableCell>{t('tableHeader.number')}</StyledTableCell>
+ <StyledTableCell align="center">{t('tableHeader.user')}</StyledTableCell>
+ <StyledTableCell align="center">{t('tableHeader.chat')}</StyledTableCell>
src/components/UserPortal/CreateGroupChat/CreateGroupChat.tsx (3)

Line range hint 191-391: Consider localizing remaining hardcoded strings.

There are several hardcoded strings in the component that should be internationalized for consistency:

  • "New Group"
  • "Group name"
  • "Next"
  • "Chat"
  • "searchFullName"
  • "Remove"
  • Table headers: "#", "user", "Chat"

Example implementation:

- <Modal.Title>New Group</Modal.Title>
+ <Modal.Title>{t('newGroup')}</Modal.Title>

- <Form.Label>Group name</Form.Label>
+ <Form.Label>{t('groupName')}</Form.Label>

- placeholder={'Group name'}
+ placeholder={t('groupName')}

- <Button>Next</Button>
+ <Button>{t('next')}</Button>

- <Modal.Title>{'Chat'}</Modal.Title>
+ <Modal.Title>{t('chat')}</Modal.Title>

- placeholder="searchFullName"
+ placeholder={t('searchFullName')}

- <Button variant="danger">Remove</Button>
+ <Button variant="danger">{t('remove')}</Button>

- <StyledTableCell>#</StyledTableCell>
- <StyledTableCell align="center">{'user'}</StyledTableCell>
- <StyledTableCell align="center">{'Chat'}</StyledTableCell>
+ <StyledTableCell>{t('tableIndex')}</StyledTableCell>
+ <StyledTableCell align="center">{t('user')}</StyledTableCell>
+ <StyledTableCell align="center">{t('chat')}</StyledTableCell>

Line range hint 191-205: Remove commented-out code.

There's a commented-out FormControl section that's duplicated below. Clean up the code by removing the commented section as it's redundant.


Line range hint 282-297: Add error handling for the createChat mutation.

The handleCreateGroupChat function should handle potential errors from the GraphQL mutation to provide better user feedback.

Example implementation:

 async function handleCreateGroupChat(): Promise<void> {
-  await createChat({
-    variables: {
-      organizationId: selectedOrganization,
-      userIds: [userId, ...userIds],
-      name: title,
-      isGroup: true,
-    },
-  });
-  chatsListRefetch();
-  toggleAddUserModal();
-  toggleCreateGroupChatModal();
-  reset();
+  try {
+    await createChat({
+      variables: {
+        organizationId: selectedOrganization,
+        userIds: [userId, ...userIds],
+        name: title,
+        isGroup: true,
+      },
+    });
+    await chatsListRefetch();
+    toggleAddUserModal();
+    toggleCreateGroupChatModal();
+    reset();
+  } catch (error) {
+    // Handle error appropriately (e.g., show error message to user)
+    console.error('Failed to create group chat:', error);
+  }
 }
schema.graphql (1)

766-767: Consider enhancing read status tracking.

While the current implementation allows marking messages as read, consider these enhancements for better message tracking:

  1. Add a lastReadMessageId field to track each user's read position
  2. Add a readBy field to ChatMessage type for granular read status
  3. Consider adding a subscription for read status updates

This would enable:

  • Unread message counts
  • Read receipts
  • More efficient message fetching
src/screens/UserPortal/Chat/Chat.test.tsx (1)

Line range hint 2724-2764: Add test coverage for mark-as-read functionality

The test case for "create new direct chat" lacks coverage for the new mark-as-read feature. Consider adding specific test cases to verify:

  1. Messages are marked as read when selecting a chat
  2. Error handling for failed mark-as-read requests
  3. UI updates after marking messages as read

Add new test cases:

test('marks messages as read when selecting a chat', async () => {
  // Setup mocks
  const mock = [
    ...MARK_CHAT_MESSAGES_AS_READ_MOCK,
    // Other required mocks
  ];
  
  // Render component
  render(
    <MockedProvider mocks={mock}>
      <Chat />
    </MockedProvider>
  );
  
  // Select a chat
  const chatItem = await screen.findByTestId('chat-item-1');
  fireEvent.click(chatItem);
  
  // Verify messages are marked as read
  await waitFor(() => {
    expect(screen.queryByTestId('unread-indicator')).not.toBeInTheDocument();
  });
});

test('handles mark-as-read errors gracefully', async () => {
  // Similar structure with error mock
});
src/components/UserPortal/CreateDirectChat/CreateDirectChat.test.tsx (2)

Line range hint 2775-2791: Standardize async testing patterns.

The test uses a mix of wait() and waitFor() for handling async operations. Standardize on waitFor() as it provides better error messages and retry behavior.

test('Open and close create new direct chat modal', async () => {
  render(/* ... */);
  
  await waitFor(() => {
    expect(screen.getByTestId('dropdown')).toBeInTheDocument();
  });
  
  fireEvent.click(screen.getByTestId('dropdown'));
  
  await waitFor(() => {
    expect(screen.getByTestId('newDirectChat')).toBeInTheDocument();
  });
  // Continue with standardized waitFor pattern
});

Line range hint 2827-2869: Add test cases for error scenarios and edge cases.

The current tests only cover the happy path. Consider adding test cases for:

  • Network errors in GraphQL mutations
  • Invalid user selections
  • Empty user list
  • Error handling when creating a chat fails

Would you like me to help generate additional test cases for these scenarios?

📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between 6393648 and da51531.

📒 Files selected for processing (19)
  • public/locales/en/translation.json (1 hunks)
  • public/locales/fr/translation.json (1 hunks)
  • public/locales/hi/translation.json (1 hunks)
  • public/locales/sp/translation.json (1 hunks)
  • public/locales/zh/translation.json (1 hunks)
  • schema.graphql (1 hunks)
  • src/GraphQl/Mutations/OrganizationMutations.ts (2 hunks)
  • src/GraphQl/Mutations/mutations.ts (0 hunks)
  • src/GraphQl/Queries/PlugInQueries.ts (2 hunks)
  • src/components/UserPortal/ChatRoom/ChatRoom.tsx (5 hunks)
  • src/components/UserPortal/ContactCard/ContactCard.module.css (2 hunks)
  • src/components/UserPortal/ContactCard/ContactCard.test.tsx (1 hunks)
  • src/components/UserPortal/ContactCard/ContactCard.tsx (3 hunks)
  • src/components/UserPortal/CreateDirectChat/CreateDirectChat.test.tsx (18 hunks)
  • src/components/UserPortal/CreateDirectChat/CreateDirectChat.tsx (3 hunks)
  • src/components/UserPortal/CreateGroupChat/CreateGroupChat.test.tsx (17 hunks)
  • src/components/UserPortal/CreateGroupChat/CreateGroupChat.tsx (3 hunks)
  • src/screens/UserPortal/Chat/Chat.test.tsx (20 hunks)
  • src/screens/UserPortal/Chat/Chat.tsx (9 hunks)
💤 Files with no reviewable changes (1)
  • src/GraphQl/Mutations/mutations.ts
🧰 Additional context used
🪛 Biome
src/screens/UserPortal/Chat/Chat.tsx

[error] 170-170: Change to an optional chain.

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)

🔇 Additional comments (24)
src/components/UserPortal/ContactCard/ContactCard.module.css (1)

23-25: LGTM! Layout changes improve element spacing.

The updated layout properties create a better structure for displaying contact name and unseen message count.

src/components/UserPortal/ContactCard/ContactCard.test.tsx (1)

35-36: Verify prop types in test setup.

The unseenMessages prop is initialized with a number, but it's recommended to verify if this matches the type definition in the component interface.

✅ Verification successful

Props match the component's type definition.

From the search results, we can see in src/components/UserPortal/ContactCard/ContactCard.tsx that unseenMessages is indeed defined as a number in the component's interface:

unseenMessages: number;

This matches the test setup where it's initialized with a numeric value of 2. The prop type is correctly used in the test.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for the ContactCard interface/type definition
ast-grep --pattern 'interface $interface {
  $$$
  unseenMessages$_
  $$$
}'

Length of output: 78


Script:

#!/bin/bash
# Let's try a different pattern to find type definitions for ContactCard
ast-grep --pattern 'type ContactCard = {
  $$$
  unseenMessages$_
  $$$
}'

# Also search for prop type definitions
ast-grep --pattern 'type ContactCardProps = {
  $$$
  unseenMessages$_
  $$$
}'

# Let's also try to find any interface or type containing unseenMessages
rg "unseenMessages.*:" -A 1 -B 1

Length of output: 26924

src/GraphQl/Queries/PlugInQueries.ts (1)

151-151: LGTM! The changes align with the feature requirements.

The addition of unseenMessagesByUsers to both queries is consistent and supports the PR objective of enabling users to view unread messages. The field placement is logical within the chat data structure.

Also applies to: 191-191

src/GraphQl/Mutations/OrganizationMutations.ts (1)

Line range hint 39-63: Good architectural decision to consolidate chat creation mutations.

The replacement of separate CREATE_GROUP_CHAT and CREATE_DIRECT_CHAT mutations with a single CREATE_CHAT mutation using an isGroup flag is a clean architectural improvement that reduces code duplication.

src/components/UserPortal/CreateDirectChat/CreateDirectChat.tsx (3)

28-31: LGTM! Improved type safety.

Good improvement in type safety:

  • Using string instead of any for the id parameter
  • Using unknown instead of any for the return type follows TypeScript best practices

Line range hint 1-207: Verify relationship to unread messages functionality.

While this component handles direct chat creation, it doesn't directly implement the PR's main objectives of viewing unread messages or marking messages as read. Could you clarify how this component fits into the larger feature implementation?

#!/bin/bash
# Description: Look for related changes implementing unread messages functionality

# Test 1: Search for unread message related code
echo "Checking for unread message related code:"
rg -i "unread|unseen|mark.*read" --type ts --type tsx

# Test 2: Search for related GraphQL operations
echo "Checking for related GraphQL operations:"
rg -i "mutation.*mark.*read|query.*(unread|unseen)" --type graphql

8-8: Verify the CREATE_CHAT mutation structure.

The switch from CREATE_DIRECT_CHAT to CREATE_CHAT suggests a consolidated mutation. Let's verify that the mutation structure matches the component's usage.

✅ Verification successful

The CREATE_CHAT mutation is correctly structured for both direct and group chats

The verification shows that the CREATE_CHAT mutation in OrganizationMutations.ts is properly consolidated to handle both direct and group chats through the isGroup parameter. The mutation structure matches the component's usage as evidenced by:

  • The mutation accepts required parameters: userIds, isGroup
  • Optional parameters: organizationId, name (for group chats)
  • Test files confirm correct usage for both direct chats (isGroup: false) and group chats (isGroup: true)
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify the CREATE_CHAT mutation structure and its usage

# Test 1: Check the mutation definition
echo "Checking CREATE_CHAT mutation definition:"
ast-grep --pattern 'const CREATE_CHAT = gql`
  mutation $_($$$) {
    $$$
  }
`'

# Test 2: Check for any other usages of CREATE_CHAT
echo "Checking other CREATE_CHAT usages:"
rg "CREATE_CHAT" -A 5

Length of output: 368


Script:

#!/bin/bash
# Let's try a different approach to verify the mutation structure and usage

# Check for GraphQL mutation files
echo "Checking for GraphQL mutation files:"
fd -e ts -e tsx -e graphql "Mutations" 

# Search for CREATE_CHAT or CREATE_DIRECT_CHAT in the codebase
echo -e "\nSearching for CREATE_CHAT and CREATE_DIRECT_CHAT:"
rg -l "CREATE_CHAT|CREATE_DIRECT_CHAT"

# If we find the files, let's look at their content
echo -e "\nChecking content of files containing mutations:"
rg "const CREATE_CHAT|const CREATE_DIRECT_CHAT" -A 10

Length of output: 3907

src/components/UserPortal/CreateGroupChat/CreateGroupChat.tsx (3)

39-39: LGTM! Good type safety improvement.

Changing from any to unknown is a good practice as it provides better type safety by requiring explicit type checking.


370-370: LGTM! Good internationalization improvements.

The button text has been properly internationalized using the translation hook.

Also applies to: 388-388


Line range hint 1-391: Verify alignment with PR objectives.

This component appears to be unrelated to the PR objectives of "viewing unread messages and marking messages as read". Please clarify how this component contributes to those objectives or if it should be part of a different PR.

Let's verify the relationship between this component and the PR objectives:

schema.graphql (1)

766-766: LGTM! Improved message sending with reply support.

The mutation signature has been simplified by removing the redundant 'type' parameter while adding support for message replies through the optional 'replyTo' parameter.

public/locales/zh/translation.json (2)

1162-1169: LGTM! Chat action translations are appropriate.

The Chinese translations for chat actions are contextually accurate and properly localized:

  • "添加" (add) - correct translation for adding contacts/chats
  • "创造" (create) - appropriate for creating new chats
  • "新聊天" (new chat) - clear and natural translation
  • "新群聊" (new group chat) - properly distinguishes group chat

1173-1174: LGTM! Message action translations are accurate.

The Chinese translations for message actions are clear and natural:

  • "发信息" (send message) - commonly used phrase
  • "回复" (reply) - correct translation for replying to messages
public/locales/en/translation.json (2)

1162-1169: LGTM: Chat creation translations added.

The new translations support chat creation functionality with clear, concise labels for creating both individual and group chats.


1173-1174: LGTM: Reply functionality translation added.

The addition of the "reply" translation supports the new reply feature in chat rooms.

public/locales/hi/translation.json (2)

1162-1169: LGTM! The Hindi translations for chat actions are accurate and natural.

The translations maintain proper semantic meaning while being culturally appropriate and easily understandable by Hindi speakers.


1173-1174: LGTM! The Hindi translations for chat room actions are well-translated.

The translations are concise and accurately convey the meaning of the English terms.

public/locales/fr/translation.json (2)

1162-1169: LGTM! The French translations for chat actions are accurate.

The translations maintain consistency with French language conventions and accurately convey the meaning of the chat-related actions.


1173-1174: LGTM! The French translations for message actions are accurate.

The translations "Envoyer le message" and "répondre" are grammatically correct and effectively convey the intended actions.

public/locales/sp/translation.json (2)

1163-1170: LGTM! Chat action translations are accurate.

The Spanish translations for chat actions and UI elements are linguistically correct and maintain consistency with the English version.


1174-1175: LGTM! Message action translations are accurate.

The Spanish translations for message actions are linguistically correct and maintain consistency with the English version.

src/screens/UserPortal/Chat/Chat.test.tsx (1)

Line range hint 2633-2672: LGTM: Well-structured test utilities

The test utilities are well-implemented with:

  • Proper async wait helper
  • Comprehensive window.matchMedia mock
  • Mocked scrollIntoView behavior
src/components/UserPortal/CreateGroupChat/CreateGroupChat.test.tsx (2)

1340-1343: LGTM: Consistent mock data structure for unread messages tracking.

The unseenMessagesByUsers field is well-structured and consistently implemented across all mock responses, properly representing the unread message counts per user.

Also applies to: 1404-1407, 1468-1471, 1560-1566, 1639-1645, 1732-1738, 1811-1817, 1983-1989, 2076-2082, 2155-2161, 2248-2254, 2327-2333, 2420-2426, 2499-2505, 2594-2600, 2691-2697, 2785-2791


2798-2875: Verify the empty chatId in MARK_CHAT_MESSAGES_AS_READ mock.

While the mutation mock is well-structured, using an empty string for chatId in the test cases might not accurately represent real-world scenarios and could mask potential issues.

Consider using valid chat IDs from the mock data:

- chatId: '',
+ chatId: '65844efc814dd4003db811c4',

Comment on lines +46 to +48
.unseenMessagesCount {
border-radius: 50%;
}
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

Add essential styles for the notification badge.

The current styling only makes the badge circular but lacks other necessary properties for a proper notification indicator.

 .unseenMessagesCount {
   border-radius: 50%;
+  background-color: #ff4444;  /* or your theme's notification color */
+  color: white;
+  min-width: 20px;
+  min-height: 20px;
+  padding: 2px 6px;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  font-size: 12px;
+  font-weight: bold;
 }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
.unseenMessagesCount {
border-radius: 50%;
}
.unseenMessagesCount {
border-radius: 50%;
background-color: #ff4444; /* or your theme's notification color */
color: white;
min-width: 20px;
min-height: 20px;
padding: 2px 6px;
display: flex;
align-items: center;
justify-content: center;
font-size: 12px;
font-weight: bold;
}

Comment on lines +40 to +44
.lastMessage {
margin-bottom: 0;
font-size: 14px;
color: rgba(163, 163, 163, 0.839);
}
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Consider adding text overflow handling for long messages.

The last message preview should gracefully handle long text to prevent layout issues.

 .lastMessage {
   margin-bottom: 0;
   font-size: 14px;
   color: rgba(163, 163, 163, 0.839);
+  white-space: nowrap;
+  overflow: hidden;
+  text-overflow: ellipsis;
+  max-width: 70%;  /* Adjust based on design needs */
 }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
.lastMessage {
margin-bottom: 0;
font-size: 14px;
color: rgba(163, 163, 163, 0.839);
}
.lastMessage {
margin-bottom: 0;
font-size: 14px;
color: rgba(163, 163, 163, 0.839);
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
max-width: 70%; /* Adjust based on design needs */
}

Comment on lines +72 to +75
<div>
<b>{props.title}</b>{' '}
<p className={styles.lastMessage}>{props.lastMessage}</p>
</div>
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Enhance accessibility and user experience.

Consider the following improvements:

  1. Add ARIA labels for better screen reader support
  2. Add text truncation for long messages to maintain consistent layout
-          <div>
+          <div role="text" aria-label={`Contact: ${props.title}`}>
             <b>{props.title}</b>{' '}
-            <p className={styles.lastMessage}>{props.lastMessage}</p>
+            <p className={`${styles.lastMessage} text-truncate`} title={props.lastMessage}>
+              {props.lastMessage}
+            </p>
           </div>

Don't forget to add the corresponding CSS:

.lastMessage {
  max-width: 200px; /* adjust based on your layout */
  margin-bottom: 0;
}

Comment on lines +13 to +14
unseenMessages: number;
lastMessage: any;
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Consider adding proper typing for lastMessage.

Using any type reduces type safety. Consider creating a proper interface for the message structure:

-  lastMessage: any;
+  lastMessage?: {
+    content: string;
+    timestamp?: Date;
+    // Add other relevant fields
+  };

Committable suggestion was skipped due to low confidence.

Comment on lines +76 to +80
{!!props.unseenMessages && (
<Badge className={styles.unseenMessagesCount}>
{props.unseenMessages}
</Badge>
)}
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Improve badge accessibility and code clarity.

The badge should be more accessible to screen readers and the boolean check could be more explicit.

-          {!!props.unseenMessages && (
+          {props.unseenMessages > 0 && (
             <Badge 
+              aria-label={`${props.unseenMessages} unread messages`}
+              role="status"
               className={styles.unseenMessagesCount}>
               {props.unseenMessages}
             </Badge>
           )}
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
{!!props.unseenMessages && (
<Badge className={styles.unseenMessagesCount}>
{props.unseenMessages}
</Badge>
)}
{props.unseenMessages > 0 && (
<Badge
aria-label={`${props.unseenMessages} unread messages`}
role="status"
className={styles.unseenMessagesCount}>
{props.unseenMessages}
</Badge>
)}

Comment on lines +280 to +281
chat.messages[chat.messages.length - 1]
?.messageContent,
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

Handle empty messages array to prevent errors

Accessing the last message without checking if the messages array is empty can lead to undefined values.

Apply this diff to safely access the last message:

-     lastMessage:
-       chat.messages[chat.messages.length - 1]
-         ?.messageContent,
+     lastMessage:
+       chat.messages && chat.messages.length > 0
+         ? chat.messages[chat.messages.length - 1]?.messageContent
+         : '',
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
chat.messages[chat.messages.length - 1]
?.messageContent,
chat.messages && chat.messages.length > 0
? chat.messages[chat.messages.length - 1]?.messageContent
: '',

React.useEffect(() => {
if (chatsListData) {
if (chatsListData && chatsListData?.chatsByUserId.length) {
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Simplify condition using optional chaining

You can simplify the condition by relying on optional chaining, making the code cleaner and more concise.

Apply this diff:

-     if (chatsListData && chatsListData?.chatsByUserId.length) {
+     if (chatsListData?.chatsByUserId?.length) {
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
if (chatsListData && chatsListData?.chatsByUserId.length) {
if (chatsListData?.chatsByUserId?.length) {
🧰 Tools
🪛 Biome

[error] 170-170: Change to an optional chain.

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)

Comment on lines +163 to +167
useEffect(() => {
markChatMessagesAsRead().then(() => {
chatsListRefetch({ id: userId });
});
}, [selectedContact]);
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

Add error handling for markChatMessagesAsRead mutation

In the useEffect hook, the markChatMessagesAsRead() mutation is called without error handling. If the mutation fails, it could result in unhandled promise rejections and the UI may not reflect the failure.

Apply this diff to handle errors:

 useEffect(() => {
-   markChatMessagesAsRead().then(() => {
-     chatsListRefetch({ id: userId });
-   });
+   markChatMessagesAsRead()
+     .then(() => {
+       chatsListRefetch({ id: userId });
+     })
+     .catch((error) => {
+       console.error('Error marking messages as read:', error);
+       // Optionally, display an error notification to the user
+     });
 }, [selectedContact]);
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
useEffect(() => {
markChatMessagesAsRead().then(() => {
chatsListRefetch({ id: userId });
});
}, [selectedContact]);
useEffect(() => {
markChatMessagesAsRead()
.then(() => {
chatsListRefetch({ id: userId });
})
.catch((error) => {
console.error('Error marking messages as read:', error);
// Optionally, display an error notification to the user
});
}, [selectedContact]);

Comment on lines +156 to +161
const [markChatMessagesAsRead] = useMutation(MARK_CHAT_MESSAGES_AS_READ, {
variables: {
chatId: selectedContact,
userId: userId,
},
});
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

Pass variables during mutation execution to prevent stale data

Passing variables in the useMutation hook options can cause stale data issues if selectedContact or userId changes. It's better to pass variables when calling the mutation to ensure they are up-to-date.

Apply this diff to pass variables during mutation execution:

-   const [markChatMessagesAsRead] = useMutation(MARK_CHAT_MESSAGES_AS_READ, {
-     variables: {
-       chatId: selectedContact,
-       userId: userId,
-     },
-   });
+   const [markChatMessagesAsRead] = useMutation(MARK_CHAT_MESSAGES_AS_READ);

Then, update the call in the useEffect hook:

 useEffect(() => {
-   markChatMessagesAsRead().then(() => {
+   markChatMessagesAsRead({
+     variables: {
+       chatId: selectedContact,
+       userId: userId,
+     },
+   })
+     .then(() => {
      chatsListRefetch({ id: userId });
    })
+     .catch((error) => {
+       console.error('Error marking messages as read:', error);
+       // Optionally, display an error notification to the user
+     });
 }, [selectedContact]);

Committable suggestion was skipped due to low confidence.

Comment on lines +276 to +278
unseenMessages: JSON.parse(chat.unseenMessagesByUsers)[
userId
],
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

Ensure safe parsing of JSON data

Using JSON.parse without error handling can lead to runtime exceptions if the data is invalid. It's safer to add error handling when parsing JSON.

Apply this diff to add error handling:

-     unseenMessages: JSON.parse(chat.unseenMessagesByUsers)[
-       userId
-     ],
+     let unseenMessages = 0;
+     try {
+       const unseenMessagesData = JSON.parse(chat.unseenMessagesByUsers);
+       unseenMessages = unseenMessagesData[userId] || 0;
+     } catch (error) {
+       console.error('Failed to parse unseenMessagesByUsers:', error);
+     }
+     // Pass unseenMessages to cardProps

Alternatively, ensure that chat.unseenMessagesByUsers is parsed before being passed to this component.

Committable suggestion was skipped due to low confidence.

Copy link

github-actions bot commented Nov 5, 2024

This pull request did not get any activity in the past 10 days and will be closed in 180 days if no update occurs. Please verify it has no conflicts with the develop branch and rebase if needed. Mention it now if you need help or give permission to other people to finish your work.

@github-actions github-actions bot added the no-pr-activity No pull request activity label Nov 5, 2024
@palisadoes
Copy link
Contributor

@disha1202

Please:

  1. Fix the conflicting file
  2. Make the code coverage tests pass
  3. Make code rabbit approve the PR

@github-actions github-actions bot removed the no-pr-activity No pull request activity label Nov 6, 2024
Copy link

This pull request did not get any activity in the past 10 days and will be closed in 180 days if no update occurs. Please verify it has no conflicts with the develop branch and rebase if needed. Mention it now if you need help or give permission to other people to finish your work.

@github-actions github-actions bot added the no-pr-activity No pull request activity label Nov 16, 2024
@noman2002
Copy link
Member

@disha1202 Any update on this one ?

@github-actions github-actions bot removed the no-pr-activity No pull request activity label Nov 20, 2024
@palisadoes
Copy link
Contributor

@disha1202 We have made significant changes to the develop-postgres branch that there will be major conflicts with this PR when we merge.

Can you close this and merge against that branch?

@palisadoes palisadoes changed the base branch from develop to develop-postgres November 30, 2024 05:27
@palisadoes
Copy link
Contributor

@disha1202 I rebased your PR against the develop-postgres branch. We did some changes to the UI/UX color scheme. Please make sure that those are maintained when you refactor the conflicting files.

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.

3 participants