/* eslint-disable @typescript-eslint/no-unsafe-call */ import htmlTruncate from 'html-truncate' import Markdown from 'react-markdown' import rehypeRaw from 'rehype-raw' import remarkBreaks from 'remark-breaks' import remarkGfm from 'remark-gfm' import remarkParse from 'remark-parse' import remarkRehype from 'remark-rehype' import rehypeStringify from 'rehype-stringify' import { unified } from 'unified' import { useAddFilterTag } from '#components/Map/hooks/useFilter' import { useTags } from '#components/Map/hooks/useTags' import { decodeTag } from '#utils/FormatTags' import type { Item } from '#types/Item' export const TextPreview = ({ item }: { item: Item }) => { if (!item.text) return null // Convert Markdown to HTML and truncate with awareness of markup const html = unified() .use(remarkParse) .use(remarkGfm) .use(remarkBreaks) .use(remarkRehype, { allowDangerousHtml: true }) .use(rehypeRaw) .use(rehypeStringify, { allowDangerousHtml: true }) .processSync(item.text) .toString() // decrease heading levels similar to previous Markdown manipulation const withSmallHeadings = html.replace(/<(\/?)h([1-6])/g, (_m, slash, level) => { const newLevel = Math.min(6, Number(level) + 2) return `<${slash}h${newLevel}` }) // Text auf ~100 Zeichen stutzen (inkl. Ellipse „…“) const previewRaw = htmlTruncate(withSmallHeadings, 100, { ellipsis: '…', reserveLastWord: true, }) return (
{previewRaw}
) } export const HashTag = ({ tag }: { tag: string }) => { const tags = useTags() const t = tags.find((t) => t.name === tag.slice(1)) const addFilterTag = useAddFilterTag() if (!t) return {tag} return ( { e.stopPropagation() addFilterTag(t) }} > {decodeTag(tag)} ) } export const Span = (node) => { if (node['data-type'] === 'mention') { return } return {node.children} }