Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Conversation

@ignaciosantise
Copy link
Collaborator

@ignaciosantise ignaciosantise commented Nov 4, 2025

This pull request primarily improves the flexibility and rendering of the QR code component, especially regarding logo customization and QR code generation. The changes introduce asynchronous QR code generation, allow for custom logo size and border radius, and enhance the rendering logic for better visual quality and performance.

QR Code Component Improvements

  • Added support for custom logoSize and logoBorderRadius props in the QrCode component, allowing more control over the QR code's embedded logo appearance. [1] [2]
  • Changed QR code generation to be asynchronous using a new QRCodeUtil.generateAsync method, improving responsiveness and reliability.
  • Updated the rendering logic to use rect, circle, and line SVG primitives based on structured QR data, replacing the previous approach and enabling more precise and customizable QR visuals.

Component and Style Adjustments

  • Updated the logic for displaying the logo and fallback icon to use the new sizing and border radius props and removed redundant styles. [1] [2] [3]
  • Enhanced the component's memoization to account for the new logoBorderRadius prop, preventing unnecessary re-renders.

Consumer Updates

  • Updated the ConnectingQrCode component to pass the new logoBorderRadius and logoSize props to the QrCode component, ensuring consistent appearance.

Other Minor Changes

  • Updated the WalletConnect SVG asset to use a new, simplified path and viewBox, likely for visual consistency or optimization.
  • Minor style tweak to the modal card to ensure no border is rendered.

Note

Make QR code logo size/border radius configurable and switch to structured SVG rendering, update consumer and WalletConnect icon, and set modal card borderWidth to 0.

  • QR Code UI:
    • Add logoSize and logoBorderRadius props to QrCode and render centered logo/image accordingly in packages/ui/src/composites/wui-qr-code/index.tsx.
    • Replace dot generation with structured SVG rendering (render rects, circles, lines).
    • Improve memoization to include logoBorderRadius.
  • QR Data Generation (packages/ui/src/utils/QRCodeUtil.tsx):
    • Refactor to return structured QR data via QRCodeUtil.generate(uri, size, logoSize, logoBorderRadius).
    • Support circular or rounded-rectangle logo cutout and optimized matrix processing.
  • Consumer:
    • Pass logoSize and logoBorderRadius from ConnectingQrCode to QrCode in packages/appkit/src/partials/w3m-connecting-qrcode/index.tsx.
  • Assets:
    • Update WalletConnect SVG paths and viewBox in packages/ui/src/assets/svg/WalletConnect.tsx.
  • Styles:
    • Set borderWidth: 0 on modal card in packages/appkit/src/modal/w3m-modal/styles.ts.
  • Changeset:
    • Add patch releases for affected React Native packages.

Written by Cursor Bugbot for commit b92831d. This will update automatically on new commits. Configure here.

Copilot AI review requested due to automatic review settings November 4, 2025 18:01
@changeset-bot
Copy link

changeset-bot bot commented Nov 4, 2025

🦋 Changeset detected

Latest commit: b92831d

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 9 packages
Name Type
@reown/appkit-react-native Patch
@reown/appkit-ui-react-native Patch
@reown/appkit-bitcoin-react-native Patch
@reown/appkit-coinbase-react-native Patch
@reown/appkit-common-react-native Patch
@reown/appkit-core-react-native Patch
@reown/appkit-ethers-react-native Patch
@reown/appkit-solana-react-native Patch
@reown/appkit-wagmi-react-native Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@claude
Copy link

claude bot commented Nov 4, 2025

Claude finished @ignaciosantise's task —— View job


Code Review Complete

Critical Issues

1. Missing error handling in QR component - packages/ui/src/composites/wui-qr-code/index.tsx:61-65

The error catch block silently swallows errors without logging or user feedback:

.catch(() => {
  if (!cancelled) {
    setQrData(null);
  }
});

Recommendation: Log errors for debugging and consider showing an error state to users:

.catch((error) => {
  if (!cancelled) {
    console.error('QR code generation failed:', error);
    setQrData(null);
  }
});

2. Incomplete memoization dependencies - packages/ui/src/composites/wui-qr-code/index.tsx:162-169

The memo comparison is missing critical props:

  • imageSrc - can change and affect logo rendering
  • icon - can change the fallback icon
  • arenaClear - changes logo visibility
  • logoSize - affects QR generation

Recommendation:

export const QrCode = memo(QrCode_, (prevProps, nextProps) => {
  return (
    prevProps.size === nextProps.size &&
    prevProps.uri === nextProps.uri &&
    prevProps.style === nextProps.style &&
    prevProps.logoBorderRadius === nextProps.logoBorderRadius &&
    prevProps.imageSrc === nextProps.imageSrc &&
    prevProps.icon === nextProps.icon &&
    prevProps.arenaClear === nextProps.arenaClear &&
    prevProps.logoSize === nextProps.logoSize
  );
});

3. Questionable async implementation - packages/ui/src/utils/QRCodeUtil.tsx:316-337

The setTimeout(..., 0) wrapper provides minimal benefit:

