diff --git a/PLAN.md b/PLAN.md index dc6cfdf..db14e9a 100644 --- a/PLAN.md +++ b/PLAN.md @@ -594,13 +594,16 @@ Open details: deployment target/host; dashboards; load expectations. game, an "add to friends" item flips to a disabled "request sent"; chat send/nudge became ⬆️/πŸ›ŽοΈ icons; a **finished game** drops its last-word highlight, hides Check word / Drop game, disables zoom, and draws an **inert footer** (greyed rack + tab - bar) instead of hiding it. A second **iPhone-simulator** pass then made the chat - and modals keyboard-aware (`dvh` sizing), returned the away window to a native - `` (the iOS wheel with 10-minute steps; the timezone - stays a native offset ``** (the away window as hour + 10-minute selects, the + timezone as a UTC-offset select): native time/wheel inputs render differently per + OS and can't be forced to match, and a select also avoids the iOS "clear" button + that would empty a time field. ## Deferred TODOs (cross-stage) @@ -639,3 +642,9 @@ Open details: deployment target/host; dashboards; load expectations. exists (Stage 9), wrap a code in a deep link and render it as a QR so a friend can add you by scanning rather than typing. The code semantics (12 h TTL, single use, one active per issuer) stay as-is; only the delivery changes. +- **TODO-6 β€” smart default for the friend-game "game type" (owner's idea, Stage 8).** + The play-with-friends form has no preselected variant today (an empty, required + pick). Default it from the player's history (the variant they play most, from + `account_stats` or a games query), falling back to their interface language + (en β†’ English, ru β†’ Russian/Π­Ρ€ΡƒΠ΄ΠΈΡ‚). Until then the explicit pick avoids guessing + wrong. diff --git a/ui/src/components/Modal.svelte b/ui/src/components/Modal.svelte index 7449b5e..acd189d 100644 --- a/ui/src/components/Modal.svelte +++ b/ui/src/components/Modal.svelte @@ -6,11 +6,38 @@ onclose, children, }: { title?: string; onclose?: () => void; children?: Snippet } = $props(); + + // Track the visual viewport so the backdrop covers only the area above an open + // mobile keyboard: dvh alone shrinks the sheet but the fixed, layout-viewport + // backdrop still centres it behind the keyboard. Sizing the backdrop to + // visualViewport keeps the sheet (and the start of a chat) fully on screen. + let vh = $state(0); + let top = $state(0); + $effect(() => { + const vv = typeof window !== 'undefined' ? window.visualViewport : null; + if (!vv) return; + const update = () => { + vh = vv.height; + top = vv.offsetTop; + }; + update(); + vv.addEventListener('resize', update); + vv.addEventListener('scroll', update); + return () => { + vv.removeEventListener('resize', update); + vv.removeEventListener('scroll', update); + }; + }); -
onclose?.()}> +
onclose?.()} +>