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

fix: double tap reaction + keyboard staying in place when long press on message + fix for new SDK senderInboxId + many other stuff #1401

Merged
merged 5 commits into from
Dec 20, 2024

Conversation

thierryskoda
Copy link
Collaborator

@thierryskoda thierryskoda commented Dec 19, 2024

Summary by CodeRabbit

Release Notes

  • New Features

    • Introduced a new component for handling message gestures, including long press, tap, and double tap actions.
    • Enhanced the ConversationNewDm component with improved UI and state management for new conversations.
  • Improvements

    • Streamlined the handling of conversation messages and user reactions, focusing on topics instead of conversations.
    • Enhanced error handling and clarity in message delivery and reaction processes.
  • Bug Fixes

    • Removed unnecessary types and properties related to conversations for better state management.
  • Deprecated

    • Removed several unused components and hooks related to conversation management.
  • Refactor

    • Updated various components and hooks to improve code clarity and maintainability.
    • Simplified logic for determining message ownership and series relationships.

Copy link
Contributor

coderabbitai bot commented Dec 19, 2024

Warning

Rate limit exceeded

@thierryskoda has exceeded the limit for the number of commits or files that can be reviewed per hour. Please wait 22 minutes and 42 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

📥 Commits

Reviewing files that changed from the base of the PR and between 50a088b and 7a084e2.

📒 Files selected for processing (42)
  • containers/GroupScreenMembersTable.tsx (1 hunks)
  • data/store/chatStore.ts (0 hunks)
  • features/GroupInvites/joinGroup/JoinGroup.client.ts (1 hunks)
  • features/conversation/conversation-composer/conversation-composer-reply-preview.tsx (2 hunks)
  • features/conversation/conversation-header/conversation-dm-header-title.tsx (2 hunks)
  • features/conversation/conversation-header/conversation-group-header-title.tsx (4 hunks)
  • features/conversation/conversation-header/conversation-header-title.tsx (1 hunks)
  • features/conversation/conversation-header/conversation-new-dm-header-title.tsx (2 hunks)
  • features/conversation/conversation-keyboard-filler.tsx (3 hunks)
  • features/conversation/conversation-message-gestures.tsx (0 hunks)
  • features/conversation/conversation-message/conversation-message-content-types/conversation-message-remote-attachment.tsx (3 hunks)
  • features/conversation/conversation-message/conversation-message-context-menu/conversation-message-context-menu-above-message-reactions.tsx (3 hunks)
  • features/conversation/conversation-message/conversation-message-context-menu/conversation-message-context-menu.tsx (5 hunks)
  • features/conversation/conversation-message/conversation-message-gestures.tsx (1 hunks)
  • features/conversation/conversation-message/conversation-message-layout.tsx (2 hunks)
  • features/conversation/conversation-message/conversation-message-reactions/conversation-message-reactions.types.ts (0 hunks)
  • features/conversation/conversation-message/conversation-message-status/conversation-message-status.tsx (1 hunks)
  • features/conversation/conversation-message/conversation-message.store-context.tsx (2 hunks)
  • features/conversation/conversation-message/conversation-message.utils.tsx (3 hunks)
  • features/conversation/conversation-messages-list.tsx (0 hunks)
  • features/conversation/conversation-new-dm-no-messages-placeholder.tsx (0 hunks)
  • features/conversation/conversation-new-dm.tsx (2 hunks)
  • features/conversation/conversation.tsx (4 hunks)
  • features/conversation/conversation.utils.ts (1 hunks)
  • features/conversation/hooks/use-group-name-convos.ts (0 hunks)
  • features/conversation/hooks/use-react-on-message.ts (3 hunks)
  • features/conversation/hooks/use-remove-reaction-on-message.ts (3 hunks)
  • features/conversation/hooks/use-send-message.ts (2 hunks)
  • features/conversation/utils/has-previous-message-in-serie.ts (1 hunks)
  • features/conversation/utils/is-latest-message-settled-from-peer.ts (0 hunks)
  • features/conversation/utils/is-latest-settled-from-current-user.ts (0 hunks)
  • features/conversation/utils/message-is-from-current-user.ts (1 hunks)
  • features/notifications/utils/background/notificationSpamScore.ts (1 hunks)
  • hooks/useGroupMembers.ts (2 hunks)
  • hooks/useGroupName.ts (1 hunks)
  • queries/useConversationMessages.ts (1 hunks)
  • queries/useGroupMembersQuery.ts (2 hunks)
  • queries/useGroupQuery.ts (2 hunks)
  • screens/Navigation/navHelpers.ts (2 hunks)
  • utils/conversation.ts (1 hunks)
  • utils/events.ts (0 hunks)
  • utils/xmtpRN/messages.ts (2 hunks)

Walkthrough

This pull request introduces significant refactoring of conversation management across multiple files in the project. The changes primarily focus on simplifying conversation-related types, updating component structures, and streamlining message interaction logic. Key modifications include removing complex conversation types, updating gesture handling for messages, and enhancing hooks for group names and message reactions. The refactoring aims to create a more straightforward and maintainable approach to managing conversations and message interactions.

Changes

