Skip to content
This repository was archived by the owner on Jul 11, 2025. It is now read-only.

feat: Expo notifications + many other fixes#1647

Merged
thierryskoda merged 6 commits intomainfrom
ts/25-03-2025
Mar 28, 2025
Merged

feat: Expo notifications + many other fixes#1647
thierryskoda merged 6 commits intomainfrom
ts/25-03-2025

Conversation

@thierryskoda
Copy link
Copy Markdown
Contributor

@thierryskoda thierryskoda commented Mar 27, 2025

Device Management, Error Handling and Group Features Overhaul

Added device and identity management system for multi-device support. Consolidated group update operations into a single mutation. Moved to a structured error handling system with typed errors and context data. Added Expo push notifications support. Reorganized group feature files into a more logical structure. Added new EditGroup screen and UI components.

📍Where to Start

The device management system implementation starting at devices.api.ts, which defines the core API functions for device registration and management.


Macroscope summarized 3cd3a04.

Summary by CodeRabbit

  • New Features

    • Introduced a new group editing interface for updating details like name, description, and avatar.
    • Added a dedicated group members list screen for easier participant management.
    • Added functionality for managing device identities and notifications, including new API methods for fetching and creating identities.
  • Improvements

    • Enhanced profile update flows for smoother avatar uploads.
    • Improved push and background notification handling for more reliable alerts.
    • Optimized app stability with refined error handling and performance enhancements.
    • Streamlined error reporting across various components and services for better debugging and user feedback.

@thierryskoda thierryskoda requested review from a team as code owners March 27, 2025 19:04
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Mar 27, 2025

Walkthrough

The update spans multiple modules, with many import paths revised to follow a new directory structure across groups, queries, notifications, devices, identities, and profiles. Error handling has been standardized by wrapping errors in structured objects like GenericError, AuthenticationError, and NotificationError. Several new files and hooks were introduced for improved device storage, push notification registration, and identity management, while some legacy code was removed or refactored. Changes include adjustments to type definitions and function signatures, the introduction of new mutation hooks for group updates, and updates to UI components for group and profile management. Overall, the modifications streamline module organization and error reporting while preserving existing functionality.

✨ Finishing Touches
  • 📝 Generate Docstrings

🪧 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.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai plan to trigger planning for file edits and PR creation.
  • @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.

Copy link
Copy Markdown
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: 7

🧹 Nitpick comments (17)
features/conversation/conversation-chat/conversation-composer/conversation-composer-text-input.tsx (1)

66-77: Enhanced platform-specific behavior

The macOS-specific Enter key handling looks good, but the @ts-ignore should be addressed.

Consider creating a proper type definition for macOS keyboard events:

