feat(social): asymmetric per-user block, in-game block control, admin lists
CI / changes (pull_request) Successful in 2s
CI / unit (pull_request) Successful in 9s
CI / integration (pull_request) Successful in 15s
CI / ui (pull_request) Successful in 51s
CI / gate (pull_request) Successful in 0s
CI / deploy (pull_request) Successful in 1m19s
CI / changes (pull_request) Successful in 2s
CI / unit (pull_request) Successful in 9s
CI / integration (pull_request) Successful in 15s
CI / ui (pull_request) Successful in 51s
CI / gate (pull_request) Successful in 0s
CI / deploy (pull_request) Successful in 1m19s
Make a per-user block one-directional and non-destructive: the blocker stops
receiving everything from the blocked user (chat, nudge, friend requests,
invitations) and the matchmaker never pairs them, while the blocked user
notices nothing — their sends still persist by the normal rules but are never
delivered or surfaced (born-read). A block no longer deletes the friendship
(an unblock cleanly restores it) and instant-reads any unread the blocked user
had left for the blocker.
- backend: a directional blockExists guard across chat/nudge/friends/invitations
(store-but-hide for the blocked->blocker direction, refuse blocker->blocked);
the matchmaker excludes a block-related pair (both directions) from auto-match;
user_blocked/user_unblocked notifications to the blocker only (in-app only).
- ui: the opponent score card gains a block ✖️ control mirroring add-friend
(red "Block?" confirm, mutual-hide while confirming, struck name, hidden chat
composer when blocked); optimistic apply + event confirm + rollback for both.
- admin: the user card gains cross-linked blocks / blocked-by / friends lists.
- docs: FUNCTIONAL(+ru), ARCHITECTURE §10 + decision record, UI_DESIGN, PRERELEASE.
This commit is contained in:
+10
-6
@@ -131,10 +131,14 @@ except Login uses `Screen`.
|
||||
(badged with unread chat) at the right, icon-only. A **single-word-rule** game (a Russian
|
||||
game with "multiple words per turn" off) centres a **"One word per turn"** label between
|
||||
those two icons, and the status bar shows a small **1️⃣** in the score-preview slot that
|
||||
yields to the live word/score preview while tiles are pending; standard games show neither. Each **opponent**'s card also gains a
|
||||
🤝 **add-friend** control (non-guests; hidden once a friend, disabled once requested) that
|
||||
confirms via the fading-✅ tap, swapping the card's score for "Add friend?" while armed
|
||||
(see Controls); the name and score stay centred — the 🤝 is pinned to the card's edge.
|
||||
yields to the live word/score preview while tiles are pending; standard games show neither. Each **opponent**'s card also gains two
|
||||
edge-pinned controls (non-guests): a 🤝 **add-friend** on the right (hidden once a friend,
|
||||
disabled once requested) and a ✖️ **block** on the left. Each confirms via the fading-✅ tap,
|
||||
swapping the card's score for "Add friend?" — or **"Block?" in the danger colour** — while
|
||||
armed (see Controls); while one is armed the other hides so they never overlap. Once the
|
||||
opponent is **blocked** both controls go and the **name is struck through** (and the comms-hub
|
||||
chat composer is hidden — only the log remains). The name and score stay centred — the controls
|
||||
are pinned to the card's edges.
|
||||
Unread chat is also badged on the score bar itself, so it shows with the history closed.
|
||||
- **Vertical fit & keyboard**: when the game does not fit the viewport, only the
|
||||
board area scrolls vertically (`Screen` `column` mode; the score bar, status, rack and tab
|
||||
@@ -180,8 +184,8 @@ except Login uses `Screen`.
|
||||
tap-to-confirm control. A first tap arms a ~2 s window showing a **fading ✅** (no fade
|
||||
under reduce-motion, but the window still holds); a tap on the ✅ within it confirms,
|
||||
otherwise it reverts. Used by the **Hint** tab (the icon morphs to ✅, no label — replacing
|
||||
the old press-and-hold popover) and the in-game **add-friend 🤝**. The
|
||||
**Drop game** action keeps its `Modal` confirmation (a destructive, less-frequent action).
|
||||
the old press-and-hold popover) and the in-game **add-friend 🤝** and **block ✖️** card
|
||||
controls. The **Drop game** action keeps its `Modal` confirmation (a destructive, less-frequent action).
|
||||
- **MakeMove / Reset**: when ≥1 tile is pending the rack collapses its used slots
|
||||
and shifts left, a **borderless ✅ icon button** (styled like a tab, not a filled accent
|
||||
button) beside the rack commits the move — no popover, and disabled while the pending word
|
||||
|
||||
Reference in New Issue
Block a user