Skip to content

Comments

feat/PRO-3166/search-contract-address#275

Merged
RanaBug merged 1 commit intostagingfrom
feat/PRO-3166/search-contract-address
Mar 28, 2025
Merged

feat/PRO-3166/search-contract-address#275
RanaBug merged 1 commit intostagingfrom
feat/PRO-3166/search-contract-address

Conversation

@RanaBug
Copy link
Collaborator

@RanaBug RanaBug commented Mar 27, 2025

Description

  • Added feature to be able to search token with their token address and auto select that token

How Has This Been Tested?

  • Exiting Unit tests and Manual testing

Screenshots (if appropriate):

Types of changes

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)

Summary by CodeRabbit

  • New Features
    • Enhanced token search functionality with expanded criteria, improving overall search precision.
    • Introduced automatic token selection when a single matching token is available.
    • Streamlined token selection actions to provide a more intuitive experience when interacting with different interfaces.

@RanaBug RanaBug requested a review from IAmKio March 27, 2025 16:42
@RanaBug RanaBug self-assigned this Mar 27, 2025
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Mar 27, 2025

Walkthrough

The changes enhance token selection and search state management across components. A new centralized handleClick function is introduced in the exchange dropdown component to manage token selection, conditionally triggering swap or receive actions. A useEffect hook is added to automate token selection if only one option matches the searchToken. Similar updates are applied to the token atlas components, where dispatches now update a new searchToken state in Redux slices. Additionally, the search functionality in the token data service now considers the contract field.

Changes

File(s) Change Summary
src/apps/the-exchange/{components/DropdownTokensList/DropdownTokenList.tsx, components/TokenSearchInput/TokenSearchInput.tsx}
src/apps/the-exchange/reducer/theExchangeSlice.ts
Introduces a centralized handleClick in DropdownTokenList with conditional dispatching, and a useEffect for auto-selection. TokenSearchInput now dispatches setSearchToken, and theExchangeSlice adds a new searchToken property with its corresponding reducer.
src/apps/token-atlas/{components/TokensSearchInput/TokensSearchInput.tsx, components/TokensSearchResult/TokensSearchResult.tsx}
src/apps/token-atlas/reducer/tokenAtlasSlice.ts
Adds dispatch for setSearchToken in TokensSearchInput. TokensSearchResult now retrieves searchToken from Redux and uses a useEffect to auto-select a token when the token list has one matching entry. The tokenAtlasSlice is updated with a new searchToken property and reducer.
src/services/tokensData.ts Updates the searchTokens function to include the contract field in the search criteria.

Sequence Diagram(s)

sequenceDiagram
    participant UI as DropdownTokenList Component
    participant Redux as theExchangeSlice
    participant Effect as AutoSelect useEffect
    participant Action as handleClick Function

    UI->>Redux: User clicks token (or auto-selection triggered)
    Redux-->>Effect: Check token list and compare with searchToken
    Effect->>Action: Conditions met? → Call handleClick
    Action->>Redux: Dispatch swap/receive token and chain actions
    Redux-->>UI: Update state and close corresponding interface
Loading
sequenceDiagram
    participant Input as TokensSearchInput Component
    participant Redux as tokenAtlasSlice
    participant UI as TokensSearchResult Component
    participant Effect as AutoSelect useEffect

    Input->>Redux: Dispatch setSearchToken on search input
    Redux-->>UI: Update searchToken state
    UI->>Effect: useEffect monitors tokenList changes
    Effect->>UI: Auto-select token if only one token matches searchToken
Loading

Suggested reviewers

  • IAmKio

Poem

I'm a hopping little coder, a rabbit so keen,
Watching tokens line up like carrots in a scene.
Auto-select magic with each thoughtful click,
Redux updates and logic so slick.
Hop along with me—code's as sweet as a dream! 🥕🐰

✨ Finishing Touches
  • 📝 Generate Docstrings

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

❤️ Share
🪧 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.

@cloudflare-workers-and-pages
Copy link

Deploying x with  Cloudflare Pages  Cloudflare Pages

Latest commit: 3803242
Status: ✅  Deploy successful!
Preview URL: https://3f06fc33.x-e62.pages.dev
Branch Preview URL: https://feat-pro-3166-search-contrac.x-e62.pages.dev

View logs

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (1)
src/apps/token-atlas/components/TokensSearchResult/TokensSearchResult.tsx (1)

82-88: Implemented auto-selection for matched token addresses

This useEffect hook implements the core functionality of automatically selecting a token when there's exactly one match and the search term matches the token's contract address. This enhances the user experience by eliminating the need for manual selection when searching by token address.

However, the dependency array only includes tokenList and not searchToken. If the search token changes but the token list remains the same, this effect won't run.

- }, [tokenList]);
+ }, [tokenList, searchToken]);
📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 9438072 and 3803242.