+ // Define macOS specific keyboard event properties
+ interface MacOSKeyboardEvent extends TextInputKeyPressEventData {
+   shiftKey?: boolean;
+   altKey?: boolean;
+   metaKey?: boolean;
+ }

  onKeyPress={(event: NativeSyntheticEvent<TextInputKeyPressEventData>) => {
    // Only handle Enter key on macOS
    if (Platform.OS === "macos") {
      const hasModifier =
-       // @ts-ignore - macOS keyboard events have modifier properties
-       event.nativeEvent.shiftKey || event.nativeEvent.altKey || event.nativeEvent.metaKey
+       (event.nativeEvent as MacOSKeyboardEvent).shiftKey || 
+       (event.nativeEvent as MacOSKeyboardEvent).altKey || 
+       (event.nativeEvent as MacOSKeyboardEvent).metaKey
features/notifications/notifications-listeners.ts (1)

22-22: Logging reduction

Commenting out debug logging reduces noise. Just make sure this wasn't important for debugging.

features/devices/devices.types.ts (1)

9-9: Consider runtime validation for branded type

The z.custom<IDeviceId>() validation may not provide runtime validation since branded types are TypeScript-only concepts. If validation is needed at runtime, consider adding a custom validator.

features/notifications/notifications-init.ts (1)

114-114: Commented out debug log

Just noting that a debug log was commented out - not a problem, but maybe consider removing it if it's not needed.

features/groups/mutations/update-group.mutation.ts (2)

23-60: Parallel updates are nice.
If partial failures matter, consider tailored error handling per promise.


77-88: Error revert is correct.
Maybe log more context if needed.

features/groups/screens/edit-group.screen.tsx (1)

107-107: Debug logging
Console log for debugging is fine, but consider removing in production if noisy.

features/current-user/use-create-user-if-no-exist.ts (2)

35-123: Function wraps necessary device creation and identity checks well.
Potential concurrency concern if multiple calls happen simultaneously, but for now it seems fine.


185-229: useEffect with subscription looks good.
Might need a guard in case unsubscribing triggers mid-process.

features/devices/devices.api.ts (1)

27-45: fetchUserDevices
Handles arrays well. Consider pagination if lists get large.

features/identities/identities.api.ts (6)

12-21: Schema clarity
Consider adding more validation rules (e.g., .email(), .url()) if needed for privyAddress or others. The schema is fine otherwise.


24-36: Error handling
Here, validation errors are captured but code still returns data. Throwing or returning a fallback might help prevent downstream misusage.


38-49: Reuse potential
fetchUserIdentities duplicates much of fetchDeviceIdentities. You could unify them with a parameter-driven function if you like.


64-67: Input shape
ICreateIdentityInput is minimal. Validate more fields if that’s expected (e.g., .optional() or stricter constraints).


104-116: Link function
Straightforward POST with no schema check. If the response format changes, might want to validate.


118-127: Unlink
Same note as link: consider a safe parse or at least a success check.

features/notifications/notifications.service.ts (1)

78-79: Registering installation
You handle token registration in a robust manner. Possibly log or handle partial successes if needed.

Also applies to: 89-89, 93-100

📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between b718196 and 5ef7f5f.

⛔ Files ignored due to path filters (1)
  • yarn.lock is excluded by !**/yarn.lock, !**/*.lock
📒 Files selected for processing (107)
  • App.tsx (3 hunks)
  • components/avatar.tsx (2 hunks)
  • components/debug-provider.tsx (10 hunks)
  • components/group-avatar.tsx (1 hunks)
  • config/shared.ts (1 hunks)
  • design-system/TextField/TextField.props.tsx (1 hunks)
  • design-system/TextField/TextField.tsx (3 hunks)
  • features/auth-onboarding/components/auth-onboarding-contact-card/auth-onboarding-contact-card-footer.tsx (3 hunks)
  • features/auth-onboarding/contexts/auth-onboarding.context.tsx (3 hunks)
  • features/authentication/authentication.api.ts (1 hunks)
  • features/authentication/authentication.headers.ts (2 hunks)
  • features/authentication/authentication.types.ts (1 hunks)
  • features/authentication/create-user.api.ts (0 hunks)
  • features/authentication/hydrate-auth.ts (3 hunks)
  • features/authentication/multi-inbox.store.ts (1 hunks)
  • features/authentication/use-logout.ts (1 hunks)
  • features/authentication/use-refresh-jwt.axios-interceptor.ts (2 hunks)
  • features/consent/use-allow-group.mutation.ts (1 hunks)
  • features/consent/use-deny-group.mutation.ts (1 hunks)
  • features/consent/use-group-consent-for-current-sender.ts (1 hunks)
  • features/conversation/conversation-chat/conversation-attachment/remote-attachment-local-storage.ts (2 hunks)
  • features/conversation/conversation-chat/conversation-composer/conversation-composer-add-attachment-button.tsx (1 hunks)
  • features/conversation/conversation-chat/conversation-composer/conversation-composer-text-input.tsx (2 hunks)
  • features/conversation/conversation-chat/conversation-composer/conversation-composer.tsx (2 hunks)
  • features/conversation/conversation-chat/conversation-consent-popup/conversation-consent-popup-group.tsx (2 hunks)
  • features/conversation/conversation-chat/conversation-message/conversation-message-gestures.tsx (2 hunks)
  • features/conversation/conversation-chat/conversation-message/conversation-message-reactions/conversation-message-reaction-drawer/conversation-message-reaction-drawer.tsx (2 hunks)
  • features/conversation/conversation-chat/conversation-messages.tsx (3 hunks)
  • features/conversation/conversation-chat/conversation.store-context.tsx (2 hunks)
  • features/conversation/conversation-chat/use-react-on-message.mutation.ts (2 hunks)
  • features/conversation/conversation-create/mutations/create-conversation-and-send-first-message.mutation.ts (1 hunks)
  • features/conversation/conversation-create/queries/search-existing-dms.query.ts (2 hunks)
  • features/conversation/conversation-create/queries/search-existing-groups-by-group-members.query.ts (2 hunks)
  • features/conversation/conversation-list/conversation-list-awaiting-requests.tsx (3 hunks)
  • features/conversation/conversation-list/conversation-list-item/conversation-list-item-dm.tsx (2 hunks)
  • features/conversation/conversation-list/conversation-list-item/conversation-list-item-group.tsx (1 hunks)
  • features/conversation/conversation-list/conversation-list.screen.tsx (2 hunks)
  • features/conversation/conversation-list/hooks/use-conversation-list-item-context-menu-props.tsx (4 hunks)
  • features/conversation/conversation-list/hooks/use-delete-dm.ts (3 hunks)
  • features/conversation/conversation-list/hooks/use-delete-group.ts (3 hunks)
  • features/conversation/conversation-list/hooks/use-message-content-string-value.ts (2 hunks)
  • features/conversation/conversation-metadata/conversation-metadata.api.ts (3 hunks)
  • features/conversation/conversation-metadata/conversation-metadata.query.ts (1 hunks)
  • features/conversation/conversation-requests-list/conversation-requests-list.screen.tsx (2 hunks)
  • features/conversation/conversation-requests-list/use-conversation-requests-list-items.tsx (2 hunks)
  • features/conversation/hooks/use-send-message.mutation.ts (2 hunks)
  • features/conversation/utils/inbox-id-is-part-of-converastion.ts (1 hunks)
  • features/current-user/create-user.api.ts (1 hunks)
  • features/current-user/create-user.mutation.ts (1 hunks)
  • features/current-user/current-user-api.ts (0 hunks)
  • features/current-user/current-user.api.ts (1 hunks)
  • features/current-user/current-user.query.ts (3 hunks)
  • features/current-user/current-user.types.ts (1 hunks)
  • features/current-user/use-create-user-if-no-exist.ts (5 hunks)
  • features/current-user/use-create-user.ts (0 hunks)
  • features/devices/device.storage.ts (1 hunks)
  • features/devices/devices.api.ts (1 hunks)
  • features/devices/devices.types.ts (1 hunks)
  • features/devices/devices.utils.ts (1 hunks)
  • features/devices/user-device.query.ts (1 hunks)
  • features/groups/components/add-group-members-confirm-button.component.tsx (2 hunks)
  • features/groups/components/add-group-members-search-results-list.component.tsx (2 hunks)
  • features/groups/components/add-group-members-search-users-input.component.tsx (1 hunks)
  • features/groups/components/add-group-members-search-users-results-list-item-eth-address.component.tsx (1 hunks)
  • features/groups/components/add-group-members-search-users-results-list-item-user-.component.tsx (1 hunks)
  • features/groups/components/group-details-members-list-item.component.tsx (2 hunks)
  • features/groups/components/group-details-members-list.component.tsx (2 hunks)
  • features/groups/components/group-member-details/group-member-details.bottom-sheet.tsx (8 hunks)
  • features/groups/components/group-member-details/group-member-details.service.tsx (1 hunks)
  • features/groups/components/group-member-details/group-member-details.store.tsx (1 hunks)
  • features/groups/group-description.mutation.ts (0 hunks)
  • features/groups/group-details/add-group-members/add-group-members.types.ts (0 hunks)
  • features/groups/group-details/members-list/group-members-list.screen.tsx (0 hunks)
  • features/groups/group-name.mutation.ts (0 hunks)
  • features/groups/group-photo.mutation.ts (0 hunks)
  • features/groups/hooks/use-group-members.ts (1 hunks)
  • features/groups/hooks/use-group-name.ts (1 hunks)
  • features/groups/mutations/add-group-members.mutation.ts (1 hunks)
  • features/groups/mutations/promote-group-member-to-admin.mutation.ts (1 hunks)
  • features/groups/mutations/promote-group-member-to-super-admin.mutation.ts (1 hunks)
  • features/groups/mutations/remove-group-members-from-group.mutation.ts (1 hunks)
  • features/groups/mutations/revoke-group-member-from-admin.mutation.ts (1 hunks)
  • features/groups/mutations/revoke-group-member-from-super-admin.mutation.ts (1 hunks)
  • features/groups/mutations/update-group.mutation.ts (1 hunks)
  • features/groups/screens/add-group-members.screen.tsx (1 hunks)
  • features/groups/screens/edit-group.screen.tsx (1 hunks)
  • features/groups/screens/group-details.screen-header.tsx (3 hunks)
  • features/groups/screens/group-details.screen.tsx (2 hunks)
  • features/groups/screens/group-members-list.screen.tsx (1 hunks)
  • features/identities/identities.api.ts (1 hunks)
  • features/notifications/background-notifications-handler.ts (4 hunks)
  • features/notifications/notification-assertions.ts (2 hunks)
  • features/notifications/notification-clear.ts (1 hunks)
  • features/notifications/notification-service-guide.md (0 hunks)
  • features/notifications/notifications-conversations-subscriptions.ts (3 hunks)
  • features/notifications/notifications-init.ts (2 hunks)
  • features/notifications/notifications-listeners.ts (2 hunks)
  • features/notifications/notifications.service.ts (6 hunks)
  • features/notifications/notifications.types.ts (3 hunks)
  • features/preferred-display-info/preferred-display-info.utils.ts (4 hunks)
  • features/profiles/components/profile-contact-card/profile-contact-card-layout.tsx (1 hunks)
  • features/profiles/components/profile-contact-card/profile-contact-card.tsx (1 hunks)
  • features/profiles/components/profile-social-names.tsx (2 hunks)
  • features/profiles/hooks/use-save-profile.ts (1 hunks)
  • features/profiles/profile-me.screen-header.tsx (1 hunks)
  • features/profiles/profile-me.tsx (2 hunks)
  • features/profiles/profile.types.ts (0 hunks)
⛔ Files not processed due to max files limit (33)
  • features/profiles/profiles.api.ts
  • features/profiles/profiles.query.ts
  • features/profiles/profiles.types.ts
  • features/profiles/schemas/profile-validation.schema.ts
  • features/streams/stream-messages.ts
  • features/streams/streams.ts
  • features/wallets/connect-wallet/components/connect-wallet-choose-app.tsx
  • features/wallets/connect-wallet/components/connect-wallet-choose-name.tsx
  • features/wallets/connect-wallet/components/connect-wallet-link-to-inbox.tsx
  • features/wallets/connect-wallet/components/connect-wallet-rotate-inbox.tsx
  • features/xmtp/xmtp-client/xmtp-client-db-encryption-key.ts
  • features/xmtp/xmtp-client/xmtp-client.ts
  • features/xmtp/xmtp-conversations/xmtp-conversations-group.ts
  • features/xmtp/xmtp-installations/xmtp-installations.ts
  • features/xmtp/xmtp-logs.ts
  • features/xmtp/xmtp-messages/xmtp-messages.ts
  • features/xmtp/xmtp.helpers.ts
  • hooks/use-better-focus-effect.ts
  • hooks/use-focus-rerender.ts
  • hooks/use-persist-state.ts
  • navigation/app-navigator.tsx
  • navigation/navigation.types.tsx
  • package.json
  • utils/capture-error.ts
  • utils/convos-api/convos-api-error.ts
  • utils/device-metadata.ts
  • utils/error.ts
  • utils/objects.ts
  • utils/react-query/react-query-persister.ts
  • utils/react-query/react-query.client.ts
  • utils/react-query/react-query.helpers.ts
  • utils/sentry/sentry-identity.ts
  • utils/storage/secure-storage.ts
💤 Files with no reviewable changes (10)
  • features/notifications/notification-service-guide.md
  • features/groups/group-photo.mutation.ts
  • features/groups/group-description.mutation.ts
  • features/groups/group-details/add-group-members/add-group-members.types.ts
  • features/groups/group-name.mutation.ts
  • features/current-user/use-create-user.ts
  • features/authentication/create-user.api.ts
  • features/profiles/profile.types.ts
  • features/current-user/current-user-api.ts
  • features/groups/group-details/members-list/group-members-list.screen.tsx
🧰 Additional context used
🧬 Code Definitions (54)
features/devices/devices.utils.ts (1)
features/devices/devices.types.ts (1)
  • IDeviceOS (4-4)
features/conversation/conversation-chat/conversation-composer/conversation-composer.tsx (2)
utils/capture-error.ts (1)
  • captureErrorWithToast (32-48)
utils/error.ts (1)
  • GenericError (71-75)
features/conversation/conversation-requests-list/conversation-requests-list.screen.tsx (1)
hooks/use-better-focus-effect.ts (1)
  • useBetterFocusEffect (4-20)
features/groups/components/group-details-members-list-item.component.tsx (1)
features/groups/components/group-member-details/group-member-details.service.tsx (1)
  • openGroupMemberDetailsBottomSheet (7-10)
features/notifications/notification-assertions.ts (1)
features/notifications/notifications.types.ts (1)
  • IExpoNewMessageNotification (14-19)
features/conversation/conversation-chat/conversation-composer/conversation-composer-add-attachment-button.tsx (2)
utils/capture-error.ts (1)
  • captureErrorWithToast (32-48)
utils/error.ts (1)
  • GenericError (71-75)
features/authentication/use-logout.ts (5)
features/authentication/multi-inbox.store.ts (2)
  • getCurrentSender (178-180)
  • resetMultiInboxStore (211-213)
utils/react-query/react-query.client.ts (1)
  • reactQueryClient (8-105)
utils/react-query/react-query-persister.ts (1)
  • reactQueryMMKV (10-10)
features/xmtp/xmtp-client/xmtp-client.ts (1)
  • logoutXmtpClient (198-239)
utils/capture-error.ts (1)
  • captureError (6-30)
features/conversation/conversation-create/queries/search-existing-dms.query.ts (2)
utils/capture-error.ts (1)
  • captureError (6-30)
utils/error.ts (1)
  • GenericError (71-75)
features/conversation/conversation-requests-list/use-conversation-requests-list-items.tsx (2)
utils/capture-error.ts (1)
  • captureError (6-30)
utils/error.ts (1)
  • GenericError (71-75)
features/conversation/conversation-chat/conversation-message/conversation-message-reactions/conversation-message-reaction-drawer/conversation-message-reaction-drawer.tsx (2)
utils/capture-error.ts (1)
  • captureErrorWithToast (32-48)
utils/error.ts (1)
  • GenericError (71-75)
features/profiles/components/profile-social-names.tsx (2)
utils/capture-error.ts (1)
  • captureErrorWithToast (32-48)
utils/error.ts (1)
  • GenericError (71-75)
features/conversation/conversation-chat/use-react-on-message.mutation.ts (2)
utils/capture-error.ts (1)
  • captureErrorWithToast (32-48)
utils/error.ts (1)
  • GenericError (71-75)
features/auth-onboarding/contexts/auth-onboarding.context.tsx (2)
utils/capture-error.ts (1)
  • captureErrorWithToast (32-48)
utils/error.ts (1)
  • AuthenticationError (95-99)
features/conversation/conversation-create/queries/search-existing-groups-by-group-members.query.ts (2)
utils/capture-error.ts (1)
  • captureError (6-30)
utils/error.ts (1)
  • GenericError (71-75)
features/profiles/profile-me.tsx (2)
utils/capture-error.ts (1)
  • captureErrorWithToast (32-48)
utils/error.ts (1)
  • GenericError (71-75)
features/conversation/conversation-chat/conversation-message/conversation-message-gestures.tsx (2)
utils/capture-error.ts (1)
  • captureErrorWithToast (32-48)
utils/error.ts (1)
  • GenericError (71-75)
features/conversation/conversation-list/conversation-list-item/conversation-list-item-dm.tsx (2)
utils/capture-error.ts (1)
  • captureErrorWithToast (32-48)
utils/error.ts (1)
  • GenericError (71-75)
features/conversation/conversation-chat/conversation.store-context.tsx (2)
utils/capture-error.ts (1)
  • captureError (6-30)
utils/error.ts (1)
  • GenericError (71-75)
features/conversation/hooks/use-send-message.mutation.ts (2)
utils/capture-error.ts (1)
  • captureError (6-30)
utils/error.ts (1)
  • GenericError (71-75)
features/conversation/conversation-list/hooks/use-delete-dm.ts (2)
utils/capture-error.ts (1)
  • captureErrorWithToast (32-48)
utils/error.ts (1)
  • GenericError (71-75)
features/current-user/current-user.query.ts (1)
features/current-user/current-user.types.ts (1)
  • IConvosCurrentUser (8-8)
features/notifications/notifications-listeners.ts (2)
utils/capture-error.ts (1)
  • captureError (6-30)
utils/error.ts (1)
  • NotificationError (113-117)
features/authentication/authentication.headers.ts (1)
features/xmtp/xmtp-installations/xmtp-installations.ts (1)
  • signWithXmtpInstallationId (58-83)
features/conversation/conversation-list/conversation-list.screen.tsx (2)
utils/capture-error.ts (1)
  • captureError (6-30)
utils/error.ts (1)
  • GenericError (71-75)
features/conversation/conversation-metadata/conversation-metadata.query.ts (1)
features/conversation/conversation-metadata/conversation-metadata.api.ts (1)
  • getConversationMetadata (23-60)
features/authentication/use-refresh-jwt.axios-interceptor.ts (2)
utils/capture-error.ts (1)
  • captureError (6-30)
utils/error.ts (1)
  • AuthenticationError (95-99)
features/authentication/hydrate-auth.ts (2)
utils/logger.ts (1)
  • authLogger (120-120)
features/authentication/multi-inbox.store.ts (1)
  • getCurrentSender (178-180)
features/conversation/conversation-chat/conversation-attachment/remote-attachment-local-storage.ts (2)
utils/capture-error.ts (1)
  • captureError (6-30)
utils/error.ts (1)
  • GenericError (71-75)
features/conversation/conversation-list/hooks/use-conversation-list-item-context-menu-props.tsx (2)
utils/capture-error.ts (1)
  • captureErrorWithToast (32-48)
utils/error.ts (1)
  • GenericError (71-75)
features/conversation/conversation-list/hooks/use-delete-group.ts (2)
utils/capture-error.ts (1)
  • captureErrorWithToast (32-48)
utils/error.ts (1)
  • GenericError (71-75)
features/conversation/conversation-chat/conversation-messages.tsx (3)
hooks/use-better-focus-effect.ts (1)
  • useBetterFocusEffect (4-20)
utils/capture-error.ts (1)
  • captureError (6-30)
utils/error.ts (1)
  • GenericError (71-75)
features/conversation/conversation-list/hooks/use-message-content-string-value.ts (2)
utils/capture-error.ts (1)
  • captureError (6-30)
utils/error.ts (1)
  • GenericError (71-75)
features/groups/components/add-group-members-confirm-button.component.tsx (2)
utils/capture-error.ts (1)
  • captureErrorWithToast (32-48)
utils/error.ts (1)
  • GenericError (71-75)
features/notifications/notifications-init.ts (2)
features/notifications/notification-assertions.ts (2)
  • isNotificationXmtpNewMessageNotification (15-28)
  • isNotificationExpoNewMessageNotification (30-34)
features/notifications/notifications.service.ts (1)
  • maybeDisplayLocalNewMessageNotification (199-294)
features/notifications/notifications-conversations-subscriptions.ts (4)
utils/react-query/react-query.helpers.ts (1)
  • createQueryObserverWithPreviousData (120-163)
features/notifications/notifications-permissions.query.ts (1)
  • getNotificationsPermissionsQueryConfig (5-13)
features/authentication/multi-inbox.store.ts (1)
  • useMultiInboxStore (50-172)
utils/logger.ts (1)
  • notificationsLogger (124-124)
features/preferred-display-info/preferred-display-info.utils.ts (1)
features/profiles/profiles.types.ts (1)
  • IConvosProfile (32-32)
features/conversation/conversation-list/conversation-list-awaiting-requests.tsx (1)
hooks/use-better-focus-effect.ts (1)
  • useBetterFocusEffect (4-20)
features/conversation/conversation-chat/conversation-consent-popup/conversation-consent-popup-group.tsx (2)
utils/capture-error.ts (1)
  • captureErrorWithToast (32-48)
utils/error.ts (1)
  • GenericError (71-75)
features/groups/components/group-details-members-list.component.tsx (1)
features/groups/components/group-member-details/group-member-details.bottom-sheet.tsx (1)
  • GroupMemberDetailsBottomSheet (36-307)
features/groups/screens/group-details.screen.tsx (1)
features/groups/screens/group-details.screen-header.tsx (1)
  • useGroupDetailsScreenHeader (10-51)
features/auth-onboarding/components/auth-onboarding-contact-card/auth-onboarding-contact-card-footer.tsx (3)
features/authentication/authentication.types.ts (1)
  • IPrivyUserId (1-1)
utils/capture-error.ts (1)
  • captureErrorWithToast (32-48)
utils/error.ts (1)
  • GenericError (71-75)
features/groups/components/group-member-details/group-member-details.service.tsx (1)
features/groups/components/group-member-details/group-member-details.store.tsx (1)
  • useGroupMemberDetailsBottomSheetStore (21-29)
features/devices/device.storage.ts (3)
utils/storage/secure-storage.ts (1)
  • secureStorage (23-27)
features/devices/devices.types.ts (1)
  • IDeviceId (6-6)
utils/error.ts (1)
  • StorageError (137-141)
components/debug-provider.tsx (3)
utils/capture-error.ts (1)
  • captureError (6-30)
utils/error.ts (1)
  • GenericError (71-75)
features/notifications/notifications.service.ts (1)
  • getDevicePushNotificationsToken (131-158)
features/notifications/notification-clear.ts (2)
utils/capture-error.ts (1)
  • captureError (6-30)
utils/error.ts (1)
  • NotificationError (113-117)
features/groups/mutations/update-group.mutation.ts (2)
features/groups/queries/group.query.ts (2)
  • getGroupQueryData (37-42)
  • updateGroupQueryData (65-71)
features/xmtp/xmtp-conversations/xmtp-conversations-group.ts (3)
  • updateXmtpGroupName (196-226)
  • updateXmtpGroupDescription (133-162)
  • updateXmtpGroupImage (164-194)
features/current-user/use-create-user-if-no-exist.ts (8)
features/current-user/current-user.types.ts (1)
  • IConvosCurrentUserId (6-6)
features/devices/device.storage.ts (1)
  • getStoredDeviceId (7-16)
features/devices/devices.types.ts (1)
  • IDevice (19-19)
features/devices/devices.api.ts (3)
  • fetchDevice (10-25)
  • IDeviceCreateInput (58-58)
  • createDevice (60-78)
features/identities/identities.api.ts (2)
  • fetchDeviceIdentities (25-36)
  • createIdentity (69-86)
features/authentication/authentication.types.ts (1)
  • IPrivyUserId (1-1)
features/current-user/current-user.api.ts (1)
  • fetchCurrentUser (6-24)
features/current-user/create-user.mutation.ts (1)
  • ICreateUserMutationArgs (9-9)
features/devices/devices.api.ts (3)
features/devices/devices.types.ts (2)
  • IDevice (19-19)
  • deviceSchema (8-17)
utils/capture-error.ts (1)
  • captureError (6-30)
utils/convos-api/convos-api-error.ts (1)
  • handleApiError (97-107)
features/profiles/hooks/use-save-profile.ts (2)
features/profiles/profiles.api.ts (2)
  • ISaveProfileUpdates (21-23)
  • saveProfile (26-43)
features/profiles/profiles.query.ts (3)
  • getProfileQueryData (79-81)
  • updateProfileQueryData (39-50)
  • setProfileQueryData (34-37)
features/identities/identities.api.ts (3)
features/devices/devices.types.ts (1)
  • IDeviceId (6-6)
utils/capture-error.ts (1)
  • captureError (6-30)
utils/error.ts (1)
  • ValidationError (131-135)
features/groups/components/group-member-details/group-member-details.bottom-sheet.tsx (4)
features/groups/components/group-member-details/group-member-details.store.tsx (1)
  • useGroupMemberDetailsBottomSheetStore (21-29)
features/groups/components/group-member-details/group-member-details.service.tsx (2)
  • closeGroupMemberDetailsBottomSheet (12-14)
  • groupMemberDetailsBottomSheetRef (5-5)
utils/capture-error.ts (1)
  • captureErrorWithToast (32-48)
utils/error.ts (1)
  • GenericError (71-75)
features/current-user/create-user.api.ts (6)
features/devices/devices.types.ts (1)
  • deviceSchema (8-17)
features/current-user/current-user.types.ts (2)
  • identitySchema (10-14)
  • IConvosCurrentUserId (6-6)
features/profiles/profiles.types.ts (2)
  • ConvosProfileSchema (7-30)
  • IConvosProfile (32-32)
features/authentication/authentication.types.ts (1)
  • IPrivyUserId (1-1)
features/devices/devices.utils.ts (2)
  • getDeviceOs (9-11)
  • getDeviceModelId (5-7)
utils/convos-api/convos-api-error.ts (1)
  • ApiError (21-95)
features/groups/screens/edit-group.screen.tsx (9)
navigation/navigation.types.tsx (1)
  • NavigationParamList (3-57)
features/authentication/multi-inbox.store.ts (1)
  • useSafeCurrentSender (190-196)
features/groups/queries/group.query.ts (1)
  • useGroupQuery (25-35)
features/groups/mutations/update-group.mutation.ts (1)
  • useUpdateGroup (17-90)
utils/capture-error.ts (1)
  • captureErrorWithToast (32-48)
utils/error.ts (1)
  • GenericError (71-75)
design-system/TextField/TextField.tsx (1)
  • TextField (13-166)
components/avatar.tsx (1)
  • Avatar (20-112)
components/group-avatar.tsx (1)
  • GroupAvatar (83-170)
features/notifications/background-notifications-handler.ts (3)
utils/error.ts (1)
  • NotificationError (113-117)
features/notifications/notifications.service.ts (1)
  • maybeDisplayLocalNewMessageNotification (199-294)
utils/capture-error.ts (1)
  • captureError (6-30)
🪛 Biome (1.9.4)
features/notifications/notifications-init.ts

[error] 105-109: Unsafe usage of 'return'.

'return' in 'finally' overwrites the control flow statements inside 'try' and 'catch'.

(lint/correctness/noUnsafeFinally)

🔇 Additional comments (234)
design-system/TextField/TextField.props.tsx (1)

44-44: Nice type extension for helper prop!

Expanding the helper prop type to accept React nodes gives you way more flexibility - now you can pass in rich components instead of just text.

design-system/TextField/TextField.tsx (3)

70-73: Good container style extraction

Moving margin and padding to a dedicated container style makes total sense here.


149-162: Smart conditional rendering implementation

This cleanly handles both string helpers and React node helpers, making the component much more versatile.


191-193: Clean style separation

Good call removing layout styles from the text style - keeps things clean and the comment helps future devs understand your intent.

features/groups/mutations/revoke-group-member-from-super-admin.mutation.ts (1)

8-8: Import Path Update Looks Great!
The import from @/features/groups/queries/group.query is spot on—nice work keeping the structure tidy.

features/consent/use-group-consent-for-current-sender.ts (1)

7-7: Updated Import Path is Spot On!
The switch to the new import path for getGroupQueryOptions and useGroupQuery keeps things consistent with our reorganized directories.

features/conversation/conversation-list/conversation-list-item/conversation-list-item-group.tsx (1)

13-13: Import Updated!
Great job updating useGroupQuery to use the new path—it makes our code cleaner and easier to follow.

features/groups/components/add-group-members-search-users-input.component.tsx (1)

3-3: Absolute Import for Store is Clean!
Changing the path to @/features/groups/stores/add-group-members.store enhances clarity and consistency.

features/groups/mutations/revoke-group-member-from-admin.mutation.ts (1)

8-8: Nice and Clean Import Revision!
Updating this import to the new directory structure is exactly what we need—great job!

features/groups/mutations/promote-group-member-to-super-admin.mutation.ts (1)

8-8: Import path updated correctly

The import path has been updated to reflect the new directory structure, moving group query functions to a dedicated 'queries' subdirectory.

features/consent/use-allow-group.mutation.ts (1)

17-17: Import path properly updated

Good job on updating this import path to match the new directory structure. Keeps things consistent with the rest of the codebase changes.

components/group-avatar.tsx (1)

9-9: Import path correctly updated

The import path for useGroupQuery has been updated to reflect the new directory structure.

features/groups/mutations/remove-group-members-from-group.mutation.ts (1)

8-8: Import path updated correctly

Import path has been updated to match the new directory structure where group queries live in a dedicated subdirectory.

features/conversation/conversation-chat/conversation.store-context.tsx (2)

7-7: Added GenericError import for better error handling

Good addition - this will support the improved error handling pattern.


55-55: Improved error handling with context

Nice upgrade to the error handling - wrapping errors in GenericError with additional context makes debugging easier.

features/conversation/conversation-requests-list/conversation-requests-list.screen.tsx (2)

7-7: New custom hook imported

Added a new import for useBetterFocusEffect which will replace the standard useFocusEffect.


43-47: Changed to useBetterFocusEffect

Switched from useFocusEffect to useBetterFocusEffect. This is a good change since the new hook only runs the effect once instead of every time the component gains focus.

Double-check that this behavior change (running only once vs. every focus) is what you want for this screen. This might affect behavior when navigating away and back.

features/groups/components/add-group-members-search-users-results-list-item-eth-address.component.tsx (1)

4-4: Updated import path

Changed from relative to absolute import path. Looks good - this makes the code more maintainable and consistent with the codebase standards.

features/conversation/utils/inbox-id-is-part-of-converastion.ts (1)

3-3: Updated import path for reorganized structure

Updated the import path to reflect the new location of group.query in the queries subdirectory.

features/groups/mutations/add-group-members.mutation.ts (1)

8-8: Updated import path

Changed import path to use the new queries subdirectory structure, maintaining consistency with other files.

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

13-13: New import to support improved error handling

Added import for GenericError to support the enhanced error handling implemented below.


85-87: Better error handling with more context

Nice improvement here! Wrapping the raw error in GenericError adds helpful context ("Error reacting on message") that will make debugging easier.

features/consent/use-deny-group.mutation.ts (1)

11-11: Updated import path as part of code reorganization

This path change reflects the move of group queries to a dedicated subdirectory. Good organization!

features/groups/mutations/promote-group-member-to-admin.mutation.ts (1)

9-9: Updated import path to match new folder structure

Consistent with other imports being updated throughout the codebase to use the new queries subdirectory.

features/conversation/conversation-chat/conversation-attachment/remote-attachment-local-storage.ts (2)

6-6: New import for enhanced error handling

Added GenericError import to support the improved error handling below.


31-33: Better error reporting with context

Wrapping the error in GenericError with "Error getting stored remote attachment" message makes debugging much easier. Consistent with the error handling approach used elsewhere.

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

26-26: Added GenericError import for improved error handling

This import introduces a standardized error wrapper class from the utils directory.


190-195: Better error handling with context

Nice improvement! You're now wrapping the error in a GenericError with additional context instead of passing it directly to captureError. This makes debugging easier by providing more info about where the error occurred.

features/profiles/components/profile-contact-card/profile-contact-card.tsx (2)

7-7: Added IXmtpInboxId import for local type definition

Adding this import to support the local type definition.


10-12: Local type definition instead of imported type

Smart move defining the type locally instead of importing it from profile.types. Keeps the component more self-contained and makes dependencies clearer.

features/conversation/conversation-list/conversation-list-awaiting-requests.tsx (2)

1-1: Replaced useFocusEffect with useBetterFocusEffect

Updated imports to use the new custom focus hook.

Also applies to: 18-18


32-36: Performance improvement with useBetterFocusEffect

Great optimization! The new useBetterFocusEffect ensures refetch() only runs once instead of every time the component gains focus, preventing unnecessary API calls.

config/shared.ts (1)

51-51: Changed React Query persist cache to enabled by default

Smart switch from opt-in to opt-out for cache persistence. This will improve performance by default while still allowing it to be disabled when needed.

features/groups/screens/add-group-members.screen.tsx (1)

4-4: Import paths updated correctly

You've updated the import paths to match the new directory structure. This aligns with the broader reorganization.

Also applies to: 9-11

features/groups/components/add-group-members-search-users-results-list-item-user-.component.tsx (1)

6-6: Import path standardized

Switched from relative path to absolute path for consistency. Looks good.

features/groups/hooks/use-group-members.ts (1)

2-2: Updated import to new directory structure

Import path now points to the new queries subdirectory. Matches with other organizational changes.

features/conversation/conversation-requests-list/use-conversation-requests-list-items.tsx (1)

7-7: Improved error handling with GenericError

Nice upgrade to error handling - wrapping the error with additional context makes debugging easier. This follows the pattern used elsewhere in the codebase.

Also applies to: 57-57

features/conversation/conversation-list/conversation-list.screen.tsx (2)

32-32: Nice import addition.

Adding the GenericError import is the first step to improving error handling throughout the codebase.


80-80: Good error handling improvement.

Wrapping errors with GenericError and providing additional context ("Error refreshing conversations") makes debugging easier and provides more structured error information. This is a good practice for consistent error handling.

features/conversation/conversation-list/hooks/use-delete-dm.ts (3)

16-16: Good import addition.

Adding the GenericError import aligns with the changes in other files for consistent error handling.


80-82: Nice error handling improvement.

Wrapping errors with GenericError and providing additional context ("Error deleting dm") makes debugging easier and provides more structured error information. This follows the same pattern used elsewhere in the codebase.


96-98: Consistent error handling update.

This change mirrors the one in the previous action handler, maintaining a consistent approach to error handling throughout the file.

features/conversation/conversation-chat/conversation-consent-popup/conversation-consent-popup-group.tsx (2)

15-15: Good import addition.

The GenericError import supports the enhanced error handling in this component.


51-51: Improved error handling.

Wrapping the error with GenericError and providing additional context ("Failed to allow group") is consistent with the pattern used elsewhere in the codebase. This makes debugging easier and improves error reporting.

features/conversation/conversation-chat/conversation-message/conversation-message-gestures.tsx (2)

14-14: Good import addition.

The GenericError import supports the enhanced error handling in this component.


57-59: Improved error handling.

Wrapping the error with GenericError and providing additional context ("Error showing context menu") follows the same pattern used elsewhere. This makes debugging easier and provides more structured error information.

features/conversation/conversation-chat/conversation-message/conversation-message-reactions/conversation-message-reaction-drawer/conversation-message-reaction-drawer.tsx (2)

20-20: Added GenericError import for improved error handling.

This import supports the enhanced error handling below.


93-95: Better error handling with structured error.

Nice improvement! Wrapping the raw error in a GenericError with context message makes debugging easier and provides better user feedback.

components/avatar.tsx (2)

15-15: Added new xxl size option to Avatar component.

This expands the Avatar component's flexibility by adding an extra size variant.


39-39: Implemented xxl size in avatarSize mapping.

This correctly maps the new "xxl" size option to the theme's avatar sizes.

features/conversation/conversation-list/conversation-list-item/conversation-list-item-dm.tsx (3)

22-22: Added GenericError import for improved error handling.

This import enables the enhanced error handling below.


85-85: Better error handling with structured error.

Wrapping the error with context "Error deleting dm" improves error reporting and user feedback.


93-95: Enhanced error handling for toggling read status.

This follows the same pattern of using GenericError with context, making error reporting more consistent across the app.

features/conversation/conversation-list/hooks/use-message-content-string-value.ts (2)

23-23: Added GenericError import for improved error handling.

This import enables the enhanced error handling below.


235-240: Better error handling with structured error.

This change improves error reporting by providing better context ("Error getting message content string value") when something goes wrong.

features/groups/screens/group-details.screen-header.tsx (3)

5-5: Props updated to accept conversation ID

Function now properly accepts xmtpConversationId as a parameter instead of relying on global state, improving reusability.

Also applies to: 10-12


26-27: Navigation to edit screen implemented

Navigation to edit group screen now correctly passes the conversation ID parameter. Dependencies list properly updated to include it.


41-47: Header action buttons implemented

The previously commented-out header component is now implemented with buttons for sharing, editing, and menu access. Good use of HStack with appropriate spacing.

features/groups/hooks/use-group-name.ts (2)

3-3: Updated import path for group query

Import path updated to reflect new directory structure, aligning with the codebase reorganization.


1-48:

Details

✅ Verification successful

Removed group name mutation functionality

The mutation logic for updating group names has been removed from this hook. Note that this functionality appears to have been moved elsewhere as part of a restructuring.


🏁 Script executed:

#!/bin/bash
# Look for where group name mutation might have been moved to
rg -A 2 "updateGroupName|useGroupNameMutation" --type ts

Length of output: 1201


Heads-up: Group Name Mutation Relocated
The mutation logic for updating group names was intentionally removed from this hook and has now been moved to the module at features/xmtp/xmtp-conversations/xmtp-conversations-group.ts, as confirmed by our search. Everything seems in order here.

features/conversation/conversation-list/hooks/use-conversation-list-item-context-menu-props.tsx (4)

15-15: Added GenericError import

Added import for the GenericError class to standardize error handling.


124-126: Improved error handling for pinning conversations

Error handling now wraps errors in GenericError with a descriptive message, providing better context for debugging.


182-182: Improved error handling for group deletion

Error handling now uses GenericError with additional context message.


199-201: Improved error handling for conversation deletion

Error handling now uses GenericError with descriptive message.

features/conversation/conversation-list/hooks/use-delete-group.ts (4)

10-10: Updated import path for group query

Import path updated to reflect new directory structure. Good for consistency with other imports.


15-15: Added GenericError import

Added import for standardized error handling.


69-71: Improved error handling for group deletion

Error handling now wraps the caught error in a GenericError with a descriptive message, providing better context for debugging and user feedback.


86-88: Improved error handling for delete and block action

Error handling for the delete and block action now uses the same standardized approach with GenericError.

features/groups/components/add-group-members-confirm-button.component.tsx (3)

9-11: Import paths reorganized

Import paths have been updated to reflect a new directory structure, with a more organized approach to mutations, queries, and stores.


15-15: New import for error handling

Added GenericError import to support improved error handling.


52-54: Better error handling with context

The error is now wrapped in a GenericError with a helpful message instead of being passed directly to captureErrorWithToast.

features/groups/components/group-member-details/group-member-details.service.tsx (1)

1-14: Good new service implementation for bottom sheet

This is a well-structured service that properly handles the bottom sheet modal for group member details. The separation of open and close functions is clean and follows good practices.

components/debug-provider.tsx (12)

14-14: Function renamed for clarity

Function renamed from getPushNotificationsToken to getDevicePushNotificationsToken for better specificity.


181-181: Improved error handling

Error is now wrapped with additional context to make debugging easier.


247-252: Consistent error handling pattern

Following the same pattern of wrapping errors with context for better debugging.


262-267: Improved error message

Better context for error when requesting notification permissions.


291-296: Consistent error handling

Error now includes specific context about registration failure.


304-309: Error context added

Similar improvement for the outer try/catch block.


337-342: Better error context

Added specific message about badge count error.


348-348: Updated function call

Using the renamed function getDevicePushNotificationsToken for consistency.


365-370: Improved error reporting

Better error context for device token issues.


390-395: Consistent error handling style

Follows the same pattern used throughout the file.


411-416: Clear error context

Helpful message specific to test notification failures.


443-448: Proper menu error handling

Good error context for the notifications menu.

features/preferred-display-info/preferred-display-info.utils.ts (2)

2-2: Updated import for profile type

Changed to use IConvosProfile instead of IConvosProfileForInbox.


12-12:

Details

✅ Verification successful

Updated parameter types

Type changed from IConvosProfileForInbox to IConvosProfile for all functions. Make sure this won't break any existing calls.

Also applies to: 32-32, 48-48


🏁 Script executed:

#!/bin/bash
# Check if there are any references to IConvosProfileForInbox in the codebase
rg "IConvosProfileForInbox" -A 1 -B 1

Length of output: 285


Parameter type update verified: All good here!

The changes correctly update parameters from IConvosProfileForInbox to IConvosProfile. Our grep search only found commented-out references (in features/current-user/create-user.mutation.ts), so no active code still depends on the old type.

features/groups/components/add-group-members-search-results-list.component.tsx (1)

16-38: Nice type safety implementation!

Good job adding discriminated union types with type guards for search results. This makes handling different result types much safer throughout the component.

features/groups/components/group-member-details/group-member-details.bottom-sheet.tsx (6)

15-19: Good refactoring of imports

Renaming to include "GroupMemberDetails" prefix makes the code more explicit about what it's handling.


21-25: Clean organization of mutation imports

Moving these to a dedicated mutations directory improves code organization.


34-34: Adding proper error handling

Good addition of GenericError import which will be used for better error handling.


36-37: Improved naming consistency

Renaming the component and updating the store reference matches the new naming pattern.


127-129: Better error handling

Wrapping errors with additional context messages improves debugging. Nice improvement!


235-239: Updated bottom sheet modal props

Good cleanup of the component props and ref handling.

features/notifications/notifications.types.ts (5)

5-11: Smart use of generics for notification types

Creating a reusable generic type for notifications with data is a good pattern for type safety.


13-19: Well-defined Expo notification type

Clear structure for Expo push notifications with all required fields.


21-23: Helpful documentation comment

Good explanation of how XMTP differs from standard notification structure.


52-67: Comprehensive background notification type

All the necessary fields for Expo background notifications are properly typed.


69-71: Clear documentation for platform differences

Good explanation of iOS-specific nesting for XMTP background notifications.

features/authentication/authentication.types.ts (1)

1-1: Great use of branded types

Using a branded type for IPrivyUserId prevents accidental use of regular strings where a specific ID type is required. This improves type safety across the app.

features/authentication/multi-inbox.store.ts (1)

215-217: Clean addition that follows existing patterns

This new function gives direct access to the senders list following the same pattern as other getters in this file.

features/devices/devices.utils.ts (2)

5-7: Looks good, simple and clear

The function provides a clean wrapper around the expo-device model ID.


9-11:

Details

❓ Verification inconclusive

Clean implementation, but verify type safety

Nice simple approach. Just make sure Platform.OS values always align with the expected IDeviceOS type.


🏁 Script executed:

#!/bin/bash
# Check what values are allowed in the DeviceOSSchema
rg -A 5 "DeviceOSSchema" --type ts

Length of output: 943


Type Safety Verification for Device OS
Hey, the implementation in features/devices/devices.utils.ts looks clean. Given that the DeviceOSSchema is defined as:

z.enum(["ios", "android", "web", "macos"])

the conversion via Platform.OS.toLowerCase() aligns with these allowed values, assuming that Platform.OS always returns a recognizable value. Just double-check that no unexpected OS strings (e.g., for platforms not covered by the enum) could slip through; if there's any doubt, consider adding a runtime check or fallback.

features/profiles/profile-me.tsx (1)

281-281: Better error handling approach

Nice improvement - wrapping the raw error in GenericError gives more context and follows the pattern being adopted across the app.

features/conversation/conversation-chat/conversation-composer/conversation-composer.tsx (1)

37-39: Improved error handling with better context

The error is now properly wrapped in a GenericError with a clear message, making debugging easier.

features/conversation/conversation-create/mutations/create-conversation-and-send-first-message.mutation.ts (1)

24-24: Import path updated to reflect new directory structure

The import path for setGroupQueryData has been updated to the new location in the /queries subdirectory, aligning with the codebase reorganization.

features/notifications/notification-assertions.ts (2)

4-4: New import added for notification type

Added import for IExpoNewMessageNotification which will be used by the new function.


30-34: New helper function for Expo notifications

Good addition that follows the existing pattern for notification type checking. This will help with proper handling of Expo push notifications for messages.

features/authentication/authentication.api.ts (1)

2-2: Import path updated for ApiError

The import path has been updated to get ApiError from a more specific location, which is good for better organization of error handling.

features/authentication/authentication.headers.ts (1)

38-46: Nice performance boost with concurrent operations!

You've improved the code by using Promise.all to run the installation ID fetch and signature generation in parallel. Smart move - this should make authentication faster.

features/profiles/components/profile-social-names.tsx (3)

15-15: New GenericError import - good addition!

This import supports the improved error handling below.


40-42: Better error handling with GenericError

Nice improvement on error context by wrapping the raw error in a GenericError with meaningful message.


48-50: Consistent error handling pattern

Following the same pattern here as above - good for consistency!

features/conversation/conversation-create/queries/search-existing-dms.query.ts (2)

11-11: New GenericError import

Added to support improved error handling below.


71-73: Better error handling

Good improvement! Using GenericError with additional context makes debugging easier when things go wrong.

features/groups/components/group-details-members-list-item.component.tsx (2)

5-5: Updated import paths

These path changes look like part of a broader reorganization. Make sure all imports are consistent across the codebase.

Also applies to: 12-12


24-24: Updated function call to match new structure

Changed from openMemberDetailsBottomSheet to openGroupMemberDetailsBottomSheet to match the new organization.

features/authentication/use-logout.ts (2)

19-19: Good use of an important comment

Adding this comment helps future developers understand that the order matters in this function.


31-32: TODO with clear intent

The TODO comment clearly indicates future work for multiple identity support.

features/conversation/conversation-chat/conversation-composer/conversation-composer-add-attachment-button.tsx (1)

97-99: Improved error handling

Nice job wrapping the error in a GenericError with a specific message. This makes debugging easier and provides better context.

features/auth-onboarding/contexts/auth-onboarding.context.tsx (3)

22-22: Appropriate import

Good addition of the AuthenticationError import to support your improved error handling.


151-153: Better error context

Wrapping the error in AuthenticationError with a specific message improves error reporting and user feedback.


234-236: Consistent error handling approach

Good job applying the same improved error handling pattern here for signup failures.

features/conversation/conversation-chat/conversation-composer/conversation-composer-text-input.tsx (1)

3-8: More specific imports

Good job importing specific types instead of generic ones.

features/conversation/conversation-create/queries/search-existing-groups-by-group-members.query.ts (1)

12-12: Nice error handling upgrade 👍

Added structured error handling using GenericError to provide better context about what went wrong during group member searches. Makes debugging way easier.

Also applies to: 74-79

features/groups/components/group-member-details/group-member-details.store.tsx (1)

1-29: Clean Zustand store implementation

Well-structured store with clear types and actions. Good separation of concerns with state and actions.

features/profiles/components/profile-contact-card/profile-contact-card-layout.tsx (1)

1-1: Good move defining the props type locally

Adding the ICardLayoutProps type definition in the file makes the component more maintainable and self-contained.

Also applies to: 6-10

features/profiles/profile-me.screen-header.tsx (1)

143-143: Parameter naming consistency

Renamed parameter from profile to profileUpdates which better reflects what's actually being passed - nice clarity improvement.

App.tsx (2)

20-20: Consider documenting performance investigation details.

The comment states that useSyncQueries slows down the app, but doesn't provide specifics. Adding performance metrics or concrete observations would help future developers understand why this feature was disabled.

Also applies to: 64-65


29-29:

Details

❓ Verification inconclusive

Folder naming updated.

The import path change reflects a correction in file structure, going from "background-notification-handler" to "background-notifications-handler". Make sure all related imports across the codebase have been updated.


🏁 Script executed:

#!/bin/bash
# Check if any files still import from the old path
rg "background-notification-handler" --type ts --type tsx

Length of output: 85


#!/bin/bash
echo "Searching in ts files:"
rg "background-notification-handler" --type ts
echo "Searching in tsx files:"
rg "background-notification-handler" -g "*.tsx"

Heads up on TSX search error:
The original script hit an issue because RG didn’t recognize the tsx file type. I've updated the script above to explicitly search in both .ts and .tsx files. Please run this script and verify that there are no remaining imports using the old path across your codebase.

features/devices/device.storage.ts (3)

1-16: LGTM! Well-structured device ID retrieval.

The implementation properly handles error cases and provides informative error messages.


18-27: Proper error handling for device storage.

The function follows the pattern established in the codebase for storage operations with appropriate error wrapping.


29-38: Clean implementation of device ID removal.

Consistent with the other storage functions, with proper error handling and clear error messages.

features/conversation/conversation-chat/conversation-messages.tsx (2)

25-25: Smart hook replacement to prevent unnecessary refreshes.

Switching from useFocusEffect to useBetterFocusEffect is a good change since it only runs once when the component is first focused, preventing wasteful refreshes on subsequent focus events.

Also applies to: 30-30, 61-65


94-98: Improved error context for debugging.

The new error handling provides better context with the specific operation that failed ("Error refreshing conversation messages"), making debugging easier.

features/current-user/current-user.types.ts (3)

6-6: Good use of branded types for type safety.

Using a branded type for IConvosCurrentUserId prevents accidental string assignments and improves type checking.


10-14: Clean schema definition for user identities.

The schema clearly defines the structure expected for identity objects.


16-22: Consider finalizing deviceId implementation.

There's a commented-out section for deviceId in the schema. Is this something that should be implemented now or deliberately left for future work?

If deviceId integration is planned, when will it be implemented? The commented code suggests it's a work in progress.

features/conversation/conversation-metadata/conversation-metadata.query.ts (1)

17-17: Update looks good!

The function now correctly passes the clientInboxId parameter to the getConversationMetadata function, which aligns with the API requirements. This parameter is needed to find the corresponding device identity.

features/authentication/use-refresh-jwt.axios-interceptor.ts (2)

7-10: Import clarification needed

You're importing both ApiError and GenericError, but GenericError doesn't seem to be used in the visible changes. Is it needed?


26-26: Better error handling - nice!

Using AuthenticationError with additional context improves error tracing and debugging.

features/notifications/notifications-listeners.ts (1)

51-56: Improved error context - nice!

Enhanced error handling with NotificationError and additional context makes debugging easier.

features/devices/devices.types.ts (1)

1-20: Well-structured type definitions

Good use of Zod schemas and branded types for type safety. The schema includes all necessary fields for device data.

features/current-user/current-user.query.ts (3)

4-5: Updated imports for better organization

Changing import paths to local references and adding type imports from dedicated type files. Nice cleanup!


21-21: Type signature updated for better type safety

Updated to use the Zod-inferred IConvosCurrentUser type instead of the previous ICurrentUser type.


36-38: Useful query data helper added

This new function ensures the current user data is available in the query cache - handy utility for components that need guaranteed data access.

features/authentication/hydrate-auth.ts (1)

10-10: Improved log messages for better debugging

The updated log messages now provide more context about what's happening during the auth hydration process. Good DX improvement.

Also applies to: 15-15, 31-31, 40-40, 47-47

features/notifications/notifications-init.ts (4)

3-6: Added support for Expo notifications

Importing the new isNotificationExpoNewMessageNotification function alongside the existing XMTP notification check.


27-103: Enhanced error handling with try-catch in notification handler

The notification handling now has proper error handling wrapped in a try-catch block, which prevents failures from blocking other notifications.


64-76: XMTP notification handling looks good

Processing XMTP notifications and preventing duplicates by marking them as processed.


78-90: Added Expo notification support

New handler for Expo-specific notifications with similar pattern to XMTP handler.

features/current-user/create-user.mutation.ts (3)

1-8: Well-structured imports for the new mutation file

Clean organization of imports for React Query, current user, devices, profiles, and utilities.


53-75: Review the deviceId handling

You're storing the device ID but it's commented out in the user object. Is this intentional?

  setCurrentUserQueryData({
    user: {
      id: data.id,
-     // deviceId: data.device.id,
+     deviceId: data.device.id,
      identities: [data.identity],
    },
  })

79-89: Clean hook and mutation implementation

Good job providing both a React hook and a programmatic function for different usage scenarios.

features/groups/components/group-details-members-list.component.tsx (4)

9-9: Nice import!
Glad to see the bottom sheet is being directly referenced here.


11-11: Import path update looks clean.
Consistency is on point.


15-15: Good rename.
Keeping files consistently named helps.


94-94: Nice addition of the new bottom sheet.
Your approach slots well into the existing layout.

features/groups/mutations/update-group.mutation.ts (5)

1-9: Imports look good.
Everything seems neatly organized.


11-15: Type definition is concise.
Well-structured optional fields.


17-20: Function signature is clear.
Looks straightforward to pass props here.


61-76: Optimistic update logic is on point.
Should provide a snappy user experience.


89-90: Closing braces look good.
No issues spotted.

features/devices/user-device.query.ts (5)

1-8: Neat imports.
This lays a good foundation for device querying.


9-13: Type definition is straightforward.
Makes things more readable.


14-26: Query options are nicely formed.
Good call on enabling conditionally.


28-36: Great job ensuring device data.
Error handling is on target.


38-44: setQueryData usage is solid.
Straightforward and maintainable.

features/conversation/conversation-metadata/conversation-metadata.api.ts (4)

3-3: Switch to ensureCurrentUserQueryData is nice.
This avoids possible null user scenarios.


18-21: New type for metadata args is great.
Keeps everything typed and tidy.


23-60: Solid approach to fetching conversation metadata.
Clear error checks and device identity logic are helpful.

🧰 Tools
🪛 Biome (1.9.4)

[error] 58-58: The catch clause that only rethrows the original error is useless.

An unnecessary catch clause can be confusing.
Unsafe fix: Remove the try/catch clause.

(lint/complexity/noUselessCatch)


185-185: Ensuring user data in updateConversationMetadata is consistent.
Gives a safer flow overall.

features/groups/screens/group-details.screen.tsx (3)

11-11: Imports aligned
Refactored import path for GroupDetailsMembersList looks good.


13-13: Query import refactor
Importing useGroupQuery from the new location is consistent with the folder structure.


37-37: Header usage
useGroupDetailsScreenHeader({ xmtpConversationId }) is neatly integrated. Good job.

features/auth-onboarding/components/auth-onboarding-contact-card/auth-onboarding-contact-card-footer.tsx (2)

9-14: Nice additions
Adding IPrivyUserId, useCreateUserMutation, and GenericError improves type safety and error handling.


54-54: Casting privyUserId and error handling
Casting privyUser.id to IPrivyUserId is okay if you're sure it meets the contract. Also, using GenericError inside captureErrorWithToast looks solid for consistent error reporting.

Also applies to: 59-60, 81-86

features/profiles/hooks/use-save-profile.ts (9)

2-2: No concerns
Import statements look fine here.


7-7: Neat addition
Great to see updateProfileQueryData included—keeps things consistent.


12-14: Fits the flow
Switching to ISaveProfileArgs with profileUpdates makes sense for partial updates.


19-20: Streamlined approach
Returning saveProfile(args) directly is neat and clear.


23-23: Good usage
The onMutate function structure is tidy.


25-26: Readability
Pulling previousProfile is a nice step for optimistic updates.


29-31: Works well
Updating profile data optimistically is straightforward here.


37-37: Error handling
Reverting to previousProfile is a safe fallback. Good job.


40-40: Nice clarity
Explicitly naming profile: context.previousProfile is easy to follow.

features/groups/screens/edit-group.screen.tsx (11)

1-25: Imports look solid
All necessary modules are clearly referenced.


27-45: Basic screen definition
The EditGroupScreen setup with route params is quite clean.


46-49: Simple cancel
handleCancelPress is straightforward, no issues.


50-54: Clean up
Resetting state on unmount avoids leftover data in store. Good call.


56-82: Update logic
Collecting changes from the store and updating with updateGroupAsync is a tidy flow.


84-91: Header config
Easy to read, consistent with the rest of the app.


92-105: Edge case
Good check for !group with an empty state. Looks functional.


109-137: Main layout
UI structure is clear, usage of VStack and text fields is nice.


140-187: Avatar editor
Solid approach to uploading and fallback with error handling.


189-217: Counters
Live char counters for name & description are straightforward. Nicely done.


219-251: Zustand store
Centralizing group edits ensures consistent state. Looks good.

features/notifications/notifications-conversations-subscriptions.ts (5)

16-16: Refactor
Replacing QueryObserver with createQueryObserverWithPreviousData is a nice improvement.


25-32: Smart callback
Comparing data vs previousData avoids redundant subscription updates.


38-42: Store watchers
Triggering subscription updates on senders length change is efficient.


60-61: Helpful logs
"Updating conversation subscriptions" clarifies the process.


225-226: Silent notifications
Setting isSilent helps control user experience. Good addition.

features/notifications/notification-clear.ts (4)

1-9: Modules
Imports for expo and custom assertions are straightforward.


11-14: Clear all
Simple one-liner to dismiss all. Looks fine.


16-20: Dismiss single
Passing the identifier is direct and easy to read.


22-82: Conversation-based clearing
Filtering notifications by conversation is well-structured with safe checks.

features/current-user/use-create-user-if-no-exist.ts (5)

6-10: Looks clean, no issues with the new imports.


11-15: Neat imports.


16-34: Import changes look straightforward.


125-173: Flow handles user creation vs. existing user logic.
Consider verifying if createUserMutation fails, and confirm we gracefully handle that.


257-269: New profile fields as null are fine.
All set with random naming.

features/devices/devices.api.ts (3)

1-25: fetchDevice
Everything seems fine, returns validated data.


51-78: createDevice
Input validation and schema usage look good.


84-114: updateDevice
Works similarly to create, looks consistent.

features/notifications/background-notifications-handler.ts (6)

1-1: Importing Device is fine.
Just ensure we check platform cases if running in web vs. native.


27-37: Validates background data quickly.
Throws if missing contentTopic. That’s correct.


40-41: Sending the right fields to local message notification.
Double-check that the encryptedMessage is properly decrypted after.


62-70: Skipping registration on simulator is a great catch.
Saves devs from simulator quirks.


109-121: Unregistering tasks thoroughly.
Seems handy for fresh restarts; concurrency issues appear minimal.


122-148: Logs all tasks for debugging.
Direct and helpful.

features/identities/identities.api.ts (5)

1-9: Looks neat!
Imports and references look well-structured. Good use of typed IDs and helper utilities.


10-11: Type branding
The branded type for IDeviceIdentityId is consistent with your device conventions. Nice.


22-23: Type export
Exporting IDeviceIdentity from the schema is straightforward. No issues seen.


69-86: Creation flow
Looks good. The code is consistent with the rest. Just watch for partial data usage if validation fails.


88-102: Update pattern
Mirror of create. Fine overall. Same note about the safe-parse approach.

features/notifications/notifications.service.ts (10)

11-13: Device updates
Imports for fetching user/device are flexible. Good structure.


29-35: Token fetch
Cool approach with parallel token fetching. If either fails, you handle it below. Looks good.


43-49: User check
Throwing NotificationError is consistent. Helps keep errors contextual.


51-59: Device check
Same pattern. You handle missing device properly.


61-69: Updating device
All good. You do try/catch around it to catch issues. Practical approach.


70-76: Error collector
Storing errors in an array provides aggregated error reporting. No concerns.


102-107: Aggregated throw
If any error occurred, you throw them all at once. That’s neat.


110-129: Expo token retrieval
Good checks for device usage and permissions. Clear error messages. Nicely done.


131-157: Device token
Similar pattern. The new NotificationError usage is consistent with the rest. Looks smooth.


205-207: Local notification
Nice logging steps. The parallel fetch + decrypt is efficient. The final error gets wrapped properly too.

Also applies to: 221-235, 245-253, 255-287

@macroscopeapp
Copy link
Copy Markdown

macroscopeapp bot commented Mar 27, 2025

Refactor: Device Management, Error Handling and Group Features

Added device and identity management system with multi-device support. Consolidated group update operations into a single mutation. Replaced individual error handling with structured error types. Added Expo notification support. Moved group-related files to new directory structure. Changed React Query cache to be enabled by default. Added xxl size to Avatar component. Updated TextField to support React nodes in helper text.

📍Where to Start

The device management implementation in devices.api.ts and identities.api.ts, which form the foundation for the new multi-device support system.


Macroscope summarized daf5316.

Copy link
Copy Markdown
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

♻️ Duplicate comments (1)
features/notifications/notifications-init.ts (1)

97-110: ⚠️ Potential issue

Fix the return in finally block

The final return statement outside the try-catch will override any returns from the try block, which could cause unexpected behavior.

  } catch (error) {
    captureError(
      new NotificationError({
        error,
      }),
    )
+   return {
+     shouldShowAlert: true,
+     shouldPlaySound: true,
+     shouldSetBadge: true,
+   }
  }
-
-  // Let's always show the notification anyway
-  return {
-    shouldShowAlert: true,
-    shouldPlaySound: true,
-    shouldSetBadge: true,
-  }
🧹 Nitpick comments (5)
features/groups/screens/group-members-list.screen.tsx (3)

67-67: Remove unnecessary optional chaining

You're already checking if group exists on line 52, so the ?. on line 67 isn't needed.

-          data={group?.members.ids}
+          data={group.members.ids}

66-70: Add keyExtractor to FlashList

FlashList needs a keyExtractor to avoid potential rendering issues and React key warnings.

        <FlashList
          data={group?.members.ids}
          renderItem={({ item }) => <MemberListItem memberInboxId={item} />}
          estimatedItemSize={60}
+         keyExtractor={(item) => item}
        />

65-71: Consider adding an empty state for no members

The current implementation doesn't handle the case when the group exists but has no members. Consider adding an empty state.

        <FlashList
          data={group?.members.ids}
          renderItem={({ item }) => <MemberListItem memberInboxId={item} />}
          estimatedItemSize={60}
+         ListEmptyComponent={
+           <EmptyState 
+             title="No members" 
+             description="This group has no members yet." 
+           />
+         }
        />
features/current-user/create-user.api.ts (1)

87-96: Consider throwing errors on invalid response validation

Currently you're capturing validation errors but still returning potentially invalid data. It might be better to throw an error if validation fails instead of just logging it.

if (!responseValidation.success) {
-  captureError(
-    new ApiError({
-      error: responseValidation.error,
-      additionalMessage: "Invalid create user response data",
-    }),
-  )
+  throw new ApiError({
+    error: responseValidation.error,
+    additionalMessage: "Invalid create user response data",
+  })
}
features/current-user/use-create-user-if-no-exist.ts (1)

40-41: Remove commented parameters

These commented parameters appear to be leftover from development and should be removed to keep the code clean.

async function makeSureDeviceAndIdentitiesAreCreated(args: {
  userId: IConvosCurrentUserId
-  // privyAddress: IEthereumAddress
-  // xmtpId: IXmtpInboxId
}) {
📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 5ef7f5f and 79e0df3.

⛔ Files ignored due to path filters (1)
  • yarn.lock is excluded by !**/yarn.lock, !**/*.lock
📒 Files selected for processing (9)
  • eslint.config.mjs (1 hunks)
  • features/authentication/use-logout.ts (1 hunks)
  • features/current-user/create-user.api.ts (1 hunks)
  • features/current-user/use-create-user-if-no-exist.ts (5 hunks)
  • features/groups/screens/group-members-list.screen.tsx (1 hunks)
  • features/notifications/notifications-init.ts (2 hunks)
  • features/xmtp/xmtp-client/xmtp-client.ts (5 hunks)
  • utils/file-system/file-system.ts (1 hunks)
  • utils/logger.ts (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • features/authentication/use-logout.ts
🧰 Additional context used
🧬 Code Definitions (2)
features/current-user/create-user.api.ts (6)
features/devices/devices.types.ts (1)
  • deviceSchema (8-17)
features/current-user/current-user.types.ts (2)
  • identitySchema (10-14)
  • IConvosCurrentUserId (6-6)
features/profiles/profiles.types.ts (2)
  • ConvosProfileSchema (7-30)
  • IConvosProfile (32-32)
features/authentication/authentication.types.ts (1)
  • IPrivyUserId (1-1)
features/devices/devices.utils.ts (2)
  • getDeviceOs (9-11)
  • getDeviceModelId (5-7)
utils/convos-api/convos-api-error.ts (1)
  • ApiError (21-95)
features/current-user/use-create-user-if-no-exist.ts (14)
features/current-user/current-user.types.ts (1)
  • IConvosCurrentUserId (6-6)
features/devices/device.storage.ts (2)
  • getStoredDeviceId (7-16)
  • storeDeviceId (18-27)
features/devices/devices.types.ts (1)
  • IDevice (19-19)
features/devices/devices.api.ts (3)
  • fetchDevice (10-25)
  • IDeviceCreateInput (58-58)
  • createDevice (60-78)
utils/error.ts (1)
  • AuthenticationError (95-99)
features/notifications/notifications.service.ts (2)
  • getExpoPushNotificationsToken (110-129)
  • getDevicePushNotificationsToken (131-158)
features/devices/devices.utils.ts (2)
  • getDeviceOs (9-11)
  • getDeviceModelId (5-7)
features/devices/user-device.query.ts (1)
  • setUserDeviceQueryData (38-44)
features/identities/identities.api.ts (2)
  • fetchDeviceIdentities (25-36)
  • createIdentity (69-86)
features/authentication/multi-inbox.store.ts (2)
  • getMultiInboxStoreSenders (215-217)
  • getSafeCurrentSender (182-188)
features/current-user/current-user.query.ts (1)
  • invalidateCurrentUserQuery (26-30)
features/authentication/authentication.types.ts (1)
  • IPrivyUserId (1-1)
features/current-user/current-user.api.ts (1)
  • fetchCurrentUser (6-24)
features/current-user/create-user.mutation.ts (2)
  • createUserMutation (83-89)
  • ICreateUserMutationArgs (9-9)
🪛 Biome (1.9.4)
features/xmtp/xmtp-client/xmtp-client.ts

[error] 269-273: This code is unreachable

... because this statement will return from the function beforehand

(lint/correctness/noUnreachable)

🔇 Additional comments (17)
utils/logger.ts (1)

76-76: Improved type safety by removing generic any parameter

Nice cleanup! Removing <any> is a good practice as it improves type safety. The function correctly specifies its parameter types explicitly in the function signature, making the generic parameter unnecessary.

utils/file-system/file-system.ts (1)

67-67:

Details

✅ Verification successful

Changed buffer handling in hash function

You've switched from using buffer.buffer to buffer.toString("binary") when updating the hash. This changes how the file data is processed by the SHA-256 hash function. Make sure this was intended and tested, as it will produce different hash values for the same files compared to the previous implementation.


🏁 Script executed:

#!/bin/bash
# Test the hash function with a simple file to verify consistency
echo "test content" > test_file.txt
node -e "
const fs = require('fs');
const crypto = require('crypto');

// Read the file
const buffer = fs.readFileSync('test_file.txt');

// Old method (using buffer directly)
const hash1 = crypto.createHash('sha256');
hash1.update(buffer);
console.log('Old method result:', hash1.digest('hex'));

// New method (using binary string)
const hash2 = crypto.createHash('sha256');
hash2.update(buffer.toString('binary'));
console.log('New method result:', hash2.digest('hex'));

// Should match this method
const hash3 = crypto.createHash('sha256');
hash3.update(buffer);
console.log('Node.js standard method:', hash3.digest('hex'));
"
rm test_file.txt

Length of output: 1010


Hash function consistency verified – approved change

The test confirms that switching to buffer.toString("binary") produces identical SHA-256 hash results compared to using the buffer directly. No issues found.

features/groups/screens/group-members-list.screen.tsx (1)

48-61: Good job fixing the loading states

Thanks for addressing the previous redundant loading condition by properly separating the loading check from the "group not found" check.

features/notifications/notifications-init.ts (4)

3-6: Import update for Expo notifications looks good.

Nice addition of the new assertion function for Expo notifications.


26-60: Try-catch implementation is solid.

Good job wrapping the notification handling in a try-catch block for better error management.


78-90: New Expo notification handling looks good.

The implementation for handling Expo notifications follows the same pattern as the XMTP notifications - nice and consistent.


114-114: Commented debug log is fine.

Removing debug logs helps reduce noise in the console.

features/xmtp/xmtp-client/xmtp-client.ts (4)

88-93: Nice environment config update!

You're now using config.xmtpEnv consistently and adding the custom local URL option when needed. This makes the configuration cleaner and more centralized.


151-156: Good job keeping the changes consistent

You've applied the same environment configuration pattern in both client creation methods, which maintains consistency throughout the codebase.


198-211: Better type safety with discriminated union 👍

The new signature makes it clear that ethAddress is required when deleteDatabase is true. This prevents potential runtime errors and makes the API more self-documenting.


237-239: Improved logout flow

Using the explicitly passed ethAddress parameter is cleaner than trying to find the sender elsewhere. This makes the function more self-contained.

features/current-user/create-user.api.ts (2)

13-31: Request schema properly includes description field 👍

The schema now correctly includes the description field in the profile pick, which resolves the previous schema mismatch issue that was flagged in earlier reviews.


66-105: Well-structured API function with proper error handling

Nice implementation with clear validation of both request and response data. The error handling is comprehensive and properly wraps errors with detailed context.

features/current-user/use-create-user-if-no-exist.ts (4)

38-123: Well-implemented device and identity management

This function nicely handles the complex flow of device registration and identity creation with good logging and error handling. The approach of checking existing devices first before creating new ones is robust.


125-170: Clean and logical flow implementation

The startFlow function provides a clear process for ensuring users, devices, and identities exist. Good use of error handling and status code checking.


263-264: Switched from undefined to null

Changed avatar and description from undefined to null, which is a better approach for JSON serialization and API consistency.


114-114:

Details

❓ Verification inconclusive

Address EOA connection edge case

There's a comment questioning what happens if it's not a privy address and connected via EOA. This needs to be addressed or documented.


🏁 Script executed:

#!/bin/bash
# Check if there are other places in the codebase that handle EOA connections differently
rg -A 5 "connected via EOA" --type ts
rg -A 5 "EOA connection" --type ts

Length of output: 639


Confirm and Document EOA Handling

It looks like the current code just assigns sender.ethereumAddress as the privyAddress without additional checks for cases where the connection is via EOA. Since our search didn’t reveal any alternative handling elsewhere, please confirm whether a non-Privy address (i.e., an EOA) is supported. If not, update the implementation or add clear documentation to explain the expected behavior for EOA connections.

  • File: features/current-user/use-create-user-if-no-exist.ts (line 114)
  • Action: Ensure the edge case for non-Privy addresses is either properly handled or documented.

"react/react-in-jsx-scope": "off",
"react/jsx-key": "error",
"react/jsx-no-bind": "off",
"react/jsx-no-target-blank": "off", // Was causing weird eslint issues
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Disabling target blank rule could introduce security risks.

Turning off the react/jsx-no-target-blank rule means links with target="_blank" won't require rel="noopener noreferrer" attributes. This could potentially expose your app to reverse tabnabbing attacks.

Consider keeping this rule enabled and fixing the specific issues rather than disabling it completely. If there are legitimate cases where you need this behavior, use a more targeted approach:

- "react/jsx-no-target-blank": "off", // Was causing weird eslint issues
+ "react/jsx-no-target-blank": ["warn", { "allowReferrer": true }],

This still alerts you to potential security issues while allowing more flexibility.

📝 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
"react/jsx-no-target-blank": "off", // Was causing weird eslint issues
"react/jsx-no-target-blank": ["warn", { "allowReferrer": true }],

Comment on lines +252 to 274
function getXmtpLocalUrl() {
if (config.xmtpEnv !== "local") {
throw new XMTPError({
error: new Error("XMTP environment is not local"),
})
}
const hostIp = Constants.expoConfig?.hostUri?.split(":")[0]

const hostIp = Constants.expoConfig?.hostUri?.split(":")[0]
if (!hostIp) {
throw new XMTPError({
error: new Error("No host IP found"),
additionalMessage: "Failed to get device IP for local XMTP environment",
})
}

if (!hostIp) {
throw new XMTPError({
error: new Error("No host IP found"),
})
}
return hostIp

xmtpEnv = `${hostIp}:caca` as IXmtpEnv
}
} catch (error) {
captureError(
new XMTPError({
error,
additionalMessage: "Failed to get XMTP environment",
}),
)
}
const localUrl = `http://${hostIp}:5555` as IXmtpEnv

xmtpLogger.debug(`Using XMTP environment: ${xmtpEnv}`)
xmtpLogger.debug(`Using XMTP custom local url: ${localUrl}`)

return xmtpEnv
return localUrl
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Fix unreachable code in getXmtpLocalUrl function

There's an early return at line 267 that makes the rest of the function unreachable. Looks like you're returning just the IP instead of the full URL.

-  return hostIp
-
   const localUrl = `http://${hostIp}:5555` as IXmtpEnv
 
   xmtpLogger.debug(`Using XMTP custom local url: ${localUrl}`)
 
   return localUrl
📝 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
function getXmtpLocalUrl() {
if (config.xmtpEnv !== "local") {
throw new XMTPError({
error: new Error("XMTP environment is not local"),
})
}
const hostIp = Constants.expoConfig?.hostUri?.split(":")[0]
const hostIp = Constants.expoConfig?.hostUri?.split(":")[0]
if (!hostIp) {
throw new XMTPError({
error: new Error("No host IP found"),
additionalMessage: "Failed to get device IP for local XMTP environment",
})
}
if (!hostIp) {
throw new XMTPError({
error: new Error("No host IP found"),
})
}
return hostIp
xmtpEnv = `${hostIp}:caca` as IXmtpEnv
}
} catch (error) {
captureError(
new XMTPError({
error,
additionalMessage: "Failed to get XMTP environment",
}),
)
}
const localUrl = `http://${hostIp}:5555` as IXmtpEnv
xmtpLogger.debug(`Using XMTP environment: ${xmtpEnv}`)
xmtpLogger.debug(`Using XMTP custom local url: ${localUrl}`)
return xmtpEnv
return localUrl
}
function getXmtpLocalUrl() {
if (config.xmtpEnv !== "local") {
throw new XMTPError({
error: new Error("XMTP environment is not local"),
})
}
const hostIp = Constants.expoConfig?.hostUri?.split(":")[0]
if (!hostIp) {
throw new XMTPError({
error: new Error("No host IP found"),
additionalMessage: "Failed to get device IP for local XMTP environment",
})
}
const localUrl = `http://${hostIp}:5555` as IXmtpEnv
xmtpLogger.debug(`Using XMTP custom local url: ${localUrl}`)
return localUrl
}
🧰 Tools
🪛 Biome (1.9.4)

[error] 269-273: This code is unreachable

... because this statement will return from the function beforehand

(lint/correctness/noUnreachable)

@thierryskoda thierryskoda merged commit 2c59bff into main Mar 28, 2025
8 checks passed
@thierryskoda thierryskoda deleted the ts/25-03-2025 branch March 28, 2025 12:14
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant