8000 feat(trade): display quote refetch indicator by shoom3301 · Pull Request #5859 · cowprotocol/cowswap · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

feat(trade): dis 8000 play quote refetch indicator #5859

New issue

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

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

Already on GitHub? Sign in to your account

Merged
merged 12 commits into from
Jun 24, 2025
Merged

Conversation

shoom3301
Copy link
Collaborator
@shoom3301 shoom3301 commented Jun 19, 2025

Summary

As we recently discovered, expiration in quote response might be too far in the future, so we have to cap it.
I've capped it with 1 minute, from my perspective this is a valid limit.

There are two commits:
1. Just a refactoring in order to simplify useTradeQuotePolling, no logic changes: 52c3e71
2. Actual fix. isQuoteExpired now caps the expirationTime with 1 minute: 743a548

After Elenas comment, I decided to simplify logic and make it clear.
Now quote refereshes every 30 seconds, that's all.
Along with that logic I added an indicator of the quote interval counter. If you think it's excessive - please let me know, I can delete it.

quote-counter-demo.mov

To Test

  1. Any quote should be updated every 30 seconds (Swap/Twap/Hooks)
  2. There should not be automatic quote update in Limit orders
  3. "Quote referesh" value in confirmation screen must be in sync with actual quote refreshing

Summary by CodeRabbit

Summary by CodeRabbit

  • New Features
    • Added visual quote polling progress indicator with countdown tooltip.
    • Introduced configurable static price mode to suppress quote countdown.
  • Refactor
    • Simplified and modularized trade quote polling logic using external callback and polling counter.
    • Centralized quote polling operations into a dedicated service module.
    • Removed manual countdown timers in favor of centralized polling state.
    • Updated trade widget header to group settings and polling progress.
  • Bug Fixes
    • Improved quote expiration logic with capped maximum expiration window and better missing data handling.
  • Tests
    • Enhanced test coverage for quote expiration logic and standardized timestamp handling.
  • Style
    • Updated function annotations for improved code consistency.
  • Chores
    • Added relaxed linting rules for test files to accommodate complexity and length.
    • Exported new UI components and hooks for broader use.

@shoom3301 shoom3301 requested review from a team June 19, 2025 06:38
@shoom3301 shoom3301 self-assigned this Jun 19, 2025
Copy link
vercel bot commented Jun 19, 2025

The latest updates on your projects. Learn more about Vercel for Git ↗︎

Name Status Preview Updated (UTC)
cowfi 🔄 Building (Inspect) Visit Preview Jun 24, 2025 5:56am
explorer-dev 🔄 Building (Inspect) Visit Preview Jun 24, 2025 5:56am
sdk-tools 🔄 Building (Inspect) Visit Preview Jun 24, 2025 5:56am
swap-dev 🔄 Building (Inspect) Visit Preview Jun 24, 2025 5:56am
2 Skipped Deployments
Name Status Preview Updated (UTC)
cosmos ⬜️ Ignored (Inspect) Visit Preview Jun 24, 2025 5:56am
widget-configurator ⬜️ Ignored (Inspect) Visit Preview Jun 24, 2025 5:56am

Copy link
Contributor
coderabbitai bot commented Jun 19, 2025

