- H13 offer threads: the seller is ALWAYS the listing author (derived from the event pubkey), never a self-declared role tag — a non-owner can no longer appear as the seller with a payment pointer. - H12 trade reputation: a preimage/deposit proof counts at most once, so a real payment can't be reused across attestations to inflate payment-verified. - Crew alerts: listed crews are filtered against the user's own membership confirmation labels (one batched query), so a confirmed member no longer gets a phantom 'confirm to join' badge/notification when the crew is edited. - Error boundaries (app + route) and DesktopNavManager are translated; the class boundary renders a translated functional ErrorFallback. New batch4 namespaces errorsUi.* / desktopNav.*.
45 lines
1.6 KiB
TypeScript
45 lines
1.6 KiB
TypeScript
import { useLocation } from 'react-router-dom';
|
|
import { ErrorBoundary } from '@/components/ErrorBoundary';
|
|
import { ErrorFallback } from '@/components/ErrorFallback';
|
|
|
|
/**
|
|
* Per-route error boundary.
|
|
*
|
|
* The app has a single top-level ErrorBoundary (in main.tsx) as a last resort,
|
|
* but on its own that means ANY component throwing blanks the ENTIRE app. This
|
|
* wrapper adds a second, inner boundary around the routed page content so a
|
|
* crash in one page shows a recoverable message while the app keeps running.
|
|
*
|
|
* It is keyed by the current pathname: navigating to a different route remounts
|
|
* the boundary and clears the error automatically, so a broken page never
|
|
* "sticks" once the user moves away.
|
|
*/
|
|
export function RouteErrorBoundary({ children }: { children: React.ReactNode }) {
|
|
const location = useLocation();
|
|
|
|
// After a deploy an already-open tab can hold a stale module graph, so a lazy
|
|
// route import 404s. `lazyWithRetry` reloads once; if it still fails the
|
|
// boundary is shown — so give the user a real way out: clear the "already
|
|
// reloaded" flag and do a fresh reload (fetching the new index + chunks).
|
|
const hardReload = () => {
|
|
try { sessionStorage.removeItem('skatespots:chunk-reload'); } catch { /* ignore */ }
|
|
window.location.reload();
|
|
};
|
|
|
|
return (
|
|
<ErrorBoundary
|
|
key={location.pathname}
|
|
fallback={
|
|
<ErrorFallback
|
|
variant="route"
|
|
onReload={hardReload}
|
|
onBack={() => window.history.back()}
|
|
/>
|
|
}
|
|
>
|
|
{children}
|
|
</ErrorBoundary>
|
|
);
|
|
}
|
|
|
|
export default RouteErrorBoundary;
|