refactor: migrate post operations to use case architecture with differential updates
Migrate post-related operations from direct service/store calls to a new use case architecture featuring differential updates. Key changes include: (1) introduce ProcessPostUseCase to handle like, unlike, favorite, unfavorite, delete, and fetch operations with proper state management, (2) add useDifferentialPosts hook for efficient list rendering with minimal re-renders, (3) add PostDiffCalculator and PostUpdateBatcher in infrastructure layer for incremental updates, (4) deprecate NotificationItem component in favor of SystemMessageItem, (5) remove deprecated interactive methods from userStore, (6) add posts_cache table to local datasource, (7) clean up legacy MessageDTO and ConversationDTO types, (8) remove deprecated hook useBreakpointCheck, (9) refactor MessageBubble to use measureInWindow directly for better React Native compatibility
This commit is contained in:
@@ -32,6 +32,7 @@ import { Post, Comment, VoteResultDTO } from '../../types';
|
||||
import { useUserStore } from '../../stores';
|
||||
import { useCurrentUser } from '../../stores/authStore';
|
||||
import { postService, commentService, uploadService, authService, showPrompt, voteService } from '../../services';
|
||||
import { processPostUseCase } from '../../core/usecases/ProcessPostUseCase';
|
||||
import { useCursorPagination } from '../../hooks/useCursorPagination';
|
||||
import { CommentItem, VoteCard } from '../../components/business';
|
||||
import { Avatar, Button, Loading, EmptyState, Text, ImageGallery, ImageGrid, ImageGridItem, AdaptiveLayout } from '../../components/common';
|
||||
@@ -62,15 +63,6 @@ export const PostDetailScreen: React.FC = () => {
|
||||
const responsivePadding = useResponsiveSpacing({ xs: 12, sm: 14, md: 16, lg: 20, xl: 24, '2xl': 28, '3xl': 32, '4xl': 40 });
|
||||
const responsiveGap = useResponsiveSpacing({ xs: 8, sm: 10, md: 12, lg: 16, xl: 20, '2xl': 24, '3xl': 28, '4xl': 32 });
|
||||
|
||||
const {
|
||||
likePost,
|
||||
unlikePost,
|
||||
favoritePost,
|
||||
unfavoritePost,
|
||||
likeComment,
|
||||
unlikeComment
|
||||
} = useUserStore();
|
||||
|
||||
const currentUser = useCurrentUser();
|
||||
|
||||
const [post, setPost] = useState<Post | null>(null);
|
||||
@@ -144,14 +136,15 @@ export const PostDetailScreen: React.FC = () => {
|
||||
}
|
||||
|
||||
try {
|
||||
// 从API获取帖子详情
|
||||
const postData = await postService.getPost(postId);
|
||||
// 使用 ProcessPostUseCase 获取帖子详情
|
||||
const postData = await processPostUseCase.fetchPostById(postId);
|
||||
if (postData) {
|
||||
setPost(postData);
|
||||
// 类型转换:将 core/entities/Post 转换为 PostDTO 以保持兼容性
|
||||
setPost(postData as unknown as Post);
|
||||
// 初始化关注状态
|
||||
if (postData.author) {
|
||||
setIsFollowing(postData.author.is_following || false);
|
||||
setIsFollowingMe(postData.author.is_following_me || false);
|
||||
setIsFollowing((postData.author as any).is_following || false);
|
||||
setIsFollowingMe((postData.author as any).is_following_me || false);
|
||||
}
|
||||
// 只在首次加载时记录浏览量
|
||||
if (recordView && !hasRecordedView.current) {
|
||||
@@ -163,7 +156,7 @@ export const PostDetailScreen: React.FC = () => {
|
||||
}
|
||||
|
||||
// 如果是投票帖子,立即加载投票数据
|
||||
if (postData.is_vote) {
|
||||
if ((postData as any).is_vote) {
|
||||
setIsVoteLoading(true);
|
||||
try {
|
||||
const voteData = await voteService.getVoteResult(postId);
|
||||
@@ -184,8 +177,8 @@ export const PostDetailScreen: React.FC = () => {
|
||||
setPost(updatedPost);
|
||||
// 初始化关注状态
|
||||
if (updatedPost.author) {
|
||||
setIsFollowing(updatedPost.author.is_following || false);
|
||||
setIsFollowingMe(updatedPost.author.is_following_me || false);
|
||||
setIsFollowing((updatedPost.author as any).is_following || false);
|
||||
setIsFollowingMe((updatedPost.author as any).is_following_me || false);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -361,10 +354,11 @@ export const PostDetailScreen: React.FC = () => {
|
||||
|
||||
try {
|
||||
if (oldIsLiked) {
|
||||
await unlikePost(post.id);
|
||||
await processPostUseCase.unlikePost(post.id);
|
||||
} else {
|
||||
await likePost(post.id);
|
||||
await processPostUseCase.likePost(post.id);
|
||||
}
|
||||
// UseCase 会更新 store,本地状态已经是乐观更新的,无需再次更新
|
||||
} catch (error) {
|
||||
console.error('点赞操作失败:', error);
|
||||
// 失败时回滚状态
|
||||
@@ -374,7 +368,7 @@ export const PostDetailScreen: React.FC = () => {
|
||||
likes_count: oldLikesCount
|
||||
} : null);
|
||||
}
|
||||
}, [post, likePost, unlikePost]);
|
||||
}, [post]);
|
||||
|
||||
// 收藏帖子
|
||||
const handleFavorite = useCallback(async () => {
|
||||
@@ -393,10 +387,11 @@ export const PostDetailScreen: React.FC = () => {
|
||||
|
||||
try {
|
||||
if (oldIsFavorited) {
|
||||
await unfavoritePost(post.id);
|
||||
await processPostUseCase.unfavoritePost(post.id);
|
||||
} else {
|
||||
await favoritePost(post.id);
|
||||
await processPostUseCase.favoritePost(post.id);
|
||||
}
|
||||
// UseCase 会更新 store,本地状态已经是乐观更新的,无需再次更新
|
||||
} catch (error) {
|
||||
console.error('收藏操作失败:', error);
|
||||
// 失败时回滚状态
|
||||
@@ -406,7 +401,7 @@ export const PostDetailScreen: React.FC = () => {
|
||||
favorites_count: oldFavoritesCount
|
||||
} : null);
|
||||
}
|
||||
}, [post, favoritePost, unfavoritePost]);
|
||||
}, [post]);
|
||||
|
||||
// 分享帖子
|
||||
const handleShare = useCallback(async () => {
|
||||
@@ -527,17 +522,13 @@ export const PostDetailScreen: React.FC = () => {
|
||||
onPress: async () => {
|
||||
setIsDeleting(true);
|
||||
try {
|
||||
const success = await postService.deletePost(post.id);
|
||||
if (success) {
|
||||
Alert.alert('删除成功', '帖子已删除', [
|
||||
{
|
||||
text: '确定',
|
||||
onPress: () => navigation.goBack(),
|
||||
},
|
||||
]);
|
||||
} else {
|
||||
Alert.alert('删除失败', '删除帖子时发生错误,请稍后重试');
|
||||
}
|
||||
await processPostUseCase.deletePost(post.id);
|
||||
Alert.alert('删除成功', '帖子已删除', [
|
||||
{
|
||||
text: '确定',
|
||||
onPress: () => navigation.goBack(),
|
||||
},
|
||||
]);
|
||||
} catch (error) {
|
||||
console.error('删除帖子失败:', error);
|
||||
Alert.alert('删除失败', '删除帖子时发生错误,请稍后重试');
|
||||
@@ -817,9 +808,9 @@ export const PostDetailScreen: React.FC = () => {
|
||||
|
||||
try {
|
||||
if (oldIsLiked) {
|
||||
await unlikeComment(comment.id);
|
||||
await commentService.unlikeComment(comment.id);
|
||||
} else {
|
||||
await likeComment(comment.id);
|
||||
await commentService.likeComment(comment.id);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('评论点赞操作失败:', error);
|
||||
|
||||
Reference in New Issue
Block a user