"""

Walkthrough

The trade quote polling logic in the CowSwap frontend was refactored to delegate polling and update responsibilities to a new doQuotePolling service, simplifying the original hook. The quote expiration logic was updated to use a capped 1-minute window, and related tests were adjusted for timestamp consistency and expanded coverage. Explicit return types were added where missing. ESLint rules were relaxed for test files. New UI components and hooks were introduced to display polling progress and manage polling counters. Several components removed the refreshInterval prop related to quote updates.

Changes

File(s) Change Summary
.../hooks/useTradeQuotePolling.ts Refactored to delegate polling logic to new doQuotePolling service; removed unused hooks; clarified return value.
.../services/doQuotePolling.ts New module implementing centralized quote polling logic via doQuotePolling and context interface.
.../services/fetchAndProcessQuote.ts Added explicit Promise<void> return type to fetchAndProcessQuote; removed related linter comments.
.../utils/quoteDeadline.ts Updated isQuoteExpired logic: capped expiration at 1 minute, adjusted checks, removed 5s grace period, improved null handling.
.../utils/quoteDeadline.test.ts Updated tests for timestamp unit consistency; added new cases for capped expiration logic.
eslint.config.js Added ESLint config for test files to relax complexity and max lines per function rules.
.../containers/LimitOrdersConfirmModal/index.tsx Removed ESLint max-lines-per-function disable; changed isPriceStatic prop to shorthand.
.../containers/LimitOrdersWidget/index.tsx Removed ESLint max-lines-per-function disable; added isPriceStatic prop with true to TradeWidget params.
.../containers/SwapConfirmModal/index.tsx Removed import and usage of PRICE_UPDATE_INTERVAL and related ESLint disable comment.
.../containers/QuotePolingProgress/index.tsx Added new component showing circular progress of quote polling interval with tooltip.
.../containers/TradeConfirmModal/index.cosmos.tsx Removed refreshInterval property from confirmation state.
.../containers/TradeWidget/TradeWidgetForm.tsx Added isPriceStatic param; conditionally render QuotePolingProgress alongside settings widget in header.
.../containers/TradeWidget/styled.tsx Added new styled component HeaderRight for layout of header elements.
.../containers/TradeWidget/types.ts Added optional isPriceStatic boolean property to TradeWidgetParams interface.
.../pure/TradeConfirmation/CountDown.t 8000 sx Refactored QuoteCountdown to use external quote counter hook; removed internal timer and refreshInterval prop.
.../pure/TradeConfirmation/index.cosmos.tsx Removed refreshInterval prop from test fixtures.
.../pure/TradeConfirmation/index.tsx Removed refreshInterval prop from TradeConfirmationProps and component; conditionally render QuoteCountdown based on isPriceStatic.
.../tradeQuote/consts.ts Added constant QUOTE_POLLING_INTERVAL set to 30 seconds.
.../hooks/usePollQuoteCallback.ts Added new hook to provide polling callback for fetching trade quotes with parameter and state checks.
.../hooks/useTradeQuoteCounter.ts Added hooks to read and reset trade quote polling counter atom.
.../index.ts Exported useTradeQuoteCounter hook and all exports from consts.
.../state/tradeQuoteCounterAtom.ts Added new Jotai atom tradeQuoteCounterAtom initialized to QUOTE_POLLING_INTERVAL.
.../containers/TwapConfirmModal/index.tsx Removed refreshInterval prop and import from TradeConfirmation.
libs/ui/src/index.ts Exported new CircleProgress component.
libs/ui/src/pure/CircleProgress/index.tsx Added new CircleProgress React component rendering circular SVG progress indicator.

Sequence Diagram(s)

sequenceDiagram
    participant Hook as useTradeQuotePolling
    participant PollHook as usePollQuoteCallback
    participant Service as doQuotePolling
    participant Fetch as fetchAndProcessQuote

    Hook->>PollHook: get pollQuote callback
    PollHook->>Service: doQuotePolling(context)
    alt Needs to fetch quote
        Service->>Fetch: fetchAndProcessQuote(params)
        Fetch-->>Service: (updates state)
    end
    Service-->>PollHook: (no return value)
    PollHook-->>Hook: pollQuote result (boolean)
Loading
sequenceDiagram
    participant TradeWidget as TradeWidgetForm
    participant QuoteProgress as QuotePolingProgress
    participant Settings as SettingsWidget

    TradeWidget->>QuoteProgress: render if !isPriceStatic
    TradeWidget->>Settings: render if !lockScreen
Loading

Possibly related PRs

Suggested labels

RELEASE

Suggested reviewers

  • elena-zh
  • alfetopito

Poem

🐇 Hopping through code with a twitch of my nose,
New polling rhythms and fresh quotes arose.
A circle spins round, progress in sight,
Countdown ticks down with elegant light.
One minute to wait, then the quotes leap anew,
Refactored and tidy, all thanks to the crew!
🌿✨
"""

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 ESLint

If the error stems from missing dependencies, add them to the package.json file. For unrecoverable errors (e.g., due to private dependencies), disable the tool in the CodeRabbit configuration.

yarn install v1.22.22
[1/4] Resolving packages...
(node:5616) [DEP0169] DeprecationWarning: url.parse() behavior is not standardized and prone to errors that have security implications. Use the WHATWG URL API instead. CVEs are not issued for url.parse() vulnerabilities.
(Use node --trace-deprecation ... to show where the warning was created)
[2/4] Fetching packages...
error nx@21.0.3: The engine "node" is incompatible with this module. Expected version "^20.19.0 || ^22.12.0". Got "24.2.0"
error Found incompatible module.
info Visit https://yarnpkg.com/en/docs/cli/install for documentation about this command.


