mirror of
https://github.com/dergigi/boris.git
synced 2026-01-24 09:14:39 +01:00
feat(ui): resolve nprofile/npub mentions to names in content
- Add ResolvedMention component using applesauce ProfileModel - Update parsed content renderer to use ResolvedMention for mentions - Mentions now show @name and link to search page
This commit is contained in:
42
src/components/ResolvedMention.tsx
Normal file
42
src/components/ResolvedMention.tsx
Normal file
@@ -0,0 +1,42 @@
|
||||
import React from 'react'
|
||||
import { useEventModel } from 'applesauce-react/hooks'
|
||||
import { Models } from 'applesauce-core'
|
||||
import { decode, npubEncode } from 'nostr-tools/nip19'
|
||||
import { getPubkeyFromDecodeResult } from 'applesauce-core/helpers'
|
||||
|
||||
interface ResolvedMentionProps {
|
||||
encoded?: string
|
||||
}
|
||||
|
||||
const ResolvedMention: React.FC<ResolvedMentionProps> = ({ encoded }) => {
|
||||
if (!encoded) return null
|
||||
let pubkey: string | undefined
|
||||
try {
|
||||
pubkey = getPubkeyFromDecodeResult(decode(encoded))
|
||||
} catch {
|
||||
// ignore; will fallback to showing the encoded value
|
||||
}
|
||||
|
||||
const profile = pubkey ? useEventModel(Models.ProfileModel, [pubkey]) : undefined
|
||||
const display = profile?.name || profile?.display_name || profile?.nip05 || (pubkey ? `${pubkey.slice(0, 8)}...` : encoded)
|
||||
const npub = pubkey ? npubEncode(pubkey) : undefined
|
||||
|
||||
if (npub) {
|
||||
return (
|
||||
<a
|
||||
href={`https://search.dergigi.com/p/${npub}`}
|
||||
className="nostr-mention"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
@{display}
|
||||
</a>
|
||||
)
|
||||
}
|
||||
|
||||
return <span className="nostr-mention">{encoded}</span>
|
||||
}
|
||||
|
||||
export default ResolvedMention
|
||||
|
||||
|
||||
@@ -1,13 +1,14 @@
|
||||
import React from 'react'
|
||||
import { ParsedContent, ParsedNode } from '../types/bookmarks'
|
||||
import { ContentWithResolvedProfiles } from '../components/ContentWithResolvedProfiles'
|
||||
import ResolvedMention from '../components/ResolvedMention'
|
||||
// Note: ContentWithResolvedProfiles is imported by components directly to keep this file component-only for fast refresh
|
||||
|
||||
export const formatDate = (timestamp: number) => {
|
||||
return new Date(timestamp * 1000).toLocaleDateString()
|
||||
}
|
||||
|
||||
// Component to render content with resolved nprofile names
|
||||
export { default as ContentWithResolvedProfiles } from '../components/ContentWithResolvedProfiles'
|
||||
// Intentionally no exports except components and render helpers
|
||||
|
||||
// Component to render parsed content using applesauce-content
|
||||
export const renderParsedContent = (parsedContent: ParsedContent) => {
|
||||
@@ -21,17 +22,7 @@ export const renderParsedContent = (parsedContent: ParsedContent) => {
|
||||
}
|
||||
|
||||
if (node.type === 'mention') {
|
||||
return (
|
||||
<a
|
||||
key={index}
|
||||
href={`nostr:${node.encoded}`}
|
||||
className="nostr-mention"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
{node.encoded}
|
||||
</a>
|
||||
)
|
||||
return <ResolvedMention key={index} encoded={node.encoded} />
|
||||
}
|
||||
|
||||
if (node.type === 'link') {
|
||||
|
||||
Reference in New Issue
Block a user