Skip to content

feat(ui): add dismissible support banner on homepage - #337

Closed
sahilc0 wants to merge 2 commits into
masterfrom
wt-dismissible-banner-20260226
Closed

sahilc0 wants to merge 2 commits into
masterfrom
wt-dismissible-banner-20260226

Conversation

@sahilc0

@sahilc0 sahilc0 commented Feb 26, 2026 •

Copy link
Copy Markdown
Contributor

Summary

  • Replace the non-dismissible PSA banner with a reusable DismissibleBanner component on the homepage
  • Banner text: "Go to Settings > Support for help and bug reports" (removed "New!" prefix)
  • Dismissal persists in localStorage via new bannersDismissed: string[] field on Config
  • Close button uses Lucide X icon with 44px iOS tap target, proper light/dark mode contrast
  • Dismiss animation: fade out + slide down + collapse over 300ms ease-out-quint, with haptic feedback
  • Respects prefers-reduced-motion — skips animation and persists immediately
  • PSA system (VITE_PSA_MESSAGE) kept as higher-priority emergency fallback
  • Tapping the banner body navigates to Settings > Support

Files changed

File Change
src/components/DismissibleBanner.tsx New reusable component — wraps AlertBox with persistence + animation
src/components/AlertBox.tsx Exported AlertBox, replaced close icon with Lucide X + 44px tap target
src/lib/types.ts Added bannersDismissed: string[] to Config type
src/providers/config.tsx Added bannersDismissed: [] to defaultConfig
src/screens/Wallet/Index.tsx Replaced PSA InfoBox with DismissibleBanner, added click-to-navigate
package.json Added lucide-react dependency

Test plan

  • Banner appears on homepage with megaphone icon and X button
  • Tap X: haptic fires, banner fades out + slides down + content slides up smoothly
  • Reload: banner stays dismissed (check localStorage config has bannersDismissed: ["support-banner"])
  • Tap banner body (not X): navigates to Settings > Support
  • Light mode: X icon is visible with proper contrast
  • Dark mode: X icon is visible with proper contrast
  • If VITE_PSA_MESSAGE is set, PSA takes priority over support banner
  • If nudge is active, nudge takes priority over both
  • New install (clear localStorage): banner appears fresh

Summary by CodeRabbit

  • New Features

    • Added dismissible banners with persistence functionality
    • Enhanced loading animation with reduced-motion awareness
    • Added support banner in wallet screen with navigation to settings
  • Chores

    • Integrated lucide-react icon library
    • Updated development server configuration

@coderabbitai

coderabbitai Bot commented Feb 26, 2026 •

Copy link
Copy Markdown
Contributor

Warning

Rate limit exceeded

@sahilc0 has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 8 minutes and 19 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

📥 Commits

Reviewing files that changed from the base of the PR and between 039a771 and ae41708.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (6)
  • package.json
  • src/components/AlertBox.tsx
  • src/components/DismissibleBanner.tsx
  • src/lib/types.ts
  • src/providers/config.tsx
  • src/screens/Wallet/Index.tsx

Walkthrough

This PR introduces a new dismissible banner component with configuration-based dismissal tracking, updates AlertBox to use lucide-react icons as the default export, enhances LoadingBar with reduced-motion-aware RAF animation and easing functions, and extends the Config type to persist dismissed banner IDs.

Changes

Cohort / File(s) Summary
Dependencies
package.json
Added lucide-react (^0.575.0) as runtime dependency.
Component Icon Updates
src/components/AlertBox.tsx
Changed AlertBox to default export, replaced inline SVG CloseIcon with lucide-react X icon in accessible div button structure.
New Dismissible Banner Component
src/components/DismissibleBanner.tsx
Added new DismissibleBanner component that integrates with ConfigContext to track dismissed banners by ID, includes haptic feedback on dismissal, and respects reduced-motion preferences for dismissal transitions.
Animation Enhancements
src/icons/LoadingBar.tsx
Enhanced LoadingBar with reduced-motion detection, RAF-based animation loop, easing helpers (easeInOutCubic, easedSine), and data-driven segment rendering replacing hard-coded rects.
Type & Config Extensions
src/lib/types.ts, src/providers/config.tsx
Extended Config type with bannersDismissed: string[] array and updated defaultConfig with new empty array.
Screen Integration & Infrastructure
src/screens/Wallet/Index.tsx, src/index.tsx, vite.config.ts
Integrated DismissibleBanner with MegaphoneIcon in Wallet screen to prompt Settings > Support; added minor formatting in index.tsx; configured vite server allowedHosts for trycloudflare domain.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Suggested reviewers

  • pietro909
  • bordalix
🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The PR title clearly and accurately summarizes the main change: adding a dismissible support banner on the homepage, which is the primary objective reflected in all modified files and the PR description.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch wt-dismissible-banner-20260226

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

Comment @coderabbitai help to get the list of available commands and usage tips.

@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Feb 26, 2026 •

Copy link
Copy Markdown

Deploying wallet-bitcoin with  Cloudflare Pages  Cloudflare Pages

Latest commit: ae41708
Status: ✅  Deploy successful!
Preview URL: https://0ced92f3.wallet-bitcoin.pages.dev
Branch Preview URL: https://wt-dismissible-banner-202602.wallet-bitcoin.pages.dev

View logs

@sahilc0

sahilc0 commented Feb 26, 2026

Copy link
Copy Markdown
Contributor Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Feb 26, 2026

Copy link
Copy Markdown
Contributor
✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@sahilc0

sahilc0 commented Feb 26, 2026

Copy link
Copy Markdown
Contributor Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Feb 26, 2026

Copy link
Copy Markdown
Contributor
✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@coderabbitai coderabbitai Bot left a comment

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.

