feat: federate friends/social system across connected instances

Rewrites socialStore to aggregate friends and requests from all connected
instances using Promise.allSettled. Parses user@domain in friend requests
to route to the correct instance. Removes !isHome guards on social WS
events so remote friend requests arrive in real-time. Shows "via hostname"
labels on remote friends/requests in the UI.
This commit is contained in:
Jannis Braun
2026-03-04 17:28:28 +01:00
parent c7c3331dbf
commit 72d1fab930
4 changed files with 234 additions and 47 deletions
+27 -7
View File
@@ -316,26 +316,23 @@ function handleEvent(origin: string, event: ServerEvent): void {
onReactionRemoved(event.messageId, event.userId, event.emoji);
break;
// ─── Social events (home-only) ──────────────────────────────────────────
// ─── Social events (all origins — federation) ──────────────────────────
case 'friend_request_received': {
if (!isHome) break;
const { addIncomingRequest } = useSocialStore.getState();
addIncomingRequest(event.request);
addIncomingRequest(event.request, origin);
break;
}
case 'friend_request_accepted': {
if (!isHome) break;
const { addFriendFromAccepted } = useSocialStore.getState();
addFriendFromAccepted(event.friend, event.requestId);
addFriendFromAccepted(event.friend, event.requestId, origin);
break;
}
case 'friend_removed': {
if (!isHome) break;
const { removeFriendLocally } = useSocialStore.getState();
removeFriendLocally(event.userId);
removeFriendLocally(event.userId, origin);
break;
}
@@ -481,6 +478,29 @@ function handleEvent(origin: string, event: ServerEvent): void {
break;
}
// ─── Join request events (home-only) ────────────────────────────────
case 'join_request_received': {
if (!isHome) break;
console.log('[WebSocket] Join request received from', event.request.user?.username ?? event.request.userId);
break;
}
case 'join_request_accepted': {
if (!isHome) break;
// Add the server to our server list
const { addServerFromReady } = useServerStore.getState();
addServerFromReady(origin, event.server);
console.log('[WebSocket] Join request accepted for server', event.server.name);
break;
}
case 'join_request_declined': {
if (!isHome) break;
console.log('[WebSocket] Join request declined for server', event.request.serverId);
break;
}
case 'pong':
break;