File Change Summary
data/store/chatStore.ts Removed multiple conversation-related types and properties, simplifying the store structure.
features/conversation/* Extensive updates to conversation components, including title rendering, message gestures, and context menu handling.
hooks/useGroupName.ts Enhanced group name retrieval logic with improved member and preferred name processing.
queries/useConversationMessages.ts Renamed functions and improved logging for message retrieval.
utils/conversation.ts Removed commented-out code and unused imports.
utils/events.ts Removed several conversation-related event types.

Possibly related PRs

Suggested labels

3.0.0

Suggested reviewers

  • alexrisch

Poem

🐰 A Rabbit's Ode to Code Refactoring 🐰

Conversations trimmed with care,
Types and gestures dancing fair,
Messages leap with newfound grace,
In this refactored coding space!
Simplicity hops, complexity fades away 🌟


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 generate docstrings to generate docstrings for this PR. (Beta)
  • @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.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

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.

@@ -191,15 +74,12 @@ export const initChatStore = (account: string) => {
persist(
(set) =>
({
conversations: {},
Copy link
Collaborator

Choose a reason for hiding this comment

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

just so i am tracking this was moved to be handled by react query?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Exactly! the goal would be to erase ChatStore I think. So as soon as I'm moving stuff away I'm trying to clean from ChatStore

Copy link
Contributor

Choose a reason for hiding this comment

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

Yes! A chat store is fine, but the previous chat store was resulting in many things updating too often or requiring manual usage

Copy link
Contributor

github-actions bot commented Dec 19, 2024

Performance Comparison Report

  • Current: d2a8c96 - 2024-12-20 00:27:56Z
  • Baseline: release/3.0.0 (3996b51) - 2024-12-20 00:26:34Z

Significant Changes To Duration

There are no entries

Meaningless Changes To Duration

Show entries
Name Type Duration Count
Avatar Image 10 runs render 1.2 ms → 1.0 ms (-0.2 ms, -16.7%) 🟢 1 → 1
Avatar Image 50 runs render 1.0 ms → 1.1 ms (+0.0 ms, +1.9%) 1 → 1
Empty Avatar 10 runs render 0.8 ms → 0.9 ms (+0.1 ms, +12.5%) 1 → 1
Empty Avatar 50 runs render 0.7 ms → 0.7 ms (+0.0 ms, +5.7%) 1 → 1
Text Component with color prop - 10 runs render 0.5 ms → 0.3 ms (-0.2 ms, -40.0%) 🟢 1 → 1
Text Component with default props - 10 runs render 0.1 ms → 0.0 ms (-0.1 ms, -100.0%) 🟢 1 → 1
Text Component with translation key - 10 runs render 0.5 ms → 0.1 ms (-0.4 ms, -80.0%) 🟢 1 → 1
Text Component with weight and size - 10 runs render 0.2 ms → 0.4 ms (+0.2 ms, +100.0%) 🔴 1 → 1
Show details
Name Type Duration Count
Avatar Image 10 runs render Baseline
Mean: 1.2 ms
Stdev: 0.4 ms (35.1%)
Runs: 1 1 1 1 1 1 1 2 1 2
Warmup runs: 3

Current
Mean: 1.0 ms
Stdev: 0.0 ms (0.0%)
Runs: 1 1 1 1 1 1 1 1 1 1
Warmup runs: 2
Baseline
Mean: 1
Stdev: 0 (0.0%)
Runs: 1 1 1 1 1 1 1 1 1 1
Render issues:

Current
Mean: 1
Stdev: 0 (0.0%)
Runs: 1 1 1 1 1 1 1 1 1 1
Render issues:
Avatar Image 50 runs render Baseline
Mean: 1.0 ms
Stdev: 0.2 ms (19.0%)
Runs: 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 1 1 1 1 1 1 1 1 1 1 1
Warmup runs: 1

Current
Mean: 1.1 ms
Stdev: 0.3 ms (29.6%)
Runs: 1 1 2 1 1 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 0 1 1 1 1 1 1
Warmup runs: 1
Baseline
Mean: 1
Stdev: 0 (0.0%)
Runs: 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
Render issues:

Current
Mean: 1
Stdev: 0 (0.0%)
Runs: 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
Render issues:
Empty Avatar 10 runs render Baseline
Mean: 0.8 ms
Stdev: 0.6 ms (79.1%)
Runs: 1 0 1 1 2 1 1 0 0 1
Warmup runs: 3

Current
Mean: 0.9 ms
Stdev: 0.3 ms (35.1%)
Runs: 1 1 0 1 1 1 1 1 1 1
Warmup runs: 3
Baseline
Mean: 1
Stdev: 0 (0.0%)
Runs: 1 1 1 1 1 1 1 1 1 1
Render issues:

Current
Mean: 1
Stdev: 0 (0.0%)
Runs: 1 1 1 1 1 1 1 1 1 1
Render issues:
Empty Avatar 50 runs render Baseline
Mean: 0.7 ms
Stdev: 0.5 ms (66.1%)
Runs: 1 1 1 1 1 1 0 1 0 1 0 0 0 0 1 1 0 1 1 1 0 1 1 1 1 1 0 1 0 1 0 0 0 1 0 1 1 1 1 1 1 1 1 0 1 1 1 1 1 1
Warmup runs: 1

Current
Mean: 0.7 ms
Stdev: 0.4 ms (59.9%)
Runs: 1 1 1 1 1 1 0 1 1 0 0 1 1 1 1 1 0 0 1 1 1 1 1 1 1 0 1 0 0 1 1 1 1 1 0 1 1 1 0 1 1 1 1 1 0 1 0 1 0 1
Warmup runs: 1
Baseline
Mean: 1
Stdev: 0 (0.0%)
Runs: 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
Render issues:

Current
Mean: 1
Stdev: 0 (0.0%)
Runs: 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
Render issues:
Text Component with color prop - 10 runs render Baseline
Mean: 0.5 ms
Stdev: 0.5 ms (105.4%)
Runs: 0 0 1 1 1 1 0 1 0 0
Warmup runs: 1

Current
Mean: 0.3 ms
Stdev: 0.5 ms (161.0%)
Runs: 0 0 0 0 1 0 1 1 0 0
Warmup runs: 0
Baseline
Mean: 1
Stdev: 0 (0.0%)
Runs: 1 1 1 1 1 1 1 1 1 1
Render issues:

Current
Mean: 1
Stdev: 0 (0.0%)
Runs: 1 1 1 1 1 1 1 1 1 1
Render issues:
Text Component with default props - 10 runs render Baseline
Mean: 0.1 ms
Stdev: 0.3 ms (316.2%)
Runs: 0 0 0 0 0 1 0 0 0 0
Warmup runs: 1

Current
Mean: 0.0 ms
Stdev: 0.0 ms (NaN%)
Runs: 0 0 0 0 0 0 0 0 0 0
Warmup runs: 1
Baseline
Mean: 1
Stdev: 0 (0.0%)
Runs: 1 1 1 1 1 1 1 1 1 1
Render issues:

Current
Mean: 1
Stdev: 0 (0.0%)
Runs: 1 1 1 1 1 1 1 1 1 1
Render issues:
Text Component with translation key - 10 runs render Baseline
Mean: 0.5 ms
Stdev: 0.5 ms (105.4%)
Runs: 1 1 0 0 1 0 0 1 1 0
Warmup runs: 0

Current
Mean: 0.1 ms
Stdev: 0.3 ms (316.2%)
Runs: 0 0 0 0 1 0 0 0 0 0
Warmup runs: 0
Baseline
Mean: 1
Stdev: 0 (0.0%)
Runs: 1 1 1 1 1 1 1 1 1 1
Render issues:

Current
Mean: 1
Stdev: 0 (0.0%)
Runs: 1 1 1 1 1 1 1 1 1 1
Render issues:
Text Component with weight and size - 10 runs render Baseline
Mean: 0.2 ms
Stdev: 0.4 ms (210.8%)
Runs: 0 0 1 0 0 1 0 0 0 0
Warmup runs: 0

Current
Mean: 0.4 ms
Stdev: 0.5 ms (129.1%)
Runs: 0 0 0 1 0 1 1 0 0 1
Warmup runs: 0
Baseline
Mean: 1
Stdev: 0 (0.0%)
Runs: 1 1 1 1 1 1 1 1 1 1
Render issues:

Current
Mean: 1
Stdev: 0 (0.0%)
Runs: 1 1 1 1 1 1 1 1 1 1
Render issues:

Render Count Changes

There are no entries

Render Issues

There are no entries

Added Scenarios

There are no entries

Removed Scenarios

There are no entries

Generated by 🚫 dangerJS against 7a084e2

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

🔭 Outside diff range comments (1)
utils/conversation.ts (1)

Line range hint 52-71: Critical: Empty function implementation could cause runtime issues.

The conversationShouldBeDisplayed function appears to be exported but has no implementation. The commented-out code suggests important validation logic for:

  • Group conversation readiness
  • Pending status
  • Message existence
  • Deletion status
  • Version compatibility
  • Forbidden characters
  • Pinned status

This could lead to incorrect conversation display behavior.

Consider restoring the implementation:

export const conversationShouldBeDisplayed = (
  conversation: ConversationWithCodecsType,
  topicsData: TopicsData,
  pinnedConversations?: string[]
) => {
+  const isNotReady =
+    (conversation.isGroup && !conversation.groupMembers) ||
+    (!conversation.isGroup && !conversation.peerAddress);
+  if (isNotReady) return false;
+  
+  const isPending = !!conversation.pending;
+  const isNotEmpty = conversation.messages.size > 0;
+  const isDeleted = topicsData[conversation.topic]?.status === "deleted";
+  const isActive = conversation.isGroup ? conversation.isActive : true;
+  const isV1 = conversation.version === "v1";
+  const isForbidden = conversation.topic.includes("\x00");
+  const isPinned = pinnedConversations?.find(
+    (convo) => convo === conversation.topic
+  );
+  
+  return (
+    (!isPending || isNotEmpty) &&
+    !isDeleted &&
+    !isV1 &&
+    !isForbidden &&
+    !isPinned &&
+    isActive
+  );
};
🧹 Nitpick comments (16)
features/conversation/conversation-composer/conversation-composer-reply-preview.tsx (2)

Line range hint 214-252: Consider extracting message type handling into a separate component.

The ReplyPreviewMessageContent component contains multiple message type checks and renderings. Consider extracting this into a separate MessageTypeRenderer component to improve maintainability and reusability.

Example refactor:

+ const MessageTypeRenderer = memo(({ message }: { message: DecodedMessageWithCodecsType }) => {
+   if (isStaticAttachmentMessage(message)) {
+     return <Text>Static attachment</Text>;
+   }
+   if (isTransactionReferenceMessage(message)) {
+     return <Text>Transaction</Text>;
+   }
+   // ... other type checks
+ });

const ReplyPreviewMessageContent = memo(function ReplyPreviewMessageContent({
  replyMessage
}: {
  replyMessage: DecodedMessageWithCodecsType;
}) {
  const messageText = useMessageText(replyMessage);
  const clearedMessage = messageText?.replace(/(\n)/gm, " ");

-  if (isStaticAttachmentMessage(replyMessage)) {
-    // ...
-  }
-  // ... other type checks
+  return <MessageTypeRenderer message={replyMessage} />;
});

Line range hint 232-234: Add a more descriptive TODO comment.

The TODO comment for static attachment handling should be more descriptive about what needs to be implemented.

- // TODO
+ // TODO: Implement proper static attachment preview rendering
features/conversation/conversation-new-dm.tsx (1)

155-197: "ConversationNewDmNoMessagesPlaceholder" logic is clear and user-friendly.
The fallback for blocked peers returning null is concise, and the welcome message flow is straightforward. Consider making the greeting emoji configurable or localized if product requirements evolve.

features/conversation/hooks/use-react-on-message.ts (2)

39-61: Ensure conversation state is current
The function calls getCurrentAccountConversation(topics) again in onMutate. Confirm that additional calls to retrieve the conversation are valid if the conversation might have changed in between.

You could capture the conversation reference earlier and reuse it across the entire function to prevent multiple lookups:

export function useReactOnMessage(props: { topic: ConversationTopic }) {
  const { topic } = props;
  const { mutateAsync: reactOnMessageMutationAsync } = useMutation({
    mutationFn: async (variables) => {
      ...
    },
    onMutate: (variables) => {
      const currentAccount = getCurrentAccount()!;
-     const conversation = getCurrentAccountConversation(topic);
+     const conversation = cachedConversation ?? getCurrentAccountConversation(topic);
      ...
    },
    onError: ...
  });
  ...
}

88-88: Dependency array might be incomplete
Only referencing reactOnMessageMutationAsync in the dependency array is fine, but confirm that no other dependencies need to be declared (e.g. Haptics). If Haptics is an imported enum or typed constant, it’s safe. Otherwise, consider adding it to avoid potential stale references.

features/conversation/hooks/use-remove-reaction-on-message.ts (2)

40-62: Duplicate conversation fetch
As with the other hook, re-fetching the conversation within onMutate is functional but might lead to inconsistencies if the conversation changes between calls. Consider caching it if performance is a concern or calls are frequent.


88-88: Dependency array completeness
As with useReactOnMessage, confirm that only removeReactionMutationAsync is needed. If more dependencies become relevant, add them to ensure a stable reference.

queries/useConversationMessages.ts (2)

Line range hint 251-254: Address WIP comment for IOptimisticMessage type.

The "WIP" comment suggests incomplete implementation. This should be addressed to ensure the optimistic message handling is fully implemented.

Would you like help completing the implementation of the optimistic message handling? I can help design a more comprehensive type definition and related functionality.


Line range hint 183-250: Consider optimizing reaction processing for large message sets.

The reaction processing logic is well-structured but could benefit from performance optimizations when dealing with large sets of messages:

  1. Consider using Map instead of plain objects for O(1) lookups
  2. Consider batching reaction updates to reduce re-renders

Here's a suggested optimization:

 type IMessageAccumulator = {
   ids: MessageId[];
   byId: Record<MessageId, DecodedMessageWithCodecsType>;
   reactions: Record<
     MessageId,
     {
-      bySender: Record<InboxId, ReactionContent[]>;
-      byReactionContent: Record<string, InboxId[]>;
+      bySender: Map<InboxId, ReactionContent[]>;
+      byReactionContent: Map<string, InboxId[]>;
     }
   >;
 };
features/conversation/conversation.tsx (1)

313-379: Double-tap reaction logic

  1. The double-tap gesture toggles a “❤️” reaction if not already present. This is user-friendly.
  2. Consider edge cases: If the message store is empty or momentarily undefined, ensure graceful handling so that accessing messageId doesn’t raise errors.
  3. The inline arrow callbacks are concise, but be mindful of potential re-renders if dependencies are large.
hooks/useGroupName.ts (2)

6-6: Preferred names integration
Bringing in usePreferredNames integrates user-friendly references for group participants. This feature can significantly enhance the UI for group participants.


29-29: Performance consideration
Using usePreferredNames for each member is helpful. If the group is large, consider performance optimizations or caching.

features/conversation/conversation-message/conversation-message-gestures.tsx (1)

62-69: Consider adding haptic feedback for double tap.

For consistency in user experience, consider adding haptic feedback to the double tap gesture similar to the long press.

 const doubleTap = Gesture.Tap()
   .numberOfTaps(2)
   .onEnd(() => {
     if (onDoubleTap) {
+      Haptics.softImpactAsyncAnimated();
       onDoubleTap();
     }
   })
features/conversation/conversation-message/conversation-message.utils.tsx (1)

227-241: Consider adding null checks for better error handling

The new getCurrentUserAlreadyReactedOnMessage function could benefit from additional null checks to prevent potential runtime errors.

Consider updating the implementation:

 export function getCurrentUserAlreadyReactedOnMessage(args: {
   messageId: MessageId;
   topic: ConversationTopic;
   emoji: string | undefined;
 }) {
   const { messageId, topic, emoji } = args;
   const currentUserInboxId = getCurrentUserAccountInboxId();
+  if (!currentUserInboxId) return false;
   const currentAccount = getCurrentAccount()!;
   const messages = getConversationMessagesQueryData(currentAccount, topic);
+  if (!messages?.reactions) return false;
   const reactions = messages?.reactions[messageId];
   const bySender = reactions?.bySender;
   return bySender?.[currentUserInboxId]?.some(
     (reaction) => !emoji || reaction.content === emoji
   );
 }
utils/conversation.ts (2)

Line range hint 73-98: Refactor suggestion: Reduce code duplication and address TODO.

  1. There's a TODO comment about checking inboxId that needs to be addressed
  2. The group/non-group conversation handling is duplicated between functions

Consider refactoring to reduce duplication:

+ const getConversationState = (conversation: ConversationWithCodecsType) => {
+   const isGroup = conversation.version === ConversationVersion.GROUP;
+   return { isGroup, state: conversation.state };
+ };

export const conversationShouldBeInInbox = (
  conversation: ConversationWithCodecsType
) => {
-  if (conversation.version === ConversationVersion.GROUP) {
-    const isGroupBlocked = conversation.state === "denied";
-    const isGroupAllowed = conversation.state === "allowed";
-    if (isGroupBlocked) {
-      return false;
-    }
-    return isGroupAllowed;
-  } else {
-    const isPeerConsented = conversation.state === "allowed";
-    return isPeerConsented;
-  }
+  const { state } = getConversationState(conversation);
+  return state === "allowed";
};

export const isConversationBlocked = (
  conversation: ConversationWithCodecsType
) => {
-  if (conversation.version === ConversationVersion.GROUP) {
-    // TODO: Check if inboxId is blocked as well
-    return conversation.state === "denied";
-  } else {
-    return conversation.state === "denied";
-  }
+  const { state } = getConversationState(conversation);
+  return state === "denied";
};

Would you like me to help implement the inboxId blocking check mentioned in the TODO comment?


Line range hint 1-98: Consider documenting the conversation state management approach.

Given the significant refactoring and simplification of conversation handling:

  1. The removal of ConversationContext suggests a shift in state management
  2. The conversation display logic has been significantly altered
  3. The state handling is now more streamlined

Consider adding documentation to explain:

  • The new approach to conversation state management
  • The relationship between conversation states ("allowed", "denied")
  • The impact of these changes on the UI layer

This will help maintain consistency as the codebase evolves and make it easier for other developers to understand the design decisions.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 19422fc and 50a088b.

⛔ Files ignored due to path filters (1)
  • ios/Podfile.lock is excluded by !**/*.lock
