feat: simplify external link display

This commit is contained in:
codytseng
2025-10-17 22:37:09 +08:00
parent f23493742b
commit 21663711f8
5 changed files with 36 additions and 24 deletions

View File

@@ -20,11 +20,11 @@ import {
EmbeddedHashtag,
EmbeddedLNInvoice,
EmbeddedMention,
EmbeddedNormalUrl,
EmbeddedNote,
EmbeddedWebsocketUrl
} from '../Embedded'
import Emoji from '../Emoji'
import ExternalLink from '../ExternalLink'
import ImageGallery from '../ImageGallery'
import MediaPlayer from '../MediaPlayer'
import WebPreview from '../WebPreview'
@@ -122,7 +122,7 @@ export default function Content({
)
}
if (node.type === 'url') {
return <EmbeddedNormalUrl url={node.data} key={index} />
return <ExternalLink url={node.data} key={index} />
}
if (node.type === 'invoice') {
return <EmbeddedLNInvoice invoice={node.data} key={index} className="mt-2" />

View File

@@ -1,13 +0,0 @@
export function EmbeddedNormalUrl({ url }: { url: string }) {
return (
<a
className="text-primary hover:underline"
href={url}
target="_blank"
onClick={(e) => e.stopPropagation()}
rel="noreferrer"
>
{url}
</a>
)
}

View File

@@ -1,6 +1,5 @@
export * from './EmbeddedHashtag'
export * from './EmbeddedLNInvoice'
export * from './EmbeddedMention'
export * from './EmbeddedNormalUrl'
export * from './EmbeddedNote'
export * from './EmbeddedWebsocketUrl'

View File

@@ -1,6 +1,9 @@
import { cn } from '@/lib/utils'
import { useMemo } from 'react'
export default function ExternalLink({ url, className }: { url: string; className?: string }) {
const displayUrl = useMemo(() => getDisplayUrl(url), [url])
return (
<a
className={cn('text-primary hover:underline', className)}
@@ -8,8 +11,35 @@ export default function ExternalLink({ url, className }: { url: string; classNam
target="_blank"
onClick={(e) => e.stopPropagation()}
rel="noreferrer"
title={url}
>
{url}
{displayUrl}
</a>
)
}
const getDisplayUrl = (url: string, maxLength: number = 30) => {
try {
const urlObj = new URL(url)
let domain = urlObj.hostname
const path = urlObj.pathname
if (domain.startsWith('www.')) {
domain = domain.slice(4)
}
if (!path || path === '/') {
return domain
}
const displayUrl = domain + path
if (displayUrl.length > maxLength) {
return domain + path.slice(0, maxLength - domain.length - 3) + '...'
}
return displayUrl
} catch {
return url
}
}

View File

@@ -10,12 +10,8 @@ import { useTranslationService } from '@/providers/TranslationServiceProvider'
import { useMemo, useState } from 'react'
import { useTranslation } from 'react-i18next'
import { toast } from 'sonner'
import {
EmbeddedHashtag,
EmbeddedMention,
EmbeddedNormalUrl,
EmbeddedWebsocketUrl
} from '../Embedded'
import { EmbeddedHashtag, EmbeddedMention, EmbeddedWebsocketUrl } from '../Embedded'
import ExternalLink from '../ExternalLink'
export default function ProfileAbout({ about, className }: { about?: string; className?: string }) {
const { t, i18n } = useTranslation()
@@ -39,7 +35,7 @@ export default function ProfileAbout({ about, className }: { about?: string; cla
])
return nodes.map((node, index) => {
if (node.type === 'url') {
return <EmbeddedNormalUrl key={index} url={node.data} />
return <ExternalLink key={index} url={node.data} />
}
if (node.type === 'websocket-url') {
return <EmbeddedWebsocketUrl key={index} url={node.data} />