diff --git a/src/components/business/CommentItem.tsx b/src/components/business/CommentItem.tsx index c0b4c45..d5f781f 100644 --- a/src/components/business/CommentItem.tsx +++ b/src/components/business/CommentItem.tsx @@ -223,8 +223,11 @@ const CommentItem: React.FC = ({ const [isDeleting, setIsDeleting] = useState(false); // 格式化时间 const formatTime = (dateString: string): string => { + if (!dateString) return ''; try { - return formatDistanceToNow(new Date(dateString), { + const date = new Date(dateString); + if (Number.isNaN(date.getTime())) return ''; + return formatDistanceToNow(date, { addSuffix: true, locale: zhCN, }); diff --git a/src/components/business/SystemMessageItem.tsx b/src/components/business/SystemMessageItem.tsx index 094d4af..87a9fbb 100644 --- a/src/components/business/SystemMessageItem.tsx +++ b/src/components/business/SystemMessageItem.tsx @@ -331,8 +331,11 @@ const SystemMessageItem: React.FC = ({ // 格式化时间 const formatTime = (dateString: string): string => { + if (!dateString) return ''; try { - return formatDistanceToNow(new Date(dateString), { + const date = new Date(dateString); + if (Number.isNaN(date.getTime())) return ''; + return formatDistanceToNow(date, { addSuffix: true, locale: zhCN, }); diff --git a/src/components/business/UserProfileHeader.tsx b/src/components/business/UserProfileHeader.tsx index 0b4e81b..f68ecc7 100644 --- a/src/components/business/UserProfileHeader.tsx +++ b/src/components/business/UserProfileHeader.tsx @@ -274,8 +274,11 @@ const UserProfileHeader: React.FC = ({ - 加入于 {new Date(user.created_at || Date.now()).getFullYear()}年 - {new Date(user.created_at || Date.now()).getMonth() + 1}月 + {(() => { + const d = new Date(user.created_at || Date.now()); + if (Number.isNaN(d.getTime())) return '加入于 未知时间'; + return `加入于 ${d.getFullYear()}年${d.getMonth() + 1}月`; + })()} diff --git a/src/screens/message/GroupInfoScreen.tsx b/src/screens/message/GroupInfoScreen.tsx index 54fa78d..2321602 100644 --- a/src/screens/message/GroupInfoScreen.tsx +++ b/src/screens/message/GroupInfoScreen.tsx @@ -661,7 +661,10 @@ const GroupInfoScreen: React.FC = () => { {announcements[0].content} - {new Date(announcements[0].created_at).toLocaleDateString()} + {(() => { + const d = new Date(announcements[0].created_at); + return Number.isNaN(d.getTime()) ? '' : d.toLocaleDateString(); + })()} diff --git a/src/screens/message/MessageListScreen.tsx b/src/screens/message/MessageListScreen.tsx index b7d5eab..344c0ab 100644 --- a/src/screens/message/MessageListScreen.tsx +++ b/src/screens/message/MessageListScreen.tsx @@ -245,8 +245,10 @@ export const MessageListScreen: React.FC = () => { // 格式化时间(稳定引用,配合会话行 memo) const formatTime = useCallback((dateString: string): string => { + if (!dateString) return ''; try { const date = new Date(dateString); + if (Number.isNaN(date.getTime())) return ''; const now = new Date(); const diffInHours = (now.getTime() - date.getTime()) / (1000 * 60 * 60); @@ -483,7 +485,10 @@ export const MessageListScreen: React.FC = () => { const aPinned = a.is_pinned ? 1 : 0; const bPinned = b.is_pinned ? 1 : 0; if (aPinned !== bPinned) return bPinned - aPinned; - return new Date(b.updated_at).getTime() - new Date(a.updated_at).getTime(); + const aTime = new Date(a.updated_at || 0).getTime(); + const bTime = new Date(b.updated_at || 0).getTime(); + if (Number.isNaN(aTime) || Number.isNaN(bTime)) return 0; + return bTime - aTime; }); const listConvRef = useRef(new Map()); diff --git a/src/screens/message/components/ChatScreen/GroupInfoPanel.tsx b/src/screens/message/components/ChatScreen/GroupInfoPanel.tsx index 52d3c8f..8c6f42c 100644 --- a/src/screens/message/components/ChatScreen/GroupInfoPanel.tsx +++ b/src/screens/message/components/ChatScreen/GroupInfoPanel.tsx @@ -241,7 +241,10 @@ export const GroupInfoPanel: React.FC = ({ {announcements[0].content} - {new Date(announcements[0].created_at).toLocaleDateString()} + {(() => { + const d = new Date(announcements[0].created_at); + return Number.isNaN(d.getTime()) ? '' : d.toLocaleDateString(); + })()} @@ -311,7 +314,10 @@ export const GroupInfoPanel: React.FC = ({ 创建时间 {groupInfo?.created_at - ? new Date(groupInfo.created_at).toLocaleDateString('zh-CN') + ? (() => { + const d = new Date(groupInfo.created_at); + return Number.isNaN(d.getTime()) ? '-' : d.toLocaleDateString('zh-CN'); + })() : '-'} diff --git a/src/screens/message/components/ChatScreen/GroupInfoPanel.web.tsx b/src/screens/message/components/ChatScreen/GroupInfoPanel.web.tsx index 939f995..ee30172 100644 --- a/src/screens/message/components/ChatScreen/GroupInfoPanel.web.tsx +++ b/src/screens/message/components/ChatScreen/GroupInfoPanel.web.tsx @@ -246,7 +246,10 @@ export const GroupInfoPanel: React.FC = ({ {announcements[0].content} - {new Date(announcements[0].created_at).toLocaleDateString()} + {(() => { + const d = new Date(announcements[0].created_at); + return Number.isNaN(d.getTime()) ? '' : d.toLocaleDateString(); + })()} @@ -316,7 +319,10 @@ export const GroupInfoPanel: React.FC = ({ 创建时间 {groupInfo?.created_at - ? new Date(groupInfo.created_at).toLocaleDateString('zh-CN') + ? (() => { + const d = new Date(groupInfo.created_at); + return Number.isNaN(d.getTime()) ? '-' : d.toLocaleDateString('zh-CN'); + })() : '-'} diff --git a/src/screens/message/components/ChatScreen/LongPressMenu.tsx b/src/screens/message/components/ChatScreen/LongPressMenu.tsx index eef96b5..bbe7ace 100644 --- a/src/screens/message/components/ChatScreen/LongPressMenu.tsx +++ b/src/screens/message/components/ChatScreen/LongPressMenu.tsx @@ -78,10 +78,12 @@ export const LongPressMenu: React.FC = ({ if (!message) return null; const isMyMessage = message.sender_id === currentUserId; - const messageTime = new Date(message.created_at).getTime(); + const messageDate = new Date(message.created_at); + const messageTime = Number.isNaN(messageDate.getTime()) ? 0 : messageDate.getTime(); const now = Date.now(); const canRecall = isMyMessage && message.status !== 'recalled' && + messageTime > 0 && (now - messageTime) < RECALL_TIME_LIMIT; // 检查是否是图片消息 diff --git a/src/screens/message/components/ChatScreen/MessageBubble.tsx b/src/screens/message/components/ChatScreen/MessageBubble.tsx index a9aaefc..2ec28da 100644 --- a/src/screens/message/components/ChatScreen/MessageBubble.tsx +++ b/src/screens/message/components/ChatScreen/MessageBubble.tsx @@ -426,10 +426,10 @@ const MessageBubbleInner: React.FC = ({ {/* 群聊模式:显示发送者昵称 */} - {isGroupChat && !isMe && senderInfo && ( - {senderInfo.nickname} + {isGroupChat && senderInfo && ( + {senderInfo.nickname} )} - + {renderMessageContent()} {/* 私聊模式:显示已读标记 */} diff --git a/src/screens/message/components/ChatScreen/styles.ts b/src/screens/message/components/ChatScreen/styles.ts index 88b0bb0..f0b3249 100644 --- a/src/screens/message/components/ChatScreen/styles.ts +++ b/src/screens/message/components/ChatScreen/styles.ts @@ -262,14 +262,13 @@ export function createChatScreenStyles(colors: AppColors, dynamicStyles?: { messageRow: { flexDirection: 'row', marginBottom: spacing.md, - alignItems: 'flex-end', + alignItems: 'flex-start', }, myMessageRow: { justifyContent: 'flex-end', }, theirMessageRow: { justifyContent: 'flex-start', - alignItems: 'flex-start', }, // 头像 - 更大一点 @@ -303,6 +302,11 @@ export function createChatScreenStyles(colors: AppColors, dynamicStyles?: { marginLeft: 4, fontWeight: '600', }, + mySenderName: { + marginLeft: 0, + marginRight: 4, + alignSelf: 'flex-end', + }, // 消息气泡 - 动态圆角支持 messageBubbleOuter: { @@ -315,7 +319,7 @@ export function createChatScreenStyles(colors: AppColors, dynamicStyles?: { elevation: 1, }, myBubbleOuter: { - borderBottomRightRadius: Math.max(4, messageRadius * 0.3), // 微信的小尾巴更尖 + borderTopRightRadius: Math.max(4, messageRadius * 0.3), // 箭头在右上 }, theirBubbleOuter: { borderTopLeftRadius: Math.max(4, messageRadius * 0.3), @@ -330,7 +334,7 @@ export function createChatScreenStyles(colors: AppColors, dynamicStyles?: { }, myBubbleInner: { backgroundColor: myBubbleBg, - borderBottomRightRadius: Math.max(4, messageRadius * 0.3), + borderTopRightRadius: Math.max(4, messageRadius * 0.3), }, theirBubbleInner: { backgroundColor: theirBubbleBg, @@ -394,7 +398,7 @@ export function createChatScreenStyles(colors: AppColors, dynamicStyles?: { elevation: 4, }, myImageBubble: { - borderBottomRightRadius: 8, + borderTopRightRadius: 8, }, theirImageBubble: { borderTopLeftRadius: 8, diff --git a/src/screens/message/components/ChatScreen/useChatScreen.ts b/src/screens/message/components/ChatScreen/useChatScreen.ts index 9522eeb..0031600 100644 --- a/src/screens/message/components/ChatScreen/useChatScreen.ts +++ b/src/screens/message/components/ChatScreen/useChatScreen.ts @@ -657,8 +657,10 @@ export const useChatScreen = (props?: ChatScreenProps) => { // 格式化时间 const formatTime = useCallback((dateString: string): string => { + if (!dateString) return ''; try { const date = new Date(dateString); + if (Number.isNaN(date.getTime())) return ''; const now = new Date(); const diffInHours = (now.getTime() - date.getTime()) / (1000 * 60 * 60); @@ -680,9 +682,10 @@ export const useChatScreen = (props?: ChatScreenProps) => { if (index === 0) return true; const currentMsg = messages[index]; const prevMsg = messages[index - 1]; - const currentTime = new Date(currentMsg.created_at).getTime(); - const prevTime = new Date(prevMsg.created_at).getTime(); - return (currentTime - prevTime) > TIME_SEPARATOR_INTERVAL; + const currentDate = new Date(currentMsg.created_at); + const prevDate = new Date(prevMsg.created_at); + if (Number.isNaN(currentDate.getTime()) || Number.isNaN(prevDate.getTime())) return false; + return (currentDate.getTime() - prevDate.getTime()) > TIME_SEPARATOR_INTERVAL; }, [messages]); // 处理输入变化,检测@符号 diff --git a/src/screens/message/components/ConversationListRow.tsx b/src/screens/message/components/ConversationListRow.tsx index 5ce9ebb..a83a4af 100644 --- a/src/screens/message/components/ConversationListRow.tsx +++ b/src/screens/message/components/ConversationListRow.tsx @@ -223,14 +223,7 @@ function createConversationRowStyles(colors: AppColors) { width: 56, height: 56, }, - groupAvatarPlaceholder: { - width: 56, - height: 56, - borderRadius: borderRadius.md, - backgroundColor: colors.primary.main, - alignItems: 'center', - justifyContent: 'center', - }, + timeText: { color: colors.text.hint, fontSize: 12, @@ -324,13 +317,7 @@ const ConversationListRowInner: React.FC = ({ ) : isGroupChat ? ( - {displayAvatar ? ( - - ) : ( - - - - )} + ) : ( diff --git a/src/stores/message/services/WSMessageHandler.ts b/src/stores/message/services/WSMessageHandler.ts index c1ce9dd..fa4260a 100644 --- a/src/stores/message/services/WSMessageHandler.ts +++ b/src/stores/message/services/WSMessageHandler.ts @@ -137,7 +137,9 @@ export class WSMessageHandler implements IWSMessageHandler { if (message.created_at) { const store = useMessageStore.getState(); const currentLast = store.lastSystemMessageAt; - if (!currentLast || new Date(message.created_at) > new Date(currentLast)) { + const msgDate = new Date(message.created_at); + if (Number.isNaN(msgDate.getTime())) return; + if (!currentLast || msgDate > new Date(currentLast)) { store.setLastSystemMessageAt(message.created_at); } } @@ -335,7 +337,7 @@ export class WSMessageHandler implements IWSMessageHandler { content: textContent, type: segments?.find((s: any) => s.type === 'image') ? 'image' : 'text', isRead: isActiveConversation, - createdAt: new Date(created_at).toISOString(), + createdAt: (() => { const d = new Date(created_at); return Number.isNaN(d.getTime()) ? new Date().toISOString() : d.toISOString(); })(), seq, status: 'normal', segments, @@ -451,7 +453,7 @@ export class WSMessageHandler implements IWSMessageHandler { : [], status: 'normal', category: 'notification', - created_at: new Date(timestamp || Date.now()).toISOString(), + created_at: (() => { const d = new Date(timestamp || Date.now()); return Number.isNaN(d.getTime()) ? new Date().toISOString() : d.toISOString(); })(), }; const updatedMessages = [...existingMessages, systemNoticeMessage].sort((a, b) => a.seq - b.seq); diff --git a/src/stores/message/store.ts b/src/stores/message/store.ts index abba7e0..b7ff030 100644 --- a/src/stores/message/store.ts +++ b/src/stores/message/store.ts @@ -134,6 +134,7 @@ function sortConversationList(conversations: Map): } const aTime = new Date(a.last_message_at || a.updated_at || 0).getTime(); const bTime = new Date(b.last_message_at || b.updated_at || 0).getTime(); + if (Number.isNaN(aTime) || Number.isNaN(bTime)) return 0; return bTime - aTime; }); }