Files
5chan/src/components/Post.jsx
T

73 lines
1.8 KiB
React
Raw Normal View History

2023-03-29 13:37:36 +02:00
import React from 'react';
import ReactMarkdown from 'react-markdown';
2023-04-13 17:08:35 +02:00
import { Link } from 'react-router-dom';
2023-03-29 13:37:36 +02:00
import DOMPurify from 'dompurify';
const blockquoteToGreentext = () => (tree) => {
2023-04-14 18:10:41 +02:00
tree.children.forEach((node) => {
if (node.type === 'blockquote') {
node.children.forEach((child) => {
if (child.type === 'paragraph' && child.children.length > 0) {
const prefix = {
type: 'text',
value: '>',
};
child.children.unshift(prefix);
}
});
node.type = 'div';
node.data = {
hName: 'div',
hProperties: {
className: 'greentext',
},
};
}
2023-03-29 13:37:36 +02:00
});
};
2023-04-14 16:42:09 +02:00
const createQuotelink = (handlequoteclick, comment, children) => {
2023-04-13 17:08:35 +02:00
const text = children.map((child) => (typeof child === 'string' ? child : child.props.children)).join('');
const regex = /(\s|^)(c\/[A-Za-z0-9]{12}|c\/[A-Za-z0-9]{45})(?=\s|$)/g;
const parts = text.split(regex);
return parts.flatMap((part, i) => {
if (regex.test(part)) {
return [
<Link
key={`link-${i}`}
className="quotelink"
to=""
2023-04-14 16:42:09 +02:00
onClick={handlequoteclick}
2023-04-13 17:08:35 +02:00
>
{part.trim()}
</Link>,
];
} else {
return [part];
}
});
};
2023-04-14 16:42:09 +02:00
const Post = ({ content, handlequoteclick, comment }) => {
2023-03-29 13:37:36 +02:00
const sanitizedContent = DOMPurify.sanitize(content);
return (
<ReactMarkdown
children={sanitizedContent}
remarkPlugins={[blockquoteToGreentext]}
components={{
img: () => null,
video: () => null,
source: () => null,
gif: () => null,
2023-04-13 17:08:35 +02:00
p: ({ children }) => (
2023-04-14 16:42:09 +02:00
<p>{createQuotelink(handlequoteclick, comment, children)}</p>
2023-04-13 17:08:35 +02:00
),
2023-03-29 13:37:36 +02:00
}}
/>
);
};
export default Post;