Round-6 follow-up: UX polish + client-IP fix
CI / changes (pull_request) Successful in 2s
CI / unit (pull_request) Successful in 8s
CI / integration (pull_request) Successful in 13s
CI / ui (pull_request) Successful in 32s
CI / gate (pull_request) Successful in 0s
CI / deploy (pull_request) Successful in 1m8s

- Client IP: the compose caddy trusts X-Forwarded-For from private-range
  upstreams (trusted_proxies private_ranges), so the real client IP survives
  the host-caddy hop (it was logging the docker caddy hop 172.18.0.x for chat
  moderation and bucketing the gateway per-IP rate limiter on it). Correct and
  spoof-safe in both contours (prod has no host caddy); peerIP unit-tested.
- Ad banner gated off behind a compile-time SHOW_AD_BANNER=false (the if-branch,
  the AdBanner import and banner.ts are tree-shaken out of the prod bundle).
- Landing: the Telegram entry is just the 64px logo (clickable, no button/text).
- TG-fullscreen header: title + menu centred as a pair (hamburger right of the
  title), pinned to the bottom of the TG nav band.
- Edge-swipe back (Screen): a left-edge rightward drag navigates to back
  (touch/pen only, armed from <=24px; skipped inside Telegram).
- Chat soft-keyboard: a bottom-sheet Modal lifted above the keyboard by a
  visualViewport-driven transform (compositor-only, no page/sheet relayout).
  iOS-specific, needs on-device tuning; native resize=none awaits Capacitor.
- Tests: e2e for the in-game '✓ in friends' item and a board→board tile
  relocation; codec units for last_activity_unix + OutgoingRequestList.

Deferred to the next PR (agreed): #4 enrich the your-turn/game-end push; #5 hide
finished games from the lobby.
This commit is contained in:
Ilia Denisov
2026-06-08 21:31:44 +02:00
parent f95a6cb9c8
commit 645df52c0b
12 changed files with 229 additions and 29 deletions
+25
View File
@@ -1387,6 +1387,31 @@ provided cert) at the contour caddy; prod VPN; rollback.
`kind='message'`, the source via a SQL `CASE`), reusing the now-exported `account.LikePattern`
glob helper. Owner decisions: messages only (no nudges), separate name/ext masks (matching the
Users section), a top-level nav entry plus the card deep-links.
- **Round-6 follow-up — UX polish + client-IP fix (this PR):**
- **Client IP through the edge.** The compose caddy now sets `trusted_proxies static
private_ranges`, so the real client IP survives the host-caddy hop (it was logging the
docker-network caddy hop `172.18.0.x` for chat moderation, and bucketing the gateway's
per-IP rate limiter on it). Correct + spoof-safe in **both** contours (prod has no host
caddy → public clients untrusted → real peer used). `peerIP` unit-tested.
- **Ad banner** gated **off** behind a compile-time `SHOW_AD_BANNER=false` in `Screen.svelte`
— the `{#if}` branch, the `AdBanner` import and `banner.ts` are tree-shaken out of the prod
bundle (code kept for post-release polish).
- **Landing** Telegram entry is now just the **64px logo** (clickable, no button/caption).
- **TG-fullscreen header** reworked again: title + menu are one **centred pair** (hamburger
right of the title) pinned to the **bottom** of the TG nav band, lining up with Telegram's
own controls.
- **Edge-swipe back** (`Screen.svelte`): a left-edge rightward drag navigates to `back`
(touch/pen only, armed only from ≤24px so it never fights the board's gestures; skipped
inside Telegram, which has its own back).
- **Chat soft-keyboard** is a **bottom-sheet** `Modal` lifted above the keyboard by a
`transform` driven by `visualViewport` (compositor-only — the board behind and the sheet
no longer relayout as the keyboard animates). iOS-specific; needs on-device fine-tuning.
The native `Keyboard.setResizeMode('none')` path waits for Capacitor (not yet wired).
- **Tests backfilled** for the merged round-6 work: e2e for the in-game "✓ in friends" item
and a board→board tile relocation; codec units for `last_activity_unix` + `OutgoingRequestList`.
- **Deferred to the next PR (agreed):** #4 enrich the out-of-app "your turn" / game-end push
with the opponent's name, last word and score; #5 let a player hide finished games from
their lobby (swipe + a desktop affordance).
## Deferred TODOs (cross-stage)