refactor: standardize pagination response structure and enhance cursor handling
- Update various services and hooks to replace 'items' with 'list' for consistency in pagination responses. - Modify PostRepository, commentService, groupService, messageService, and postService to align with the new response structure. - Enhance cursor pagination logic in hooks and components to ensure proper handling of pagination states. - Refactor HomeScreen, PostDetailScreen, SearchScreen, and other components to utilize the updated pagination structure.
This commit is contained in:
@@ -64,10 +64,14 @@ export interface PostsState {
|
||||
hasMore: boolean;
|
||||
/** 错误信息 */
|
||||
error: string | null;
|
||||
/** 当前游标 */
|
||||
/** 当前游标(cursor 模式) */
|
||||
cursor: string | null;
|
||||
/** 当前页码(page 模式) */
|
||||
currentPage: number;
|
||||
/** 最后加载时间 */
|
||||
lastLoadTime: number | null;
|
||||
/** 上次请求的参数(用于加载更多和刷新) */
|
||||
lastParams?: GetPostsParams;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -198,6 +202,7 @@ class ProcessPostUseCase {
|
||||
hasMore: true,
|
||||
error: null,
|
||||
cursor: null,
|
||||
currentPage: 1,
|
||||
lastLoadTime: null,
|
||||
};
|
||||
this.postsState.set(key, state);
|
||||
@@ -257,29 +262,32 @@ class ProcessPostUseCase {
|
||||
* @param key 列表键(用于区分不同的列表)
|
||||
*/
|
||||
async fetchPosts(params?: GetPostsParams, key: string = 'default'): Promise<PostsResult> {
|
||||
const state = this.getPostsState(key);
|
||||
|
||||
// 更新加载状态
|
||||
this.updatePostsState(key, { isLoading: true, error: null });
|
||||
|
||||
try {
|
||||
// 合并分页参数
|
||||
// 默认传递空字符串 cursor 来启动 cursor 模式
|
||||
// 注意:cursor 要放在 ...params 后面,这样只有在 params 没有传 cursor 时才使用默认值
|
||||
const queryParams: GetPostsParams = {
|
||||
page: params?.page || 1,
|
||||
pageSize: params?.pageSize || DEFAULT_PAGE_SIZE,
|
||||
cursor: params?.cursor || state.cursor || undefined,
|
||||
...params,
|
||||
cursor: params?.cursor !== undefined ? params.cursor : '', // 默认使用空字符串启动 cursor 模式
|
||||
};
|
||||
|
||||
const result = await postRepository.getPosts(queryParams);
|
||||
|
||||
// 更新状态
|
||||
// 判断是否为 cursor 模式(有 next_cursor 返回)
|
||||
const isCursorMode = result.nextCursor !== undefined && result.nextCursor !== null;
|
||||
|
||||
// 更新状态(保存请求参数以便加载更多时使用)
|
||||
this.updatePostsState(key, {
|
||||
posts: result.posts,
|
||||
hasMore: result.hasMore,
|
||||
cursor: result.nextCursor || null,
|
||||
cursor: isCursorMode ? result.nextCursor : null, // cursor 模式保存 cursor,否则设为 null 表示 page 模式
|
||||
currentPage: isCursorMode ? undefined : 1, // page 模式从第 1 页开始
|
||||
isLoading: false,
|
||||
lastLoadTime: Date.now(),
|
||||
lastParams: params, // 保存请求参数
|
||||
});
|
||||
|
||||
// 通知订阅者
|
||||
@@ -312,20 +320,29 @@ class ProcessPostUseCase {
|
||||
* @param key 列表键
|
||||
*/
|
||||
async refreshPosts(key: string = 'default'): Promise<PostsResult> {
|
||||
const state = this.getPostsState(key);
|
||||
|
||||
// 更新刷新状态
|
||||
this.updatePostsState(key, { isRefreshing: true, error: null });
|
||||
|
||||
try {
|
||||
// 使用保存的请求参数(如 post_type)进行刷新
|
||||
// 默认传递空字符串 cursor 来启动 cursor 模式
|
||||
const result = await postRepository.getPosts({
|
||||
page: 1,
|
||||
pageSize: DEFAULT_PAGE_SIZE,
|
||||
...state.lastParams,
|
||||
cursor: state.lastParams?.cursor !== undefined ? state.lastParams.cursor : '', // 默认使用空字符串启动 cursor 模式
|
||||
});
|
||||
|
||||
// 判断是否为 cursor 模式(有 next_cursor 返回)
|
||||
const isCursorMode = result.nextCursor !== undefined && result.nextCursor !== null;
|
||||
|
||||
// 更新状态
|
||||
this.updatePostsState(key, {
|
||||
posts: result.posts,
|
||||
hasMore: result.hasMore,
|
||||
cursor: result.nextCursor || null,
|
||||
cursor: isCursorMode ? result.nextCursor : null,
|
||||
currentPage: isCursorMode ? undefined : 1,
|
||||
isRefreshing: false,
|
||||
lastLoadTime: Date.now(),
|
||||
});
|
||||
@@ -372,21 +389,45 @@ class ProcessPostUseCase {
|
||||
this.updatePostsState(key, { isLoading: true, error: null });
|
||||
|
||||
try {
|
||||
const queryParams: GetPostsParams = {
|
||||
pageSize: DEFAULT_PAGE_SIZE,
|
||||
cursor: state.cursor || undefined,
|
||||
};
|
||||
// 判断使用哪种分页模式:cursor 不为 null 表示使用 cursor 模式
|
||||
const useCursorMode = state.cursor !== null && state.cursor !== undefined;
|
||||
|
||||
// 必须先展开 lastParams,再由本次分页字段覆盖。
|
||||
// lastParams 来自首次 fetch(通常含 page:1),若写在展开之前会把 nextPage/cursor 覆盖掉,导致永远请求第 1 页、无法加载第 3 页及以后。
|
||||
const base = { ...(state.lastParams ?? {}) } as GetPostsParams;
|
||||
let queryParams: GetPostsParams;
|
||||
|
||||
if (useCursorMode) {
|
||||
delete base.page;
|
||||
queryParams = {
|
||||
...base,
|
||||
pageSize: DEFAULT_PAGE_SIZE,
|
||||
cursor: state.cursor!,
|
||||
};
|
||||
} else {
|
||||
const nextPage = (state.currentPage || 1) + 1;
|
||||
delete base.cursor;
|
||||
queryParams = {
|
||||
...base,
|
||||
pageSize: DEFAULT_PAGE_SIZE,
|
||||
page: nextPage,
|
||||
};
|
||||
}
|
||||
|
||||
const result = await postRepository.getPosts(queryParams);
|
||||
|
||||
// 合并新数据
|
||||
const newPosts = [...state.posts, ...result.posts];
|
||||
|
||||
// 判断响应是否为 cursor 模式(有 next_cursor 返回)
|
||||
const responseIsCursorMode = result.nextCursor !== undefined && result.nextCursor !== null;
|
||||
|
||||
// 更新状态
|
||||
this.updatePostsState(key, {
|
||||
posts: newPosts,
|
||||
hasMore: result.hasMore,
|
||||
cursor: result.nextCursor || null,
|
||||
cursor: responseIsCursorMode ? result.nextCursor : null,
|
||||
currentPage: useCursorMode ? state.currentPage : ((state.currentPage || 1) + 1),
|
||||
isLoading: false,
|
||||
lastLoadTime: Date.now(),
|
||||
});
|
||||
@@ -398,6 +439,7 @@ class ProcessPostUseCase {
|
||||
};
|
||||
} catch (error) {
|
||||
const errorMessage = error instanceof Error ? error.message : '加载更多帖子失败';
|
||||
console.error('[ProcessPostUseCase] Load more error:', errorMessage);
|
||||
this.updatePostsState(key, {
|
||||
isLoading: false,
|
||||
error: errorMessage,
|
||||
|
||||
Reference in New Issue
Block a user