⛔ Files ignored due to path filters (2)
  • src/apps/pillarx-app/components/MediaGridCollection/tests/__snapshots__/DisplayCollectionImage.test.tsx.snap is excluded by !**/*.snap
  • src/apps/pillarx-app/components/PointsTile/test/__snapshots__/PointsTile.test.tsx.snap is excluded by !**/*.snap
📒 Files selected for processing (7)
  • src/apps/the-exchange/components/DropdownTokensList/DropdownTokenList.tsx (4 hunks)
  • src/apps/the-exchange/components/TokenSearchInput/TokenSearchInput.tsx (2 hunks)
  • src/apps/the-exchange/reducer/theExchangeSlice.ts (4 hunks)
  • src/apps/token-atlas/components/TokensSearchInput/TokensSearchInput.tsx (2 hunks)
  • src/apps/token-atlas/components/TokensSearchResult/TokensSearchResult.tsx (3 hunks)
  • src/apps/token-atlas/reducer/tokenAtlasSlice.ts (4 hunks)
  • src/services/tokensData.ts (1 hunks)
🧰 Additional context used
🧬 Code Definitions (2)
src/apps/token-atlas/components/TokensSearchResult/TokensSearchResult.tsx (1)
src/apps/token-atlas/hooks/useReducerHooks.tsx (1)
  • useAppSelector (6-6)
src/apps/the-exchange/components/DropdownTokensList/DropdownTokenList.tsx (3)
src/apps/the-exchange/hooks/useReducerHooks.tsx (1)
  • useAppSelector (6-6)
src/services/tokensData.ts (1)
  • Token (9-17)
src/apps/the-exchange/reducer/theExchangeSlice.ts (7)
  • setSwapToken (74-76)
  • setSwapChain (68-70)
  • setSearchTokenResult (89-91)
  • setIsSwapOpen (62-64)
  • setReceiveToken (77-79)
  • setReceiveChain (71-73)
  • setIsReceiveOpen (65-67)
⏰ Context from checks skipped due to timeout of 90000ms (3)
  • GitHub Check: unit-tests
  • GitHub Check: build
  • GitHub Check: Cloudflare Pages
🔇 Additional comments (18)
src/apps/token-atlas/components/TokensSearchInput/TokensSearchInput.tsx (2)

12-15: Added support for tracking search token state

The import statement has been updated to include setSearchToken action alongside the existing setSearchTokenResult. This is a necessary change to support the new search-by-contract feature.


51-52: New dispatch enhances token search state management

This new dispatch call updates the searchToken state in the Redux store with the current search term, which is essential for the automatic token selection functionality when searching by contract address.

src/apps/token-atlas/components/TokensSearchResult/TokensSearchResult.tsx (2)

1-2: ESLint directive added for useEffect dependencies

The ESLint disable directive for react-hooks/exhaustive-deps prevents warnings while still ensuring that the code functions correctly. The useEffect import is needed for the new auto-selection functionality.


43-45: Added searchToken state from Redux

The component now accesses the search token input value from the Redux store. This is a necessary addition to support the auto-selection feature when searching by contract address.

src/apps/the-exchange/components/TokenSearchInput/TokenSearchInput.tsx (2)

9-12: Added support for tracking search token state

The import statement has been updated to include setSearchToken action alongside the existing setSearchTokenResult. This maintains consistency with the token-atlas implementation and supports the contract address search feature.


66-67: Enhanced token search state management

This new dispatch call updates the searchToken state in the Redux store, which is necessary for implementing the automatic token selection feature when searching by contract address. This implementation keeps the behavior consistent with the token-atlas component.

src/services/tokensData.ts (1)

213-213:

Details

❓ Verification inconclusive

Added contract field to search criteria

This change is the core enhancement that enables searching tokens by their contract address in addition to name, symbol, and blockchain. The addition of 'contract' to the Fuse.js search keys is essential for the contract address search feature.

You might want to consider testing this change with various contract address formats (checksummed, lowercase, etc.) to ensure consistent search behavior across different input formats.


🏁 Script executed:

#!/bin/bash
# Check if the contract address search works with different address formats

# Sample function to test searching with different address formats
echo "Testing contract address search with different formats"
echo "Please manually verify that the search works with:"
echo "1. Checksummed addresses (0xAbCdEf...)"
echo "2. Lowercase addresses (0xabcdef...)"
echo "3. Uppercase addresses (0xABCDEF...)"
echo "4. Partial addresses (first few characters)"

# Let's find a few example tokens with contract addresses to test with
echo "Example tokens with contract addresses to test search functionality:"
grep -r "contract:" src/data/tokens.json | head -5

Length of output: 777


Attention: Contract Field Search Enhancement Verified

The inclusion of the contract key in the Fuse.js search keys within src/services/tokensData.ts (line 213) correctly implements the intended enhancement for searching tokens by contract address. The verification script confirms that instructions for manually testing various contract address formats (checksummed, lowercase, uppercase, and partial matches) are in place. Please ensure that:

  • You manually verify searches with different contract address formats.
  • The sample tokens in src/data/tokens.json properly display contract addresses to support these tests.
