import { Item } from '../../../../types';
import { useTags } from '../../hooks/useTags';
import { useAddFilterTag } from '../../hooks/useFilter';
import { hashTagRegex } from '../../../../Utils/HashTagRegex';
import { fixUrls, mailRegex } from '../../../../Utils/ReplaceURLs';
import Markdown from 'react-markdown';
import { getValue } from '../../../../Utils/GetValue';
import remarkBreaks from 'remark-breaks';
import { decodeTag } from '../../../../Utils/FormatTags';
import { memo } from 'react';
export const TextView = ({ item, truncate = false, itemTextField, rawText }: { item?: Item, truncate?: boolean, itemTextField?: string, rawText?: string }) => {
const tags = useTags();
const addFilterTag = useAddFilterTag();
let text = "";
let replacedText = "";
if (rawText)
text = replacedText = rawText;
else if (itemTextField && item)
text = getValue(item, itemTextField);
else
text = item?.layer?.itemTextField && item ? getValue(item, item.layer?.itemTextField) : "";
if (item && text && truncate) text = truncateText(removeMarkdownKeepLinksAndParagraphs(text), 100);
item && text ? replacedText = fixUrls(text) : "";
// eslint-disable-next-line no-useless-escape
replacedText ? replacedText = replacedText.replace(/(? {
let shortUrl = url;
// eslint-disable-next-line no-useless-escape
if (url.match('^https:\/\/')) {
shortUrl = url.split('https://')[1];
}
// eslint-disable-next-line no-useless-escape
if (url.match('^http:\/\/')) {
shortUrl = url.split('http://')[1];
}
return `[${shortUrl}](${url})`;
}) : "";
replacedText ? replacedText = replacedText.replace(mailRegex, (url) => {
return `[${url}](mailto:${url})`;
}) : "";
replacedText ? replacedText = replacedText.replace(hashTagRegex, (match) => {
return `[${match}](${match})`;
}) : "";
// eslint-disable-next-line react/prop-types
const CustomH1 = ({ children }) => (
{children}
);
// eslint-disable-next-line react/prop-types
const CustomH2 = ({ children }) => (
{children}
);
// eslint-disable-next-line react/prop-types
const CustomH3 = ({ children }) => (
{children}
);
// eslint-disable-next-line react/prop-types
const CustomH4 = ({ children }) => (
{children}
);
// eslint-disable-next-line react/prop-types
const CustomH5 = ({ children }) => (
{children}
);
// eslint-disable-next-line react/prop-types
const CustomH6 = ({ children }) => (
{children}
);
// eslint-disable-next-line react/prop-types
const CustomParagraph = ({ children }) => (
{children}
);
// eslint-disable-next-line react/prop-types
const CustomUnorderdList = ({ children }) => (
);
// eslint-disable-next-line react/prop-types
const CustomOrderdList = ({ children }) => (
{children}
);
// eslint-disable-next-line react/prop-types
const CustomHorizontalRow = ({ children }) => (
{children}
);
// eslint-disable-next-line react/prop-types
const CustomImage = ({ alt, src, title }) => (
);
// eslint-disable-next-line react/prop-types
const CustomExternalLink = ({ href, children }) => (
{children}
);
/* eslint-disable react/prop-types */
const CustomHashTagLink = ({ children, tag, item }) => {
return (
{
e.stopPropagation();
addFilterTag(tag!);
}}>{decodeTag(children)}
)
};
/* eslint-enable react/prop-types */
// eslint-disable-next-line react/display-name
const MemoizedVideoEmbed = memo(({ url }: { url: string }) => (
));
return (
{
// eslint-disable-next-line react/prop-types
const isYouTubeVideo = href?.startsWith('https://www.youtube.com/watch?v=');
// eslint-disable-next-line react/prop-types
const isRumbleVideo = href?.startsWith('https://rumble.com/embed/');
if (isYouTubeVideo) {
// eslint-disable-next-line react/prop-types
const videoId = href?.split('v=')[1].split('&')[0];
const youtubeEmbedUrl = `https://www.youtube-nocookie.com/embed/${videoId}`;
return (
);
}
if (isRumbleVideo) {
return (
);
}
// eslint-disable-next-line react/prop-types
if (href?.startsWith("#")) {
const tag = tags.find(t => t.name.toLowerCase() === decodeURI(href).slice(1).toLowerCase());
return {children};
} else {
return (
{children}
);
}
},
ul: CustomUnorderdList,
ol: CustomOrderdList,
img: CustomImage,
hr: CustomHorizontalRow,
h1: CustomH1,
h2: CustomH2,
h3: CustomH3,
h4: CustomH4,
h5: CustomH5,
h6: CustomH6,
}}>
{replacedText}
);
};
function removeMarkdownKeepLinksAndParagraphs(text) {
// Remove Markdown syntax using regular expressions but keep links and paragraphs
return text
.replace(/!\[.*?\]\(.*?\)/g, '') // Remove images
.replace(/(`{1,3})(.*?)\1/g, '$2') // Remove inline code
.replace(/(\*{1,2}|_{1,2})(.*?)\1/g, '$2') // Remove bold and italic
.replace(/(#+)\s+(.*)/g, '$2') // Remove headers
.replace(/>\s+(.*)/g, '$1') // Remove blockquotes
.replace(/^\s*\n/gm, '\n') // Preserve empty lines
.replace(/(\r\n|\n|\r)/gm, '\n'); // Preserve line breaks
}
function truncateText(text, limit) {
if (text.length <= limit) {
return text;
}
let truncated = "";
let length = 0;
// Split the text by paragraphs
const paragraphs = text.split('\n');
for (const paragraph of paragraphs) {
if (length + paragraph.length > limit) {
truncated += paragraph.slice(0, limit - length) + '...';
break;
} else {
truncated += paragraph + '\n';
length += paragraph.length;
}
}
return truncated.trim();
}