📒 Files selected for processing (27)
  • data/store/chatStore.ts (0 hunks)
  • features/conversation/conversation-composer/conversation-composer-reply-preview.tsx (2 hunks)
  • features/conversation/conversation-header/conversation-dm-header-title.tsx (2 hunks)
  • features/conversation/conversation-header/conversation-group-header-title.tsx (3 hunks)
  • features/conversation/conversation-header/conversation-header-title.tsx (1 hunks)
  • features/conversation/conversation-header/conversation-new-dm-header-title.tsx (2 hunks)
  • features/conversation/conversation-keyboard-filler.tsx (3 hunks)
  • features/conversation/conversation-message-gestures.tsx (0 hunks)
  • features/conversation/conversation-message/conversation-message-context-menu/conversation-message-context-menu.tsx (4 hunks)
  • features/conversation/conversation-message/conversation-message-gestures.tsx (1 hunks)
  • features/conversation/conversation-message/conversation-message-reactions/conversation-message-reactions.types.ts (0 hunks)
  • features/conversation/conversation-message/conversation-message-status/conversation-message-status.tsx (1 hunks)
  • features/conversation/conversation-message/conversation-message.utils.tsx (3 hunks)
  • features/conversation/conversation-messages-list.tsx (0 hunks)
  • features/conversation/conversation-new-dm-no-messages-placeholder.tsx (0 hunks)
  • features/conversation/conversation-new-dm.tsx (2 hunks)
  • features/conversation/conversation.tsx (4 hunks)
  • features/conversation/conversation.utils.ts (1 hunks)
  • features/conversation/hooks/use-group-name-convos.ts (0 hunks)
  • features/conversation/hooks/use-react-on-message.ts (3 hunks)
  • features/conversation/hooks/use-remove-reaction-on-message.ts (3 hunks)
  • features/conversation/hooks/use-send-message.ts (2 hunks)
  • features/notifications/utils/background/notificationSpamScore.ts (1 hunks)
  • hooks/useGroupName.ts (1 hunks)
  • queries/useConversationMessages.ts (1 hunks)
  • utils/conversation.ts (1 hunks)
  • utils/events.ts (0 hunks)
