Skip to content

feat: add a mutuals tab next to followers and following - #1006

Merged
nunomaduro merged 7 commits into
dev-null-sh:productionfrom
kachelle:feat/friendships-tab
Oct 26, 2026
Merged

nunomaduro merged 7 commits into
dev-null-sh:productionfrom
kachelle:feat/friendships-tab

Conversation

@kachelle

@kachelle kachelle commented Oct 22, 2026 •

Copy link
Copy Markdown
Contributor

When we follow eachother, we are mutuals, introducing a new tab: mutuals.

Desktop:
image

Iphone SE (!) - so small screen
image

Summary by CodeRabbit

  • New Features
    • Added a Mutuals tab to profiles, showing people the profile owner follows who also follow them back.
    • Added a public page for viewing a profile’s mutual connections, with pagination and an empty state.
    • Mutual connections are listed with the newest connections first, and visitors can browse additional results as they become available.

Lists the people a user follows who follow them back, newest follow first.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@younes-io

Copy link
Copy Markdown
Contributor

@kachelle : so the set of friends is the intersection of both followers and following sets? what are the implications of this new abstraction? can we now send messages to each other? my friends will be the only ones I can message on Remotes?

@kachelle
kachelle marked this pull request as ready for review October 22, 2026 22:32
@kachelle

kachelle commented Oct 22, 2026 •

Copy link
Copy Markdown
Contributor Author

@younes-io no implications, it's just a list.

Messaging works the same as before: if someone follows you, you can start a conversation with them on Remotes, as long as you both have Remotes enabled and neither has blocked the other.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@kachelle kachelle changed the title feat: add a friendships tab next to followers and following feat: add a mutuals tab next to followers and following Oct 23, 2026
@kachelle

Copy link
Copy Markdown
Contributor Author

renamed friendships to mutuals
cc @paulinevos

Comment thread app/Http/Controllers/UserMutualsController.php Outdated

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟢 Approval recommended

The changes are focused, follow existing connection-list patterns, and have no identified blocking issues.

No open issues 🎉

What changed in this PR

Adds a Mutuals tab to profile connection lists, showing people the profile owner follows who follow them back.

Changes:

  • Adds a cursor-paginated mutuals endpoint with block-aware access checks.
  • Extends connection tabs, empty states, and page metadata for mutuals.
  • Adds feature tests and documents the new tab.
File Description
tests/​Feature/​Controllers/​UserMutualsControllerTest.php Tests membership, ordering, follow status, blocking, guest access, and metadata.
routes/​web.php Registers the mutuals endpoint.
resources/​js/​pages/​user/​connections.tsx Adds the Mutuals tab, title, and empty state.
KNOWLEDGE_BASE.md Documents mutual connections.
app/​Services/​PageMetadata.php Adds mutuals preview metadata and canonical URL.
app/​Http/​Requests/​ListUserMutualsRequest.php Enforces block-aware access to mutuals.
app/​Http/​Controllers/​UserMutualsController.php Queries reciprocal follows and renders the connection list.

Review effort: Balanced

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@ashkesarmaa

Copy link
Copy Markdown
Contributor

I don't think either “Friendships” or “Mutuals” is a good name. This isn't a new concept or feature where we need to come up with a suitable name. X already has this concept, so I don't see a reason to change the naming.

image

By the way, I already opened a PR for the same topic a while ago, so it might be worth taking a look at it.
#733

@paulinevos

Copy link
Copy Markdown
Contributor

@ashkesarmaa That is not the same concept though... Mutuals is an already existing concept, and it is not the same as Followers you know.

Mutuals: the list of people that someone follows that follow them back.
Followers you know: list of people that follow a profile that you also follow

@paulinevos

Copy link
Copy Markdown
Contributor

@ashkesarmaa That being said... I think the latter is probably the more valuable list for people visiting a profile.

It could also take the form of "followed by ..." on a profile, which could click to show the full list of people you also follow.

@kachelle

Copy link
Copy Markdown
Contributor Author

its just something different.

This 'mutuals' list, is just the intersection. So this is a list of people that mutually know eachother. thats it. Nothing more. 😅

The reason i wanted it was that i was curious who on my list of followers (which is small to be clear 🫣), i also followed. Thats it.

@ashkesarmaa

Copy link
Copy Markdown
Contributor

@paulinevos, @kachelle Thanks for the clarification! Sorry, I misunderstood it. 🙂

@paulinevos

Copy link
Copy Markdown
Contributor

@ashkesarmaa np! And I am in favor of your feature. But I would like to have both, in which case I would prefer "followers you know" to have the profile link approach, so that we don't get too many tabs

@kachelle

Copy link
Copy Markdown
Contributor Author

okey, let me know if and what i should adjust here @paulinevos !

@paulinevos

Copy link
Copy Markdown
Contributor

@kachelle Nothing, just waiting for @ashkesarmaa to confirm the change to link instead of tab on his end. Then we can have both, and I'll merge yours.

@kachelle

Copy link
Copy Markdown
Contributor Author

lets go! nice chatting folks! 🫶🏼

@coderabbitai

coderabbitai Bot commented Oct 26, 2026 •

Copy link
Copy Markdown

Review in Change Stack →

Caution

Review failed

The pull request is closed.

