Skip to content
Open
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
37 changes: 37 additions & 0 deletions src/pages/Landing.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -109,4 +109,41 @@ describe('Landing Page', () => {
// Check if the #how-it-works anchor exists
expect(container.querySelector('#how-it-works')).toBeInTheDocument();
});

it('shows final stat values immediately when prefers-reduced-motion is true', () => {
const originalMatchMedia = window.matchMedia;

Object.defineProperty(window, 'matchMedia', {
writable: true,
value: vi.fn().mockImplementation((query) => ({
matches: query === '(prefers-reduced-motion: reduce)',
media: query,
onchange: null,
addListener: vi.fn(),
removeListener: vi.fn(),
addEventListener: vi.fn(),
removeEventListener: vi.fn(),
dispatchEvent: vi.fn(),
})),
});

render(
<MemoryRouter>
<Landing />
</MemoryRouter>
);

// mockLandingStats has totalRounds: 1247
// formatStat formats it as 1,247
expect(screen.getByText('1,247')).toBeInTheDocument();

// mockLandingStats has vXlmDistributed: 4200000
// formatStat formats it as 4.2M
expect(screen.getByText(/4\.2M/i)).toBeInTheDocument();

// mockLandingStats has activePlayers: 893
expect(screen.getByText('893')).toBeInTheDocument();

window.matchMedia = originalMatchMedia;
});
});
20 changes: 18 additions & 2 deletions src/pages/Landing.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,28 @@ import ModeCards from '../components/ModeCards';
import { useNetworkStats } from '../hooks/useNetworkStats';

function useCountUp(target: number, durationMs = 1800) {
const [value, setValue] = useState(0);
const prefersReducedMotion =
typeof window !== 'undefined' &&
window.matchMedia &&
window.matchMedia('(prefers-reduced-motion: reduce)').matches;

const [value, setValue] = useState(prefersReducedMotion ? target : 0);
// Track the last displayed value so re-targeting (mock -> live stats) animates
// smoothly from where it is rather than snapping back to zero.
const latestRef = useRef(0);
const latestRef = useRef(prefersReducedMotion ? target : 0);

useEffect(() => {
const prefersReducedMotion =
typeof window !== 'undefined' &&
window.matchMedia &&
window.matchMedia('(prefers-reduced-motion: reduce)').matches;

if (prefersReducedMotion) {
setValue(target);
latestRef.current = target;
return;
}

let frame = 0;
const startValue = latestRef.current;
const start = performance.now();
Expand Down