Skip to content

fix: prevent race conditions and add retry for fee estimator#166

Open
dinahmaccodes wants to merge 5 commits into
Sorokit:mainfrom
dinahmaccodes:issueb
Open

fix: prevent race conditions and add retry for fee estimator#166
dinahmaccodes wants to merge 5 commits into
Sorokit:mainfrom
dinahmaccodes:issueb

Conversation

@dinahmaccodes

Copy link
Copy Markdown

PR Description

This PR addresses four UI component issues related to race conditions, accessibility, and visual consistency.

Changes Made

Issue #89 - FeeEstimator: Race Conditions & Error Recovery

  • Added loadingRef to prevent concurrent load() calls from racing
  • Preserved last known fee value during refresh cycles with subtle spinner overlay
  • Added "Retry" button that re-triggers load() from error state
  • Implemented proper cleanup for async operations in effects

Issue #90 - AssetBadge: Color Variety & Export

  • Replaced static 5-color map with deterministic hash-based color picker (10 colors)
  • All unique asset codes now render with distinct, consistent colors
  • Ensured 1-character asset codes are properly centered in icon circle
  • Exported AssetPill from src/components/index.ts for library consumers

Issue #91 - SorobanInvokeButton: Double-Click Guard & Error Handling

  • Added isInvokingRef guard to prevent concurrent invocations on double-click
  • Implemented disabled={!isConnected || state === "loading"} to block rapid clicks
  • Created friendlyError() utility to map raw Horizon/Soroban errors to user-friendly messages
  • Added aria-label="Reset invocation result" to Reset button for accessibility

Issue #92 - Button: Accessibility Improvements

  • Added aria-busy={loading || undefined} during loading state
  • Added screen reader text "Loading" inside spinner for announcement
  • Implemented onClick interceptor for asChild mode to block clicks when disabled/loading
  • Ensured proper event handling with preventDefault() and stopPropagation()

Testing

  • npm run build passes
  • npm run lint passes (for modified components)
  • ✅ Added tests for double-click prevention and aria-label verification

Checklist

  • Concurrent load() calls are prevented with loadingRef flag
  • Last known fee value stays visible during refresh cycle
  • Error state renders a "Retry" button
  • Every unique asset code renders with distinct color
  • 1-char asset codes are centered properly
  • AssetPill is importable from "sorokit-ui"
  • Double-clicking invoke fires only one invokeContract call
  • Known Horizon errors mapped to user-friendly messages
  • Reset button has aria-label="Reset invocation result"
  • aria-busy="true" present when loading
  • Screen readers announce "Loading" when spinner appears
  • asChild buttons with disabled don't fire onClick
  • npm run build passes

Closes #89
Closes #90
Closes #91
Closes #92

@drips-wave

drips-wave Bot commented Jun 29, 2026

Copy link
Copy Markdown

@dinahmaccodes Great news! 🎉 Based on an automated assessment of this PR, the linked Wave issue(s) no longer count against your application limits.

You can now already apply to more issues while waiting for a review of this PR. Keep up the great work! 🚀

Learn more about application limits

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment