refactor(ConversationList): streamline conversation list handling and enhance unread count management
- 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:
@@ -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);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user