mirror of
https://github.com/utopia-os/utopia-ui.git
synced 2025-12-13 07:46:10 +00:00
added hashtags
This commit is contained in:
parent
66231a5022
commit
ad7fee9ad6
@ -1,19 +1,98 @@
|
||||
import { RichTextEditor } from '#components/Input/RichTextEditor/RichTextEditor'
|
||||
import { fixUrls, mailRegex } from '#utils/ReplaceURLs'
|
||||
/* eslint-disable @typescript-eslint/no-unsafe-call */
|
||||
import truncate from 'markdown-truncate'
|
||||
import Markdown from 'react-markdown'
|
||||
import rehypeRaw from 'rehype-raw'
|
||||
import remarkBreaks from 'remark-breaks'
|
||||
import remarkGfm from 'remark-gfm'
|
||||
|
||||
import { useAddFilterTag } from '#components/Map/hooks/useFilter'
|
||||
import { useGetItemTags, useTags } from '#components/Map/hooks/useTags'
|
||||
import { decodeTag } from '#utils/FormatTags'
|
||||
|
||||
import type { Item } from '#types/Item'
|
||||
|
||||
export const TextPreview = ({ item }: { item: Item }) => {
|
||||
let replacedText = ''
|
||||
const getItemTags = useGetItemTags()
|
||||
|
||||
if (!item.text) return null
|
||||
else replacedText = fixUrls(item.text)
|
||||
// Text auf ~100 Zeichen stutzen (inkl. Ellipse „…“)
|
||||
const previewRaw = truncate(
|
||||
removeGfmTables(convertImgTagsToMarkdown(removeMentionSpans(removeHashtags(item.text)))),
|
||||
{
|
||||
limit: 150,
|
||||
ellipsis: true,
|
||||
},
|
||||
) as string
|
||||
|
||||
if (replacedText) {
|
||||
replacedText = replacedText.replace(mailRegex, (url) => {
|
||||
return `[${url}](mailto:${url})`
|
||||
})
|
||||
}
|
||||
const withExtraHashes = previewRaw.replace(
|
||||
/^(#{1,6})\s/gm,
|
||||
(_match: string, hashes: string): string => `${hashes}## `,
|
||||
)
|
||||
|
||||
return <RichTextEditor defaultValue={replacedText} readOnly={true} />
|
||||
return (
|
||||
<div className='markdown'>
|
||||
<Markdown remarkPlugins={[remarkBreaks, remarkGfm]} rehypePlugins={[rehypeRaw]}>
|
||||
{withExtraHashes}
|
||||
</Markdown>
|
||||
{getItemTags(item).map((tag) => (
|
||||
<HashTag tag={tag} key={tag} />
|
||||
))}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export const HashTag = ({ tag }: { tag: Tag }) => {
|
||||
const tags = useTags()
|
||||
const t = tags.find((t) => t.name.toLocaleLowerCase() === tag.name.toLocaleLowerCase())
|
||||
const addFilterTag = useAddFilterTag()
|
||||
if (!t) return null
|
||||
return (
|
||||
<a
|
||||
className='hashtag'
|
||||
style={{ color: t.color }}
|
||||
key={`${t.name}`}
|
||||
onClick={(e) => {
|
||||
e.stopPropagation()
|
||||
addFilterTag(t)
|
||||
}}
|
||||
>
|
||||
{`#${decodeTag(tag.name)} `}
|
||||
</a>
|
||||
)
|
||||
}
|
||||
|
||||
export function removeMentionSpans(html: string): string {
|
||||
const mentionSpanRegex =
|
||||
/<span\b(?=[^>]*\bdata-type="mention")(?=[^>]*\bclass="mention")[^>]*>[\s\S]*?<\/span>/gi
|
||||
return html.replace(mentionSpanRegex, '')
|
||||
}
|
||||
|
||||
export function removeHashtags(input: string): string {
|
||||
const hashtagRegex = /(^|\s)(?!#{1,6}\s)(#[A-Za-z0-9_]+)\b/g
|
||||
return input.replace(hashtagRegex, '$1').trim()
|
||||
}
|
||||
|
||||
export function convertImgTagsToMarkdown(input: string): string {
|
||||
return input.replace(/<img\s+[^>]*>/gi, (imgTag) => {
|
||||
const srcMatch = imgTag.match(/src\s*=\s*"([^"]+)"/i)
|
||||
if (!srcMatch) {
|
||||
return imgTag
|
||||
}
|
||||
const src = srcMatch[1]
|
||||
|
||||
const altMatch = imgTag.match(/alt\s*=\s*"([^"]*)"/i)
|
||||
const alt = altMatch ? altMatch[1] : ''
|
||||
|
||||
const titleMatch = imgTag.match(/title\s*=\s*"([^"]*)"/i)
|
||||
const title = titleMatch ? titleMatch[1] : ''
|
||||
|
||||
return ``
|
||||
})
|
||||
}
|
||||
|
||||
export function removeGfmTables(input: string): string {
|
||||
const gfmTableRegex =
|
||||
// eslint-disable-next-line security/detect-unsafe-regex
|
||||
/^[ \t]*\|.*\|.*\r?\n^[ \t]*\|[ \t\-:|]+\r?\n(?:^[ \t]*\|.*\|.*(?:\r?\n|$))*/gm
|
||||
return input.replace(gfmTableRegex, '')
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user