refactor: migrate post operations to use case architecture with differential updates
Some checks failed
Frontend CI / build-and-push-web (push) Failing after 3m11s
Frontend CI / ota-android (push) Failing after 16m3s
Frontend CI / build-android-apk (push) Has been cancelled

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:
lafay
2026-03-21 20:55:36 +08:00
parent 25071d2303
commit d273569911
30 changed files with 4395 additions and 572 deletions

View File

@@ -265,7 +265,7 @@ export const MessageListScreen: React.FC = () => {
}, [isFocused]);
// 【新架构】使用focus刷新hook从ChatScreen返回时自动刷新未读数
useMessageListRefresh(isFocused);
useMessageListRefresh();
// 同步未读数到userStore用于TabBar角标显示
useEffect(() => {

View File

@@ -29,7 +29,8 @@ import { SystemMessageItem } from '../../components/business';
import { Text, EmptyState, ResponsiveContainer } from '../../components/common';
import { useCursorPagination } from '../../hooks/useCursorPagination';
import { RootStackParamList } from '../../navigation/types';
import { useMessageManagerSystemUnreadCount, useUserStore } from '../../stores';
import { useMessageManagerSystemUnreadCount } from '../../stores';
import { messageManager } from '../../stores/messageManager';
const MESSAGE_TYPES = [
{ key: 'all', title: '全部' },
@@ -46,7 +47,6 @@ const GROUP_SYSTEM_TYPES = new Set(['group_invite', 'group_join_apply', 'group_j
export const NotificationsScreen: React.FC<{ onBack?: () => void }> = ({ onBack }) => {
const isFocused = useIsFocused();
const fetchMessageUnreadCount = useUserStore(state => state.fetchMessageUnreadCount);
const { setSystemUnreadCount, decrementSystemUnreadCount } = useMessageManagerSystemUnreadCount();
const navigation = useNavigation<NativeStackNavigationProp<RootStackParamList>>();
@@ -158,11 +158,11 @@ export const NotificationsScreen: React.FC<{ onBack?: () => void }> = ({ onBack
setUnreadCount(0);
setSystemUnreadCount(0);
// 同步更新全局 TabBar 红点
fetchMessageUnreadCount();
messageManager.fetchUnreadCount();
} catch (error) {
console.error('一键已读失败:', error);
}
}, [refresh, fetchMessageUnreadCount, setSystemUnreadCount]);
}, [refresh, setSystemUnreadCount]);
// 页面加载和获得焦点时刷新,并自动标记所有消息为已读
// 使用 ref 防止重复执行,避免无限循环
@@ -281,7 +281,7 @@ export const NotificationsScreen: React.FC<{ onBack?: () => void }> = ({ onBack
}
// 更新本地未读数以及全局 TabBar 红点
fetchUnreadCount();
fetchMessageUnreadCount();
messageManager.fetchUnreadCount();
// 根据消息类型处理导航
const { system_type, extra_data } = message;

View File

@@ -9,8 +9,6 @@ import {
View,
TouchableOpacity,
Image,
findNodeHandle,
UIManager,
GestureResponderEvent,
StyleSheet,
Dimensions,
@@ -219,22 +217,17 @@ export const MessageBubble: React.FC<MessageBubbleProps> = ({
// 处理长按并获取位置
const handleLongPress = () => {
if (bubbleRef.current) {
const node = findNodeHandle(bubbleRef.current);
if (node) {
UIManager.measureInWindow(node, (x, y, width, height) => {
const position: MenuPosition = {
x,
y,
width,
height,
pressX: pressPositionRef.current.x,
pressY: pressPositionRef.current.y,
};
onLongPress(message, position);
});
} else {
onLongPress(message);
}
bubbleRef.current.measureInWindow((x, y, width, height) => {
const position: MenuPosition = {
x,
y,
width,
height,
pressX: pressPositionRef.current.x,
pressY: pressPositionRef.current.y,
};
onLongPress(message, position);
});
} else {
onLongPress(message);
}

View File

@@ -73,8 +73,6 @@ export interface MessageBubbleProps {
otherUser: { id?: string; nickname?: string; avatar?: string | null } | null;
isGroupChat: boolean;
groupMembers: GroupMemberResponse[];
/** @deprecated 发送者信息现在直接从 message.sender 获取,不再使用 senderCache */
senderCache?: Map<string, UserDTO>;
otherUserLastReadSeq: number;
selectedMessageId: string | null;
// 消息映射,用于查找被回复的消息