Friend Request Management
Branch: feat/friend-request-management
Merged into: develop
Date: March 2026
Overview
Wired up the complete friend request accept/reject flow. FriendService.acceptFriendRequest() existed in the codebase but was unreachable from any UI — a classic case of “dead code by incomplete wiring”. This feature completes the chain from service all the way to inline Accept/Reject buttons displayed in the Notifications screen.
Why It Was Built
The MVP roadmap lists “Friend requests and acceptance” as a core social feature for Phase 1. Without the ability to accept or decline requests, the social graph would never grow — users could send requests but the recipient had no mechanism to respond. The backend table (friendships with status = 'pending') was already in place.
What Changed
Service (friend_service.dart)
Two new methods added:
getPendingRequests()
Queries friendships where friend_id = me and status = 'pending', joining with profiles!friendships_user_id_fkey to return full User objects for each sender.
rejectFriendRequest(userId)
Deletes the matching friendships row where user_id = sender and friend_id = me.
The existing acceptFriendRequest() was also cleaned up (whitespace only).
Repository (social_repository.dart)
Exposed all three methods as thin wrappers:
getPendingRequests()acceptFriendRequest(userId)rejectFriendRequest(userId)
State & Logic (social_notifier.dart)
SocialState gained a new pendingRequests: List<User> field.
SocialNotifier gained three new methods:
| Method | Behavior |
|---|---|
loadPendingRequests() | Fetches pending requests and stores in state |
acceptFriendRequest(userId) | Calls repo, then optimistically removes from pendingRequests and prepends to friends |
rejectFriendRequest(userId) | Calls repo, then optimistically removes from pendingRequests |
A new pendingRequestsProvider selector was added for convenient widget consumption.
UI (notifications_screen.dart)
- Added imports for
SocialNotifier,User,ProfileAvatar - On
initState: loads pending requests alongside notifications buildnow watchespendingRequestsProvider- The
ListView.builderwas replaced with aCustomScrollViewcontaining twoSliverLists:- Friend requests section (only rendered when
pendingRequests.isNotEmpty) — shows a section header with a coral count badge, followed by one_buildFriendRequestCardper request - Regular notifications section — unchanged list of notification items
- Friend requests section (only rendered when
- Pull-to-refresh now refreshes both lists simultaneously
Friend Request Card Design
Each card shows:
- Avatar (tappable → navigates to
/user/:id) - Display name +
@username - “Rifiuta” outlined button (grey border) — removes request
- “Accetta” filled button (coral) — accepts and shows a snackbar confirmation
Optimistic State Updates
Both accept and reject update the UI immediately before the server confirms:
- Accept: user disappears from requests, appears in friends list
- Reject: user disappears from requests
If the server fails, state.error is set, but the UI has already moved. For social actions with near-zero failure rates, this trade-off prioritises perceived performance.