Files
boris/src/components/HighlightItem.tsx
2025-10-05 22:50:20 +01:00

112 lines
3.4 KiB
TypeScript

import React, { useEffect, useRef } from 'react'
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
import { faQuoteLeft, faExternalLinkAlt } from '@fortawesome/free-solid-svg-icons'
import { Highlight } from '../types/highlights'
import { formatDistanceToNow } from 'date-fns'
import { useEventModel } from 'applesauce-react/hooks'
import { Models } from 'applesauce-core'
interface HighlightWithLevel extends Highlight {
level?: 'mine' | 'friends' | 'nostrverse'
}
interface HighlightItemProps {
highlight: HighlightWithLevel
onSelectUrl?: (url: string) => void
isSelected?: boolean
onHighlightClick?: (highlightId: string) => void
}
export const HighlightItem: React.FC<HighlightItemProps> = ({ highlight, onSelectUrl, isSelected, onHighlightClick }) => {
const itemRef = useRef<HTMLDivElement>(null)
// Resolve the profile of the user who made the highlight
const profile = useEventModel(Models.ProfileModel, [highlight.pubkey])
// Get display name for the user
const getUserDisplayName = () => {
if (profile?.name) return profile.name
if (profile?.display_name) return profile.display_name
return `${highlight.pubkey.slice(0, 8)}...` // fallback to short pubkey
}
useEffect(() => {
if (isSelected && itemRef.current) {
itemRef.current.scrollIntoView({ behavior: 'smooth', block: 'center' })
}
}, [isSelected])
const handleItemClick = () => {
if (onHighlightClick) {
onHighlightClick(highlight.id)
}
}
const handleLinkClick = (url: string, e: React.MouseEvent) => {
if (onSelectUrl) {
e.preventDefault()
onSelectUrl(url)
}
}
const getSourceLink = () => {
if (highlight.eventReference) {
return `https://search.dergigi.com/e/${highlight.eventReference}`
}
return highlight.urlReference
}
const sourceLink = getSourceLink()
return (
<div
ref={itemRef}
className={`highlight-item ${isSelected ? 'selected' : ''} ${highlight.level ? `level-${highlight.level}` : ''}`}
data-highlight-id={highlight.id}
onClick={handleItemClick}
style={{ cursor: onHighlightClick ? 'pointer' : 'default' }}
>
<div className="highlight-quote-icon">
<FontAwesomeIcon icon={faQuoteLeft} />
</div>
<div className="highlight-content">
<blockquote className="highlight-text">
{highlight.content}
</blockquote>
{highlight.comment && (
<div className="highlight-comment">
{highlight.comment}
</div>
)}
<div className="highlight-meta">
<span className="highlight-author">
{getUserDisplayName()}
</span>
<span className="highlight-meta-separator"></span>
<span className="highlight-time">
{formatDistanceToNow(new Date(highlight.created_at * 1000), { addSuffix: true })}
</span>
{sourceLink && (
<a
href={sourceLink}
target="_blank"
rel="noopener noreferrer"
onClick={(e) => highlight.urlReference && onSelectUrl ? handleLinkClick(highlight.urlReference, e) : undefined}
className="highlight-source"
title={highlight.eventReference ? 'Open on Nostr' : 'Open source'}
>
<FontAwesomeIcon icon={faExternalLinkAlt} />
</a>
)}
</div>
</div>
</div>
)
}