mirror of
https://github.com/MBombeck/HealthLog.git
synced 2026-11-12 06:06:10 +00:00
Quality-leap release between two HealthKit milestones. The headline is a P0 hotfix for the `/api/analytics` 500 that broke the Insights mother page for any account with more than a few thousand measurements: the six per-metric status helpers were spreading the entire numeric history into `Math.min` / `Math.max`, which trips a stack overflow once a single argument list exceeds the V8 spread cap. Both the surfaced symptom and the latent risk in five sibling helpers were folded onto a reduce-based min/max path. Around that hotfix landed a deep polish pass: the Insights mother page now defers three below-the-fold blocks behind `next/dynamic` to trim the cold mount cost, the analytics endpoint gained a `?slice=summaries` slim slice that the per-metric sub-pages now ride, the Coach snapshot builder picked up a 60 s LRU keyed on `(userId, scope)`, the Settings shell consolidated three duplicate copies of the about / notifications / about-dropdown surfaces, the navigation strip dropped a redundant "Home" group label and a colliding "Notifications" sibling, every icon-only button on the medications and admin surfaces gained an accessible name, every Progress bar gained one too, three pages had their heading hierarchy repaired to a sequential h1 → h2 → h3, the mobile Coach FAB now hides while a chart tooltip is open so it cannot occlude the read-out, and the auth shell normalised every authenticated route to a single `max-w-screen-xl` container. Also lands the Apple App Site Association handler at `/.well-known/apple-app-site-association` on every host that fronts the app, advertising the iOS bundle's App ID prefix (S8WDX4W5KX.dev.healthlog.app) under `webcredentials.apps` so the passkey ceremony shares cleanly between the web origin and the iOS app. The release closes nineteen issues from a five-surface audit + a runtime bug-hunt pass, plus six follow-up tracks of polish across the affected surfaces.
35 lines
1.4 KiB
TypeScript
35 lines
1.4 KiB
TypeScript
"use client";
|
|
|
|
import { useEffect } from "react";
|
|
|
|
/**
|
|
* v1.4.33 IW9 — single source of truth for the "scroll to top on
|
|
* route mount" affordance.
|
|
*
|
|
* The pre-v1.4.33 wiring had `<SubPageShell>` AND the insights mother
|
|
* page each firing their own `requestAnimationFrame → scrollTo({top:0})`
|
|
* on mount. Two consumers doing the same trick is the kind of
|
|
* duplication that drifts; the second `scrollTo` lands ~16 ms after the
|
|
* first and re-snaps the viewport once the chart skeleton has inflated.
|
|
* On slow hydrates the user sees a visible "jump" — exactly the
|
|
* complaint in `.planning/round-v1433-audit-polish.md` §2.1.
|
|
*
|
|
* This hook is the single owner of that reset. Both the shell and the
|
|
* mother page call into it; the effect is mount-only and uses
|
|
* `requestAnimationFrame` so the scroll lands after the first paint
|
|
* (chart skeleton heights have settled, no double-snap).
|
|
*
|
|
* `behavior: "auto"` is intentional — `prefers-reduced-motion` users
|
|
* get the same instant reset everyone else does. A smooth scroll on
|
|
* a route change is itself a motion that some users opt out of.
|
|
*/
|
|
export function useScrollResetOnRoute() {
|
|
useEffect(() => {
|
|
if (typeof window === "undefined") return;
|
|
const handle = window.requestAnimationFrame(() => {
|
|
window.scrollTo({ top: 0, behavior: "auto" });
|
|
});
|
|
return () => window.cancelAnimationFrame(handle);
|
|
}, []);
|
|
}
|