refactor(ProcessPostUseCase, useCursorPagination, useDifferentialPosts): enhance post merging and loading states
All checks were successful
Frontend CI / build-and-push-web (push) Successful in 4m57s
Frontend CI / ota-android (push) Successful in 10m48s
Frontend CI / build-android-apk (push) Successful in 52m58s

- Introduced new methods for merging posts and comments efficiently, improving performance during data updates.
- Updated loading state management in hooks to include initial loading and loading more states for better user feedback.
- Refactored HomeScreen and PostDetailScreen to utilize the new loading states and merging logic, enhancing user experience during data fetching.
- Improved pagination handling in useCursorPagination and useDifferentialPosts to ensure consistent data management across components.
This commit is contained in:
lafay
2026-03-24 01:19:09 +08:00
parent aaf53d1c3b
commit 5c9cb6acea
11 changed files with 475 additions and 101 deletions

View File

@@ -119,6 +119,8 @@ export const HomeScreen: React.FC = () => {
const {
posts,
loading: isLoading,
isInitialLoading,
isLoadingMore,
refreshing: isRefreshing,
hasMore,
error,
@@ -135,17 +137,23 @@ export const HomeScreen: React.FC = () => {
// 加载更多方法
const loadMore = useCallback(async () => {
if (hasMore && !isLoading && !isLoadingMoreRef.current) {
if (hasMore && !isLoadingMore && !isLoadingMoreRef.current) {
isLoadingMoreRef.current = true;
const startedAt = Date.now();
try {
await processPostUseCase.loadMorePosts(listKey);
console.log('[PostPerf] home loadMore', {
listKey,
costMs: Date.now() - startedAt,
totalItems: posts.length,
});
} catch (err) {
console.error('加载更多失败:', err);
} finally {
isLoadingMoreRef.current = false;
}
}
}, [listKey, hasMore, isLoading]);
}, [posts.length, listKey, hasMore, isLoadingMore]);
// 网格模式滚动处理 - 检测是否滚动到底部
const handleGridScroll = useCallback((event: any) => {
@@ -366,7 +374,9 @@ export const HomeScreen: React.FC = () => {
};
// 渲染帖子卡片(列表模式)
const renderPostList = ({ item }: { item: Post }) => {
const keyExtractor = useCallback((item: Post) => item.id, []);
const renderPostList = useCallback(({ item }: { item: Post }) => {
const authorId = item.author?.id || '';
const isPostAuthor = currentUser?.id === authorId;
return (
@@ -394,7 +404,7 @@ export const HomeScreen: React.FC = () => {
/>
</View>
);
};
}, [currentUser?.id, handleBookmark, handleDeletePost, handleImagePress, handleLike, handlePostPress, handleShare, handleUserPress, isMobile, listItemWidth, responsiveGap]);
// 估算帖子在瀑布流中的高度(用于均匀分配)
const estimatePostHeight = (post: Post, columnWidth: number): number => {
@@ -558,8 +568,8 @@ export const HomeScreen: React.FC = () => {
};
// 渲染空状态
const renderEmpty = () => {
if (isLoading) return null;
const renderEmpty = useCallback(() => {
if (isInitialLoading) return null;
return (
<EmptyState
@@ -567,7 +577,7 @@ export const HomeScreen: React.FC = () => {
description={activeIndex === 1 ? '关注一些用户来获取内容吧' : '暂无帖子,快去发布第一条内容吧'}
/>
);
};
}, [activeIndex, isInitialLoading]);
// 渲染列表内容
const renderListContent = () => {
@@ -581,7 +591,7 @@ export const HomeScreen: React.FC = () => {
<FlatList
data={displayPosts}
renderItem={renderPostList}
keyExtractor={item => item.id}
keyExtractor={keyExtractor}
contentContainerStyle={[
styles.listContent,
{
@@ -602,7 +612,12 @@ export const HomeScreen: React.FC = () => {
onEndReached={loadMore}
onEndReachedThreshold={0.3}
ListEmptyComponent={renderEmpty}
ListFooterComponent={isLoading ? <Loading size="sm" /> : null}
ListFooterComponent={isLoadingMore ? <Loading size="sm" /> : null}
initialNumToRender={8}
maxToRenderPerBatch={8}
updateCellsBatchingPeriod={60}
windowSize={7}
removeClippedSubviews
/>
);
};
@@ -661,7 +676,9 @@ export const HomeScreen: React.FC = () => {
// 移动端:使用 GestureDetector 支持手势切换 Tab
<GestureDetector gesture={swipeGesture}>
<View style={styles.contentContainer}>
{viewMode === 'list' ? (
{isInitialLoading ? (
<Loading fullScreen />
) : viewMode === 'list' ? (
renderListContent()
) : (
// 网格模式:使用响应式网格
@@ -672,7 +689,9 @@ export const HomeScreen: React.FC = () => {
) : (
// 桌面端/平板端:不使用 GestureDetector避免拦截侧边栏点击
<View style={styles.contentContainer}>
{viewMode === 'list' ? (
{isInitialLoading ? (
<Loading fullScreen />
) : viewMode === 'list' ? (
renderListContent()
) : (
// 网格模式:使用响应式网格