export async function generateQRDataAsync(...): Promise<QRData> {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      try {
        // synchronous operations
      } catch (error) {
        reject(error);
      }
    }, 0);
  });
}

This doesn't make the QR generation truly async—getMatrix and processQRMatrix still run synchronously on the main thread. The setTimeout only defers execution by one event loop tick.

Recommendation: Either:

  1. Remove the async wrapper if not needed for true concurrency
  2. Or use Web Workers / native threads for actual background processing
  3. Or keep it only if the intent is to prevent blocking the initial render

4. Missing TypeScript type safety - packages/ui/src/utils/QRCodeUtil.tsx:92,189,204

Multiple uses of optional chaining with continue statements where type guards would be clearer:

const qr = qrList[qrIdx];
if (!qr) continue;  // Array access could be undefined

Recommendation: Use proper type assertions or restructure to avoid relying on optional array access.

Performance Concerns

5. Array pre-allocation with arbitrary sizing - packages/ui/src/utils/QRCodeUtil.tsx:68-80

const rects: QRData['rects'] = [];
rects.length = 27; // Fixed size assumption

Pre-allocating arrays to specific sizes then trimming later is an optimization that may not be necessary and could introduce bugs if assumptions change.

Recommendation: Use standard push() and let the JS engine handle array growth, or document why these specific sizes were chosen.

6. Missing key extraction optimization - packages/ui/src/composites/wui-qr-code/index.tsx:119-155

SVG elements use index-based keys (rect_${idx}, circle_${idx}, line_${idx}), which is acceptable but could be improved if elements have stable identities across renders.

Type Safety Issues

7. Loose error typing - packages/ui/src/utils/QRCodeUtil.tsx:332

} catch (error) {
  reject(error);
}

Consider using proper error types or wrapping in a known error class for better type safety.

Minor Issues

8. Unused import cleanup needed - packages/appkit/src/partials/w3m-connecting-qrcode/index.tsx:57

The onConnect function is called inside useEffect but ESLint may flag the missing dependency. Consider using useCallback if this needs to be stable.

9. Magic numbers - packages/appkit/src/partials/w3m-connecting-qrcode/index.tsx:68

Hard-coded values logoBorderRadius={20} and logoSize={60} should be constants or theme values:

const LOGO_BORDER_RADIUS = 20;
const LOGO_SIZE = 60;

10. Missing changeset

The changeset-bot correctly flagged that this PR needs a changeset file. This appears to be a patch change for @reown/appkit-react-native and @reown/appkit-ui-react-native.


Summary

Must Fix:

Should Fix:

Consider:


Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull Request Overview

This PR refactors the QR code generation logic to improve performance and add configurability. The main objective is to optimize QR code rendering by moving from synchronous to asynchronous generation and implementing data-driven rendering.

Key changes:

  • Converted QR code generation from synchronous to asynchronous using generateQRDataAsync
  • Introduced data structure (QRData) to separate QR code calculation from rendering
  • Added logoSize and logoBorderRadius props for customizable QR code appearance
  • Optimized array operations with pre-allocation and direct indexing strategies

Reviewed Changes

Copilot reviewed 7 out of 7 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
packages/ui/src/utils/QRCodeUtil.tsx Refactored QR generation logic to be async, added QRData interface, optimized with pre-allocation and direct indexing
packages/ui/src/composites/wui-qr-code/index.tsx Updated to use async QR generation with useEffect/useState, added logoSize and logoBorderRadius props, changed rendering to use data arrays
packages/ui/src/composites/wui-qr-code/styles.ts Removed unused icon style
packages/ui/src/assets/svg/WalletConnect.tsx Updated SVG viewBox and paths for new icon design
packages/appkit/src/partials/w3m-connecting-qrcode/index.tsx Added logoBorderRadius and logoSize props to QrCode component
packages/appkit/src/modal/w3m-modal/styles.ts Added borderWidth style property

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines 162 to 169
export const QrCode = memo(QrCode_, (prevProps, nextProps) => {
return (
prevProps.size === nextProps.size &&
prevProps.uri === nextProps.uri &&
prevProps.style === nextProps.style
prevProps.style === nextProps.style &&
prevProps.logoBorderRadius === nextProps.logoBorderRadius
);
});
Copy link

Copilot AI Nov 4, 2025

Choose a reason for hiding this comment

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

The memo comparison function is missing checks for logoSize, imageSrc, icon, arenaClear, and testID props. This will cause the component to incorrectly skip re-renders when these props change, leading to stale UI. Either add all props to the comparison or remove the custom comparison function to use the default shallow comparison.

Copilot uses AI. Check for mistakes.
cursor[bot]

This comment was marked as outdated.

@ignaciosantise
Copy link
Collaborator Author

@claude review

@claude
Copy link

claude bot commented Nov 4, 2025

Claude finished @ignaciosantise's task —— View job


🔄 Incremental PR Review

Tasks

  • Read repository guidelines (CLAUDE.md)
  • Read all changed files to understand current code state
  • Validate previously reported issues against current code
  • Identify any new issues in latest commits
  • Post comprehensive review feedback

Issues Status Analysis

✅ Resolved Since Previous Reviews

