Repository navigation
feat: mute and block people from the API - #555
Merged
Merged
Conversation
This was referenced Oct 19, 2026
simonhamp
marked this pull request as ready for review
October 19, 2026 08:47
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Lets the mobile app mute and block people, and list who the user mutes and blocks, the way Settings → Safety does on the web. It follows #130, which added the signed API, and is one of a few small PRs for the endpoints the app (NativePHP/dev-null-app) uses on top of it.
Endpoints
All signed.
POST /api/v1/users/{username}/mute200with the user andis_muting: trueDELETE /api/v1/users/{username}/mute200with the user andis_muting: falsePOST /api/v1/users/{username}/block200with the user andis_blocking: trueDELETE /api/v1/users/{username}/block200with the user andis_blocking: falseGET /api/v1/me/mutedGET /api/v1/me/blockedThey reuse the web's actions and mirror its form requests. Nobody can mute or block themselves (
403), and undoing is always allowed. Muting is silent. Blocking ends the follows both ways, and unblocking doesn't bring them back. The web has no rate limit of its own on these, so they only get the signed API's 120 a minute.The
user_blockederror now also carries the blockeduser, so the app's blocked page can show their name and avatar the way the web's page does.user_unavailablestill says nothing about who.Worth checking
ApiException::acrossBlock()takes a third argument, theUserResourceto send. The arch preset doesn't letApp\ExceptionsuseApp\Http, so the form requests that throw it build the resource and pass it in. This PR updates the two callers on production.shown: UserResource::make($user)added toListApiUserFollowersRequestandListApiUserFollowingRequest.created_atwith the user id as a tie-break, likeSafetyController. A test with 25 people muted at the same moment checks the paging.The log already leaves muted people out through the web's queries, and the existing log tests cover it, so nothing changed there.
Testing
Everything CI runs passes on this branch locally: Pint, Rector, the JS lint, PHPStan, tsc, type coverage, and all 2,976 tests at 100% coverage.
The app's mute and block actions, and the lists under its account screen (NativePHP/dev-null-app#6), have been running against these endpoints on a phone.