refactor: improve relay list display with airplane icons

- Remove separate 'Offline' section, show all relays in one list
- Local relays always shown first (sorted to top)
- Local relays use airplane icon instead of checkmark
- Airplane icon is green when connected, red when offline
- Remote relays use green checkmark (connected) or red dot (offline)
- Last seen timestamp shown only for disconnected relays
- Simplified layout for better readability
This commit is contained in:
Gigi
2025-10-09 13:31:09 +01:00
parent d090b953bf
commit b511d40375

View File

@@ -11,9 +11,6 @@ interface RelaySettingsProps {
}
const RelaySettings: React.FC<RelaySettingsProps> = ({ relayStatuses }) => {
const activeRelays = relayStatuses.filter(r => r.isInPool)
const recentRelays = relayStatuses.filter(r => !r.isInPool)
const formatRelayUrl = (url: string) => {
return url.replace(/^wss?:\/\//, '').replace(/\/$/, '')
}
@@ -26,150 +23,109 @@ const RelaySettings: React.FC<RelaySettingsProps> = ({ relayStatuses }) => {
}
}
// Sort relays: local relays first, then by connection status, then by URL
const sortedRelays = [...relayStatuses].sort((a, b) => {
const aIsLocal = isLocalRelay(a.url)
const bIsLocal = isLocalRelay(b.url)
// Local relays always first
if (aIsLocal && !bIsLocal) return -1
if (!aIsLocal && bIsLocal) return 1
// Within local or remote groups, connected before disconnected
if (a.isInPool !== b.isInPool) return a.isInPool ? -1 : 1
// Finally sort by URL
return a.url.localeCompare(b.url)
})
const getRelayIcon = (relay: RelayStatus) => {
const isLocal = isLocalRelay(relay.url)
const isConnected = relay.isInPool
if (isLocal) {
return {
icon: faPlane,
color: isConnected ? '#22c55e' : '#ef4444',
size: '1rem'
}
} else {
if (isConnected) {
return {
icon: faCheckCircle,
color: '#22c55e',
size: '1rem'
}
} else {
return {
icon: faCircle,
color: '#ef4444',
size: '0.7rem'
}
}
}
}
return (
<div className="settings-section">
<h3>Relays</h3>
{activeRelays.length > 0 && (
<div className="relay-group" style={{ marginBottom: '1.5rem' }}>
<div className="relay-list">
{activeRelays.map((relay) => (
<div
key={relay.url}
className="relay-item"
style={{
display: 'flex',
alignItems: 'center',
gap: '0.75rem',
padding: '0.75rem',
background: 'var(--surface-secondary)',
borderRadius: '6px',
marginBottom: '0.5rem'
}}
>
<FontAwesomeIcon
icon={faCheckCircle}
style={{
color: 'var(--success, #22c55e)',
fontSize: '1rem'
}}
/>
<div style={{ flex: 1, minWidth: 0 }}>
<div style={{
fontSize: '0.9rem',
fontFamily: 'var(--font-mono, monospace)',
whiteSpace: 'nowrap',
overflow: 'hidden',
textOverflow: 'ellipsis',
display: 'flex',
alignItems: 'center',
gap: '0.5rem'
}}>
{formatRelayUrl(relay.url)}
{isLocalRelay(relay.url) && (
<span
title="Local relay"
style={{
display: 'inline-flex',
alignItems: 'center',
padding: '0.15rem 0.4rem',
background: 'rgba(245, 158, 11, 0.15)',
borderRadius: '4px',
color: '#f59e0b',
fontSize: '0.75rem',
flexShrink: 0
}}
>
<FontAwesomeIcon icon={faPlane} />
</span>
)}
</div>
</div>
</div>
))}
</div>
</div>
)}
{recentRelays.length > 0 && (
{sortedRelays.length > 0 && (
<div className="relay-group">
<h4 style={{
fontSize: '0.85rem',
fontWeight: 600,
color: '#ef4444',
marginBottom: '0.75rem',
textTransform: 'uppercase',
letterSpacing: '0.05em'
}}>
Offline
</h4>
<div className="relay-list">
{recentRelays.map((relay) => (
<div
key={relay.url}
className="relay-item"
style={{
display: 'flex',
alignItems: 'center',
gap: '0.75rem',
padding: '0.75rem',
background: 'var(--surface-secondary)',
borderRadius: '6px',
marginBottom: '0.5rem',
opacity: 0.7
}}
>
<FontAwesomeIcon
icon={faCircle}
style={{
color: '#ef4444',
fontSize: '0.7rem'
}}
/>
<div style={{ flex: 1, minWidth: 0 }}>
<div style={{
fontSize: '0.9rem',
fontFamily: 'var(--font-mono, monospace)',
whiteSpace: 'nowrap',
overflow: 'hidden',
textOverflow: 'ellipsis',
{sortedRelays.map((relay) => {
const iconConfig = getRelayIcon(relay)
const isDisconnected = !relay.isInPool
return (
<div
key={relay.url}
className="relay-item"
style={{
display: 'flex',
alignItems: 'center',
gap: '0.5rem'
}}>
{formatRelayUrl(relay.url)}
{isLocalRelay(relay.url) && (
<span
title="Local relay"
style={{
display: 'inline-flex',
alignItems: 'center',
padding: '0.15rem 0.4rem',
background: 'rgba(245, 158, 11, 0.15)',
borderRadius: '4px',
color: '#f59e0b',
fontSize: '0.75rem',
flexShrink: 0
}}
>
<FontAwesomeIcon icon={faPlane} />
</span>
)}
gap: '0.75rem',
padding: '0.75rem',
background: 'var(--surface-secondary)',
borderRadius: '6px',
marginBottom: '0.5rem',
opacity: isDisconnected ? 0.7 : 1
}}
>
<FontAwesomeIcon
icon={iconConfig.icon}
style={{
color: iconConfig.color,
fontSize: iconConfig.size
}}
/>
<div style={{ flex: 1, minWidth: 0 }}>
<div style={{
fontSize: '0.9rem',
fontFamily: 'var(--font-mono, monospace)',
whiteSpace: 'nowrap',
overflow: 'hidden',
textOverflow: 'ellipsis'
}}>
{formatRelayUrl(relay.url)}
</div>
</div>
{isDisconnected && (
<div style={{
display: 'flex',
alignItems: 'center',
gap: '0.5rem',
fontSize: '0.8rem',
color: 'var(--text-tertiary)',
whiteSpace: 'nowrap'
}}>
<FontAwesomeIcon icon={faClock} />
{formatLastSeen(relay.lastSeen)}
</div>
)}
</div>
<div style={{
display: 'flex',
alignItems: 'center',
gap: '0.5rem',
fontSize: '0.8rem',
color: 'var(--text-tertiary)',
whiteSpace: 'nowrap'
}}>
<FontAwesomeIcon icon={faClock} />
{formatLastSeen(relay.lastSeen)}
</div>
</div>
))}
)
})}
</div>
</div>
)}