refactor(PostCard, PostCard.legacy): remove legacy PostCard component and update exports
All checks were successful
Frontend CI / build-and-push-web (push) Successful in 8m37s
Frontend CI / ota-android (push) Successful in 10m53s
Frontend CI / build-android-apk (push) Successful in 51m16s

- Deleted the legacy PostCard component to streamline the codebase and improve maintainability.
- Updated exports in PostCard and index files to remove references to the legacy component.
- Adjusted PostCardProps to eliminate legacy properties, ensuring only the new API is supported.
- Enhanced the PostCard component to focus on modern implementation and features.
This commit is contained in:
lafay
2026-03-24 04:23:13 +08:00
parent 82e99d24d8
commit 357c1d4995
24 changed files with 1662 additions and 2243 deletions

View File

@@ -165,6 +165,8 @@ class MessageManager {
/** 正在加载会话列表下一页 */
private loadingMoreConversations = false;
/** 聊天页活跃期间延迟的会话列表刷新 */
private deferredConversationRefresh = false;
/** 远端会话列表(游标或页码,由注入/remoteListKind 决定) */
private readonly remoteConversationListSource: IConversationListPagedSource;
@@ -274,6 +276,32 @@ class MessageManager {
});
}
private shouldDeferConversationRefresh(source: string, forceRefresh: boolean): boolean {
if (!this.state.currentConversationId) return false;
if (!forceRefresh) return false;
// 列表域后台刷新来源:聊天活跃期间一律延后执行
return source === 'sse-reconnect' || source === 'prefetch' || source === 'hooks-initial-refresh';
}
async requestConversationListRefresh(
source: string,
options?: { force?: boolean; allowDefer?: boolean }
): Promise<void> {
const forceRefresh = options?.force ?? true;
const allowDefer = options?.allowDefer ?? true;
if (allowDefer && this.shouldDeferConversationRefresh(source, forceRefresh)) {
this.deferredConversationRefresh = true;
if (__DEV__) {
console.log('[MessageManager] defer conversation refresh request', {
source,
activeConversationId: this.state.currentConversationId,
});
}
return;
}
await this.fetchConversations(forceRefresh, source);
}
/**
* 按 message_id 合并消息并按 seq 排序。
* 后者覆盖前者,可用来吸收更完整的同 ID 消息体(例如服务端回包/SSE
@@ -430,7 +458,7 @@ class MessageManager {
this.initSSEListeners();
// 3. 加载会话列表
await this.fetchConversations();
await this.fetchConversations(false, 'initialize');
// 4. 加载未读数
await this.fetchUnreadCount();
@@ -539,9 +567,16 @@ class MessageManager {
const now = Date.now();
if (now - this.lastReconnectSyncAt > 1500) {
this.lastReconnectSyncAt = now;
this.fetchConversations(true).catch(error => {
console.error('[MessageManager] 连接后同步会话失败:', error);
});
// 聊天页活跃时不强刷会话列表,避免触发不必要的 UI 抖动/重算
if (!this.state.currentConversationId) {
this.requestConversationListRefresh('sse-reconnect', { force: true, allowDefer: true }).catch(error => {
console.error('[MessageManager] 连接后同步会话失败:', error);
});
} else {
this.fetchUnreadCount().catch(error => {
console.error('[MessageManager] 连接后同步未读数失败:', error);
});
}
if (this.state.currentConversationId) {
this.fetchMessages(this.state.currentConversationId).catch(error => {
console.error('[MessageManager] 连接后同步当前会话消息失败:', error);
@@ -1146,11 +1181,30 @@ class MessageManager {
/**
* 获取会话列表(首屏/下拉刷新:优先网络游标;可回退 SQLite对 UI 透明)
*/
async fetchConversations(forceRefresh = false): Promise<void> {
async fetchConversations(forceRefresh = false, source: string = 'unknown'): Promise<void> {
if (this.state.isLoadingConversations && !forceRefresh) {
return;
}
if (this.shouldDeferConversationRefresh(source, forceRefresh)) {
this.deferredConversationRefresh = true;
if (__DEV__) {
console.log('[MessageManager] defer fetchConversations', {
source,
activeConversationId: this.state.currentConversationId,
});
}
return;
}
if (__DEV__) {
console.log('[MessageManager] fetchConversations', {
source,
forceRefresh,
activeConversationId: this.state.currentConversationId,
});
}
// 非强制刷新且内存为空:先用本地源暖机,便于离线/弱网先展示列表
if (!forceRefresh && this.state.conversations.size === 0) {
const warmed = await this.hydrateConversationsFromLocalSource();
@@ -1304,21 +1358,29 @@ class MessageManager {
const mergeMessages = (base: MessageResponse[], incoming: MessageResponse[]): MessageResponse[] => {
return this.mergeMessagesById(base, incoming);
};
const existingMessagesAtStart = this.state.messagesMap.get(conversationId) || [];
const hasInMemoryMessages = existingMessagesAtStart.length > 0;
let baselineMaxSeq = hasInMemoryMessages
? existingMessagesAtStart.reduce((max, m) => Math.max(max, m.seq || 0), 0)
: 0;
// 1. 先从本地数据库加载(确保立即有数据展示)
if (!afterSeq) {
let localMessages: any[] = [];
let localMaxSeq = 0;
try {
localMessages = await getMessagesByConversation(conversationId, 20);
localMaxSeq = await getMaxSeq(conversationId);
} catch (error) {
// 架构原则:本地存储异常不阻断在线同步
console.warn('[MessageManager] 读取本地消息失败,回退到服务端同步:', error);
if (!hasInMemoryMessages) {
try {
localMessages = await getMessagesByConversation(conversationId, 20);
localMaxSeq = await getMaxSeq(conversationId);
baselineMaxSeq = localMaxSeq;
} catch (error) {
// 架构原则:本地存储异常不阻断在线同步
console.warn('[MessageManager] 读取本地消息失败,回退到服务端同步:', error);
}
}
if (localMessages.length > 0) {
if (!hasInMemoryMessages && localMessages.length > 0) {
// 转换格式
const formattedMessages: MessageResponse[] = localMessages.map(m => ({
id: m.id,
@@ -1343,7 +1405,7 @@ class MessageManager {
});
// 异步填充 sender 信息
this.enrichMessagesWithSenderInfo(conversationId, formattedMessages);
} else {
} else if (!hasInMemoryMessages) {
// 冷启动兜底:先下发空列表事件,避免 ChatScreen 长时间停留在 loading
this.state.messagesMap.set(conversationId, []);
this.notifySubscribers({
@@ -1434,8 +1496,8 @@ class MessageManager {
// 2.2 再基于 localMaxSeq 做增量补齐(防止快照窗口不足导致漏更老的新消息)
const snapshotMaxSeq = snapshotMessages.reduce((max, m) => Math.max(max, m.seq || 0), 0);
if (snapshotMaxSeq > localMaxSeq) {
const incrementalResp = await messageService.getMessages(conversationId, localMaxSeq);
if (snapshotMaxSeq > baselineMaxSeq) {
const incrementalResp = await messageService.getMessages(conversationId, baselineMaxSeq);
const newMessages = incrementalResp?.messages || [];
if (newMessages.length > 0) {
const existingMessages = this.state.messagesMap.get(conversationId) || [];
@@ -2226,6 +2288,12 @@ class MessageManager {
setActiveConversation(conversationId: string | null): void {
const normalizedConversationId = conversationId ? this.normalizeConversationId(conversationId) : null;
this.state.currentConversationId = normalizedConversationId;
if (!normalizedConversationId && this.deferredConversationRefresh) {
this.deferredConversationRefresh = false;
this.requestConversationListRefresh('deferred-after-chat', { force: true, allowDefer: false }).catch(error => {
console.error('[MessageManager] 延迟会话刷新失败:', error);
});
}
}
/**