docs(safety): record USER_SAFETY step 4, the app's chat-line menu #401
@@ -1062,7 +1062,8 @@ push, and Play (M6–M8) follow the designed app.
|
||||
and it takes `MODULE_API` 1.20.0 (org lead, 2026-10-29). The app's part, the *Delete my
|
||||
account* screen reached from *My account*, was built 2026-10-30 (that plan's §6 step 4).
|
||||
4. **Report, block and hide** across `website`, `Module-Rust`, the kit and this app
|
||||
(`USER_SAFETY.md` §7), now `MODULE_API` 1.21.0.
|
||||
(`USER_SAFETY.md` §7), now `MODULE_API` 1.21.0. The app's part, a long-press menu on Rust
|
||||
chat lines and *Account → Blocked*, was built 2026-10-30 (that plan's §7 step 4).
|
||||
5. **The cutover**, `edge` → `main`, once 1-4 have landed, so the first Play bundle carries
|
||||
all of it. **Before it merges, the org lead enrolls the existing keystore as the app-signing
|
||||
key** in Play Console (App integrity, "use my own key"). `PLAY_SERVICE_ACCOUNT_JSON` is
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# Report, block and hide — user safety on the website and in the app
|
||||
|
||||
**Status:** plan of record, 2026-10-29. Steps 2 (core) and 3 (Module-Rust, Integration Kit) built
|
||||
2026-10-30 (§7); the rest not yet.
|
||||
**Status:** plan of record, 2026-10-29. Steps 2 (core), 3 (Module-Rust, Integration Kit) and 4
|
||||
(Android) built 2026-10-30 (§7); the rest not yet.
|
||||
Each phase stops for the org lead before the next one starts. Built after account deletion
|
||||
([`ACCOUNT_DELETION.md`](ACCOUNT_DELETION.md)), which is why it is `MODULE_API` 1.21.0. §4 was
|
||||
amended by S11-S14 (§5) when the core was built.
|
||||
@@ -148,11 +148,22 @@ All of it is in `server/safety.js`, beside the events route that uses it.
|
||||
|
||||
### 4.3 Android app (chat lines only, S4)
|
||||
|
||||
- **Long-press a chat line** for the same menu. Report opens a sheet with the six reasons and an
|
||||
optional detail. A member who is signed out gets *Sign in to report or block*.
|
||||
- **Account → Blocked** lists blocks and undoes them, mirroring the web page.
|
||||
- The feed is already filtered by the server (S11); the app refetches after a block or a hide and
|
||||
offers *Block player* only where the line says `canBlock`.
|
||||
- **Long-press a chat line** for the same menu, in a bottom sheet: *Report* (the six reasons and
|
||||
an optional detail), *Hide for me*, *Block player* (where the line says `canBlock`, after a
|
||||
confirmation that says the player is not told) and, for admins and moderators, *Hide for
|
||||
everyone* or, on a hidden line, *Show to everyone again*. Only chat lines answer the press. A
|
||||
member who is signed out gets *Sign in to report or block*, which opens the app's login screen.
|
||||
Back on the report form or the block confirmation returns to the menu, keeping what was typed.
|
||||
- The calls are core's (`/player/reports`, `/auth/me/blocks`, `/auth/me/hidden`) and the
|
||||
module's two staff routes. Each refusal has its own sentence: already reported or blocked,
|
||||
gone, staff (S8), too many reports, the module not answering, the demo's lock.
|
||||
- The feed is already filtered by the server (S11); the app reads it again after a hide, a block
|
||||
or a staff hide, and never drops a line itself. A report changes nothing, so it does not. Staff
|
||||
see a line hidden for everyone dimmed and marked *Hidden by staff* (S10).
|
||||
- **Account → Blocked** (from *My account*) lists blocks with *Unblock*, mirroring the web page:
|
||||
an account block by its username, a Steam-ID block by its ID and "not linked to an account", and
|
||||
a block whose target is now staff with *Not applied* and why (S8). *Show them again* clears the
|
||||
member's hides.
|
||||
|
||||
## 5. Further decisions (org lead, 2026-10-29)
|
||||
|
||||
@@ -224,6 +235,24 @@ Play declarations gain "user-generated content: collected". M21 says so.
|
||||
a moderator *Hide for everyone* / *Show to everyone again* with the *Hidden by staff* marker and
|
||||
the Reports queue showing both chat-line reports from their snapshots. No console errors.
|
||||
4. **Android** (`edge`): §4.3. One PR.
|
||||
|
||||
**Built 2026-10-30** as Android-app `feat/user-safety`. `./gradlew testDebugUnitTest lintDebug
|
||||
assembleDebug` green: 827 tests, 29 of them new (the menu's rules, the repository's refusals,
|
||||
both view models), and no lint findings in the new code. Walked on the `Medium_Phone_API_36.1`
|
||||
emulator against a core on its own port with Module-Rust installed and a throwaway database,
|
||||
chat lines and Steam links written into the tables: signed out, a long press offered only
|
||||
*Sign in*, which opened the login screen; as a member, a report reached `content_reports`
|
||||
with its reason, detail and snapshot, and a second one was refused as already reported; *Hide
|
||||
for me* took one line out; blocking an unlinked speaker made a Steam-ID block and took their
|
||||
chat (not their death) out; blocking a linked speaker made an account block; the moderator's
|
||||
line and the member's own offered no *Block*, and a death offered no menu. *Account →
|
||||
Blocked* listed both; linking the Steam ID turned that block into an account block (S14);
|
||||
making that account a moderator showed *Not applied* (S8); *Unblock* and *Show them again*
|
||||
brought the lines back. As a moderator, *Hide for everyone* dimmed and marked the line for
|
||||
staff, took it out of a signed-out read and wrote `rust.chat.hide` to the activity log, and
|
||||
*Show to everyone again* undid it. The walk found two things, both fixed: Back to put the
|
||||
keyboard away closed the whole sheet and lost a half-written report, and the half-open sheet
|
||||
left *Send report* below the fold.
|
||||
5. **A walk** on the demo after the next wipe: report, hide and block, each on the web and in the
|
||||
app; *Hide for everyone* from the queue; a blocked Steam ID that later links to an account stays
|
||||
blocked.
|
||||
|
||||
Reference in New Issue
Block a user