📜 Recent review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between ad99f90 and 19f693c.

📒 Files selected for processing (2)
  • apps/cowswap-frontend/src/modules/trade/containers/QuotePolingProgress/index.tsx (1 hunks)
  • apps/cowswap-frontend/src/modules/trade/pure/TradeConfirmation/CountDown.tsx (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • apps/cowswap-frontend/src/modules/trade/containers/QuotePolingProgress/index.tsx
  • apps/cowswap-frontend/src/modules/trade/pure/TradeConfirmation/CountDown.tsx
⏰ Context from checks skipped due to timeout of 90000ms (2)
  • GitHub Check: Setup
  • GitHub Check: Cypress
✨ 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.
    • Explain this complex logic.
    • 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 explain this code block.
    • @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 explain its main purpose.
    • @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.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

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 generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

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

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.

@shoom3301 shoom3301 force-pushed the fix/quote-caching branch from 743a548 to 614ba7a Compare June 19, 2025 06:42
Copy link
Contributor
@elena-zh elena-zh left a comment

Choose a reason for hiding this comment

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

Hey @shoom3301 , works as described.
However, I have some concerns:

  1. on the 'Confirm' modal we show that a quote is updated once per 30 seconds. IIMO, it is a reasonable time for a quote update instead of 1 minute
  2. Quote for regular (not eth-flow) orders started to be updated in 1 minute. However, now the time is 30 seconds, so I'd leave this time as it is.
    WDYT?

@shoom3301 shoom3301 changed the title fix(trade): cap quote expiration time by 1 minute feat(trade): display quote refetch indicator Jun 20, 2025
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: 0

🧹 Nitpick comments (3)
apps/cowswap-frontend/src/modules/trade/containers/QuotePolingProgress/index.tsx (2)

10-10: Fix component name typo.

The component name has a typo: "QuotePolingProgress" should be "QuotePollingProgress" (missing 'l' in "Polling").

-export function QuotePolingProgress(): ReactNode {
+export function QuotePollingProgress(): ReactNode {

12-12: Consider UX implications of progress direction.

The current calculation makes the progress bar start full and empty as time passes, which might be counterintuitive to users who typically expect progress bars to fill up over time.

Consider if this countdown-style progress bar aligns with user expectations, or if it should be inverted to show elapsed time instead:

-  const percent = Math.ceil((counter * 100) / QUOTE_POLLING_INTERVAL)
+  const percent = Math.ceil(((QUOTE_POLLING_INTERVAL - counter) * 100) / QUOTE_POLLING_INTERVAL)

This would make the progress bar start empty and fill up as time elapses, which might be more intuitive.

apps/cowswap-frontend/src/modules/tradeQuote/hooks/useTradeQuotePolling.ts (1)

17-17: Consider using the existing ms macro for consistency.

The hardcoded ONE_SEC = 1000 constant works, but consider using ms\1s`` for consistency with other timing constants in the codebase.

-const ONE_SEC = 1000
+const ONE_SEC = ms`1s`
📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 3d91927 and 4e80d28.

📒 Files selected for processing (20)
  • apps/cowswap-frontend/src/modules/limitOrders/containers/LimitOrdersConfirmModal/index.tsx (2 hunks)
  • apps/cowswap-frontend/src/modules/limitOrders/containers/LimitOrdersWidget/index.tsx (2 hunks)
  • apps/cowswap-frontend/src/modules/swap/containers/SwapConfirmModal/index.tsx (1 hunks)
  • apps/cowswap-frontend/src/modules/trade/containers/QuotePolingProgress/index.tsx (1 hunks)
  • apps/cowswap-frontend/src/modules/trade/containers/TradeConfirmModal/index.cosmos.tsx (0 hunks)
  • apps/cowswap-frontend/src/modules/trade/containers/TradeWidget/TradeWidgetForm.tsx (3 hunks)
  • apps/cowswap-frontend/src/modules/trade/containers/TradeWidget/styled.tsx (1 hunks)
  • apps/cowswap-frontend/src/modules/trade/containers/TradeWidget/types.ts (1 hunks)
  • apps/cowswap-frontend/src/modules/trade/pure/TradeConfirmation/CountDown.tsx (1 hunks)
  • apps/cowswap-frontend/src/modules/trade/pure/TradeConfirmation/index.cosmos.tsx (0 hunks)
  • apps/cowswap-frontend/src/modules/trade/pure/TradeConfirmation/index.tsx (1 hunks)
  • apps/cowswap-frontend/src/modules/tradeQuote/consts.ts (1 hunks)
  • apps/cowswap-frontend/src/modules/tradeQuote/hooks/usePollQuoteCallback.ts (1 hunks)
  • apps/cowswap-frontend/src/modules/tradeQuote/hooks/useTradeQuoteCounter.ts (1 hunks)
  • apps/cowswap-frontend/src/modules/tradeQuote/hooks/useTradeQuotePolling.ts (1 hunks)
  • apps/cowswap-frontend/src/modules/tradeQuote/index.ts (1 hunks)
  • apps/cowswap-frontend/src/modules/tradeQuote/state/tradeQuoteCounterAtom.ts (1 hunks)
  • apps/cowswap-frontend/src/modules/twap/containers/TwapConfirmModal/index.tsx (0 hunks)
  • libs/ui/src/index.ts (1 hunks)
  • libs/ui/src/pure/CircleProgress/index.tsx (1 hunks)
💤 Files with no reviewable changes (3)
  • apps/cowswap-frontend/src/modules/trade/containers/TradeConfirmModal/index.cosmos.tsx
  • apps/cowswap-frontend/src/modules/twap/containers/TwapConfirmModal/index.tsx
  • apps/cowswap-frontend/src/modules/trade/pure/TradeConfirmation/index.cosmos.tsx
✅ Files skipped from review due to trivial changes (8)
  • apps/cowswap-frontend/src/modules/trade/containers/TradeWidget/types.ts
  • libs/ui/src/index.ts
  • apps/cowswap-frontend/src/modules/limitOrders/containers/LimitOrdersConfirmModal/index.tsx
  • apps/cowswap-frontend/src/modules/swap/containers/SwapConfirmModal/index.tsx
  • apps/cowswap-frontend/src/modules/tradeQuote/index.ts
  • apps/cowswap-frontend/src/modules/tradeQuote/consts.ts
  • apps/cowswap-frontend/src/modules/trade/containers/TradeWidget/styled.tsx
  • apps/cowswap-frontend/src/modules/tradeQuote/state/tradeQuoteCounterAtom.ts
🧰 Additional context used
🧬 Code Graph Analysis (7)
apps/cowswap-frontend/src/modules/tradeQuote/hooks/useTradeQuoteCounter.ts (2)
apps/cowswap-frontend/src/modules/tradeQuote/index.ts (1)
  • useTradeQuoteCounter (9-9)
apps/cowswap-frontend/src/modules/tradeQuote/state/tradeQuoteCounterAtom.ts (1)
  • tradeQuoteCounterAtom (5-5)
libs/ui/src/pure/CircleProgress/index.tsx (2)
libs/ui/src/pure/Loader/index.tsx (1)
  • Loader (32-43)
libs/common-hooks/src/useTheme.ts (1)
  • styled (26-26)
apps/cowswap-frontend/src/modules/trade/pure/TradeConfirmation/index.tsx (1)
apps/cowswap-frontend/src/modules/trade/pure/TradeConfirmation/CountDown.tsx (1)
  • QuoteCountdown (11-31)
apps/cowswap-frontend/src/modules/tradeQuote/hooks/usePollQuoteCallback.ts (9)
apps/cowswap-frontend/src/modules/tradeQuote/hooks/useQuoteParams.ts (1)
  • QuoteParams (24-28)
apps/cowswap-frontend/src/modules/tradeQuote/state/tradeQuoteInputAtom.ts (1)
  • tradeQuoteInputAtom (13-13)
apps/cowswap-frontend/src/modules/tradeQuote/hooks/useTradeQuote.ts (1)
  • useTradeQuote (14-29)
libs/wallet/src/api/hooks.ts (1)
  • useWalletInfo (16-18)
apps/cowswap-frontend/src/modules/tradeQuote/hooks/useTradeQuoteManager.ts (1)
  • useTradeQuoteManager (28-80)
libs/common-utils/src/getCurrencyAddress.ts (1)
  • getCurrencyAddress (6-8)
apps/cowswap-frontend/src/modules/tradeQuote/types.ts (1)
  • TradeQuoteFetchParams (3-7)
apps/cowswap-frontend/src/modules/tradeQuote/services/fetchAndProcessQuote.ts (1)
  • fetchAndProcessQuote (27-80)
apps/cowswap-frontend/src/modules/tradeQuote/services/doQuotePolling.ts (2)
  • QuoteUpdateContext (15-25)
  • doQuotePolling (27-63)
apps/cowswap-frontend/src/modules/trade/pure/TradeConfirmation/CountDown.tsx (2)
apps/cowswap-frontend/src/modules/tradeQuote/hooks/useTradeQuoteCounter.ts (1)
  • useTradeQuoteCounter (6-8)
apps/cowswap-frontend/src/modules/trade/pure/TradeConfirmation/styled.tsx (1)
  • QuoteCountdownWrapper (87-106)
apps/cowswap-frontend/src/modules/tradeQuote/hooks/useTradeQuotePolling.ts (9)
apps/cowswap-frontend/src/modules/tradeQuote/state/tradeQuoteInputAtom.ts (1)
  • tradeQuoteInputAtom (13-13)
apps/cowswap-frontend/src/modules/tradeQuote/state/tradeQuoteCounterAtom.ts (1)
  • tradeQuoteCounterAtom (5-5)
apps/cowswap-frontend/src/modules/tradeQuote/hooks/useTradeQuoteCounter.ts (1)
  • useResetQuoteCounter (10-12)
apps/cowswap-frontend/src/modules/tradeQuote/hooks/useTradeQuote.ts (1)
  • useTradeQuote (14-29)
apps/cowswap-frontend/src/modules/tradeQuote/hooks/useQuoteParams.ts (1)
  • useQuoteParams (30-110)
apps/cowswap-frontend/src/modules/tradeQuote/hooks/useTradeQuoteManager.ts (1)
  • useTradeQuoteManager (28-80)
libs/common-utils/src/getCurrencyAddress.ts (1)
  • getCurrencyAddress (6-8)
apps/cowswap-frontend/src/modules/tradeQuote/hooks/usePollQuoteCallback.ts (1)
  • usePollQuoteCallback (18-82)
apps/cowswap-frontend/src/modules/tradeQuote/consts.ts (1)
  • QUOTE_POLLING_INTERVAL (3-3)
apps/cowswap-frontend/src/modules/trade/containers/TradeWidget/TradeWidgetForm.tsx (1)
apps/cowswap-frontend/src/modules/trade/containers/QuotePolingProgress/index.tsx (1)
  • QuotePolingProgress (10-27)
⏰ Context from checks skipped due to timeout of 90000ms (2)
  • GitHub Check: Setup
  • GitHub Check: Cypress
🔇 Additional comments (22)
apps/cowswap-frontend/src/modules/limitOrders/containers/LimitOrdersWidget/index.tsx (2)

64-64: LGTM: ESLint rule adjustment is appropriate.

Removing the max-lines-per-function ESLint rule is reasonable given the existing TODO comment about breaking down the large function.


241-241: LGTM: Static price configuration is correct for limit orders.

Setting isPriceStatic: true is appropriate for limit orders since they should have static prices and don't require dynamic quote polling UI elements.

apps/cowswap-frontend/src/modules/tradeQuote/hooks/useTradeQuoteCounter.ts (1)

1-12: LGTM: Clean and well-structured hook implementation.

The hooks properly utilize Jotai atoms with good separation of concerns - one for reading the counter value and one for resetting it.

apps/cowswap-frontend/src/modules/trade/containers/TradeWidget/TradeWidgetForm.tsx (3)

42-42: LGTM: Import added correctly.

The import for the new QuotePolingProgress component is properly added.


88-88: LGTM: Parameter addition is well-implemented.

The isPriceStatic parameter is properly added with an appropriate default value of false.


200-203: LGTM: Conditional rendering logic is correct.

The HeaderRight wrapper appropriately groups the quote polling progress and settings widget, with correct conditional rendering based on isPriceStatic and lockScreen states.

libs/ui/src/pure/CircleProgress/index.tsx (1)

1-49: LGTM: Solid circular progress component implementation.

The SVG-based progress component is well-implemented with:

  • Proper circle positioning and sizing calculations
  • Correct stroke-dasharray/stroke-dashoffset usage for progress visualization
  • Appropriate rotation to start progress from the top
  • Clean TypeScript interface with all necessary styling props
apps/cowswap-frontend/src/modules/trade/pure/TradeConfirmation/index.tsx (2)

37-37: Good addition of isPriceStatic prop for conditional UI control.

The new isPriceStatic prop provides appropriate control over when quote-related UI elements should be displayed, aligning with the centralized polling state management approach.


138-138: Excellent simplification of QuoteCountdown rendering logic.

The removal of the refreshInterval prop and addition of the isPriceStatic condition simplifies the component while maintaining proper conditional rendering. The QuoteCountdown component now uses the centralized useTradeQuoteCounter hook for timing.

apps/cowswap-frontend/src/modules/trade/pure/TradeConfirmation/CountDown.tsx (3)

1-1: Good import cleanup and addition of centralized counter hook.

The updated imports reflect the refactoring from internal state management to using the centralized useTradeQuoteCounter hook.

Also applies to: 5-5


11-11: Proper return type annotation added.

Adding explicit ReactNode return type improves type safety.


14-14: Excellent refactoring to use centralized counter state.

The component is significantly simplified by:

  • Using useTradeQuoteCounter() instead of internal interval management
  • Simplifying the blink trigger logic to check counter === 0
  • Using setTimeout for the blink effect instead of complex state management
  • Directly displaying counter / ONE_SEC for the countdown

This makes the component more predictable and reduces complexity while maintaining the same user experience.

Also applies to: 17-17, 20-20, 24-24, 28-28

apps/cowswap-frontend/src/modules/tradeQuote/hooks/usePollQuoteCallback.ts (5)

18-21: Well-designed hook interface.

The function signature clearly indicates the two key parameters needed for polling: confirmation modal state and quote parameters. The return type as a callback function provides a clean interface for triggering polling.


22-36: Proper dependency setup and ref usage.

Good use of refs to avoid stale closures, especially for tradeQuoteRef and isOnlineRef. The dependency gathering is comprehensive and well-organized.


38-47: Robust validation logic with appropriate early returns.

The validation checks handle all the necessary edge cases:

  • Missing trade quote manager or parameters
  • Unsupported tokens
  • Zero amount case with proper cleanup

The early returns prevent unnecessary processing and the tradeQuoteManager.reset() call for zero amounts is appropriate.


49-70: Clean delegation to the doQuotePolling service.

The context object creation is comprehensive and the delegation to doQuotePolling provides good separation of concerns. The inline fetchQuote function properly captures the closure variables.


71-81: Comprehensive dependency array ensures proper memoization.

The dependency array includes all the relevant values that could affect the callback behavior, ensuring proper re-memoization when needed.

apps/cowswap-frontend/src/modules/tradeQuote/hooks/useTradeQuotePolling.ts (5)

1-1: Good import updates for the refactored architecture.

The updated imports reflect the new centralized state management approach using atoms and the extracted polling callback hook.

Also applies to: 7-7, 10-10, 13-16


20-22: Excellent refactoring to use centralized state and extracted callback.

The hook is significantly simplified by:

  • Using tradeQuoteCounterAtom for centralized counter state
  • Delegating complex polling logic to usePollQuoteCallback
  • Removing internal complexity while maintaining the same interface

This improves maintainability and testability.

Also applies to: 31-31, 38-38


58-61: Clean parameter change handling.

The logic properly triggers immediate polling when parameters change and resets the counter, which ensures users get fresh quotes quickly when they modify trade parameters.


66-70: Simplified polling trigger when counter reaches zero.

The refactored logic cleanly triggers polling with forceUpdate: true when the counter reaches zero, maintaining the periodic refresh behavior.


75-93: Verify counter timing precision and confirm modal behavior.

The counter tick logic looks correct, but consider these aspects:

  • The setInterval with 1-second precision should align with the expected polling behavior
  • Resetting the counter when isConfirmOpen changes ensures proper state management
  • The counter reset to QUOTE_POLLING_INTERVAL when it goes below 0 maintains the cycle

The logic appears sound for the 30-second polling interval mentioned in the PR objectives.

Let me verify that the polling interval aligns with the 1-minute quote expiration cap mentioned in the PR objectives:

#!/bin/bash
# Description: Verify the QUOTE_POLLING_INTERVAL constant value
# Expected: Should be 30 seconds or less to support 1-minute expiration cap

# Search for QUOTE_POLLING_INTERVAL definition
rg -A 2 "QUOTE_POLLING_INTERVAL.*=" --type ts

@shoom3301
Copy link
Collaborator Author
shoom3301 commented Jun 20, 2025

@elena-zh thanks!
I decided to make it as simple as stupid.
Now it refreshes quote every 30 seconds, no less, no more.
I also updated the PR description.

@elena-zh
Copy link
Contributor

Hey @shoom3301 , great!
However, I have some doubts in terms of this new countdown displaying on the form.

  1. See the case:
  • I'm on the Swap form
    Screenshot_6
  • after 10-15 seconds I switch to the confirm modal --> the countdown restarts
    30
  • I close the modal --> the countdown restarts again.
    back to 30

Confusing, because it should be synced, IMO.

  1. Then, the countdown is displayed on the TWAP form with unlock screen on it
    twap lock screen

  2. In the widget, it expands the min width more in a mobile view (however, it also does not look good atm)
    image

So, there are 2 options:

  1. address all these issues above :)
  2. hide the countdown from the swap form :)

Also, there is a quote update on limit orders page. No need to fix it, as it is OK, but just letting you know :)

