Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import OfflineBanner from './components/common/OfflineBanner';
import GlobalPauseBanner from './components/common/GlobalPauseBanner';
import PendingTransactionBanner from './components/common/PendingTransactionBanner';
import SessionExpiryWatcher from './components/common/SessionExpiryWatcher';
import BadgeAchievementListener from './components/common/BadgeAchievementListener';
import { useContractPausedStore } from './hooks/useContractPausedStore';
import { routes } from './routes';
import { useRouteChangeLogging } from './hooks/useRouteChangeLogging';
Expand Down Expand Up @@ -56,6 +57,8 @@ function App() {
}}
/>
<SessionExpiryWatcher navigate={path => router.navigate(path)} />
{/* Badge achievement celebrations, app-wide (#1222) */}
<BadgeAchievementListener navigate={path => router.navigate(path)} />
<RouterProvider router={router} />
</AppErrorBoundary>
);
Expand Down
39 changes: 39 additions & 0 deletions src/components/common/BadgeAchievementListener.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import { useCallback } from 'react';
import { useAccount } from 'wagmi';
import { useBadgeAchievements } from '@/hooks/useBadgeAchievements';

export interface BadgeAchievementListenerProps {
/**
* Navigates to the given path. Passed in (rather than pulled from
* `useNavigate`) so this component can be mounted at the app root, outside
* the `RouterProvider` tree where router hooks aren't available —
* `App.tsx` passes the `router.navigate` bound method from the same
* `createBrowserRouter` instance it renders.
*/
navigate: (path: string) => void;
}

/**
* Mounted once at the app root so badge achievements are celebrated wherever
* the user happens to be (#1222).
*
* Watches the connected wallet for newly earned badges and shows the
* achievement toast. The toast's "View Badges" CTA deep-links to the
* wallet's badge showcase on the profile page.
*/
export default function BadgeAchievementListener({
navigate,
}: BadgeAchievementListenerProps) {
const { address } = useAccount();

const handleViewBadges = useCallback(
(profilePath: string) => {
navigate(profilePath);
},
[navigate]
);

useBadgeAchievements(address, { onViewBadges: handleViewBadges });

return null;
}
Loading
Loading