💤 Files with no reviewable changes (7)
  • features/conversation/conversation-message-gestures.tsx
  • features/conversation/hooks/use-group-name-convos.ts
  • features/conversation/conversation-message/conversation-message-reactions/conversation-message-reactions.types.ts
  • features/conversation/conversation-new-dm-no-messages-placeholder.tsx
  • features/conversation/conversation-messages-list.tsx
  • data/store/chatStore.ts
  • utils/events.ts
🔇 Additional comments (52)
features/conversation/conversation-composer/conversation-composer-reply-preview.tsx (2)

15-15: LGTM! Clean import organization.

The import of DecodedMessageWithCodecsType is properly placed and removes duplication.


60-60: LGTM! Type inference improvement.

Good cleanup by removing the redundant type assertion. The type is correctly inferred from the usePreferredInboxName hook.

features/conversation/conversation-new-dm.tsx (6)

3-6: Imports from the new design system modules look good.
These imports are straightforward and match the usage in the code below.


10-10: Confirmed correct import path for "NewConversationTitle".
Ensures that the correct header title is used for the new DM flow.


16-17: Imports for name resolution and internationalization appear correct.
Using "usePreferredName" and "translate" is appropriate for dynamic naming and localized text.


21-21: Usage of "useAppTheme" for dynamic styling is on point.
This allows consistent theme-based design across components.