src/apps/token-atlas/reducer/tokenAtlasSlice.ts (4)

32-32: Good addition of the searchToken state property

Adding the searchToken property to the TokenAltasState type is a clean way to implement the contract address search functionality. This follows the existing pattern of state management in the application.


52-52: Appropriate initialization of searchToken state

Initializing the searchToken property with an empty string is consistent with the state initialization pattern used throughout the file.


110-112: Well-implemented reducer function

The setSearchToken reducer follows the same pattern as other reducers in this slice, making it easy to understand and maintain.


130-130: Correctly exported action creator

The setSearchToken action is properly exported, making it available for components to dispatch.

src/apps/the-exchange/reducer/theExchangeSlice.ts (4)

24-24: Good addition of the searchToken state property

Adding the searchToken property to the SwapState type is consistent with the implementation in the token atlas slice, promoting a unified approach to state management across the application.


49-49: Appropriate initialization of searchToken state

Initializing the searchToken property with an empty string aligns with the pattern used for other string properties in the state.


101-103: Well-implemented reducer function

The setSearchToken reducer follows the consistent pattern of other reducers in this slice, which is good for maintainability.


123-123: Correctly exported action creator

The setSearchToken action is properly exported for use in components that need to update the search token state.

src/apps/the-exchange/components/DropdownTokensList/DropdownTokenList.tsx (3)

80-82: Good use of the selector hook

Accessing the searchToken state using the typed selector hook ensures type safety and follows the established pattern in the component.


135-177: Well-organized token selection logic

Centralizing the token selection logic in a single handleClick function improves code organization and reduces duplication. The function handles both swap and receive token selection flows with appropriate actions dispatched in each case.


263-263: Clean update to the List itemData prop

Using the centralized handleClick function in the itemData prop is a good refactoring that improves maintainability.

Comment on lines +180 to +195
useEffect(() => {
if (
isSwapOpen &&
swapTokenList.length === 1 &&
swapTokenList[0].contract === searchToken
) {
handleClick(swapTokenList[0]);
} else if (
!isSwapOpen &&
receiveTokenList.length === 1 &&
receiveTokenList[0].contract === searchToken
) {
handleClick(receiveTokenList[0]);
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [swapTokenList, receiveTokenList, isSwapOpen]);
Copy link
Contributor

@coderabbitai coderabbitai bot Mar 27, 2025

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Add searchToken to the dependency array

The useEffect hook should include searchToken in its dependency array since it's used in the conditions for auto-selecting a token. Without this, the auto-selection might not trigger when only the searchToken changes.

-  // eslint-disable-next-line react-hooks/exhaustive-deps
-  }, [swapTokenList, receiveTokenList, isSwapOpen]);
+  }, [swapTokenList, receiveTokenList, isSwapOpen, searchToken]);
📝 Committable suggestion

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

Suggested change
useEffect(() => {
if (
isSwapOpen &&
swapTokenList.length === 1 &&
swapTokenList[0].contract === searchToken
) {
handleClick(swapTokenList[0]);
} else if (
!isSwapOpen &&
receiveTokenList.length === 1 &&
receiveTokenList[0].contract === searchToken
) {
handleClick(receiveTokenList[0]);
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [swapTokenList, receiveTokenList, isSwapOpen]);
useEffect(() => {
if (
isSwapOpen &&
swapTokenList.length === 1 &&
swapTokenList[0].contract === searchToken
) {
handleClick(swapTokenList[0]);
} else if (
!isSwapOpen &&
receiveTokenList.length === 1 &&
receiveTokenList[0].contract === searchToken
) {
handleClick(receiveTokenList[0]);
}
}, [swapTokenList, receiveTokenList, isSwapOpen, searchToken]);

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Not needed here as the swapTokenList and receiveTokenList is the result of searchToken

Copy link
Contributor

Choose a reason for hiding this comment

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

@RanaBug You're absolutely right! I reviewed the code flow and can see that both swapTokenList and receiveTokenList are derived directly from searchTokenResult when there are search results. Since these lists will update when search results change (which happens after searchToken is updated), the effect will correctly trigger from the existing dependencies. Adding searchToken to the dependency array would be redundant in this case.


✏️ Learnings added
Learnt from: RanaBug
PR: pillarwallet/x#275
File: src/apps/the-exchange/components/DropdownTokensList/DropdownTokenList.tsx:180-195
Timestamp: 2025-03-28T09:22:22.581Z
Learning: In the Exchange app, `swapTokenList` and `receiveTokenList` are derived from `searchTokenResult` when search is active, so including `searchToken` in the useEffect dependency array that uses these lists would be redundant as the lists will update when search results change.

Note: Learnings are effective only in the context of similar code segments. To apply general coding guidelines, please configure review instructions. You can manage existing learnings in the app.

Copy link
Collaborator

@IAmKio IAmKio left a comment

Choose a reason for hiding this comment

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

LGTM

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.

2 participants