feat: simplify external link display
This commit is contained in:
@@ -20,11 +20,11 @@ import {
|
|||||||
EmbeddedHashtag,
|
EmbeddedHashtag,
|
||||||
EmbeddedLNInvoice,
|
EmbeddedLNInvoice,
|
||||||
EmbeddedMention,
|
EmbeddedMention,
|
||||||
EmbeddedNormalUrl,
|
|
||||||
EmbeddedNote,
|
EmbeddedNote,
|
||||||
EmbeddedWebsocketUrl
|
EmbeddedWebsocketUrl
|
||||||
} from '../Embedded'
|
} from '../Embedded'
|
||||||
import Emoji from '../Emoji'
|
import Emoji from '../Emoji'
|
||||||
|
import ExternalLink from '../ExternalLink'
|
||||||
import ImageGallery from '../ImageGallery'
|
import ImageGallery from '../ImageGallery'
|
||||||
import MediaPlayer from '../MediaPlayer'
|
import MediaPlayer from '../MediaPlayer'
|
||||||
import WebPreview from '../WebPreview'
|
import WebPreview from '../WebPreview'
|
||||||
@@ -122,7 +122,7 @@ export default function Content({
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
if (node.type === 'url') {
|
if (node.type === 'url') {
|
||||||
return <EmbeddedNormalUrl url={node.data} key={index} />
|
return <ExternalLink url={node.data} key={index} />
|
||||||
}
|
}
|
||||||
if (node.type === 'invoice') {
|
if (node.type === 'invoice') {
|
||||||
return <EmbeddedLNInvoice invoice={node.data} key={index} className="mt-2" />
|
return <EmbeddedLNInvoice invoice={node.data} key={index} className="mt-2" />
|
||||||
|
|||||||
@@ -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>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
@@ -1,6 +1,5 @@
|
|||||||
export * from './EmbeddedHashtag'
|
export * from './EmbeddedHashtag'
|
||||||
export * from './EmbeddedLNInvoice'
|
export * from './EmbeddedLNInvoice'
|
||||||
export * from './EmbeddedMention'
|
export * from './EmbeddedMention'
|
||||||
export * from './EmbeddedNormalUrl'
|
|
||||||
export * from './EmbeddedNote'
|
export * from './EmbeddedNote'
|
||||||
export * from './EmbeddedWebsocketUrl'
|
export * from './EmbeddedWebsocketUrl'
|
||||||
|
|||||||
@@ -1,6 +1,9 @@
|
|||||||
import { cn } from '@/lib/utils'
|
import { cn } from '@/lib/utils'
|
||||||
|
import { useMemo } from 'react'
|
||||||
|
|
||||||
export default function ExternalLink({ url, className }: { url: string; className?: string }) {
|
export default function ExternalLink({ url, className }: { url: string; className?: string }) {
|
||||||
|
const displayUrl = useMemo(() => getDisplayUrl(url), [url])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<a
|
<a
|
||||||
className={cn('text-primary hover:underline', className)}
|
className={cn('text-primary hover:underline', className)}
|
||||||
@@ -8,8 +11,35 @@ export default function ExternalLink({ url, className }: { url: string; classNam
|
|||||||
target="_blank"
|
target="_blank"
|
||||||
onClick={(e) => e.stopPropagation()}
|
onClick={(e) => e.stopPropagation()}
|
||||||
rel="noreferrer"
|
rel="noreferrer"
|
||||||
|
title={url}
|
||||||
>
|
>
|
||||||
{url}
|
{displayUrl}
|
||||||
</a>
|
</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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -10,12 +10,8 @@ import { useTranslationService } from '@/providers/TranslationServiceProvider'
|
|||||||
import { useMemo, useState } from 'react'
|
import { useMemo, useState } from 'react'
|
||||||
import { useTranslation } from 'react-i18next'
|
import { useTranslation } from 'react-i18next'
|
||||||
import { toast } from 'sonner'
|
import { toast } from 'sonner'
|
||||||
import {
|
import { EmbeddedHashtag, EmbeddedMention, EmbeddedWebsocketUrl } from '../Embedded'
|
||||||
EmbeddedHashtag,
|
import ExternalLink from '../ExternalLink'
|
||||||
EmbeddedMention,
|
|
||||||
EmbeddedNormalUrl,
|
|
||||||
EmbeddedWebsocketUrl
|
|
||||||
} from '../Embedded'
|
|
||||||
|
|
||||||
export default function ProfileAbout({ about, className }: { about?: string; className?: string }) {
|
export default function ProfileAbout({ about, className }: { about?: string; className?: string }) {
|
||||||
const { t, i18n } = useTranslation()
|
const { t, i18n } = useTranslation()
|
||||||
@@ -39,7 +35,7 @@ export default function ProfileAbout({ about, className }: { about?: string; cla
|
|||||||
])
|
])
|
||||||
return nodes.map((node, index) => {
|
return nodes.map((node, index) => {
|
||||||
if (node.type === 'url') {
|
if (node.type === 'url') {
|
||||||
return <EmbeddedNormalUrl key={index} url={node.data} />
|
return <ExternalLink key={index} url={node.data} />
|
||||||
}
|
}
|
||||||
if (node.type === 'websocket-url') {
|
if (node.type === 'websocket-url') {
|
||||||
return <EmbeddedWebsocketUrl key={index} url={node.data} />
|
return <EmbeddedWebsocketUrl key={index} url={node.data} />
|
||||||
|
|||||||
Reference in New Issue
Block a user