feat(ui): unify design system to Twitter/X style across screens and improve message handling
Redesign multiple screens and components from card-based responsive design to Twitter/X flat design: - UserProfileHeader: adopt Twitter/X style with larger icons, simplified buttons, and block functionality - AppBackButton: update to chevron-left icon with larger size, remove background styling - Update SettingsScreen, EditProfileScreen, and UserProfileScreen with flat layout approach - ConversationListRow: convert from bordered cards to flat list rows with updated typography Improve message system with WebSocket notification handling: - Add real-time system unread count updates via WebSocket - Track lastSystemMessageAt for accurate system message timestamps - Add notification deduplication and read-status filtering - Combine system and conversation unread counts in background sync - Clear system notifications from notification center on mark as read
This commit is contained in:
@@ -376,6 +376,18 @@ export class MessageSyncService implements IMessageSyncService {
|
||||
|
||||
store.setUnreadCount(totalUnread, systemUnread);
|
||||
|
||||
// 获取最后一条系统通知的时间
|
||||
if (systemUnread > 0) {
|
||||
try {
|
||||
const latestSystemMsg = await messageService.getSystemMessagesCursor({ cursor: '', page_size: 1 });
|
||||
if (latestSystemMsg?.list?.[0]?.created_at) {
|
||||
store.setLastSystemMessageAt(latestSystemMsg.list[0].created_at);
|
||||
}
|
||||
} catch {
|
||||
// 获取最后系统通知时间失败,不影响主流程
|
||||
}
|
||||
}
|
||||
|
||||
// 服务端汇总未读为 0 时,清掉内存中残留的红点
|
||||
if (totalUnread === 0) {
|
||||
const currentConversations = store.getState().conversations;
|
||||
|
||||
@@ -16,6 +16,7 @@ import type {
|
||||
WSGroupRecallMessage,
|
||||
WSGroupTypingMessage,
|
||||
WSGroupNoticeMessage,
|
||||
WSNotificationMessage,
|
||||
} from '@/services/core';
|
||||
import { wsService, GroupNoticeType } from '@/services/core';
|
||||
import { eventBus } from '@/core/events/EventBus';
|
||||
@@ -128,6 +129,20 @@ export class WSMessageHandler implements IWSMessageHandler {
|
||||
this.handleGroupNotice(message);
|
||||
});
|
||||
|
||||
// 监听系统通知,实时更新系统未读数
|
||||
wsService.on('notification', (message: WSNotificationMessage) => {
|
||||
if (!message.is_read) {
|
||||
this.incrementSystemUnread();
|
||||
}
|
||||
if (message.created_at) {
|
||||
const store = useMessageStore.getState();
|
||||
const currentLast = store.lastSystemMessageAt;
|
||||
if (!currentLast || new Date(message.created_at) > new Date(currentLast)) {
|
||||
store.setLastSystemMessageAt(message.created_at);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// 监听连接状态
|
||||
wsService.onConnect(() => {
|
||||
useMessageStore.getState().setSSEConnected(true);
|
||||
@@ -484,6 +499,12 @@ export class WSMessageHandler implements IWSMessageHandler {
|
||||
}
|
||||
}
|
||||
|
||||
private incrementSystemUnread(): void {
|
||||
const store = useMessageStore.getState();
|
||||
const currentUnread = store.getUnreadCount();
|
||||
store.setUnreadCount(currentUnread.total + 1, currentUnread.system + 1);
|
||||
}
|
||||
|
||||
private markMessageAsRecalled(conversationId: string, messageId: string): void {
|
||||
const store = useMessageStore.getState();
|
||||
const messages = store.getMessages(conversationId);
|
||||
|
||||
@@ -31,6 +31,9 @@ export interface MessageState {
|
||||
totalUnreadCount: number;
|
||||
systemUnreadCount: number;
|
||||
|
||||
// 最后一条系统通知时间
|
||||
lastSystemMessageAt: string | null;
|
||||
|
||||
// 连接状态
|
||||
isWSConnected: boolean;
|
||||
|
||||
@@ -75,6 +78,7 @@ export interface MessageActions {
|
||||
addMessage: (conversationId: string, message: MessageResponse) => void;
|
||||
updateMessage: (conversationId: string, messageId: string, updates: Partial<MessageResponse>) => void;
|
||||
setUnreadCount: (total: number, system: number) => void;
|
||||
setLastSystemMessageAt: (time: string | null) => void;
|
||||
setSSEConnected: (connected: boolean) => void;
|
||||
setCurrentConversation: (conversationId: string | null) => void;
|
||||
setLoading: (loading: boolean) => void;
|
||||
@@ -95,6 +99,7 @@ const initialState: MessageState = {
|
||||
messagesMap: new Map(),
|
||||
totalUnreadCount: 0,
|
||||
systemUnreadCount: 0,
|
||||
lastSystemMessageAt: null,
|
||||
isWSConnected: false,
|
||||
currentConversationId: null,
|
||||
isLoadingConversations: false,
|
||||
@@ -160,6 +165,7 @@ export const useMessageStore = create<MessageStore>((set, get) => ({
|
||||
messagesMap: state.messagesMap,
|
||||
totalUnreadCount: state.totalUnreadCount,
|
||||
systemUnreadCount: state.systemUnreadCount,
|
||||
lastSystemMessageAt: state.lastSystemMessageAt,
|
||||
isWSConnected: state.isWSConnected,
|
||||
currentConversationId: state.currentConversationId,
|
||||
isLoadingConversations: state.isLoadingConversations,
|
||||
@@ -314,6 +320,10 @@ export const useMessageStore = create<MessageStore>((set, get) => ({
|
||||
set({ totalUnreadCount: total, systemUnreadCount: system });
|
||||
},
|
||||
|
||||
setLastSystemMessageAt: (time: string | null) => {
|
||||
set({ lastSystemMessageAt: time });
|
||||
},
|
||||
|
||||
setSSEConnected: (connected: boolean) => {
|
||||
set({ isWSConnected: connected });
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user