refactor(ConversationList): streamline conversation list handling and enhance unread count management
All checks were successful
Frontend CI / build-and-push-web (push) Successful in 2m49s
Frontend CI / ota-android (push) Successful in 15m30s
Frontend CI / build-android-apk (push) Successful in 59m14s

- Removed debug display for unread count in ConversationListRow to clean up UI.
- Updated updateConversationCacheUnreadCount to optionally handle myLastReadSeq for better synchronization of read status.
- Refactored message service to unify offset and cursor pagination methods, improving data fetching consistency.
- Introduced a new method to normalize unread counts based on read cursor, ensuring accurate display of unread messages.
- Consolidated conversation list source implementations to simplify remote data fetching logic.
This commit is contained in:
lafay
2026-03-25 04:07:48 +08:00
parent dc8f9061ab
commit 90d834695f
6 changed files with 185 additions and 113 deletions

View File

@@ -25,51 +25,28 @@ export interface IConversationListPagedSource {
readonly hasMore: boolean;
}
/** 远端常规分页GET /conversations?page=&page_size=(始终请求网络,避免走 getConversations 的本地短路) */
export class NetworkOffsetConversationListPagedSource implements IConversationListPagedSource {
/**
* 远端会话列表offset 与 cursor 共用实现)
* 均通过 messageService.fetchRemoteConversationListPage 拉取并落库,行为一致。
*/
export class NetworkRemoteConversationListPagedSource implements IConversationListPagedSource {
private nextPage = 1;
private nextCursor: string | null = null;
private hasMoreAfterLastLoad = false;
private loadedOnce = false;
private readonly pageSize: number;
private readonly mode: RemoteConversationListSourceKind;
constructor(pageSize: number = CONVERSATION_LIST_PAGE_SIZE) {
constructor(
mode: RemoteConversationListSourceKind,
pageSize: number = CONVERSATION_LIST_PAGE_SIZE
) {
this.mode = mode;
this.pageSize = pageSize;
}
restart(): void {
this.nextPage = 1;
this.hasMoreAfterLastLoad = false;
this.loadedOnce = false;
}
get hasMore(): boolean {
return this.loadedOnce && this.hasMoreAfterLastLoad;
}
async loadNext(): Promise<ConversationListPage> {
const response = await messageService.getConversations(this.nextPage, this.pageSize, true);
const items = response.list || [];
const totalPages = Math.max(0, response.total_pages ?? 0);
const currentPage = response.page ?? this.nextPage;
this.hasMoreAfterLastLoad = totalPages > 0 && currentPage < totalPages;
this.nextPage = currentPage + 1;
this.loadedOnce = true;
return { items, hasMore: this.hasMoreAfterLastLoad };
}
}
/** 远端游标接口 */
export class NetworkCursorConversationListPagedSource implements IConversationListPagedSource {
private nextCursor: string | null = null;
private hasMoreAfterLastLoad = false;
private loadedOnce = false;
private readonly pageSize: number;
constructor(pageSize: number = CONVERSATION_LIST_PAGE_SIZE) {
this.pageSize = pageSize;
}
restart(): void {
this.nextCursor = null;
this.hasMoreAfterLastLoad = false;
this.loadedOnce = false;
@@ -80,16 +57,22 @@ export class NetworkCursorConversationListPagedSource implements IConversationLi
}
async loadNext(): Promise<ConversationListPage> {
const response = await messageService.getConversationsCursor(
this.nextCursor == null
? { page_size: this.pageSize }
: { cursor: this.nextCursor, page_size: this.pageSize }
);
const items = response.list || [];
this.nextCursor = response.next_cursor ?? null;
this.hasMoreAfterLastLoad = Boolean(response.has_more && response.next_cursor != null);
const result = await messageService.fetchRemoteConversationListPage({
mode: this.mode,
pageSize: this.pageSize,
...(this.mode === 'offset'
? { page: this.nextPage }
: { cursor: this.nextCursor }),
});
this.hasMoreAfterLastLoad = result.hasMore;
if (this.mode === 'offset') {
this.nextPage = result.nextPage ?? this.nextPage + 1;
} else {
this.nextCursor = result.nextCursor ?? null;
}
this.loadedOnce = true;
return { items, hasMore: this.hasMoreAfterLastLoad };
return { items: result.items, hasMore: result.hasMore };
}
}
@@ -120,14 +103,12 @@ export class SqliteConversationListPagedSource implements IConversationListPaged
}
}
/** 未注入 remote 时,按类型创建默认远端源 */
/** 远端会话列表分页策略 */
export type RemoteConversationListSourceKind = 'cursor' | 'offset';
export function createRemoteConversationListSource(
kind: RemoteConversationListSourceKind,
pageSize: number = CONVERSATION_LIST_PAGE_SIZE
): IConversationListPagedSource {
return kind === 'offset'
? new NetworkOffsetConversationListPagedSource(pageSize)
: new NetworkCursorConversationListPagedSource(pageSize);
return new NetworkRemoteConversationListPagedSource(kind, pageSize);
}