Conversation
WalkthroughThis PR introduces a complete friend management system. It defines API schemas and types, provides client-side fetch functions for friend operations, implements a FriendsList component that displays and manages friends and requests, and integrates the component into AccountModal with translation strings. ChangesFriends Feature Implementation
Sequence DiagramsequenceDiagram
participant User
participant FriendsList
participant FriendsApi
participant Server
User->>FriendsList: Load friends tab
FriendsList->>FriendsApi: fetchFriendRequests()
FriendsList->>FriendsApi: fetchFriends(page, limit)
FriendsApi->>Server: GET /friends/requests
FriendsApi->>Server: GET /friends?page=X&limit=Y
Server-->>FriendsApi: incoming/outgoing requests
Server-->>FriendsApi: paginated friends list
FriendsList->>FriendsList: render lists and actions
User->>FriendsList: send friend request
FriendsList->>FriendsApi: sendFriendRequest(publicId)
FriendsApi->>Server: POST /friends/requests/{publicId}
Server-->>FriendsApi: status (requested|accepted)
FriendsApi-->>FriendsList: response or error
FriendsList->>FriendsList: update state, show toast
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@src/client/components/FriendsList.ts`:
- Around line 117-123: After mutating local lists (e.g., this.incoming,
this.friends, this.friendsTotal) in the accept/remove handlers, reset the
component's pagination cache/state and re-fetch the first page instead of only
editing the local arrays to avoid later duplicate/missing rows; specifically,
after the local update (the block that modifies this.incoming, this.friends and
this.friendsTotal), clear whatever pagination buffers you maintain (e.g., pages
array, nextCursor/currentPage) and invoke loadMore() (or a refreshFriends()
helper) to reload from the server so the client and paginated server state stay
in sync.
In `@src/core/ApiSchemas.ts`:
- Around line 221-248: Add unit tests that validate FriendEntrySchema,
FriendRequestsResponseSchema, FriendsListResponseSchema, and
SendFriendRequestResponseSchema: for FriendEntrySchema test a valid object with
publicId string and createdAt ISO datetime and invalid cases (missing publicId,
bad createdAt); for FriendRequestsResponseSchema test valid payloads where
incoming/outgoing are arrays of valid FriendEntry objects and invalid cases
(non-array, invalid entries); for FriendsListResponseSchema test a valid payload
with results array of FriendEntry objects and numeric total/page/limit and
invalid cases (missing/negative/non-numeric pagination fields, non-array
results, invalid entries); and for SendFriendRequestResponseSchema test accepted
valid enum values "requested" and "accepted" plus invalid string values. Use the
schema parse/validation methods in your test harness to assert success for valid
fixtures and thrown/failed validation for each invalid fixture, referencing the
schema symbols FriendEntrySchema, FriendRequestsResponseSchema,
FriendsListResponseSchema, and SendFriendRequestResponseSchema to locate the
code.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: a87f5d49-6e0e-4a30-828b-bc458b146182
📒 Files selected for processing (5)
resources/lang/en.jsonsrc/client/AccountModal.tssrc/client/FriendsApi.tssrc/client/components/FriendsList.tssrc/core/ApiSchemas.ts
| this.incoming = this.incoming.filter((r) => r.publicId !== publicId); | ||
| this.friends = [ | ||
| { publicId, createdAt: new Date().toISOString() }, | ||
| ...this.friends, | ||
| ]; | ||
| this.friendsTotal++; | ||
| showToast(translateText("friends.request_accepted"), "green"); |
There was a problem hiding this comment.
Re-sync paginated friends after local accept/remove updates.
On Line 117 and Line 166, local list edits can desync pagination state, which can later produce duplicate/missing rows when loadMore() requests the next server page.
Suggested fix
private async handleAccept(publicId: string): Promise<void> {
@@
if (result !== true) {
showToast(translateText(this.errorKey(result)), "red");
return;
}
this.incoming = this.incoming.filter((r) => r.publicId !== publicId);
- this.friends = [
- { publicId, createdAt: new Date().toISOString() },
- ...this.friends,
- ];
- this.friendsTotal++;
+ await this.loadAll();
showToast(translateText("friends.request_accepted"), "green");
@@
private async handleRemove(publicId: string): Promise<void> {
@@
if (result !== true) {
showToast(translateText(this.errorKey(result)), "red");
return;
}
- this.friends = this.friends.filter((f) => f.publicId !== publicId);
- this.friendsTotal = Math.max(0, this.friendsTotal - 1);
+ await this.loadAll();
showToast(translateText("friends.friend_removed"), "green");Also applies to: 166-167
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@src/client/components/FriendsList.ts` around lines 117 - 123, After mutating
local lists (e.g., this.incoming, this.friends, this.friendsTotal) in the
accept/remove handlers, reset the component's pagination cache/state and
re-fetch the first page instead of only editing the local arrays to avoid later
duplicate/missing rows; specifically, after the local update (the block that
modifies this.incoming, this.friends and this.friendsTotal), clear whatever
pagination buffers you maintain (e.g., pages array, nextCursor/currentPage) and
invoke loadMore() (or a refreshFriends() helper) to reload from the server so
the client and paginated server state stay in sync.
Description:
Add Friends tab to Account modal
Summary
<friends-list>Lit component covering the full friend lifecycle: send request, accept / deny incoming, withdraw outgoing, remove friend, paginated list with "Load more".FriendsApi.tswrappingGET/POST/DELETE /friends*endpoints with typed error codes (not_found/conflict/bad_request/request_failed).core/ApiSchemas.ts.friends.*block inen.json.Friends and pending requests are displayed by public ID via
copy-button, matching the existing clan convention.Please complete the following:
Please put your Discord username so you can be contacted if a bug or regression is found:
evan