@shoom3301
Copy link
Collaborator Author

@elena-zh thank you!

  1. Fixed as we discussed: a) when you go to confirm screen, then the countdown should NOT reset. b) when you go back from confirm screen, then the countdown should reset.
  2. Fixed
  3. When "My orders" is displayed, or is widget mode, or is mobile view, then the countdown should NOT be displayed.

Copy link
Contributor
@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🧹 Nitpick comments (2)
apps/cowswap-frontend/src/modules/tradeQuote/hooks/useTradeQuotePolling.ts (2)

67-71: Clarify the purpose of the resetPolling parameter.

The second parameter true passed to pollQuote(false, true) suggests it's a polling reset flag, but this isn't immediately clear from the context. Consider adding a comment or using named parameters for better readability.

-    pollQuote(false, true)
+    pollQuote(false, true) // Reset polling state after interval

17-17: Consider using a more descriptive constant name.

While ONE_SEC = 1000 is correct, consider a more descriptive name that indicates its purpose in the polling context.

-const ONE_SEC = 1000
+const POLLING_TICK_INTERVAL = 1000

Then update the usage:

-    }, ONE_SEC)
+    }, POLLING_TICK_INTERVAL)
📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between abd213b and ad99f90.

📒 Files selected for processing (4)
  • apps/cowswap-frontend/src/modules/trade/containers/TradeWidget/TradeWidgetForm.tsx (3 hunks)
  • apps/cowswap-frontend/src/modules/tradeQuote/hooks/usePollQuoteCallback.ts (1 hunks)
  • apps/cowswap-frontend/src/modules/tradeQuote/hooks/useTradeQuotePolling.ts (1 hunks)
  • apps/cowswap-frontend/src/modules/tradeQuote/services/doQuotePolling.ts (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (3)
  • apps/cowswap-frontend/src/modules/trade/containers/TradeWidget/TradeWidgetForm.tsx
  • apps/cowswap-frontend/src/modules/tradeQuote/hooks/usePollQuoteCallback.ts
  • apps/cowswap-frontend/src/modules/tradeQuote/services/doQuotePolling.ts
⏰ Context from checks skipped due to timeout of 90000ms (2)
  • GitHub Check: Cypress
  • GitHub Check: Setup
🔇 Additional comments (2)
apps/cowswap-frontend/src/modules/tradeQuote/hooks/useTradeQuotePolling.ts (2)

19-22: LGTM: Clean state management with Jotai atoms.

The refactor to use Jotai atoms for state management improves the architecture by centralizing the polling counter state.


58-62: ```shell
#!/bin/bash

Locate and inspect the implementation of usePollQuoteCallback

FILE=$(fd usePollQuoteCallback.ts)
echo "Inspecting $FILE"
sed -n '1,200p' "$FILE"


</details>

</blockquote></details>

</details>

<!-- This is an auto-generated comment by CodeRabbit for review status -->

Copy link
Contributor
@elena-zh elena-zh left a comment

Choose a reason for hiding this comment

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

Thnaks!

@shoom3301 shoom3301 merged commit c4f163f into develop Jun 24, 2025
6 of 12 checks passed
@shoom3301 shoom3301 deleted the fix/quote-caching branch June 24, 2025 05:56
@github-actions github-actions bot locked and limited conversation to collaborators Jun 24, 2025
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.

3 participants
0