Update comment pagination and ignore data files

This commit is contained in:
LeonspaceX
2026-01-27 12:13:19 +08:00
parent 463c793e89
commit 72204c74b0
7 changed files with 78 additions and 22 deletions

View File

@@ -175,7 +175,7 @@ export interface Article {
export const fetchArticles = async (page: number, signal?: AbortSignal): Promise<Article[]> => {
try {
const response = await fetch(`/api/10_info?page=${page}`, { signal });
const response = await fetch(`/api/posts_info?page=${page}`, { signal });
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
@@ -219,15 +219,23 @@ export interface Comment {
parent_comment_id: number;
}
export const getComments = async (id: string | number): Promise<Comment[]> => {
export interface CommentPage {
comments: Comment[];
total_pages: number;
}
export const getComments = async (id: string | number, page: number = 1): Promise<CommentPage> => {
try {
const response = await fetch(`/api/get/comment?id=${id}`);
const response = await fetch(`/api/get/comment?id=${id}&page=${page}`);
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
const json = await response.json();
if (json.code === 1000 && Array.isArray(json.data)) {
return json.data as Comment[];
if (json.code === 1000 && json.data && Array.isArray(json.data.comments)) {
return {
comments: json.data.comments as Comment[],
total_pages: Number(json.data.total_pages) || 0,
};
}
throw new Error('Invalid response code or missing data');
} catch (error) {

View File

@@ -12,7 +12,7 @@ import {
Toast,
ToastTitle,
} from '@fluentui/react-components';
import { Dismiss24Regular, ArrowReply24Regular } from '@fluentui/react-icons';
import { Dismiss24Regular, ArrowReply24Regular, ArrowClockwise24Regular } from '@fluentui/react-icons';
import { getComments, postComment } from '../api';
import type { Comment as CommentType } from '../api';
import { useLayout } from '../context/LayoutContext';
@@ -91,6 +91,15 @@ const useStyles = makeStyles({
color: tokens.colorBrandForeground1,
textDecoration: 'none',
},
loadMore: {
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
gap: tokens.spacingHorizontalXS,
color: tokens.colorBrandForeground1,
cursor: 'pointer',
marginTop: tokens.spacingVerticalS,
},
});
// 自定义 remark 插件,用于高亮 #tag
@@ -137,17 +146,29 @@ const CommentSection: React.FC<CommentSectionProps> = ({ postId }) => {
const [nickname, setNickname] = useState('');
const [replyTo, setReplyTo] = useState<CommentType | null>(null);
const [loading, setLoading] = useState(false);
const [loadingMore, setLoadingMore] = useState(false);
const [page, setPage] = useState(1);
const [totalPages, setTotalPages] = useState(0);
const commentCardRefs = useRef<Map<number, HTMLDivElement>>(new Map());
useEffect(() => {
fetchComments();
useEffect(() => {
setComments([]);
setPage(1);
setTotalPages(0);
fetchComments(1, false);
}, [postId]);
const fetchComments = async () => {
const fetchComments = async (targetPage: number, append: boolean) => {
try {
setLoading(true);
const data = await getComments(postId);
setComments(data as CommentType[]);
if (append) {
setLoadingMore(true);
} else {
setLoading(true);
}
const data = await getComments(postId, targetPage);
setComments(prev => (append ? [...prev, ...data.comments] : data.comments));
setPage(targetPage);
setTotalPages(data.total_pages || 0);
} catch (error) {
dispatchToast(
<Toast>
@@ -157,7 +178,11 @@ const CommentSection: React.FC<CommentSectionProps> = ({ postId }) => {
);
console.error('Error fetching comments:', error);
} finally {
setLoading(false);
if (append) {
setLoadingMore(false);
} else {
setLoading(false);
}
}
};
@@ -188,7 +213,7 @@ const CommentSection: React.FC<CommentSectionProps> = ({ postId }) => {
);
setContent('');
if (replyTo) setReplyTo(null);
fetchComments();
fetchComments(1, false);
} catch (error: any) {
dispatchToast(
<Toast>
@@ -300,6 +325,18 @@ const CommentSection: React.FC<CommentSectionProps> = ({ postId }) => {
{loading && <Text>..</Text>}
{!loading && comments.length === 0 && <Text></Text>}
{renderComments()}
{totalPages > 1 && page < totalPages && (
<div
className={styles.loadMore}
onClick={() => {
if (loading || loadingMore) return;
fetchComments(page + 1, true);
}}
>
<ArrowClockwise24Regular />
<Text size={200}></Text>
</div>
)}
</div>
</div>
);