28-28: "Keyboard" import supports dismissing the keyboard on screen tap.
This helps provide a cleaner user experience when dismissing the keyboard.


149-153: Well-defined prop type for "ConversationNewDmNoMessagesPlaceholder".
Defining a clear interface for props improves type safety and code maintainability.

features/conversation/hooks/use-react-on-message.ts (3)

28-31: Robust error handling
Good check for nonexistent conversation before sending a reaction. This helps avoid null pointer or undefined object errors.


66-66: Error and refetch logic
Refetching messages upon error is a good fallback strategy. Ensure that any partially updated state does not cause duplicates or conflict.


22-23: Function signature changes raise potential impact on downstream calls
By switching from passing in an entire conversation to just a topic, any dependent code that expects a conversation might break. Make sure all callers have updated references so they invoke this hook with the new signature.

Please verify with the following command to ensure all calls adhere to the new signature:

✅ Verification successful

Based on the rg results, I can see all usages of useReactOnMessage in the codebase. The hook is imported and used in two files:

  1. features/conversation/conversation.tsx
  2. features/conversation/conversation-message/conversation-message-context-menu/conversation-message-context-menu.tsx

In both cases, the hook is called with the correct new signature, passing an object with just the topic prop:

const reactOnMessage = useReactOnMessage({
  topic,
});

