From 5ca5db7122c4e31ce169069061a5581405f14d28 Mon Sep 17 00:00:00 2001 From: Jannis Braun <151788261+TheZwiss@users.noreply.github.com> Date: Wed, 1 Apr 2026 01:25:26 +0200 Subject: [PATCH] refactor(web): extract federation section from GeneralPanel --- .../instanceSettingsPanels/GeneralPanel.tsx | 168 +----------------- 1 file changed, 2 insertions(+), 166 deletions(-) diff --git a/packages/web/src/components/modals/instanceSettingsPanels/GeneralPanel.tsx b/packages/web/src/components/modals/instanceSettingsPanels/GeneralPanel.tsx index a08a7262..0c1d9b60 100644 --- a/packages/web/src/components/modals/instanceSettingsPanels/GeneralPanel.tsx +++ b/packages/web/src/components/modals/instanceSettingsPanels/GeneralPanel.tsx @@ -1,22 +1,9 @@ -import { useState, useEffect, useCallback } from 'react'; +import { useState, useEffect } from 'react'; import { useSettingsStore } from '../../../stores/settingsStore'; import { useUIStore } from '../../../stores/uiStore'; import { Toggle } from '../../ui/Toggle'; -import { api } from '../../../api/client'; import type { InstanceAdminSettings } from '@backspace/shared'; -interface FederationPeer { - id: string; - origin: string; - instanceName: string | null; - status: string; - lastSeenAt: number | null; - lastFailureAt: number | null; - consecutiveFailures: number | null; - lastSyncedAt: number | null; - createdAt: number; -} - export function GeneralPanel() { const instanceSettings = useSettingsStore((s) => s.instanceSettings); const updateInstanceSettings = useSettingsStore((s) => s.updateInstanceSettings); @@ -29,11 +16,6 @@ export function GeneralPanel() { const [gifKeyDirty, setGifKeyDirty] = useState(false); const [gifKeyDraft, setGifKeyDraft] = useState(''); - // Federation peers state - const [peers, setPeers] = useState([]); - const [peersLoading, setPeersLoading] = useState(false); - const [revokingPeerId, setRevokingPeerId] = useState(null); - useEffect(() => { if (instanceSettings) { setDraft({ ...instanceSettings }); @@ -42,30 +24,12 @@ export function GeneralPanel() { } }, [instanceSettings]); - const fetchPeers = useCallback(async () => { - setPeersLoading(true); - try { - const result = await api.federation.peers(); - setPeers(result.peers); - } catch { - // Non-critical — peers list may fail on instances without federation routes - } finally { - setPeersLoading(false); - } - }, []); - - useEffect(() => { - fetchPeers(); - }, [fetchPeers]); - if (!draft) return
Loading settings...
; const baseChanges = instanceSettings && draft ? draft.instanceName !== instanceSettings.instanceName || draft.registrationOpen !== instanceSettings.registrationOpen || - draft.discoveryEnabled !== instanceSettings.discoveryEnabled || - draft.federationRelayEnabled !== instanceSettings.federationRelayEnabled || - draft.federationRelayTtlDays !== instanceSettings.federationRelayTtlDays + draft.discoveryEnabled !== instanceSettings.discoveryEnabled : false; const hasChanges = baseChanges || gifKeyDirty; @@ -77,8 +41,6 @@ export function GeneralPanel() { instanceName: draft!.instanceName, registrationOpen: draft!.registrationOpen, discoveryEnabled: draft!.discoveryEnabled, - federationRelayEnabled: draft!.federationRelayEnabled, - federationRelayTtlDays: draft!.federationRelayTtlDays, }; if (gifKeyDirty) { payload.gifApiKey = gifKeyDraft; @@ -101,44 +63,6 @@ export function GeneralPanel() { setSaveError(''); }; - const handleRevokePeer = async (peerId: string) => { - setRevokingPeerId(peerId); - try { - await api.federation.revokePeer(peerId); - setPeers((prev) => prev.filter((p) => p.id !== peerId)); - addToast('Peer revoked', 'success', 2000); - } catch (err) { - addToast(err instanceof Error ? err.message : 'Failed to revoke peer', 'warning', 3000); - } finally { - setRevokingPeerId(null); - } - }; - - const formatRelativeTime = (timestamp: number | null): string => { - if (!timestamp) return 'Never'; - const seconds = Math.floor((Date.now() - timestamp) / 1000); - if (seconds < 60) return 'Just now'; - const minutes = Math.floor(seconds / 60); - if (minutes < 60) return `${minutes}m ago`; - const hours = Math.floor(minutes / 60); - if (hours < 24) return `${hours}h ago`; - const days = Math.floor(hours / 24); - return `${days}d ago`; - }; - - const peerStatusColor = (status: string): string => { - switch (status) { - case 'active': return 'bg-status-online/15 text-status-online'; - case 'pending': return 'bg-accent-amber/15 text-accent-amber'; - case 'unreachable': return 'bg-accent-rose/15 text-txt-danger'; - case 'revoked': return 'bg-white/5 text-txt-tertiary'; - default: return 'bg-white/5 text-txt-tertiary'; - } - }; - - // Only show non-revoked peers - const visiblePeers = peers.filter((p) => p.status !== 'revoked'); - return (
e.preventDefault()}>

General

@@ -223,94 +147,6 @@ export function GeneralPanel() { - {/* Federation */} -
-
Federation
-

- Control DM relay between federated instances. When enabled, DMs with users on peer instances are relayed server-to-server. -

-
- - -
-
Relay TTL (days)
-
How long relayed messages are retained in the outbox before cleanup
- { - const val = parseInt(e.target.value, 10); - if (!isNaN(val) && val >= 1 && val <= 365) { - setDraft({ ...draft, federationRelayTtlDays: val }); - } - }} - className="input-standard w-24" - /> -
- - {/* Peers list */} -
-
-
Peered Instances
- -
- - {visiblePeers.length === 0 && !peersLoading && ( -
- No federation peers configured. Peers are created automatically when connecting to remote instances. -
- )} - - {visiblePeers.length > 0 && ( -
- {visiblePeers.map((peer) => ( -
-
-
- - {peer.instanceName || new URL(peer.origin).host} - - - {peer.status} - -
-
{peer.origin}
-
- Last seen: {formatRelativeTime(peer.lastSeenAt)} - {peer.lastSyncedAt ? ` · Synced: ${formatRelativeTime(peer.lastSyncedAt)}` : ''} -
-
- -
- ))} -
- )} -
-
-
- {/* Status messages */} {saveError && (
{saveError}