2026-03-23 03:58:26 +08:00
|
|
|
import { useState, useRef, useCallback, useEffect } from 'react';
|
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
2026-03-21 20:55:36 +08:00
|
|
|
import {
|
|
|
|
|
PostIdentifier,
|
|
|
|
|
PostUpdate,
|
|
|
|
|
PostUpdateType,
|
|
|
|
|
PostDiffConfig,
|
|
|
|
|
} from '../infrastructure/diff/postTypes';
|
|
|
|
|
import {
|
|
|
|
|
PostDiffCalculator,
|
|
|
|
|
createPostDiffCalculator,
|
|
|
|
|
} from '../infrastructure/diff/PostDiffCalculator';
|
|
|
|
|
import {
|
|
|
|
|
PostUpdateBatcher,
|
|
|
|
|
PostBatcherOptions,
|
|
|
|
|
createPostUpdateBatcher,
|
|
|
|
|
} from '../infrastructure/diff/PostUpdateBatcher';
|
2026-04-13 01:30:37 +08:00
|
|
|
import { postSyncService } from '@/services/post';
|
|
|
|
|
import type { PostsState } from '@/services/post';
|
2026-04-13 00:26:05 +08:00
|
|
|
import { usePostListStore } from '../stores/post/postListStore';
|
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
2026-03-21 20:55:36 +08:00
|
|
|
import type { Post } from '../core/entities/Post';
|
|
|
|
|
|
|
|
|
|
export interface UseDifferentialPostsOptions<T extends PostIdentifier> {
|
|
|
|
|
diffConfig?: PostDiffConfig;
|
|
|
|
|
batcherOptions?: PostBatcherOptions;
|
|
|
|
|
enableDiff?: boolean;
|
|
|
|
|
enableBatching?: boolean;
|
|
|
|
|
maxPostCount?: number;
|
|
|
|
|
listKey?: string;
|
|
|
|
|
autoSubscribe?: boolean;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export interface DiffUpdatesInfo {
|
|
|
|
|
addedCount: number;
|
|
|
|
|
updatedCount: number;
|
|
|
|
|
deletedCount: number;
|
|
|
|
|
lastUpdateTime: number;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export interface UseDifferentialPostsResult<T extends PostIdentifier> {
|
|
|
|
|
posts: T[];
|
|
|
|
|
loading: boolean;
|
2026-03-24 01:19:09 +08:00
|
|
|
isInitialLoading: boolean;
|
|
|
|
|
isLoadingMore: boolean;
|
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
2026-03-21 20:55:36 +08:00
|
|
|
refreshing: boolean;
|
|
|
|
|
error: string | null;
|
|
|
|
|
hasMore: boolean;
|
|
|
|
|
pendingUpdateCount: number;
|
|
|
|
|
isProcessing: boolean;
|
|
|
|
|
refresh: () => Promise<void>;
|
|
|
|
|
loadMore: () => Promise<void>;
|
|
|
|
|
flush: () => void;
|
|
|
|
|
reset: () => void;
|
|
|
|
|
forceUpdate: (posts: T[]) => void;
|
2026-04-13 00:26:05 +08:00
|
|
|
getDiffStats: () => { totalBatches: number; totalUpdates: number; averageBatchSize: number };
|
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
2026-03-21 20:55:36 +08:00
|
|
|
diffUpdates: DiffUpdatesInfo;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function useDifferentialPosts<T extends PostIdentifier = Post>(
|
|
|
|
|
initialPosts: T[] = [],
|
|
|
|
|
options: UseDifferentialPostsOptions<T> = {}
|
|
|
|
|
): UseDifferentialPostsResult<T> {
|
|
|
|
|
const {
|
|
|
|
|
diffConfig,
|
|
|
|
|
batcherOptions,
|
|
|
|
|
enableDiff = true,
|
|
|
|
|
enableBatching = true,
|
|
|
|
|
maxPostCount = 10000,
|
|
|
|
|
listKey = 'default',
|
|
|
|
|
autoSubscribe = true,
|
|
|
|
|
} = options;
|
|
|
|
|
|
|
|
|
|
const [posts, setPosts] = useState<T[]>(initialPosts);
|
|
|
|
|
const [loading, setLoading] = useState(false);
|
|
|
|
|
const [refreshing, setRefreshing] = useState(false);
|
|
|
|
|
const [error, setError] = useState<string | null>(null);
|
|
|
|
|
const [hasMore, setHasMore] = useState(true);
|
|
|
|
|
const [isProcessing, setIsProcessing] = useState(false);
|
|
|
|
|
const [pendingUpdateCount, setPendingUpdateCount] = useState(0);
|
|
|
|
|
const [diffUpdates, setDiffUpdates] = useState<DiffUpdatesInfo>({
|
|
|
|
|
addedCount: 0,
|
|
|
|
|
updatedCount: 0,
|
|
|
|
|
deletedCount: 0,
|
|
|
|
|
lastUpdateTime: 0,
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
const calculatorRef = useRef<PostDiffCalculator<T> | null>(null);
|
|
|
|
|
const batcherRef = useRef<PostUpdateBatcher | null>(null);
|
|
|
|
|
const previousPostsRef = useRef<T[]>(initialPosts);
|
|
|
|
|
|
|
|
|
|
const handleBatchUpdates = useCallback((updates: PostUpdate[]) => {
|
|
|
|
|
setIsProcessing(true);
|
|
|
|
|
|
|
|
|
|
try {
|
2026-04-13 00:26:05 +08:00
|
|
|
setPosts(currentPosts => {
|
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
2026-03-21 20:55:36 +08:00
|
|
|
let newPosts = [...currentPosts];
|
|
|
|
|
let addedCount = 0;
|
|
|
|
|
let updatedCount = 0;
|
|
|
|
|
let deletedCount = 0;
|
|
|
|
|
|
|
|
|
|
for (const update of updates) {
|
|
|
|
|
switch (update.type) {
|
|
|
|
|
case PostUpdateType.ADD: {
|
|
|
|
|
const addUpdate = update as any;
|
|
|
|
|
const index = addUpdate.index ?? newPosts.length;
|
|
|
|
|
newPosts.splice(index, 0, addUpdate.post as T);
|
|
|
|
|
addedCount++;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
case PostUpdateType.BATCH_ADD: {
|
|
|
|
|
const batchAddUpdate = update as any;
|
|
|
|
|
const postsToAdd = batchAddUpdate.posts || [];
|
|
|
|
|
const startIndex = batchAddUpdate.startIndex ?? newPosts.length;
|
|
|
|
|
newPosts.splice(startIndex, 0, ...postsToAdd as T[]);
|
|
|
|
|
addedCount += postsToAdd.length;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
case PostUpdateType.UPDATE: {
|
|
|
|
|
const updatePost = update as any;
|
|
|
|
|
const index = newPosts.findIndex(p => p.id === updatePost.postId);
|
|
|
|
|
if (index !== -1) {
|
|
|
|
|
newPosts[index] = { ...newPosts[index], ...updatePost.updates };
|
|
|
|
|
updatedCount++;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
case PostUpdateType.BATCH_UPDATE: {
|
|
|
|
|
const batchUpdate = update as any;
|
|
|
|
|
const updatesList = batchUpdate.updates || [];
|
|
|
|
|
for (const { postId, changes } of updatesList) {
|
|
|
|
|
const index = newPosts.findIndex(p => p.id === postId);
|
|
|
|
|
if (index !== -1) {
|
|
|
|
|
newPosts[index] = { ...newPosts[index], ...changes };
|
|
|
|
|
updatedCount++;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
case PostUpdateType.DELETE: {
|
|
|
|
|
const deleteUpdate = update as any;
|
|
|
|
|
const prevLength = newPosts.length;
|
|
|
|
|
newPosts = newPosts.filter(p => p.id !== deleteUpdate.postId);
|
2026-04-13 00:26:05 +08:00
|
|
|
if (newPosts.length < prevLength) deletedCount++;
|
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
2026-03-21 20:55:36 +08:00
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
case PostUpdateType.BATCH_DELETE: {
|
|
|
|
|
const batchDelete = update as any;
|
|
|
|
|
const idsToDelete = new Set(batchDelete.postIds || []);
|
|
|
|
|
const prevLength = newPosts.length;
|
|
|
|
|
newPosts = newPosts.filter(p => !idsToDelete.has(p.id));
|
|
|
|
|
deletedCount += prevLength - newPosts.length;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
case PostUpdateType.MOVE: {
|
|
|
|
|
const moveUpdate = update as any;
|
|
|
|
|
const fromIndex = newPosts.findIndex(p => p.id === moveUpdate.postId);
|
|
|
|
|
if (fromIndex !== -1) {
|
|
|
|
|
const [movedPost] = newPosts.splice(fromIndex, 1);
|
|
|
|
|
newPosts.splice(moveUpdate.toIndex, 0, movedPost);
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
case PostUpdateType.RESET: {
|
|
|
|
|
const resetUpdate = update as any;
|
|
|
|
|
newPosts = resetUpdate.posts || [];
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (addedCount > 0 || updatedCount > 0 || deletedCount > 0) {
|
|
|
|
|
setDiffUpdates(prev => ({
|
|
|
|
|
addedCount: prev.addedCount + addedCount,
|
|
|
|
|
updatedCount: prev.updatedCount + updatedCount,
|
|
|
|
|
deletedCount: prev.deletedCount + deletedCount,
|
|
|
|
|
lastUpdateTime: Date.now(),
|
|
|
|
|
}));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return newPosts;
|
|
|
|
|
});
|
|
|
|
|
} finally {
|
|
|
|
|
setIsProcessing(false);
|
|
|
|
|
setPendingUpdateCount(batcherRef.current?.getPendingCount() ?? 0);
|
|
|
|
|
}
|
|
|
|
|
}, []);
|
|
|
|
|
|
2026-03-23 03:58:26 +08:00
|
|
|
useEffect(() => {
|
|
|
|
|
if (enableDiff) {
|
|
|
|
|
calculatorRef.current = createPostDiffCalculator<T>(diffConfig);
|
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
2026-03-21 20:55:36 +08:00
|
|
|
}
|
2026-04-13 00:26:05 +08:00
|
|
|
return () => { calculatorRef.current = null; };
|
2026-03-23 03:58:26 +08:00
|
|
|
}, [enableDiff, diffConfig]);
|
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
2026-03-21 20:55:36 +08:00
|
|
|
|
2026-03-23 03:58:26 +08:00
|
|
|
useEffect(() => {
|
|
|
|
|
if (!enableBatching) return;
|
|
|
|
|
batcherRef.current = createPostUpdateBatcher(batcherOptions);
|
2026-04-13 00:26:05 +08:00
|
|
|
const unsubscribe = batcherRef.current.subscribe(handleBatchUpdates);
|
2026-03-23 03:58:26 +08:00
|
|
|
return () => {
|
|
|
|
|
unsubscribe();
|
|
|
|
|
batcherRef.current?.destroy();
|
|
|
|
|
batcherRef.current = null;
|
|
|
|
|
};
|
|
|
|
|
}, [enableBatching, batcherOptions, handleBatchUpdates]);
|
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
2026-03-21 20:55:36 +08:00
|
|
|
|
2026-04-13 00:26:05 +08:00
|
|
|
const syncFromStore = useCallback((state: PostsState) => {
|
|
|
|
|
setLoading(state.isLoading);
|
|
|
|
|
setRefreshing(state.isRefreshing);
|
|
|
|
|
setError(state.error);
|
|
|
|
|
setHasMore(state.hasMore);
|
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
2026-03-21 20:55:36 +08:00
|
|
|
|
2026-04-13 00:26:05 +08:00
|
|
|
batcherRef.current?.clearPending();
|
|
|
|
|
calculatorRef.current?.reset();
|
|
|
|
|
if (state.posts && state.posts.length > 0) {
|
|
|
|
|
const next = state.posts as unknown as T[];
|
|
|
|
|
if (next.length > maxPostCount) {
|
|
|
|
|
console.warn(`[useDifferentialPosts] Post count (${next.length}) exceeds limit (${maxPostCount})`);
|
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
2026-03-21 20:55:36 +08:00
|
|
|
}
|
2026-04-13 00:26:05 +08:00
|
|
|
setPosts(next);
|
|
|
|
|
previousPostsRef.current = next;
|
|
|
|
|
} else {
|
|
|
|
|
setPosts([]);
|
|
|
|
|
previousPostsRef.current = [];
|
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
2026-03-21 20:55:36 +08:00
|
|
|
}
|
2026-04-13 00:26:05 +08:00
|
|
|
}, [maxPostCount]);
|
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
2026-03-21 20:55:36 +08:00
|
|
|
|
|
|
|
|
useEffect(() => {
|
2026-04-13 00:26:05 +08:00
|
|
|
if (!autoSubscribe) return;
|
|
|
|
|
|
|
|
|
|
const currentState = usePostListStore.getState().getPostsState(listKey);
|
|
|
|
|
syncFromStore(currentState);
|
|
|
|
|
|
2026-06-18 02:29:54 +08:00
|
|
|
// listKey 切换时,如果目标列表在 store 中还没有有效数据(首次访问),
|
|
|
|
|
// 立即进入 loading 态,避免先渲染空列表再切到 loading 造成闪烁。
|
|
|
|
|
// syncFromStore 会用 store 的 isLoading 覆盖,因此在其之后补设。
|
|
|
|
|
// 如果已有数据(曾访问过),则保留旧数据,由后续 fetch 静默刷新。
|
|
|
|
|
if (!currentState.posts || currentState.posts.length === 0) {
|
|
|
|
|
setLoading(true);
|
|
|
|
|
}
|
|
|
|
|
|
2026-04-13 00:26:05 +08:00
|
|
|
const unsubscribe = usePostListStore.subscribe(state => {
|
|
|
|
|
const postsState = state.postsStateMap.get(listKey);
|
|
|
|
|
if (postsState) syncFromStore(postsState);
|
|
|
|
|
});
|
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
2026-03-21 20:55:36 +08:00
|
|
|
|
2026-04-13 00:26:05 +08:00
|
|
|
return unsubscribe;
|
|
|
|
|
}, [autoSubscribe, listKey, syncFromStore]);
|
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
2026-03-21 20:55:36 +08:00
|
|
|
|
|
|
|
|
const refresh = useCallback(async () => {
|
|
|
|
|
setRefreshing(true);
|
|
|
|
|
setError(null);
|
|
|
|
|
try {
|
2026-04-13 00:26:05 +08:00
|
|
|
await postSyncService.refreshPosts(listKey);
|
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
2026-03-21 20:55:36 +08:00
|
|
|
} catch (err) {
|
|
|
|
|
const errorMsg = err instanceof Error ? err.message : '刷新失败';
|
|
|
|
|
setError(errorMsg);
|
|
|
|
|
} finally {
|
|
|
|
|
setRefreshing(false);
|
|
|
|
|
}
|
|
|
|
|
}, [listKey]);
|
|
|
|
|
|
|
|
|
|
const loadMore = useCallback(async () => {
|
|
|
|
|
if (hasMore && !loading) {
|
|
|
|
|
setLoading(true);
|
|
|
|
|
setError(null);
|
|
|
|
|
try {
|
2026-04-13 00:26:05 +08:00
|
|
|
await postSyncService.loadMorePosts(listKey);
|
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
2026-03-21 20:55:36 +08:00
|
|
|
} catch (err) {
|
|
|
|
|
const errorMsg = err instanceof Error ? err.message : '加载更多失败';
|
|
|
|
|
setError(errorMsg);
|
|
|
|
|
} finally {
|
|
|
|
|
setLoading(false);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}, [listKey, hasMore, loading]);
|
|
|
|
|
|
2026-04-13 00:26:05 +08:00
|
|
|
const flush = useCallback(() => { batcherRef.current?.flush(); }, []);
|
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
2026-03-21 20:55:36 +08:00
|
|
|
|
|
|
|
|
const reset = useCallback(() => {
|
|
|
|
|
calculatorRef.current?.reset();
|
|
|
|
|
batcherRef.current?.clearPending();
|
2026-06-18 02:29:54 +08:00
|
|
|
// 同步清空 store 中对应 listKey 的数据,避免 subscribe 回调
|
|
|
|
|
// 在切换 listKey 时把上一个 key 的残留数据重新同步回本地造成闪烁
|
|
|
|
|
usePostListStore.getState().updatePostsState(listKey, {
|
|
|
|
|
posts: [],
|
|
|
|
|
cursor: null,
|
|
|
|
|
currentPage: 1,
|
|
|
|
|
hasMore: true,
|
|
|
|
|
isLoading: false,
|
|
|
|
|
isRefreshing: false,
|
|
|
|
|
error: null,
|
|
|
|
|
lastParams: undefined,
|
|
|
|
|
});
|
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
2026-03-21 20:55:36 +08:00
|
|
|
setPosts([]);
|
|
|
|
|
setLoading(false);
|
|
|
|
|
setRefreshing(false);
|
|
|
|
|
setError(null);
|
|
|
|
|
setHasMore(true);
|
|
|
|
|
previousPostsRef.current = [];
|
2026-04-13 00:26:05 +08:00
|
|
|
setDiffUpdates({ addedCount: 0, updatedCount: 0, deletedCount: 0, lastUpdateTime: 0 });
|
2026-06-18 02:29:54 +08:00
|
|
|
}, [listKey]);
|
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
2026-03-21 20:55:36 +08:00
|
|
|
|
|
|
|
|
const forceUpdate = useCallback((newPosts: T[]) => {
|
|
|
|
|
setPosts(newPosts);
|
|
|
|
|
previousPostsRef.current = newPosts;
|
|
|
|
|
}, []);
|
|
|
|
|
|
|
|
|
|
const getDiffStats = useCallback(() => {
|
|
|
|
|
const batcherStats = batcherRef.current?.getStats();
|
|
|
|
|
return {
|
|
|
|
|
totalBatches: batcherStats?.totalBatches ?? 0,
|
|
|
|
|
totalUpdates: batcherStats?.totalUpdates ?? 0,
|
|
|
|
|
averageBatchSize: batcherStats?.averageBatchSize ?? 0,
|
|
|
|
|
};
|
|
|
|
|
}, []);
|
|
|
|
|
|
|
|
|
|
useEffect(() => {
|
|
|
|
|
if (!enableBatching || !batcherRef.current) return;
|
|
|
|
|
const interval = setInterval(() => {
|
|
|
|
|
setPendingUpdateCount(batcherRef.current?.getPendingCount() ?? 0);
|
|
|
|
|
}, 50);
|
|
|
|
|
return () => clearInterval(interval);
|
|
|
|
|
}, [enableBatching]);
|
|
|
|
|
|
|
|
|
|
return {
|
|
|
|
|
posts,
|
|
|
|
|
loading,
|
2026-03-24 01:19:09 +08:00
|
|
|
isInitialLoading: loading && posts.length === 0 && !refreshing,
|
|
|
|
|
isLoadingMore: loading && posts.length > 0 && !refreshing,
|
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
2026-03-21 20:55:36 +08:00
|
|
|
refreshing,
|
|
|
|
|
error,
|
|
|
|
|
hasMore,
|
|
|
|
|
pendingUpdateCount,
|
|
|
|
|
isProcessing,
|
|
|
|
|
refresh,
|
|
|
|
|
loadMore,
|
|
|
|
|
flush,
|
|
|
|
|
reset,
|
|
|
|
|
forceUpdate,
|
|
|
|
|
getDiffStats,
|
|
|
|
|
diffUpdates,
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export default useDifferentialPosts;
|