Let me generate the final response:

All usages of useReactOnMessage are already aligned with the new signature
The hook is used in two locations and both correctly pass just the topic prop, matching the new function signature. No changes are needed in the dependent code.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Verify all calls to `useReactOnMessage` have been updated to accept `{ topic }` props
rg -A 2 "useReactOnMessage" 

Length of output: 1926

features/conversation/hooks/use-remove-reaction-on-message.ts (3)

22-24: Similar shift to topic-based signature
Make sure all references to this hook have updated to pass { topic } to avoid runtime failures.


29-32: Conversation existence check
Excellent safeguard to prevent errors when the conversation is missing. This keeps the operation from silently failing.


67-67: Refetch logic
Refetching conversation messages on error is consistent with the approach in useReactOnMessage. Verify that partial state or earlier optimistic updates aren’t causing message duplication.

queries/useConversationMessages.ts (1)

Line range hint 76-83: LGTM! Verify rename impact across codebase.

The renamed function better reflects its purpose of retrieving cached query data. The implementation is correct.

Let's verify that all references to the old function name have been updated:

✅ Verification successful

Function rename is properly implemented and used consistently

The verification shows that:

  • The function is correctly imported and used in conversation-message.utils.tsx
  • Both usages in the utils file follow the correct pattern with proper parameters
  • No other files are using the old function name
  • The function is properly exported and imported where needed
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for any remaining references to the old function name
rg "getConversationMessages\(" --type ts

# Search for usages of the new function name to ensure proper adoption
rg "getConversationMessagesQueryData\(" --type ts

Length of output: 394


Script:

#!/bin/bash
# Let's check the git history to see if there are any recent changes related to this rename
git log -p --grep="getConversationMessages" --since="1 month ago"

# Let's also check the implementation in conversation-message.utils.tsx to ensure correct usage
ast-grep --pattern 'const messages = getConversationMessagesQueryData($account, $topic)'

Length of output: 90


Script:

#!/bin/bash
# Let's check the actual content of the utils file to understand the usage context
rg "getConversationMessagesQueryData" features/conversation/conversation-message/conversation-message.utils.tsx -B 2 -A 2

# Let's also verify there are no other files importing or using this function
rg "import.*getConversationMessagesQueryData" --type ts

Length of output: 828

features/notifications/utils/background/notificationSpamScore.ts (3)

91-91: LGTM: Type safety improvement with SDK update

The removal of type assertion for senderInboxId aligns with the SDK update, allowing for proper type inference. This change reduces the risk of runtime type errors.


Line range hint 1-144: Verify error handling for security-critical paths

Since this code handles spam detection, it's crucial to ensure that errors don't lead to spam messages being incorrectly scored as safe. Currently, errors result in either 0 or undefined scores, which might allow spam to bypass detection.

Consider:

  1. Logging errors for monitoring
  2. Using a more conservative default score on error
  3. Adding proper error types and handling specific error cases

Line range hint 91-144: Verify the impact of commented out syncConsent call

The syncConsent() call is commented out in computeSpamScoreGroupMessage but remains active in computeSpamScoreGroupWelcome. This inconsistency might affect consent state accuracy.

Consider refactoring duplicated consent checking logic

Both functions share similar patterns for checking consent states (inboxId, address, group). Consider extracting these checks into reusable utility functions to improve maintainability.

Example refactor:

async function checkConsentStates(
  xmtpClient: ConverseXmtpClientType,
  inboxId: InboxId,
  groupId: string
): Promise<number> {
  const [groupConsent, inboxConsent] = await Promise.all([
    xmtpClient.preferences.conversationConsentState(groupId),
    xmtpClient.preferences.inboxIdConsentState(inboxId)
  ]);
  
  if (groupConsent === "allowed" || inboxConsent === "allowed") return -1;
  if (inboxConsent === "denied") return 1;
  
  return 0;
}

Standardize error handling approach

The error handling differs between the two functions:

  • computeSpamScoreGroupWelcome returns 0 on error
  • computeSpamScoreGroupMessage silently ignores errors
    Consider standardizing the error handling approach across both functions for consistent behavior.
features/conversation/conversation-message/conversation-message-status/conversation-message-status.tsx (1)

10-10: Verify the consistency of the new import path.

The import path for IConversationMessageStatus has been moved from conversation-message/conversation-message.types to conversation-message.types. Let's ensure this change is consistent across the codebase.

✅ Verification successful

Import path change is correctly implemented

The import path change is consistent with the codebase structure. The type IConversationMessageStatus is defined in conversation-message.types.ts and correctly imported in conversation-message-status.tsx using a relative path. No other files in the codebase are importing this type, so there are no inconsistencies to address.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for any remaining imports from the old path
rg "from.*conversation-message/conversation-message\.types.*IConversationMessageStatus"

# Search for imports from the new path to confirm adoption
rg "from.*conversation-message\.types.*IConversationMessageStatus"

Length of output: 158


Script:

#!/bin/bash
# Let's first find all files that might contain IConversationMessageStatus
rg "IConversationMessageStatus" --type-list
rg "IConversationMessageStatus" -l

