Update comment pagination and ignore data files
This commit is contained in:
@@ -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) {
|
||||
|
||||
@@ -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>
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user