Commit a4faae0
fix(feedback): stop the Sentry report button covering "Next" on mobile
Sentry's feedback integration ran with `autoInject: true`, which plants a
fixed 50px actor button in the bottom-right corner. On a 390x844 viewport
that landed on top of the lesson footer's primary action: the actor at
(324,778,50x50) covered roughly 72% of the "Next" button at (338,796,40x40),
so tapping to advance a lesson opened a bug report instead.
Reporting a bug is a rare action, so it no longer holds prime thumb real
estate. `autoInject` is off and the trigger is ours:
- `components/shared/feedback-button.tsx` renders a 44px icon-only puck that
rests dimmed (opacity .45) on the right edge at 62% height, clear of both
the dashboard header and any bottom action bar. Measured clearance from
"Next" is 259px.
- It can be dragged anywhere, snaps to the nearest edge, clamps inside the
viewport (respecting `env(safe-area-inset-*)` via a probe element), and
remembers where it was parked in localStorage.
- Opening lives on `click`, not `pointerup`, so Enter and Space work; a drag
sets a flag that suppresses the trailing click. Arrow keys reposition it,
since dragging is pointer-only.
- Position moves via `transform` only, never a layout property, and the
transition list drops `transform` mid-drag so the puck tracks the finger
exactly and eases only when snapping home. Reduced motion is honoured.
- `components/user-nav.tsx` gains a "Report a problem" item: the
discoverable entry point, at zero screen cost.
Availability and reduced-motion are read through `useSyncExternalStore` with
a `false` server snapshot, so the puck can't appear in the first client
render where the server rendered nothing.
The dialog itself was English-only for Spanish tenants; it's built outside
React so it can't reach next-intl, but `<html lang>` is server-rendered and
readable at init, so the form strings are now localized too. The dialog also
follows the app's resolved theme rather than the OS, which was wrong whenever
a user had overridden the theme in-app.
Verified in Chrome at 390x844 against the seeded student on a real lesson
page: bug reproduced with `autoInject` flipped back on (overlap true), then
gone after (overlap false); drag snaps and persists across navigation;
keyboard nudges move it 62px per press; dialog opens and reads correctly in
both en and es. Build, typecheck and lint clean.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FJ4dqwXuyKUPtg11ni5BSb1 parent a6c88d3 commit a4faae0
7 files changed
Lines changed: 503 additions & 3 deletions
File tree
- app/[locale]
- components
- lib/sentry
- messages
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
3 | 3 | | |
4 | 4 | | |
5 | 5 | | |
| 6 | + | |
6 | 7 | | |
7 | 8 | | |
8 | 9 | | |
| |||
170 | 171 | | |
171 | 172 | | |
172 | 173 | | |
| 174 | + | |
173 | 175 | | |
174 | 176 | | |
175 | 177 | | |
| |||
0 commit comments