From 28dd16dfeb9df5fbc1c6ecb07dccdb60af04c3a3 Mon Sep 17 00:00:00 2001 From: Anton Tranelis Date: Fri, 4 Jul 2025 15:07:46 +0200 Subject: [PATCH] seperate hashtags --- lib/package-lock.json | 40 +++++++++++++++++ lib/package.json | 2 + .../ItemPopupComponents/TextPreview.tsx | 45 ++++++++++++------- 3 files changed, 71 insertions(+), 16 deletions(-) diff --git a/lib/package-lock.json b/lib/package-lock.json index 91d077d7..242c740f 100644 --- a/lib/package-lock.json +++ b/lib/package-lock.json @@ -57,9 +57,11 @@ "react-toastify": "^9.1.3", "rehype-raw": "^7.0.0", "rehype-sanitize": "^6.0.0", + "rehype-stringify": "^10.0.1", "remark-breaks": "^4.0.0", "remark-gfm": "^4.0.1", "remark-parse": "^11.0.0", + "remark-rehype": "^11.1.2", "tippy.js": "^6.3.7", "tiptap-markdown": "^0.8.10", "unified": "^11.0.5", @@ -7244,6 +7246,29 @@ "url": "https://opencollective.com/unified" } }, + "node_modules/hast-util-to-html": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/hast-util-to-html/-/hast-util-to-html-9.0.5.tgz", + "integrity": "sha512-OguPdidb+fbHQSU4Q4ZiLKnzWo8Wwsf5bZfbvu7//a9oTYoqD/fWpe96NuHkoS9h0ccGOTe0C4NGXdtS0iObOw==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "@types/unist": "^3.0.0", + "ccount": "^2.0.0", + "comma-separated-tokens": "^2.0.0", + "hast-util-whitespace": "^3.0.0", + "html-void-elements": "^3.0.0", + "mdast-util-to-hast": "^13.0.0", + "property-information": "^7.0.0", + "space-separated-tokens": "^2.0.0", + "stringify-entities": "^4.0.0", + "zwitch": "^2.0.4" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, "node_modules/hast-util-to-jsx-runtime": { "version": "2.3.6", "resolved": "https://registry.npmjs.org/hast-util-to-jsx-runtime/-/hast-util-to-jsx-runtime-2.3.6.tgz", @@ -12009,6 +12034,21 @@ "url": "https://opencollective.com/unified" } }, + "node_modules/rehype-stringify": { + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/rehype-stringify/-/rehype-stringify-10.0.1.tgz", + "integrity": "sha512-k9ecfXHmIPuFVI61B9DeLPN0qFHfawM6RsuX48hoqlaKSF61RskNjSm1lI8PhBEM0MRdLxVVm4WmTqJQccH9mA==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "hast-util-to-html": "^9.0.0", + "unified": "^11.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, "node_modules/remark-breaks": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/remark-breaks/-/remark-breaks-4.0.0.tgz", diff --git a/lib/package.json b/lib/package.json index 3b900e85..7261b958 100644 --- a/lib/package.json +++ b/lib/package.json @@ -145,9 +145,11 @@ "react-toastify": "^9.1.3", "rehype-raw": "^7.0.0", "rehype-sanitize": "^6.0.0", + "rehype-stringify": "^10.0.1", "remark-breaks": "^4.0.0", "remark-gfm": "^4.0.1", "remark-parse": "^11.0.0", + "remark-rehype": "^11.1.2", "tippy.js": "^6.3.7", "tiptap-markdown": "^0.8.10", "unified": "^11.0.5", diff --git a/lib/src/Components/Map/Subcomponents/ItemPopupComponents/TextPreview.tsx b/lib/src/Components/Map/Subcomponents/ItemPopupComponents/TextPreview.tsx index 19b3abd2..7b72c72c 100644 --- a/lib/src/Components/Map/Subcomponents/ItemPopupComponents/TextPreview.tsx +++ b/lib/src/Components/Map/Subcomponents/ItemPopupComponents/TextPreview.tsx @@ -6,12 +6,14 @@ import remarkBreaks from 'remark-breaks' import remarkGfm from 'remark-gfm' import { useAddFilterTag } from '#components/Map/hooks/useFilter' -import { useTags } from '#components/Map/hooks/useTags' +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 }) => { + const getItemTags = useGetItemTags() + if (!item.text) return null // Text auf ~100 Zeichen stutzen (inkl. Ellipse „…“) const previewRaw = truncate(item.text, { limit: 100, ellipsis: true }) as string @@ -23,22 +25,21 @@ export const TextPreview = ({ item }: { item: Item }) => { return (
- - {withExtraHashes} + + {removeMentionSpans(removeHashtags(withExtraHashes))} + {getItemTags(item).map((tag) => ( + + ))}
) } -export const HashTag = ({ tag }: { tag: string }) => { +export const HashTag = ({ tag }: { tag: Tag }) => { const tags = useTags() - const t = tags.find((t) => t.name === tag.slice(1)) + const t = tags.find((t) => t.name.toLocaleLowerCase() === tag.name.toLocaleLowerCase()) const addFilterTag = useAddFilterTag() - if (!t) return {tag} + if (!t) return null return ( { addFilterTag(t) }} > - {decodeTag(tag)} + {`#${decodeTag(tag.name)} `} ) } -export const Span = (node) => { - if (node['data-type'] === 'mention') { - return - } - return {node.children} +function removeMentionSpans(html) { + return html.replace( + /]*\bdata-type="mention")(?=[^>]*\bclass="mention")[^>]*>[\s\S]*?<\/span>/gi, + '', + ) } + +function removeHashtags(str) { + return str + // 1. Hashtags entfernen, außer sie stehen am Zeilenanfang als Markdown-Heading + .replace( + /(^|\s)(?!#{1,6}\s)(#[A-Za-z0-9_]+)\b/g, + '$1' + ) + + // 3. Anfangs/Ende trimmen + .trim() +} \ No newline at end of file