No actionable comments were generated in the recent review.

Recent review info
Run configuration
  • Source mode: Auto
  • Repository: Unavailable
  • Branch: Unavailable
  • File: No configuration file from this repository applied
  • Commit: Unavailable
  • Layers: defaults
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 6caef634-7e39-4b30-8c92-f49d00379237
Commits

Reviewing files that changed from the base of the PR and between dcf0d4f and 8243468.

Files selected for processing: 7
  • KNOWLEDGE_BASE.md
  • app/Http/Controllers/UserMutualsController.php
  • app/Http/Requests/ListUserMutualsRequest.php
  • app/Services/PageMetadata.php
  • resources/js/pages/user/connections.tsx
  • routes/web.php
  • tests/Feature/Controllers/UserMutualsControllerTest.php

Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 7 remain after this review.

Walkthrough

The profile connections page now includes Mutuals. A new route lists users the profile owner follows who also follow the owner. The page supports cursor pagination, block-based access checks, guest responses, and mutuals-specific metadata.

Changes: Mutuals Connections Page

Layer / File(s) Summary
Route, access, and mutuals listing
app/Http/Requests/ListUserMutualsRequest.php, routes/web.php, app/Http/Controllers/UserMutualsController.php, tests/Feature/Controllers/UserMutualsControllerTest.php
Adds a public mutuals route and an endpoint that returns cursor-paginated mutual connections. Block relationships between the viewer and profile return a 404. Tests cover filtering, ordering, follow state, guest responses, preview metadata, and partial Inertia loads.
Connection metadata and page UI
app/Services/PageMetadata.php, resources/js/pages/user/connections.tsx, KNOWLEDGE_BASE.md
Adds mutuals-specific page metadata, a Mutuals tab, and a mutuals empty state. The profile documentation paragraph was replaced with identical text.

Priority: Not assessed

Estimated code review effort: 3 (Moderate) | ~20 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Visitor
  participant WebRoute
  participant ListUserMutualsRequest
  participant UserMutualsController
  participant UserConnectionsQuery
  WebRoute->>ListUserMutualsRequest: authorize request
  WebRoute->>UserMutualsController: call index
  UserMutualsController->>UserConnectionsQuery: query mutual connections
  UserConnectionsQuery-->>UserMutualsController: return paginated connections
  UserMutualsController-->>Visitor: render connections page
Loading

Possibly related PRs

Suggested reviewers: nunomaduro, xheaven, simonhamp

Merge Risk: Minimal · up to dbe53

No actionable merge-blocking risk was identified in the new Mutuals page.

Security architecture risk: Minimal · up to dbe53

The new page preserves the existing public connections model and checks blocks in both directions. Its results are an intersection of already-public connection lists. No material security risk introduced or worsened by this change was identified.

Retained concerns
No architecture-level concerns identified.

Security review details

Security Blast Radius

  • inferred — Anonymous callers can enumerate mutual relationships for public target profiles. This packages the intersection of information already available through the target's followers and following lists; it grants no relationship-write or privileged service authority.

Trust Boundaries and Controls

  • observed — A block in either direction between the authenticated viewer and target profile produces a not-found denial. This matches existing follower/following request authorization. Guests remain allowed under the existing public-list model.
  • inferred — Blocks involving individual listed candidates are not filtered, but this behavior predates the PR in both public connection lists. Since a mutual candidate necessarily appears in both existing lists, the new route does not newly bypass a candidate-visibility control.

Resilience and Maintainability Implications

  • observed — Feature-test assertions cover both block directions, guest access, exclusion of email, mutual membership, and authenticated follow flags. These assertions were inspected, not executed.
Pre-merge checks: Passed 4 · Failed 1

Failed Failed checks: 1 warning

Check name Status Explanation Resolution
Docstring Coverage Warning Docstring coverage is 71.43% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 7 functions across 6 files. (1 skipped: 1… Write docstrings for the functions missing them to satisfy the coverage threshold.
Passed Passed checks: 4 passed
Check name Status Explanation
Description Check Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check Passed The title "feat: add a mutuals tab next to followers and following" matches the main change. The PR adds a Mutuals tab beside Followers and Following on the profile. The raw summary confirms the new c…
Linked Issues check Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check Passed Check skipped because no linked issues were found for this pull request.
Full details: Title check

Explanation

The title "feat: add a mutuals tab next to followers and following" matches the main change. The PR adds a Mutuals tab beside Followers and Following on the profile. The raw summary confirms the new controller, route, page type, and PageMetadata support for mutuals. The title is specific and concise, and it follows the conventional commit prefix style. It does not mention the newest-first ordering or the guest/block handling, which is expected for a title.

Full details: Docstring Coverage

Explanation

Docstring coverage is 71.43% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 7 functions across 6 files. (1 skipped: 1 unsupported.)

Resolution

Write docstrings for the functions missing them to satisfy the coverage threshold.

Finishing Touches
🧪 Generate unit tests (beta)
  • Create a new PR
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Comment @coderabbitai help to get the list of available commands.

…ips-tab

# Conflicts:
#	KNOWLEDGE_BASE.md
#	resources/js/pages/user/connections.tsx
@nunomaduro
nunomaduro merged commit 2910043 into dev-null-sh:production Oct 26, 2026
1 check was pending
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants