import AudioPlayer from '@/components/AudioPlayer' import { getMusicTrackFromEvent, musicTrackCaptionContent, musicTrackDisplayLine, musicTrackMetaLine } from '@/lib/music-track' import { primalR2aMirrorForBlossomPrimalUrl } from '@/lib/url' import { cn } from '@/lib/utils' import { useShouldAutoLoadMedia } from '@/hooks/useShouldAutoLoadMedia' import { Event } from 'nostr-tools' import { useMemo } from 'react' import { useTranslation } from 'react-i18next' import MarkdownArticle from './MarkdownArticle/MarkdownArticle' import MediaPlayer from '../MediaPlayer' /** Tags already shown on the music card — omit from caption markdown so they are not rendered twice. */ const MUSIC_TRACK_CAPTION_OMIT_TAGS = new Set([ 'd', 'title', 'artist', 'url', 'image', 'video', 'album', 'duration', 'format', 'language', 'track_number', 'released', 'explicit', 'alt', 'genre' ]) export default function MusicTrackNote({ event, className, loadMedia = false }: { event: Event className?: string loadMedia?: boolean }) { const autoLoadMedia = useShouldAutoLoadMedia(event.pubkey) const mustLoad = loadMedia || autoLoadMedia const { t } = useTranslation() const track = useMemo(() => getMusicTrackFromEvent(event), [event]) const metaLine = useMemo(() => (track ? musicTrackMetaLine(track) : ''), [track]) const caption = useMemo( () => (track ? musicTrackCaptionContent(event.content, track) : null), [event.content, track] ) const audioFallbackSrc = useMemo( () => (track ? primalR2aMirrorForBlossomPrimalUrl(track.audioUrl) ?? undefined : undefined), [track] ) const captionEvent = useMemo(() => { if (!caption) return null const tags = event.tags.filter(([name]) => !MUSIC_TRACK_CAPTION_OMIT_TAGS.has(name)) return { ...event, content: caption, tags } as Event }, [event, caption]) if (!track) { return (
{t('Invalid music track event', { defaultValue: 'Invalid music track event' })}
) } return ({track.title}
{track.artist ? ({track.artist}
) : null} {metaLine ? ({metaLine}
) : null}{t('Music video', { defaultValue: 'Music video' })}