feat: real-time Federation panel updates via WS events

Added federation_peers_changed (no-payload signal) broadcast from every
peer state mutation, and federation_approval_request_received when a new
approval request is queued. Client subscribes via onFederationPeersChanged
callback registry. FederationPanel and PendingApprovals debounce-refetch
on any event. sendToAdmins helper broadcasts only to admin users.
This commit is contained in:
Jannis Braun
2026-04-20 18:28:10 +02:00
parent 6afad97bd1
commit 3d8709d20a
7 changed files with 95 additions and 0 deletions
+24
View File
@@ -36,6 +36,18 @@ export function getActivePeerOrigins(): Set<string> {
return activePeerOrigins;
}
// ─── Federation change listeners (for real-time panel updates) ───────────────
const federationChangeListeners = new Set<() => void>();
export function onFederationPeersChanged(cb: () => void): () => void {
federationChangeListeners.add(cb);
return () => { federationChangeListeners.delete(cb); };
}
function notifyFederationChangeListeners(): void {
for (const cb of federationChangeListeners) cb();
}
// ─── Connection state ─────────────────────────────────────────────────────────
interface ConnectionState {
@@ -717,6 +729,7 @@ function handleEvent(origin: string, event: ServerEvent): void {
'warning',
10000,
);
notifyFederationChangeListeners();
break;
}
@@ -724,6 +737,17 @@ function handleEvent(origin: string, event: ServerEvent): void {
rejectedPeerOrigins.delete(event.peerOrigin);
awaitingApprovalPeerOrigins.delete(event.peerOrigin);
activePeerOrigins.add(event.peerOrigin);
notifyFederationChangeListeners();
break;
}
case 'federation_peers_changed': {
notifyFederationChangeListeners();
break;
}
case 'federation_approval_request_received': {
notifyFederationChangeListeners();
break;
}