Files
TX/artifacts/tx-os/index.html
T
riyadhafraa 5dac662421 notes(ipad): keep dialog above the on-screen keyboard
Task #476. On iPad Safari, opening the keyboard while writing a new
note or replying inside the note thread dialog covered the bottom of
the dialog (textarea + send button). The dialog used
`top:50%; translate(-50%,-50%)` against the layout viewport and never
reacted to the visual viewport shrinking when the keyboard appeared.

Changes:
- artifacts/tx-os/index.html: added `interactive-widget=resizes-content`
  to the viewport meta so iOS 17+ resizes the layout viewport when the
  software keyboard opens.
- artifacts/tx-os/src/hooks/use-visual-viewport.ts: new hook that
  subscribes to `window.visualViewport` `resize` / `scroll` /
  `orientationchange` events (rAF-throttled) and exposes the current
  visible height plus the bottom keyboard inset.
- artifacts/tx-os/src/components/ui/dialog.tsx: `DialogContent` now
  reads the hook and, when the keyboard inset is non-trivial (> 80px),
  pins its center to the visible viewport mid-line and caps
  `max-height` to the visible height. Desktop renders unchanged
  (inset is 0 → no inline style applied beyond what the caller passes).
- artifacts/tx-os/src/pages/notes.tsx: the thread dialog reply
  textarea and the top composer textarea now `scrollIntoView({ block:
  "center" })` on focus (after a 250ms delay so the keyboard animation
  settles), so the cursor lands inside the visible region on touch
  devices. Desktop focus is unaffected — `scrollIntoView` is a no-op
  when the element is already in the viewport.

Verification:
- `tsc --noEmit` clean.
- Existing `notes-thread-dialog` e2e still passes (dialog stays
  capped at 85% viewport height, scroller still overflows, recipient
  chips and composer remain in viewport).
2026-05-10 15:13:21 +00:00

33 lines
1.4 KiB
HTML

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1, interactive-widget=resizes-content" />
<title>Tx OS</title>
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
<!--
Fonts are now bundled locally via `src/custom-fonts.css`
(DIN Next LT Arabic, Tajawal, Helvetica Neue LT Arabic,
Helvetica Neue, Majalla). No third-party Google Fonts roundtrip
is needed at page load, which speeds up first paint and removes
the external dependency.
#350 (browser print): preload DIN Next LT Arabic — the app's
sole Arabic print font — so it's already in the HTTP cache by
the time `@font-face` (declared with `font-display: block` in
custom-fonts.css) wants to fetch it. Without this, Chrome's
print snapshot can be taken before the font is ready and the
output uses a system fallback that lacks Arabic GSUB shaping
(isolated, unjoined letters that look reversed).
-->
<link rel="preload" href="/fonts/DINNextLTArabic-Regular.ttf"
as="font" type="font/ttf" crossorigin="anonymous" />
<link rel="preload" href="/fonts/DINNextLTArabic-Bold.ttf"
as="font" type="font/ttf" crossorigin="anonymous" />
</head>
<body>
<div id="root"></div>
<script type="module" src="/src/main.tsx"></script>
</body>
</html>