You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
105 lines
2.5 KiB
105 lines
2.5 KiB
<script lang="ts"> |
|
import { goto } from '$app/navigation'; |
|
|
|
interface Props { |
|
relayUrl: string; |
|
clickable?: boolean; // If true, make badge clickable to navigate to relay feed |
|
} |
|
|
|
let { relayUrl, clickable = true }: Props = $props(); |
|
|
|
function getRelayDomain(url: string): string { |
|
try { |
|
// Remove protocol (wss://, ws://, https://, http://) |
|
const withoutProtocol = url.replace(/^wss?:\/\//, '').replace(/^https?:\/\//, ''); |
|
// Remove port if present |
|
const domain = withoutProtocol.split(':')[0]; |
|
// Remove path if present |
|
return domain.split('/')[0]; |
|
} catch { |
|
return url; |
|
} |
|
} |
|
|
|
function handleClick(e: MouseEvent) { |
|
if (clickable) { |
|
e.stopPropagation(); |
|
const domain = getRelayDomain(relayUrl); |
|
goto(`/feed/relay/${encodeURIComponent(domain)}`); |
|
} |
|
} |
|
|
|
const displayName = $derived(getRelayDomain(relayUrl)); |
|
</script> |
|
|
|
{#if clickable} |
|
<button |
|
type="button" |
|
class="relay-badge clickable" |
|
onclick={handleClick} |
|
title={`View feed from ${displayName}`} |
|
> |
|
{displayName} |
|
</button> |
|
{:else} |
|
<span |
|
class="relay-badge" |
|
title={displayName} |
|
> |
|
{displayName} |
|
</span> |
|
{/if} |
|
|
|
<style> |
|
.relay-badge { |
|
display: inline-flex; |
|
align-items: center; |
|
padding: 0.25rem 0.5rem; |
|
font-size: 0.75rem; |
|
font-weight: 500; |
|
color: var(--fog-text-light, #52667a); |
|
background: var(--fog-highlight, #f3f4f6); |
|
border: 1px solid var(--fog-border, #e5e7eb); |
|
border-radius: 0.25rem; |
|
font-family: monospace; |
|
} |
|
|
|
:global(.dark) .relay-badge { |
|
color: var(--fog-dark-text-light, #a8b8d0); |
|
background: var(--fog-dark-highlight, #374151); |
|
border-color: var(--fog-dark-border, #475569); |
|
} |
|
|
|
.relay-badge.clickable { |
|
cursor: pointer; |
|
transition: all 0.2s; |
|
} |
|
|
|
.relay-badge.clickable:hover { |
|
background: var(--fog-accent, #64748b); |
|
color: white; |
|
border-color: var(--fog-accent, #64748b); |
|
transform: translateY(-1px); |
|
} |
|
|
|
:global(.dark) .relay-badge.clickable:hover { |
|
background: var(--fog-dark-accent, #94a3b8); |
|
color: var(--fog-dark-text, #1f2937); |
|
border-color: var(--fog-dark-accent, #94a3b8); |
|
} |
|
|
|
.relay-badge.clickable:focus { |
|
outline: none; |
|
box-shadow: 0 0 0 2px var(--fog-accent, #64748b); |
|
} |
|
|
|
:global(.dark) .relay-badge.clickable:focus { |
|
box-shadow: 0 0 0 2px var(--fog-dark-accent, #94a3b8); |
|
} |
|
|
|
button.relay-badge { |
|
font-family: inherit; |
|
font-size: inherit; |
|
line-height: inherit; |
|
} |
|
</style>
|
|
|