From 56e849729dfdba2f0719364d12aae460c45bfff5 Mon Sep 17 00:00:00 2001 From: Anton Date: Mon, 15 Jan 2024 13:05:55 +0100 Subject: [PATCH] youtube video support --- package-lock.json | 9 ++ package.json | 1 + .../ItemPopupComponents/TextView.tsx | 143 ++++++++++-------- 3 files changed, 92 insertions(+), 61 deletions(-) diff --git a/package-lock.json b/package-lock.json index fe59b2d8..c167ed82 100644 --- a/package-lock.json +++ b/package-lock.json @@ -22,6 +22,7 @@ "react-leaflet-cluster": "^2.1.0", "react-markdown": "^9.0.1", "react-router-dom": "^6.16.0", + "react-string-replace": "^1.1.1", "react-toastify": "^9.1.3", "rehype-video": "^2.0.2", "tributejs": "^5.1.3", @@ -4890,6 +4891,14 @@ "react-dom": ">=16.8" } }, + "node_modules/react-string-replace": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/react-string-replace/-/react-string-replace-1.1.1.tgz", + "integrity": "sha512-26TUbLzLfHQ5jO5N7y3Mx88eeKo0Ml0UjCQuX4BMfOd/JX+enQqlKpL1CZnmjeBRvQE8TR+ds9j1rqx9CxhKHQ==", + "engines": { + "node": ">=0.12.0" + } + }, "node_modules/react-toastify": { "version": "9.1.3", "resolved": "https://registry.npmjs.org/react-toastify/-/react-toastify-9.1.3.tgz", diff --git a/package.json b/package.json index a88aa5d0..4ba7c666 100644 --- a/package.json +++ b/package.json @@ -55,6 +55,7 @@ "react-leaflet-cluster": "^2.1.0", "react-markdown": "^9.0.1", "react-router-dom": "^6.16.0", + "react-string-replace": "^1.1.1", "react-toastify": "^9.1.3", "rehype-video": "^2.0.2", "tributejs": "^5.1.3", diff --git a/src/Components/Map/Subcomponents/ItemPopupComponents/TextView.tsx b/src/Components/Map/Subcomponents/ItemPopupComponents/TextView.tsx index c8723382..24efd282 100644 --- a/src/Components/Map/Subcomponents/ItemPopupComponents/TextView.tsx +++ b/src/Components/Map/Subcomponents/ItemPopupComponents/TextView.tsx @@ -11,85 +11,90 @@ export const TextView = ({ item }: { item?: Item }) => { const tags = useTags(); const addFilterTag = useAddFilterTag(); - let replacedText; + let replacedText; if (item && item.text) replacedText = fixUrls(item.text); replacedText = replacedText.replace(/(? { - let shortUrl = url; + let shortUrl = url; if (url.match('^https:\/\/')) { shortUrl = url.split('https://')[1]; } if (url.match('^http:\/\/')) { shortUrl = url.split('http://')[1]; - } + } return `[${shortUrl}](${url})` - }) + }) -replacedText = replacedText.replace(mailRegex, (url) => { - return `[${url}](mailto:${url})` -}) + replacedText = replacedText.replace(mailRegex, (url) => { + return `[${url}](mailto:${url})` + }) -replacedText = replacedText.replace(hashTagRegex, (match) => { - return `[${match}](${match})` -}) + replacedText = replacedText.replace(hashTagRegex, (match) => { + return `[${match}](${match})` + }) -const CustomH1 = ({ children }) => ( -

{children}

-); -const CustomH2 = ({ children }) => ( -

{children}

-); -const CustomH3 = ({ children }) => ( -

{children}

-); -const CustomH4 = ({ children }) => ( -

{children}

-); -const CustomH5 = ({ children }) => ( -
{children}
-); -const CustomH6 = ({ children }) => ( -
{children}
-); -const CustomParagraph = ({ children }) => ( -

{children}

-); -const CustomUnorderdList = ({ children }) => ( - -); -const CustomOrderdList = ({ children }) => ( -
    {children}
-); -const CustomImage = ({ alt, src, title }) => ( + + const CustomH1 = ({ children }) => ( +

{children}

+ ); + const CustomH2 = ({ children }) => ( +

{children}

+ ); + const CustomH3 = ({ children }) => ( +

{children}

+ ); + const CustomH4 = ({ children }) => ( +

{children}

+ ); + const CustomH5 = ({ children }) => ( +
{children}
+ ); + const CustomH6 = ({ children }) => ( +
{children}
+ ); + const CustomParagraph = ({ children }) => ( +

{children}

+ ); + const CustomUnorderdList = ({ children }) => ( + + ); + const CustomOrderdList = ({ children }) => ( +
    {children}
+ ); + const CustomImage = ({ alt, src, title }) => ( {alt} -); -const CustomExternalLink = ({ href, children }) => ( - - {children} - -); -const CustomHashTagLink = ({ children, tag, item }) => ( - { - e.stopPropagation(); - addFilterTag(tag!); - // map.fitBounds(items) - // map.closePopup(); - }}>{children} -); + ); + const CustomExternalLink = ({ href, children }) => ( + + {children} + + ); + const CustomHashTagLink = ({ children, tag, item }) => ( + { + e.stopPropagation(); + addFilterTag(tag!); + // map.fitBounds(items) + // map.closePopup(); + }}>{children} + ); + + const isSpecialYouTubeLink = (url) => { + return /(?<=!\()[^)]+(?=\))/g.test(url); + }; return ( @@ -97,8 +102,24 @@ const CustomHashTagLink = ({ children, tag, item }) => ( { - if (href?.startsWith("#")) { - const tag = tags.find(t => t.id.toLowerCase() == href.slice(1).toLowerCase()) + // Prüft, ob der Link ein YouTube-Video ist + const isYouTubeVideo = href?.startsWith('https://www.youtube.com/watch?v='); + + if (isYouTubeVideo) { + const videoId = href?.split('v=')[1].split('&')[0]; // Extrahiert die Video-ID aus der URL + const youtubeEmbedUrl = `https://www.youtube-nocookie.com/embed/${videoId}`; + + return ( + +