Actionable comments posted: 1

🧹 Nitpick comments (2)
src/icons/LoadingBar.tsx (1)

57-57: Avoid hard-coding segment count in the animation loop.

Line 57 ties behavior to a magic number (6) while rendering is driven by SEGMENTS. If SEGMENTS changes, animation and rendering can diverge.

♻️ Proposed fix
-      for (let i = 0; i < 6; i++) {
+      for (let i = 0; i < SEGMENTS.length; i++) {
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/icons/LoadingBar.tsx` at line 57, The animation loop in LoadingBar.tsx
uses a hard-coded 6 (for (let i = 0; i < 6; i++)) which can diverge from the
rendering segments; change that loop to use the SEGMENTS constant (e.g., for
(let i = 0; i < SEGMENTS; i++)) so animation iteration count always matches
rendering, and update any related index math inside the loop that assumed 6 to
reference SEGMENTS instead.
src/components/DismissibleBanner.tsx (1)

16-17: Static reduced-motion check won't react to preference changes mid-session.

This is a common and acceptable pattern, but if a user toggles their reduced-motion preference while the app is open, it won't be detected until next module load. For a banner that's dismissed once, this is unlikely to matter in practice.

If you want reactive behavior later, consider moving this check inside the component or using a custom hook with matchMedia.addEventListener('change', ...).

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/components/DismissibleBanner.tsx` around lines 16 - 17, The module-level
prefersReducedMotion constant is evaluated once and won't update if the user
changes their OS reduced-motion setting mid-session; move the media-query logic
into the DismissibleBanner component (or a small hook like
usePrefersReducedMotion) so it uses window.matchMedia('(prefers-reduced-motion:
reduce)') inside useEffect, initialize component state from matchMedia.matches,
add a 'change' event listener to update that state, and clean up the listener on
unmount; update any usage of prefersReducedMotion in the component to read from
the new state/hook.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/components/AlertBox.tsx`:
- Around line 85-103: The dismiss control is a non-focusable div with
role='button' so replace that element with a native <button> element (preserve
aria-label='Dismiss', onClick handler, and all inline style properties) to make
it keyboard-focusable and support Enter/Space automatically; remove
role='button' and ensure you set type="button" on the button, keep the X icon
usage (X size={18} color='var(--black)') and flex layout, and retain touchAction
and cursor styles so behavior and appearance remain unchanged.

---

Nitpick comments:
In `@src/components/DismissibleBanner.tsx`:
- Around line 16-17: The module-level prefersReducedMotion constant is evaluated
once and won't update if the user changes their OS reduced-motion setting
mid-session; move the media-query logic into the DismissibleBanner component (or
a small hook like usePrefersReducedMotion) so it uses
window.matchMedia('(prefers-reduced-motion: reduce)') inside useEffect,
initialize component state from matchMedia.matches, add a 'change' event
listener to update that state, and clean up the listener on unmount; update any
usage of prefersReducedMotion in the component to read from the new state/hook.

In `@src/icons/LoadingBar.tsx`:
- Line 57: The animation loop in LoadingBar.tsx uses a hard-coded 6 (for (let i
= 0; i < 6; i++)) which can diverge from the rendering segments; change that
loop to use the SEGMENTS constant (e.g., for (let i = 0; i < SEGMENTS; i++)) so
animation iteration count always matches rendering, and update any related index
math inside the loop that assumed 6 to reference SEGMENTS instead.

ℹ️ Review info

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between c8ea13a and 039a771.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (9)
  • package.json
  • src/components/AlertBox.tsx
  • src/components/DismissibleBanner.tsx
  • src/icons/LoadingBar.tsx
  • src/index.tsx
  • src/lib/types.ts
  • src/providers/config.tsx
  • src/screens/Wallet/Index.tsx
  • vite.config.ts

Comment thread src/components/AlertBox.tsx Resolved
Replace the non-dismissible PSA banner with a reusable DismissibleBanner
component. The support banner ("Go to Settings > Support for help and bug
reports") can be closed via an X button, and the dismissal persists in
localStorage via a new `bannersDismissed` field on Config.

- New DismissibleBanner component wraps AlertBox with persistence logic
- Dismiss animation: fade out + slide down + collapse (300ms ease-out-quint)
- Haptic feedback on dismiss, respects prefers-reduced-motion
- Close button uses Lucide X icon with 44px tap target for iOS
- Close button uses var(--black) for proper light/dark mode contrast
- PSA system kept as higher-priority emergency fallback
- Tapping the banner navigates to Settings > Support
@sahilc0
sahilc0 force-pushed the wt-dismissible-banner-20260226 branch from 039a771 to 3284e41 Compare February 26, 2026 21:33
@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Feb 26, 2026 •

Copy link
Copy Markdown

Deploying wallet-mutinynet with  Cloudflare Pages  Cloudflare Pages

Latest commit: ae41708
Status: ✅  Deploy successful!
Preview URL: https://3fa7a8bb.arkade-wallet.pages.dev
Branch Preview URL: https://wt-dismissible-banner-202602.arkade-wallet.pages.dev

View logs

Replaces div[role=button] with a native <button> element for the
banner close icon so it is keyboard-focusable and handles Enter/Space
automatically. Addresses CodeRabbit review feedback on PR #337.

@bordalix bordalix left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

  • rebase master to fix conflicts
  • don't use lucide-react, there are known problems with expo, check src/icons for icons in SVG
  • currently we would never see the new banner since psaMessage is defined in the running environment and it supersedes the new banner: TODO remove psaMessage from running environment

@sahilc0

sahilc0 commented Mar 6, 2026

Copy link
Copy Markdown
Contributor Author

closing since we have #375

@sahilc0 sahilc0 closed this Mar 6, 2026
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