Update comment tags and hashtag payload

This commit is contained in:
LeonspaceX
2026-01-26 17:56:48 +08:00
parent f6d9521f80
commit 929ff68f50
2 changed files with 64 additions and 1 deletions

View File

@@ -250,6 +250,17 @@ export interface PostCommentResponse {
export const postComment = async (commentData: PostCommentRequest): Promise<PostCommentResponse> => {
try {
const identity = await get_id_token();
const hashtopic: string[] = [];
const regex = /#\S+/g;
const matches = commentData.content.match(regex);
if (matches) {
matches.forEach(tag => {
const cleanTag = tag.substring(1);
if (!hashtopic.includes(cleanTag)) {
hashtopic.push(cleanTag);
}
});
}
const response = await fetch('/api/comment', {
method: 'POST',
headers: {
@@ -257,6 +268,7 @@ export const postComment = async (commentData: PostCommentRequest): Promise<Post
},
body: JSON.stringify({
...commentData,
hashtopic,
identity,
}),
});

View File

@@ -16,6 +16,8 @@ import { Dismiss24Regular, ArrowReply24Regular } from '@fluentui/react-icons';
import { getComments, postComment } from '../api';
import type { Comment as CommentType } from '../api';
import { useLayout } from '../context/LayoutContext';
import ReactMarkdown from 'react-markdown';
import remarkGfm from 'remark-gfm';
const useStyles = makeStyles({
container: {
@@ -85,8 +87,43 @@ const useStyles = makeStyles({
height: '40px',
fontSize: '16px',
},
tag: {
color: tokens.colorBrandForeground1,
textDecoration: 'none',
},
});
// 自定义 remark 插件,用于高亮 #tag
const remarkTagPlugin = () => {
return (tree: any) => {
const transformNode = (node: any, inLink = false) => {
if (node.type === 'link') inLink = true;
if (node.children) {
node.children = node.children.flatMap((child: any) => {
if (child.type === 'text' && !inLink) {
const parts = child.value.split(/(#\S+)/g);
return parts.map((part: string) => {
if (part.match(/^#\S+$/)) {
return {
type: 'link',
url: 'tag:' + part,
children: [{ type: 'text', value: part }]
};
}
if (part === "") return [];
return { type: 'text', value: part };
}).flat();
}
return transformNode(child, inLink);
});
}
return node;
};
transformNode(tree);
};
};
interface CommentSectionProps {
postId: number;
}
@@ -188,7 +225,21 @@ const CommentSection: React.FC<CommentSectionProps> = ({ postId }) => {
<div className={styles.commentHeader}>
<Text className={styles.nickname}>{comment.nickname}</Text>
</div>
<Text>{comment.content}</Text>
<div style={{ whiteSpace: 'pre-wrap' }}>
<ReactMarkdown
remarkPlugins={[remarkGfm, remarkTagPlugin]}
components={{
a: ({ node, ...props }) => {
if (props.href && props.href.startsWith('tag:')) {
return <span className={styles.tag}>{props.children}</span>;
}
return <a {...props} />;
},
}}
>
{comment.content}
</ReactMarkdown>
</div>
<div className={styles.commentFooter}>
<Tooltip content="回复" relationship="label">
<div