# Then let's check the actual import statements more broadly
rg "from.*conversation-message.*types.*IConversationMessageStatus" -A 1

Length of output: 718


Script:

#!/bin/bash
# Let's examine the content of both files to understand the type definition and its usage
echo "=== Content of conversation-message.types.ts ==="
cat features/conversation/conversation-message/conversation-message.types.ts

echo -e "\n=== Content of conversation-message-status.tsx ==="
cat features/conversation/conversation-message/conversation-message-status/conversation-message-status.tsx

Length of output: 3077

features/conversation/hooks/use-send-message.ts (3)

84-84: LGTM: Consistent rename to senderInboxId.

The rename from senderAddress to senderInboxId aligns with the PR objectives for the new SDK integration.


Line range hint 31-49: LGTM: Robust message content handling.

The function properly handles both text and remote attachment content with appropriate type checks and null safety.


Line range hint 124-137: LGTM: Comprehensive error handling.

The error handling implementation properly captures errors, shows user-friendly toasts, and ensures data consistency through refetching.

features/conversation/conversation.tsx (9)

15-16: Consistent naming convention regarding header components
Imports for DmConversationTitle and GroupConversationTitle appear consistent with the new naming convention for header titles. Ensure all usage in the codebase follows the same pattern (e.g., ConversationHeaderTitle) to maintain clarity and consistency.


22-22: No concerns
Importing 'useMessageContextMenuStore' is straightforward; the usage context will determine whether any additional error handling is necessary.


25-28: Ensure that the replaced gestures component is fully deprecated
The re-import of ConversationMessageGestures likely replaces older references. Confirm that legacy references to these gestures are removed or updated to avoid confusion in the codebase.


33-33: Clear naming
Importing ConversationMessageStatus helps clarify UX for message acknowledgment or read receipts. This naming aligns well with the file's refactored logic.


35-38: Logical grouping for context
The updated imports for MessageContextStoreProvider and related hooks keep context usage modular. Make sure this store's lifecycle is well-scoped to avoid unexpected global states or memory leaks.


41-41: Reusable logic for reaction
Importing getCurrentUserAlreadyReactedOnMessage centralizes reaction-checking logic. This fosters maintainability and reusability.


45-46: Solid approach for adding & removing reactions
These new hooks for reacting and removing reactions on messages are intuitive. Ensure that any concurrency around their usage (e.g., quickly toggling the reaction multiple times) is well-handled in the underlying implementation.


72-72: Sensible highlight logic
ConversationMessageHighlighted is a good addition to visually emphasize messages. Confirm that highlighting doesn't interfere with gesture events in some edge scenario.


295-299: Improved gestures integration
Wrapping message content in ConversationMessageGesturesWrapper is a clean approach to unify multiple gesture handlers. This keeps the core message component simpler.

features/conversation/conversation-header/conversation-header-title.tsx (1)

15-15: Rename to reflect usage
Renaming from ConversationTitle to ConversationHeaderTitle clarifies the component’s scope. Confirm all references in the codebase have updated imports to avoid referencing a stale component name.

hooks/useGroupName.ts (6)

3-3: Query usage
Importing useGroupMembersQuery broadens the hook’s approach to building dynamic group names. This is a good step toward robust group-specific logic.


10-10: Ensure account readiness
Before usage, confirm that currentAccount() never returns an undefined or invalid account. Potentially handle fallback logic if the user is not fully logged in or if the account data is not yet ready.


11-15: Loading and error states
Renaming data → groupName and isLoading → groupNameLoading is more expressive. Confirm that any UI references are updated to use these refined names for clarity.


20-23: Parallel queries for group data
Running group members and group name queries in parallel is efficient but ensure that any new error handling merges them adequately if either fails.


25-27: Filter out self from addresses
Filtering out the current account’s address is logical when building a user-centric name. This keeps group naming distinct and relevant.


37-37: Fallback logic
Using groupName || names.join(", ") ensures at least a minimal fallback for unnamed groups. Be aware that an empty string for groupName also triggers the fallback, which might be desired or might be an unintended override.

features/conversation/conversation-header/conversation-new-dm-header-title.tsx (2)

1-1: Consistent usage
Updated import of ConversationHeaderTitle unifies the new naming convention. This boosts consistency across components.


38-38: Improved approach to DM header
Switching to ConversationHeaderTitle ensures compliance with the new naming standard and seamlessly integrates the avatar. The approach to conditionally rendering the avatar (based on isLoading) is sound.

features/conversation/conversation-header/conversation-dm-header-title.tsx (1)

Line range hint 50-64: LGTM! Clean component renaming.

The change from ConversationTitle to ConversationHeaderTitle maintains the same functionality while improving naming consistency across conversation components.

features/conversation/conversation-keyboard-filler.tsx (2)

28-42: Consider potential race condition in keyboard state management.

The keyboard state management could have a race condition if the context menu state changes rapidly. Consider debouncing the keyboard show/hide operations or adding a small delay before re-focusing.


Line range hint 64-72: LGTM! Improved variable naming.

Renaming animatedStyle to fillerAnimatedStyle better describes the variable's purpose and improves code readability.

features/conversation/conversation-message/conversation-message-gestures.tsx (1)

92-92: LGTM! Well-structured gesture composition.

The use of Gesture.Exclusive ensures proper gesture priority handling between double tap, single tap, and long press.

features/conversation/conversation-header/conversation-group-header-title.tsx (2)

40-40: LGTM: Hook usage simplified

The migration from useGroupNameConvos to useGroupName simplifies the hook usage by removing the unnecessary account parameter, making the code more maintainable.


