refactor(message): replace SubscriptionManager with Zustand selectors
All checks were successful
Frontend CI / ota-android (push) Successful in 11m17s
Frontend CI / build-and-push-web (push) Successful in 25m8s
Frontend CI / build-android-apk (push) Successful in 59m7s

Remove custom SubscriptionManager class and adopt Zustand's built-in
selector mechanism for reactive state updates. This simplifies the
architecture by eliminating manual subscription management and relying
on Zustand's automatic dependency tracking for component re-renders.

Key changes:
- Remove SubscriptionManager class from store.ts
- Replace all notifySubscribers calls with direct store updates
- Update hooks to use Zustand selectors with useShallow for complex data
- Remove subscribe/unsubscribe patterns from MessageManager
- Simplify EmbeddedChat to use selector instead of local state
- Rename requestConversationListRefresh to refreshConversations
This commit is contained in:
lafay
2026-03-31 19:15:13 +08:00
parent 94c11062f0
commit 259de04f3e
14 changed files with 198 additions and 993 deletions

View File

@@ -2,14 +2,16 @@
* 会话操作服务
* 处理会话的 CRUD 操作
*
* 重构说明:直接使用 zustand store 替代 IMessageStateManager
* 重构说明:
* - 直接使用 zustand store 替代 IMessageStateManager
* - 移除了 SubscriptionManager 调用Zustand 的 set() 会自动触发组件重渲染
*/
import type { ConversationResponse } from '../../../types/dto';
import { messageService } from '../../../services/messageService';
import { deleteConversation } from '../../../services/database';
import type { IConversationOperations } from '../types';
import { useMessageStore, subscriptionManager, normalizeConversationId } from '../store';
import { useMessageStore, normalizeConversationId } from '../store';
export class ConversationOperations implements IConversationOperations {
/**
@@ -24,21 +26,9 @@ export class ConversationOperations implements IConversationOperations {
// 添加到会话列表
store.updateConversation(conversation);
// 通知更新
subscriptionManager.notifySubscribers({
type: 'conversations_updated',
payload: { conversations: store.getConversations() },
timestamp: Date.now(),
});
return conversation;
} catch (error) {
console.error('[ConversationOperations] 创建会话失败:', error);
subscriptionManager.notifySubscribers({
type: 'error',
payload: { error, context: 'createConversation' },
timestamp: Date.now(),
});
return null;
}
}
@@ -60,13 +50,6 @@ export class ConversationOperations implements IConversationOperations {
};
store.updateConversation(updatedConv);
// 通知更新
subscriptionManager.notifySubscribers({
type: 'conversations_updated',
payload: { conversations: store.getConversations() },
timestamp: Date.now(),
});
}
/**
@@ -76,23 +59,6 @@ export class ConversationOperations implements IConversationOperations {
const store = useMessageStore.getState();
store.removeConversation(conversationId);
// 通知更新
subscriptionManager.notifySubscribers({
type: 'conversations_updated',
payload: { conversations: store.getConversations() },
timestamp: Date.now(),
});
const unreadCount = store.getUnreadCount();
subscriptionManager.notifySubscribers({
type: 'unread_count_updated',
payload: {
totalUnreadCount: unreadCount.total,
systemUnreadCount: unreadCount.system,
},
timestamp: Date.now(),
});
// 删除本地数据库中的会话
deleteConversation(conversationId).catch(error => {
console.error('[ConversationOperations] 删除本地会话失败:', error);
@@ -105,21 +71,6 @@ export class ConversationOperations implements IConversationOperations {
clearConversations(): void {
const store = useMessageStore.getState();
store.reset();
subscriptionManager.notifySubscribers({
type: 'conversations_updated',
payload: { conversations: [] },
timestamp: Date.now(),
});
subscriptionManager.notifySubscribers({
type: 'unread_count_updated',
payload: {
totalUnreadCount: 0,
systemUnreadCount: 0,
},
timestamp: Date.now(),
});
}
/**
@@ -149,22 +100,6 @@ export class ConversationOperations implements IConversationOperations {
Math.max(0, currentUnread.total + diff),
currentUnread.system
);
// 通知更新
subscriptionManager.notifySubscribers({
type: 'unread_count_updated',
payload: {
totalUnreadCount: store.getUnreadCount().total,
systemUnreadCount: store.getUnreadCount().system,
},
timestamp: Date.now(),
});
subscriptionManager.notifySubscribers({
type: 'conversations_updated',
payload: { conversations: store.getConversations() },
timestamp: Date.now(),
});
}
/**
@@ -191,22 +126,6 @@ export class ConversationOperations implements IConversationOperations {
currentUnread.total + 1,
currentUnread.system
);
// 通知更新
subscriptionManager.notifySubscribers({
type: 'unread_count_updated',
payload: {
totalUnreadCount: store.getUnreadCount().total,
systemUnreadCount: store.getUnreadCount().system,
},
timestamp: Date.now(),
});
subscriptionManager.notifySubscribers({
type: 'conversations_updated',
payload: { conversations: store.getConversations() },
timestamp: Date.now(),
});
}
/**
@@ -216,15 +135,6 @@ export class ConversationOperations implements IConversationOperations {
const store = useMessageStore.getState();
const currentUnread = store.getUnreadCount();
store.setUnreadCount(currentUnread.total, count);
subscriptionManager.notifySubscribers({
type: 'unread_count_updated',
payload: {
totalUnreadCount: currentUnread.total,
systemUnreadCount: count,
},
timestamp: Date.now(),
});
}
/**
@@ -234,15 +144,6 @@ export class ConversationOperations implements IConversationOperations {
const store = useMessageStore.getState();
const currentUnread = store.getUnreadCount();
store.setUnreadCount(currentUnread.total, currentUnread.system + 1);
subscriptionManager.notifySubscribers({
type: 'unread_count_updated',
payload: {
totalUnreadCount: currentUnread.total,
systemUnreadCount: currentUnread.system + 1,
},
timestamp: Date.now(),
});
}
/**
@@ -253,14 +154,5 @@ export class ConversationOperations implements IConversationOperations {
const currentUnread = store.getUnreadCount();
const newSystemCount = Math.max(0, currentUnread.system - count);
store.setUnreadCount(currentUnread.total, newSystemCount);
subscriptionManager.notifySubscribers({
type: 'unread_count_updated',
payload: {
totalUnreadCount: currentUnread.total,
systemUnreadCount: newSystemCount,
},
timestamp: Date.now(),
});
}
}

View File

@@ -2,14 +2,16 @@
* 消息发送服务
* 处理消息发送相关逻辑
*
* 重构说明:直接使用 zustand store 替代 IMessageStateManager
* 重构说明:
* - 直接使用 zustand store 替代 IMessageStateManager
* - 移除了 SubscriptionManager 调用Zustand 的 set() 会自动触发组件重渲染
*/
import type { MessageResponse, MessageSegment, ConversationResponse } from '../../../types/dto';
import { messageService } from '../../../services/messageService';
import { saveMessage } from '../../../services/database';
import type { IMessageSendService } from '../types';
import { useMessageStore, subscriptionManager, mergeMessagesById } from '../store';
import { useMessageStore, mergeMessagesById } from '../store';
export class MessageSendService implements IMessageSendService {
private getCurrentUserId: () => string | null;
@@ -53,28 +55,9 @@ export class MessageSendService implements IMessageSendService {
const updatedMessages = mergeMessagesById(existingMessages, [newMessage]);
store.setMessages(conversationId, updatedMessages);
// 关键:立即广播消息列表更新
subscriptionManager.notifySubscribers({
type: 'messages_updated',
payload: {
conversationId,
messages: updatedMessages,
newMessage,
source: 'send',
},
timestamp: Date.now(),
});
// 更新会话最后消息
this.updateConversationWithNewMessage(conversationId, newMessage);
// 通知消息已发送
subscriptionManager.notifySubscribers({
type: 'message_sent',
payload: { conversationId, message: newMessage },
timestamp: Date.now(),
});
// 保存到本地数据库
const textContent = segments
?.filter((s: any) => s.type === 'text')
@@ -100,11 +83,6 @@ export class MessageSendService implements IMessageSendService {
return null;
} catch (error) {
console.error('[MessageSendService] 发送消息失败:', error);
subscriptionManager.notifySubscribers({
type: 'error',
payload: { error, context: 'sendMessage' },
timestamp: Date.now(),
});
return null;
}
}

View File

@@ -2,7 +2,9 @@
* 消息同步服务
* 处理消息和会话的服务器同步逻辑
*
* 重构说明:直接使用 zustand store 替代 IMessageStateManager
* 重构说明:
* - 直接使用 zustand store 替代 IMessageStateManager
* - 移除了 SubscriptionManager 调用Zustand 的 set() 会自动触发组件重渲染
*/
import type { ConversationResponse, MessageResponse } from '../../../types/dto';
@@ -21,7 +23,7 @@ import {
CONVERSATION_LIST_PAGE_SIZE,
} from '../../conversationListSources';
import type { IMessageSyncService, MessageManagerConversationListDeps, IUserCacheService } from '../types';
import { useMessageStore, subscriptionManager, normalizeConversationId, mergeMessagesById } from '../store';
import { useMessageStore, normalizeConversationId, mergeMessagesById } from '../store';
import { ReadReceiptManager } from './ReadReceiptManager';
export class MessageSyncService implements IMessageSyncService {
@@ -94,19 +96,11 @@ export class MessageSyncService implements IMessageSyncService {
if (!forceRefresh && currentState.conversations.size === 0) {
const warmed = await this.hydrateConversationsFromLocalSource();
if (warmed) {
this.emitConversationListAndUnreadUpdates();
this.persistConversationListCache();
}
}
store.setLoading(true);
const emitLoadingToUi = store.getConversations().length === 0;
if (emitLoadingToUi) {
subscriptionManager.notifySubscribers({
type: 'conversations_loading',
payload: { loading: true },
timestamp: Date.now(),
});
}
try {
this.remoteConversationListSource.restart();
@@ -129,29 +123,17 @@ export class MessageSyncService implements IMessageSyncService {
);
store.setUnreadCount(totalUnread, store.getUnreadCount().system);
this.emitConversationListAndUnreadUpdates();
this.persistConversationListCache();
} catch (error) {
console.error('[MessageSyncService] 获取会话列表失败:', error);
if (store.getConversations().length === 0) {
const recovered = await this.hydrateConversationsFromLocalSource();
if (recovered) {
this.emitConversationListAndUnreadUpdates();
this.persistConversationListCache();
}
}
subscriptionManager.notifySubscribers({
type: 'error',
payload: { error, context: 'fetchConversations' },
timestamp: Date.now(),
});
} finally {
store.setLoading(false);
if (emitLoadingToUi) {
subscriptionManager.notifySubscribers({
type: 'conversations_loading',
payload: { loading: false },
timestamp: Date.now(),
});
}
}
}
@@ -178,14 +160,9 @@ export class MessageSyncService implements IMessageSyncService {
});
this.recomputeConversationTotalUnread();
this.emitConversationListAndUnreadUpdates();
this.persistConversationListCache();
} catch (error) {
console.error('[MessageSyncService] 加载更多会话失败:', error);
subscriptionManager.notifySubscribers({
type: 'error',
payload: { error, context: 'loadMoreConversations' },
timestamp: Date.now(),
});
} finally {
this.loadingMoreConversations = false;
}
@@ -252,27 +229,9 @@ export class MessageSyncService implements IMessageSyncService {
}));
store.setMessages(conversationId, formattedMessages);
subscriptionManager.notifySubscribers({
type: 'messages_updated',
payload: {
conversationId,
messages: formattedMessages,
source: 'local',
},
timestamp: Date.now(),
});
} else {
// 冷启动兜底:先下发空列表事件
// 冷启动兜底:先设置空列表
store.setMessages(conversationId, []);
subscriptionManager.notifySubscribers({
type: 'messages_updated',
payload: {
conversationId,
messages: [],
source: 'local_empty',
},
timestamp: Date.now(),
});
}
} catch (error) {
console.warn('[MessageSyncService] 读取本地消息失败:', error);
@@ -288,17 +247,6 @@ export class MessageSyncService implements IMessageSyncService {
const existingMessages = store.getMessages(conversationId);
const mergedSnapshot = mergeMessagesById(existingMessages, snapshotMessages);
store.setMessages(conversationId, mergedSnapshot);
subscriptionManager.notifySubscribers({
type: 'messages_updated',
payload: {
conversationId,
messages: mergedSnapshot,
newMessages: snapshotMessages,
source: 'server_snapshot',
},
timestamp: Date.now(),
});
// 持久化到本地
saveMessagesBatch(snapshotMessages.map((m: any) => ({
@@ -327,17 +275,6 @@ export class MessageSyncService implements IMessageSyncService {
const existingMessages = store.getMessages(conversationId);
const mergedMessages = mergeMessagesById(existingMessages, newMessages);
store.setMessages(conversationId, mergedMessages);
subscriptionManager.notifySubscribers({
type: 'messages_updated',
payload: {
conversationId,
messages: mergedMessages,
newMessages,
source: 'server_incremental',
},
timestamp: Date.now(),
});
saveMessagesBatch(newMessages.map((m: any) => ({
id: m.id,
@@ -368,16 +305,6 @@ export class MessageSyncService implements IMessageSyncService {
const mergedMessages = mergeMessagesById(existingMessages, newMessages);
store.setMessages(conversationId, mergedMessages);
subscriptionManager.notifySubscribers({
type: 'messages_updated',
payload: {
conversationId,
messages: mergedMessages,
newMessages,
source: 'server',
},
timestamp: Date.now(),
});
saveMessagesBatch(newMessages.map((m: any) => ({
id: m.id,
@@ -397,11 +324,6 @@ export class MessageSyncService implements IMessageSyncService {
}
} catch (error) {
console.error('[MessageSyncService] 获取消息失败:', error);
subscriptionManager.notifySubscribers({
type: 'error',
payload: { error, context: 'fetchMessages', conversationId },
timestamp: Date.now(),
});
} finally {
// 异步填充用户信息(不阻塞消息显示)
const currentMessages = store.getMessages(conversationId);
@@ -411,15 +333,6 @@ export class MessageSyncService implements IMessageSyncService {
currentMessages,
(convId, enrichedMessages) => {
store.setMessages(convId, enrichedMessages);
subscriptionManager.notifySubscribers({
type: 'messages_updated',
payload: {
conversationId: convId,
messages: enrichedMessages,
source: 'sender_enriched',
},
timestamp: Date.now(),
});
}
);
}
@@ -452,12 +365,6 @@ export class MessageSyncService implements IMessageSyncService {
const mergedMessages = this.mergeOlderMessages(existingMessages, formattedMessages);
store.setMessages(conversationId, mergedMessages);
subscriptionManager.notifySubscribers({
type: 'messages_updated',
payload: { conversationId, messages: mergedMessages, source: 'local_history' },
timestamp: Date.now(),
});
return formattedMessages;
}
@@ -484,12 +391,6 @@ export class MessageSyncService implements IMessageSyncService {
const mergedMessages = this.mergeOlderMessages(existingMessages, serverMessages);
store.setMessages(conversationId, mergedMessages);
subscriptionManager.notifySubscribers({
type: 'messages_updated',
payload: { conversationId, messages: mergedMessages, source: 'server_history' },
timestamp: Date.now(),
});
return serverMessages;
}
@@ -532,22 +433,8 @@ export class MessageSyncService implements IMessageSyncService {
// 使用 zustand set 函数正确更新状态
store.setConversations(newConversations);
this.persistConversationListCache();
subscriptionManager.notifySubscribers({
type: 'conversations_updated',
payload: { conversations: store.getConversations() },
timestamp: Date.now(),
});
}
}
subscriptionManager.notifySubscribers({
type: 'unread_count_updated',
payload: {
totalUnreadCount: totalUnread,
systemUnreadCount: systemUnread,
},
timestamp: Date.now(),
});
} catch (error) {
console.error('[MessageSyncService] 获取未读数失败:', error);
}
@@ -598,26 +485,6 @@ export class MessageSyncService implements IMessageSyncService {
store.setUnreadCount(totalUnread, store.getUnreadCount().system);
}
private emitConversationListAndUnreadUpdates(): void {
const store = useMessageStore.getState();
this.persistConversationListCache();
subscriptionManager.notifySubscribers({
type: 'conversations_updated',
payload: { conversations: store.getConversations() },
timestamp: Date.now(),
});
const unreadCount = store.getUnreadCount();
subscriptionManager.notifySubscribers({
type: 'unread_count_updated',
payload: {
totalUnreadCount: unreadCount.total,
systemUnreadCount: unreadCount.system,
},
timestamp: Date.now(),
});
}
private persistConversationListCache(): void {
const store = useMessageStore.getState();
const currentState = store.getState();

View File

@@ -2,7 +2,9 @@
* 已读回执管理器
* 管理消息已读状态的同步和保护
*
* 重构说明:直接使用 zustand store 替代 IMessageStateManager
* 重构说明:
* - 直接使用 zustand store 替代 IMessageStateManager
* - 移除了 SubscriptionManager 调用Zustand 的 set() 会自动触发组件重渲染
*/
import type { ConversationResponse } from '../../../types/dto';
@@ -10,7 +12,7 @@ import { messageService } from '../../../services/messageService';
import { markConversationAsRead, updateConversationCacheUnreadCount } from '../../../services/database';
import type { ReadStateRecord, IReadReceiptManager } from '../types';
import { READ_STATE_PROTECTION_DELAY } from '../constants';
import { useMessageStore, subscriptionManager, normalizeConversationId } from '../store';
import { useMessageStore, normalizeConversationId } from '../store';
export class ReadReceiptManager implements IReadReceiptManager {
/**
@@ -78,27 +80,7 @@ export class ReadReceiptManager implements IReadReceiptManager {
// 3. 更新本地数据库
markConversationAsRead(normalizedId).catch(console.error);
// 4. 立即通知所有订阅者
subscriptionManager.notifySubscribers({
type: 'message_read',
payload: {
conversationId: normalizedId,
unreadCount: 0,
totalUnreadCount: newTotalUnread,
},
timestamp: Date.now(),
});
subscriptionManager.notifySubscribers({
type: 'unread_count_updated',
payload: {
totalUnreadCount: newTotalUnread,
systemUnreadCount: currentUnread.system,
},
timestamp: Date.now(),
});
// 5. 调用 API完成后设置延迟清除保护
// 4. 调用 API完成后设置延迟清除保护
try {
await messageService.markAsRead(normalizedId, seq);
} catch (error) {
@@ -107,16 +89,6 @@ export class ReadReceiptManager implements IReadReceiptManager {
// 失败时回滚状态
store.updateConversation(conversation);
store.setUnreadCount(currentUnread.total, currentUnread.system);
subscriptionManager.notifySubscribers({
type: 'message_read',
payload: {
conversationId: normalizedId,
unreadCount: prevUnreadCount,
totalUnreadCount: currentUnread.total,
},
timestamp: Date.now(),
});
// API 失败时立即清除保护
this.pendingReadMap.delete(normalizedId);
@@ -156,15 +128,6 @@ export class ReadReceiptManager implements IReadReceiptManager {
store.setUnreadCount(0, currentSystem);
subscriptionManager.notifySubscribers({
type: 'unread_count_updated',
payload: {
totalUnreadCount: 0,
systemUnreadCount: currentSystem,
},
timestamp: Date.now(),
});
try {
// 标记系统消息已读
await messageService.markAllSystemMessagesRead();
@@ -182,15 +145,6 @@ export class ReadReceiptManager implements IReadReceiptManager {
console.error('[ReadReceiptManager] 标记所有已读失败:', error);
// 回滚
store.setUnreadCount(prevTotalUnread, currentSystem);
subscriptionManager.notifySubscribers({
type: 'unread_count_updated',
payload: {
totalUnreadCount: prevTotalUnread,
systemUnreadCount: currentSystem,
},
timestamp: Date.now(),
});
}
}

View File

@@ -2,7 +2,9 @@
* WebSocket 消息处理器
* 处理所有来自 WebSocket 的消息事件
*
* 重构说明:直接使用 zustand store 替代 IMessageStateManager
* 重构说明:
* - 直接使用 zustand store 替代 IMessageStateManager
* - 移除了 SubscriptionManager 调用Zustand 的 set() 会自动触发组件重渲染
*/
import type {
@@ -26,7 +28,7 @@ import type {
HandleNewMessageOptions,
} from '../types';
import { MAX_FLUSH_ITERATIONS } from '../constants';
import { useMessageStore, subscriptionManager, normalizeConversationId, mergeMessagesById } from '../store';
import { useMessageStore, normalizeConversationId, mergeMessagesById } from '../store';
export class WSMessageHandler implements IWSMessageHandler {
private deduplication: IMessageDeduplication;
@@ -134,11 +136,6 @@ export class WSMessageHandler implements IWSMessageHandler {
// 监听连接状态
wsService.onConnect(() => {
store.setSSEConnected(true);
subscriptionManager.notifySubscribers({
type: 'connection_changed',
payload: { connected: true },
timestamp: Date.now(),
});
// 冷启动/重连兜底
const now = Date.now();
@@ -166,11 +163,6 @@ export class WSMessageHandler implements IWSMessageHandler {
wsService.onDisconnect(() => {
store.setSSEConnected(false);
subscriptionManager.notifySubscribers({
type: 'connection_changed',
payload: { connected: false },
timestamp: Date.now(),
});
});
}
@@ -268,14 +260,6 @@ export class WSMessageHandler implements IWSMessageHandler {
m.id === id ? { ...m, sender: user } : m
);
store.setMessages(normalizedConversationId, updatedMessages);
subscriptionManager.notifySubscribers({
type: 'messages_updated',
payload: {
conversationId: normalizedConversationId,
messages: [...updatedMessages],
},
timestamp: Date.now(),
});
}
}
}).catch(error => {
@@ -301,16 +285,6 @@ export class WSMessageHandler implements IWSMessageHandler {
if (!messageExists) {
const updatedMessages = mergeMessagesById(existingMessages, [newMessage]);
store.setMessages(normalizedConversationId, updatedMessages);
subscriptionManager.notifySubscribers({
type: 'messages_updated',
payload: {
conversationId: normalizedConversationId,
messages: updatedMessages,
newMessage,
},
timestamp: Date.now(),
});
}
// 更新会话信息
@@ -358,17 +332,6 @@ export class WSMessageHandler implements IWSMessageHandler {
}).catch(error => {
console.error('[WSMessageHandler] 保存消息到本地失败:', error);
});
// 通知收到新消息
subscriptionManager.notifySubscribers({
type: 'message_received',
payload: {
conversationId: conversation_id,
message: newMessage,
isCurrentUser: isCurrentUserMessage,
},
timestamp: Date.now(),
});
}
/**
@@ -395,12 +358,6 @@ export class WSMessageHandler implements IWSMessageHandler {
this.markMessageAsRecalled(normalizedConversationId, message_id);
this.syncConversationLastMessageOnRecall(normalizedConversationId, message_id);
subscriptionManager.notifySubscribers({
type: 'message_recalled',
payload: { conversationId: normalizedConversationId, messageId: message_id },
timestamp: Date.now(),
});
updateMessageStatus(message_id, 'recalled', true).catch(error => {
console.error('[WSMessageHandler] 更新本地消息撤回状态失败:', error);
});
@@ -416,12 +373,6 @@ export class WSMessageHandler implements IWSMessageHandler {
this.markMessageAsRecalled(normalizedConversationId, message_id);
this.syncConversationLastMessageOnRecall(normalizedConversationId, message_id);
subscriptionManager.notifySubscribers({
type: 'message_recalled',
payload: { conversationId: normalizedConversationId, messageId: message_id, isGroup: true },
timestamp: Date.now(),
});
updateMessageStatus(message_id, 'recalled', true).catch(error => {
console.error('[WSMessageHandler] 更新本地消息撤回状态失败:', error);
});
@@ -450,11 +401,6 @@ export class WSMessageHandler implements IWSMessageHandler {
if (updatedTypingUsers.length !== currentTypingUsers.length) {
store.setTypingUsers(groupIdStr, updatedTypingUsers);
subscriptionManager.notifySubscribers({
type: 'typing_status',
payload: { groupId: groupIdStr, typingUsers: updatedTypingUsers },
timestamp: Date.now(),
});
}
}
@@ -500,34 +446,9 @@ export class WSMessageHandler implements IWSMessageHandler {
const updatedMessages = [...existingMessages, systemNoticeMessage].sort((a, b) => a.seq - b.seq);
store.setMessages(conversationId, updatedMessages);
subscriptionManager.notifySubscribers({
type: 'messages_updated',
payload: {
conversationId,
messages: updatedMessages,
newMessage: systemNoticeMessage,
source: 'group_notice',
},
timestamp: Date.now(),
});
}
}
}
// 通知订阅者群通知
subscriptionManager.notifySubscribers({
type: 'group_notice',
payload: {
groupId: groupIdStr,
noticeType: notice_type,
data,
timestamp,
messageId: message_id,
seq,
},
timestamp: Date.now(),
});
}
// ==================== 私有工具方法 ====================
@@ -550,12 +471,6 @@ export class WSMessageHandler implements IWSMessageHandler {
};
store.updateConversation(updatedConv);
}
subscriptionManager.notifySubscribers({
type: 'conversations_updated',
payload: { conversations: store.getConversations() },
timestamp: Date.now(),
});
}
private incrementUnreadCount(conversationId: string): void {
@@ -571,21 +486,6 @@ export class WSMessageHandler implements IWSMessageHandler {
const currentUnread = store.getUnreadCount();
store.setUnreadCount(currentUnread.total + 1, currentUnread.system);
subscriptionManager.notifySubscribers({
type: 'unread_count_updated',
payload: {
totalUnreadCount: store.getUnreadCount().total,
systemUnreadCount: store.getUnreadCount().system,
},
timestamp: Date.now(),
});
subscriptionManager.notifySubscribers({
type: 'conversations_updated',
payload: { conversations: store.getConversations() },
timestamp: Date.now(),
});
}
}
@@ -610,11 +510,6 @@ export class WSMessageHandler implements IWSMessageHandler {
if (!changed) return;
store.setMessages(conversationId, updatedMessages);
subscriptionManager.notifySubscribers({
type: 'messages_updated',
payload: { conversationId, messages: updatedMessages },
timestamp: Date.now(),
});
}
private syncConversationLastMessageOnRecall(conversationId: string, messageId: string): void {