You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

83 lines
3.3 KiB

import { ExtendedKind, isMusicTrackKind, isNip71StyleVideoKind } from '@/constants'
import { getMusicTrackFromEvent, musicTrackDisplayLine } from '@/lib/music-track'
import {
getLiveEventMetadataFromEvent,
getLongFormArticleMetadataFromEvent
} from '@/lib/event-metadata'
import { tagNameEquals } from '@/lib/tag'
import { stripTrailingStringifiedNostrEvent } from '@/lib/nostr-event-json'
import { Event, kinds } from 'nostr-tools'
export const PARENT_REPLY_BLURB_MAX = 150
/** Strip common markdown / asciidoc / HTML so parent reply strips stay one line (matches NotePage preview). */
export function stripMarkupForPreview(content: string): string {
let text = stripTrailingStringifiedNostrEvent(content)
text = text.replace(/^#{1,6}\s+/gm, '')
text = text.replace(/\*\*([^*]+)\*\*/g, '$1')
text = text.replace(/\*([^*]+)\*/g, '$1')
text = text.replace(/\[([^\]]+)\]\([^)]+\)/g, '$1')
text = text.replace(/^=+\s+/gm, '')
text = text.replace(/_([^_]+)_/g, '$1')
text = text.replace(/```[\s\S]*?```/g, '')
text = text.replace(/`([^`]+)`/g, '$1')
text = text.replace(/<[^>]+>/g, '')
text = text.replace(/\n{3,}/g, '\n\n')
return text.trim()
}
function truncateBlurb(s: string, max: number): string {
const normalized = s.trim().replace(/\s+/g, ' ')
if (normalized.length <= max) return normalized
return `${normalized.slice(0, max)}`
}
/**
* One-line preview for {@link ParentNotePreview}: prefer `title` / `subject` / kind metadata, else first
* {@link PARENT_REPLY_BLURB_MAX} characters of markup-stripped `content`.
*/
export function getParentReplyBlurbDisplayText(
event: Event,
maxLen: number = PARENT_REPLY_BLURB_MAX
): string {
const titleTag = event.tags.find(tagNameEquals('title'))?.[1]?.trim()
if (titleTag) return truncateBlurb(stripMarkupForPreview(titleTag), maxLen)
const subjectTag = event.tags.find(tagNameEquals('subject'))?.[1]?.trim()
if (subjectTag) return truncateBlurb(stripMarkupForPreview(subjectTag), maxLen)
if (
event.kind === kinds.LongFormArticle ||
event.kind === ExtendedKind.PUBLICATION ||
event.kind === ExtendedKind.PUBLICATION_CONTENT
) {
const meta = getLongFormArticleMetadataFromEvent(event)
if (meta.title?.trim()) return truncateBlurb(stripMarkupForPreview(meta.title.trim()), maxLen)
if (meta.summary?.trim()) {
return truncateBlurb(stripMarkupForPreview(meta.summary), maxLen)
}
}
if (event.kind === kinds.LiveEvent || event.kind === 30312 || event.kind === 30313) {
const live = getLiveEventMetadataFromEvent(event)
const rawTitle = live.title?.trim()
if (rawTitle && rawTitle !== 'no title') return truncateBlurb(stripMarkupForPreview(rawTitle), maxLen)
if (live.summary?.trim()) return truncateBlurb(stripMarkupForPreview(live.summary), maxLen)
}
if (isMusicTrackKind(event.kind)) {
const track = getMusicTrackFromEvent(event)
if (track) return truncateBlurb(musicTrackDisplayLine(track), maxLen)
}
if (event.kind === ExtendedKind.PICTURE || isNip71StyleVideoKind(event.kind)) {
const cap = truncateBlurb(stripMarkupForPreview(event.content ?? ''), maxLen)
return cap
}
return truncateBlurb(stripMarkupForPreview(event.content ?? ''), maxLen)
}
export function parentReplyPollQuestionBlurb(content: string, maxLen = PARENT_REPLY_BLURB_MAX): string {
return truncateBlurb(stripMarkupForPreview(content ?? ''), maxLen)
}