refactor: streamline post sync, fix image gallery, and clean up chat screen

- **Post sync optimization**: Clear store immediately when params change to prevent flashing old posts; replace instead of merge on refresh
- **ImageGallery fix**: Use idempotent download option, migrate to Asset.create() API, fix Android file path requirement, ensure proper cleanup
- **UserProfileScreen**: Add ImageGallery for post image viewing with consistent implementation
- **SearchScreen**: Add entrance animation and empty state
- **ChatScreen**: Remove unused state variables (lastSeq, firstSeq, isProgrammaticScrollRef) and dead imports
This commit is contained in:
lafay
2026-06-18 02:29:54 +08:00
parent 96e8de18bf
commit a921aacefd
11 changed files with 248 additions and 190 deletions

View File

@@ -62,23 +62,36 @@ class PostSyncService {
}
async fetchPosts(params?: GetPostsParams, key: string = 'default'): Promise<PostsResult> {
const store = usePostListStore.getState();
store.updatePostsState(key, { isLoading: true, error: null });
const queryParams: GetPostsParams = {
pageSize: params?.pageSize || DEFAULT_PAGE_SIZE,
...params,
cursor: params?.cursor !== undefined ? params.cursor : '',
};
// 判断参数是否变化:参数变化(切换分区/排序/筛选)时直接清空旧数据,
// 避免渲染期间残留上一个分区的帖子造成闪烁
const prevState = usePostListStore.getState().getPostsState(key);
const paramsChanged = JSON.stringify(prevState.lastParams) !== JSON.stringify(queryParams);
// 参数变化时立即写入空数据 + loading 状态,确保 UI 第一时间进入加载态
// 而不是先渲染上一个分区的旧帖子
usePostListStore.getState().updatePostsState(key, {
isLoading: true,
error: null,
...(paramsChanged ? { posts: [], cursor: null, currentPage: 1, hasMore: true } : {}),
});
try {
const queryParams: GetPostsParams = {
pageSize: params?.pageSize || DEFAULT_PAGE_SIZE,
...params,
cursor: params?.cursor !== undefined ? params.cursor : '',
};
const result = await postRepository.getPosts(queryParams);
const isCursorMode = result.nextCursor !== undefined && result.nextCursor !== null;
const currentState = usePostListStore.getState().getPostsState(key);
const incomingPosts = Array.isArray(result.posts) ? result.posts : [];
const mergeStart = Date.now();
const mergedPosts = mergeRefreshWindow(currentState.posts, incomingPosts);
// 参数变化时直接替换;同参数刷新则合并以保留滚动位置上的帖子
const mergedPosts = paramsChanged
? incomingPosts
: mergeRefreshWindow(currentState.posts, incomingPosts);
const mergeCost = Date.now() - mergeStart;
if (mergeCost >= MERGE_PERF_WARN_THRESHOLD_MS) {
console.log('[PostPerf] fetchPosts merge cost', { key, costMs: mergeCost, prev: currentState.posts.length, next: incomingPosts.length });
@@ -116,7 +129,8 @@ class PostSyncService {
const isCursorMode = result.nextCursor !== undefined && result.nextCursor !== null;
const incomingPosts = Array.isArray(result.posts) ? result.posts : [];
const mergeStart = Date.now();
const mergedPosts = mergeRefreshWindow(state.posts, incomingPosts);
// refreshPosts 是刷新操作,应直接替换当前列表,避免旧数据残留
const mergedPosts = incomingPosts;
const mergeCost = Date.now() - mergeStart;
if (mergeCost >= MERGE_PERF_WARN_THRESHOLD_MS) {
console.log('[PostPerf] refreshPosts merge cost', { key, costMs: mergeCost, prev: state.posts.length, next: incomingPosts.length });