Skip to content

Commit

Permalink
Add logics for parsing content in comments
Browse files Browse the repository at this point in the history
  • Loading branch information
marshallku committed Feb 23, 2024
1 parent b7b7a98 commit 09f3fe2
Show file tree
Hide file tree
Showing 4 changed files with 131 additions and 3 deletions.
7 changes: 4 additions & 3 deletions apps/blog/src/components/CommentBubble/index.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import { classNames, formatDate } from "@marshallku/utils";
import { type Comment } from "#api";
import styles from "./index.module.scss";
import CommentAvatar from "#components/CommentAvatar";
import Typography from "#components/Typography";
import CommentContent from "#components/CommentContent";
import styles from "./index.module.scss";

export interface CommentBubbleProps {
data: Comment;
Expand All @@ -27,8 +28,8 @@ function CommentBubble({ border, data: { name, url, body, createdAt, byPostAutho
{name}
</Typography>
</div>
<Typography variant="b1" className={cx("__text")}>
{body}
<Typography variant="b1" className={cx("__text")} component="div">
<CommentContent content={body} />
</Typography>
<Typography variant="c2" className={cx("__date")}>
{formatDate(new Date(createdAt), "yyyy. MM. dd")}
Expand Down
27 changes: 27 additions & 0 deletions apps/blog/src/components/CommentContent/index.module.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
.comment-content {
&__image,
&__video {
max-width: 100%;
height: auto;
}

&__code {
font-family: "Fira Code", monospace;
font-size: 90%;
padding: 0.2em 0.4em;
border-radius: 4px;
overflow-x: auto;
background-color: color(background-dimmed);
}

&__image,
&__video,
&__code,
p {
margin-bottom: 0.65em;
}

a {
color: color(link);
}
}
99 changes: 99 additions & 0 deletions apps/blog/src/components/CommentContent/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
import { ReactNode } from "react";
import { classNames } from "@marshallku/utils";
import styles from "./index.module.scss";

export interface CommentContentProps {
content: string;
}

const cx = classNames(styles, "comment-content");

const parseComponents = (content: string) => {
const components: ReactNode[] = [];
const lines = content.split("\n");

for (let i = 0, max = lines.length; i < max; ++i) {
const line = lines[i];

if (!line) {
continue;
}

if (line.startsWith("```")) {
const code = [];

for (++i; i < max; ++i) {
const line = lines[i];

if (line.startsWith("```")) {
components.push(
<pre key={i} className={cx("__code")}>
{code.join("\n")}
</pre>,
);
break;
}

code.push(line);
}
} else if (line.startsWith("![")) {
const alt = line.substring(2, line.indexOf("]"));
const src = line.substring(line.indexOf("(") + 1, line.indexOf(")"));

components.push(<img key={i} className={cx("__image")} alt={alt} src={src} />);
} else {
const parts = line.split(/(https?:\/\/[^\s]+|[\w.-]+@[\w.-]+\.\w+)/);
const children: ReactNode[] = [];

for (let j = 0, max = parts.length; j < max; ++j) {
const part = parts[j];

if (!part) {
continue;
}

if (part.match(/^https?:\/\//)) {
if (part.match(/\.(jpeg|jpg|gif|png)$/)) {
children.push(<img key={`${i}-${j}`} className={cx("__image")} src={part} />);
} else if (part.match(/\.mp4|webm$/)) {
children.push(
<video
key={`${i}-${j}`}
autoPlay
playsInline
loop
muted
className={cx("__video")}
src={part}
/>,
);
} else {
children.push(
<a key={`${i}-${j}`} href={part} target="_blank" rel="noopener noreferrer nofollow">
{part}
</a>,
);
}
} else if (part.match(/[\w.-]+@[\w.-]+\.\w+/)) {
children.push(
<a key={`${i}-${j}`} href={`mailto:${part}`}>
{part}
</a>,
);
} else {
children.push(<span key={`${i}-${j}`}>{part}</span>);
}
}

components.push(<p key={i}>{children}</p>);
}
}

return components;
};

function CommentContent({ content }: CommentContentProps) {
return <div className={cx()}>{parseComponents(content)}</div>;
}

export default CommentContent;
1 change: 1 addition & 0 deletions cspell.json
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@
"vercel",
"vfile",
"visualstudiocode",
"webm",
"webp",
"WPZTSDZ027",
"youtu"
Expand Down

0 comments on commit 09f3fe2

Please sign in to comment.