Line range hint 75-93: LGTM: Component update maintains functionality

The switch to ConversationHeaderTitle maintains all necessary props and functionality while improving component organization.

features/conversation/conversation-message/conversation-message.utils.tsx (1)

111-111: LGTM: Function rename improves clarity

The rename from getConversationMessages to getConversationMessagesQueryData better reflects the function's purpose and return type.

features/conversation/conversation-message/conversation-message-context-menu/conversation-message-context-menu.tsx (3)

84-88: LGTM: Simplified hook props

The removal of unnecessary props in useReactOnMessage and useRemoveReactionOnMessage hooks improves code maintainability.


96-100: LGTM: Improved reaction check logic

The use of getCurrentUserAlreadyReactedOnMessage centralizes the reaction check logic, making it more maintainable and consistent across the application.


Line range hint 109-117: Verify dependency array completeness

Ensure that all dependencies used within the callback are included in the dependency array.

utils/conversation.ts (2)

1-3: LGTM! Import cleanup aligns with type simplification.


Line range hint 4-11: Consider expanding ConversationFlatListItem type.

The ConversationFlatListItem type is currently just an alias for ConversationFlatListHiddenRequestItem. This seems overly simplified - should it include other possible item types for the conversation list?

Comment on lines 1 to 11
import { getCurrentAccount } from "@/data/store/accountsStore";
import { getConversationQueryData } from "@/queries/useConversationQuery";
import { ConversationTopic, MessageId } from "@xmtp/react-native-sdk";

export function getCurrentAccountConversation(topic: ConversationTopic) {
const currentAccount = getCurrentAccount()!;
return getConversationQueryData({
account: currentAccount,
topic: topic,
});
}
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Ensure safe usage of non-null assertion
Using getCurrentAccount()! might throw if there is no current account. Although the code suggests user must be logged in, add an early check or error message to handle the edge case.

Here's a potential approach:

export function getCurrentAccountConversation(topic: ConversationTopic) {
-  const currentAccount = getCurrentAccount()!;
-  return getConversationQueryData({ account: currentAccount, topic });
+  const currentAccount = getCurrentAccount();
+  if (!currentAccount) {
+    throw new Error("No current account set");
+  }
+  return getConversationQueryData({ account: currentAccount, topic });
}
📝 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
import { getCurrentAccount } from "@/data/store/accountsStore";
import { getConversationQueryData } from "@/queries/useConversationQuery";
import { ConversationTopic, MessageId } from "@xmtp/react-native-sdk";
export function getCurrentAccountConversation(topic: ConversationTopic) {
const currentAccount = getCurrentAccount()!;
return getConversationQueryData({
account: currentAccount,
topic: topic,
});
}
import { getCurrentAccount } from "@/data/store/accountsStore";
import { getConversationQueryData } from "@/queries/useConversationQuery";
import { ConversationTopic, MessageId } from "@xmtp/react-native-sdk";
export function getCurrentAccountConversation(topic: ConversationTopic) {
const currentAccount = getCurrentAccount();
if (!currentAccount) {
throw new Error("No current account set");
}
return getConversationQueryData({ account: currentAccount, topic });
}

@@ -79,10 +79,9 @@ export function useSendMessage(props: {
: contentTypesPrefixes.remoteAttachment,
sentNs: getTodayNs(),
fallback: "new-message",
// @ts-ignore we're adding our "own" delivery status because we want to display it in the UI
deliveryStatus: "sending" satisfies IConversationMessageStatus,
deliveryStatus: "sending" as MessageDeliveryStatus, // NOT GOOD but tmp
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Replace type assertion with type validation.

The change from satisfies to as type assertion reduces type safety. The comment "NOT GOOD but tmp" acknowledges this issue. Consider using satisfies or proper type validation instead.

-  deliveryStatus: "sending" as MessageDeliveryStatus, // NOT GOOD but tmp
+  deliveryStatus: "sending" satisfies MessageDeliveryStatus,
📝 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
deliveryStatus: "sending" as MessageDeliveryStatus, // NOT GOOD but tmp
deliveryStatus: "sending" satisfies MessageDeliveryStatus,

@@ -1,58 +0,0 @@
import { Center } from "@/design-system/Center";
Copy link
Collaborator

Choose a reason for hiding this comment

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

is this not needed any longer?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I've put it inside conversation-new-dm for now since everything this file needed was also in that one and I felt it was more clear than having this one only external file

ios/Podfile.lock Outdated Show resolved Hide resolved
ios/Podfile.lock Outdated Show resolved Hide resolved
Copy link
Collaborator

@technoplato technoplato left a comment

Choose a reason for hiding this comment

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

Everything looks good to me. The animation stuff, however, is a little bit over my head, but I trust your abilities there. I made a suggestion to fix the CocoPods version in the pod file lock. Other than that, everything looks good to me.

hooks/useGroupName.ts Outdated Show resolved Hide resolved
@alexrisch
Copy link
Contributor

You will need to import import { wait } from "@/utils/wait"; to fix the TSC issues

@thierryskoda thierryskoda marked this pull request as ready for review December 20, 2024 00:20
@thierryskoda thierryskoda requested a review from a team as a code owner December 20, 2024 00:20
@thierryskoda thierryskoda force-pushed the ts/chat-fixes-19-12-2024-2 branch from 830e586 to 6bb4853 Compare December 20, 2024 00:23
@thierryskoda thierryskoda merged commit 3996b51 into release/3.0.0 Dec 20, 2024
4 checks passed
@thierryskoda thierryskoda deleted the ts/chat-fixes-19-12-2024-2 branch December 20, 2024 00:24
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