1. Async implementation with setTimeout - packages/ui/src/utils/QRCodeUtil.tsx

  • Previous issue: The async wrapper using setTimeout(() => {...}, 0) was questioned as it didn't provide true async behavior
  • Current status:RESOLVED - The code has been simplified to a synchronous generateQRData function (lines 299-312), removing the unnecessary async wrapper entirely. This is a good improvement.

2. Array pre-allocation with incorrect sizing - packages/ui/src/utils/QRCodeUtil.tsx

  • Previous issue: Arrays were pre-allocated with rects.length = 27 and arbitrary sizes
  • Current status:RESOLVED - The pre-allocation code has been removed. Arrays now use standard push() operations (lines 67-69, 88, 200, 238, etc.), which is cleaner and more maintainable.

3. Changeset file missing

  • Previous issue: Changeset-bot flagged missing changeset
  • Current status:RESOLVED - Changeset file added at .changeset/eager-walls-tease.md

4. Magic numbers in consumer component - packages/appkit/src/partials/w3m-connecting-qrcode/index.tsx

  • Previous issue: Hard-coded values logoBorderRadius={20} and logoSize={60}
  • Current status:RESOLVED - Constants defined at top of file (lines 23-24): LOGO_SIZE = 60 and LOGO_BORDER_RADIUS = 20

⚠️ Critical Issues Still Present

1. Incomplete memo comparison in QrCode component - packages/ui/src/composites/wui-qr-code/index.tsx:138-145

Status: ⚠️ CONFIRMED STILL PRESENT

The memo comparison is missing critical props that affect rendering:

  • logoSize - Used in QR generation (line 38, 44) and logo rendering (line 60, 73)
  • imageSrc - Determines which logo template to render (line 53)
  • icon - Fallback icon when no imageSrc (line 71)
  • arenaClear - Controls whether logo is shown (line 49)

Impact: Changes to these props won't trigger re-renders, causing stale QR codes and incorrect logo display.

Recommendation:

export const QrCode = memo(QrCode_, (prevProps, nextProps) => {
  return (
    prevProps.size === nextProps.size &&
    prevProps.uri === nextProps.uri &&
    prevProps.style === nextProps.style &&
    prevProps.logoBorderRadius === nextProps.logoBorderRadius &&
    prevProps.logoSize === nextProps.logoSize &&
    prevProps.imageSrc === nextProps.imageSrc &&
    prevProps.icon === nextProps.icon &&
    prevProps.arenaClear === nextProps.arenaClear
  );
});

🔍 Other Concerns

2. Missing error handling in QR generation - packages/ui/src/composites/wui-qr-code/index.tsx:43-46

The useMemo hook calls QRCodeUtil.generate() which can throw an error (see QRCodeUtil.tsx:306), but there's no try-catch wrapper. If QR generation fails, the entire component will error out.

Recommendation:

const qrData = useMemo(() => {
  if (!uri) return null;
  try {
    return QRCodeUtil.generate(uri, qrSize, _logoSize, logoBorderRadius);
  } catch (error) {
    console.error('QR code generation failed:', error);
    return null;
  }
}, [uri, qrSize, _logoSize, logoBorderRadius]);

3. Type safety: Optional chaining in hot path - packages/ui/src/utils/QRCodeUtil.tsx:80-81, 105-106, 177-178, 191-193

Multiple uses of optional chaining with continue statements in performance-critical loops:

const qr = qrList[qrIdx];
if (!qr) continue;  // Line 80-81

These checks are unnecessary since qrList is a statically defined array and will never have undefined elements. The checks add overhead without benefit.

Recommendation: Remove unnecessary checks for statically defined arrays, or use proper type guards if truly needed.

4. Missing dependency in useEffect - packages/appkit/src/partials/w3m-connecting-qrcode/index.tsx:58-62

The useEffect depends on wcUri but calls onConnect() which isn't in the dependency array. This will trigger ESLint warnings.

Recommendation:

const onConnect = useCallback(async () => {
  await WcController.state.wcPromise;
  // ... rest of function
}, []);

useEffect(() => {
  if (wcUri) {
    onConnect();
  }
}, [wcUri, onConnect]);

✨ Positive Changes

  • Removed unnecessary async wrapper - synchronous implementation is clearer
  • Removed array pre-allocation optimization that added complexity
  • Added proper constants for magic numbers
  • Changeset file properly added
  • Clean SVG updates for WalletConnect icon

Summary

Must Fix:

Should Fix:

Consider:

The refactoring from async to sync is a good improvement. The main remaining concern is the incomplete memo comparison which could cause real bugs in production.


@ignaciosantise ignaciosantise marked this pull request as draft November 4, 2025 18:28
@sonarqubecloud
Copy link

@ignaciosantise ignaciosantise marked this pull request as ready for review November 14, 2025 13:43
@ignaciosantise ignaciosantise merged commit 8351447 into develop Nov 14, 2025
11 of 13 checks passed
@ignaciosantise ignaciosantise deleted the chore/qr-borders branch November 14, 2025 13:48
@github-actions github-actions bot locked and limited conversation to collaborators Nov 14, 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.

2 participants