hover #6
@@ -408,7 +408,7 @@ export const MessageBubble: React.FC<MessageBubbleProps> = ({
|
|||||||
)}
|
)}
|
||||||
|
|
||||||
<View style={styles.messageContent}>
|
<View style={styles.messageContent}>
|
||||||
{/* 群聊模式:显示发送者昵称 */}
|
{/* 群聊模式:显示发送者昵称 - 放在气泡上方 */}
|
||||||
{isGroupChat && !isMe && senderInfo && (
|
{isGroupChat && !isMe && senderInfo && (
|
||||||
<Text style={styles.senderName}>{senderInfo.nickname}</Text>
|
<Text style={styles.senderName}>{senderInfo.nickname}</Text>
|
||||||
)}
|
)}
|
||||||
|
|||||||
@@ -266,6 +266,43 @@ export const EmbeddedChat: React.FC<EmbeddedChatProps> = ({ conversation, onBack
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// 格式化时间
|
||||||
|
const formatTime = (dateString: string) => {
|
||||||
|
const date = new Date(dateString);
|
||||||
|
const now = new Date();
|
||||||
|
const isToday = date.toDateString() === now.toDateString();
|
||||||
|
|
||||||
|
if (isToday) {
|
||||||
|
return date.toLocaleTimeString('zh-CN', {
|
||||||
|
hour: '2-digit',
|
||||||
|
minute: '2-digit',
|
||||||
|
hour12: false
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
return date.toLocaleString('zh-CN', {
|
||||||
|
month: '2-digit',
|
||||||
|
day: '2-digit',
|
||||||
|
hour: '2-digit',
|
||||||
|
minute: '2-digit',
|
||||||
|
hour12: false
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// 判断是否需要显示时间(与上一条消息间隔超过5分钟)
|
||||||
|
const shouldShowTime = (index: number) => {
|
||||||
|
if (index === 0) return true;
|
||||||
|
const currentMsg = messages[index];
|
||||||
|
const prevMsg = messages[index - 1];
|
||||||
|
if (!currentMsg || !prevMsg) return true;
|
||||||
|
|
||||||
|
const currentTime = new Date(currentMsg.created_at).getTime();
|
||||||
|
const prevTime = new Date(prevMsg.created_at).getTime();
|
||||||
|
const diffMinutes = (currentTime - prevTime) / (1000 * 60);
|
||||||
|
|
||||||
|
return diffMinutes >= 5;
|
||||||
|
};
|
||||||
|
|
||||||
// 渲染消息内容
|
// 渲染消息内容
|
||||||
const renderMessageContent = (item: MessageResponse) => {
|
const renderMessageContent = (item: MessageResponse) => {
|
||||||
// 撤回消息
|
// 撤回消息
|
||||||
@@ -356,8 +393,9 @@ export const EmbeddedChat: React.FC<EmbeddedChatProps> = ({ conversation, onBack
|
|||||||
};
|
};
|
||||||
|
|
||||||
// 渲染消息
|
// 渲染消息
|
||||||
const renderMessage = ({ item }: { item: MessageResponse }) => {
|
const renderMessage = ({ item, index }: { item: MessageResponse; index: number }) => {
|
||||||
const isMe = String(item.sender_id) === String(currentUser?.id);
|
const isMe = String(item.sender_id) === String(currentUser?.id);
|
||||||
|
const showTime = shouldShowTime(index);
|
||||||
|
|
||||||
// 处理指针事件(鼠标右键)- 使用 onPointerDown 检测鼠标右键
|
// 处理指针事件(鼠标右键)- 使用 onPointerDown 检测鼠标右键
|
||||||
const handlePointerDown = (e: any) => {
|
const handlePointerDown = (e: any) => {
|
||||||
@@ -372,32 +410,47 @@ export const EmbeddedChat: React.FC<EmbeddedChatProps> = ({ conversation, onBack
|
|||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
<View>
|
||||||
|
{/* 时间分隔 */}
|
||||||
|
{showTime && (
|
||||||
|
<View style={styles.timeContainer}>
|
||||||
|
<Text style={styles.timeText}>{formatTime(item.created_at)}</Text>
|
||||||
|
</View>
|
||||||
|
)}
|
||||||
<View
|
<View
|
||||||
style={[styles.messageRow, isMe ? styles.messageRowRight : styles.messageRowLeft]}
|
style={[styles.messageRow, isMe ? styles.messageRowRight : styles.messageRowLeft]}
|
||||||
// @ts-ignore - React Native for Web 支持 pointer events
|
// @ts-ignore - React Native for Web 支持 pointer events
|
||||||
onPointerDown={handlePointerDown}
|
onPointerDown={handlePointerDown}
|
||||||
>
|
>
|
||||||
{!isMe && (
|
{!isMe && (
|
||||||
|
<View style={styles.avatarContainer}>
|
||||||
<Avatar
|
<Avatar
|
||||||
source={item.sender?.avatar}
|
source={item.sender?.avatar}
|
||||||
size={36}
|
size={36}
|
||||||
name={item.sender?.nickname || item.sender?.username}
|
name={item.sender?.nickname || item.sender?.username}
|
||||||
/>
|
/>
|
||||||
|
</View>
|
||||||
)}
|
)}
|
||||||
<View style={[styles.messageBubble, isMe ? styles.messageBubbleMe : styles.messageBubbleOther]}>
|
<View style={styles.messageContent}>
|
||||||
|
{/* 群聊模式:显示发送者昵称 - 顶部与头像对齐 */}
|
||||||
{isGroupChat && !isMe && (
|
{isGroupChat && !isMe && (
|
||||||
<Text style={styles.senderName}>{item.sender?.nickname || item.sender?.username}</Text>
|
<Text style={styles.senderName}>{item.sender?.nickname || item.sender?.username}</Text>
|
||||||
)}
|
)}
|
||||||
|
<View style={[styles.messageBubble, isMe ? styles.messageBubbleMe : styles.messageBubbleOther]}>
|
||||||
{renderMessageContent(item)}
|
{renderMessageContent(item)}
|
||||||
</View>
|
</View>
|
||||||
|
</View>
|
||||||
{isMe && (
|
{isMe && (
|
||||||
|
<View style={styles.avatarContainer}>
|
||||||
<Avatar
|
<Avatar
|
||||||
source={currentUser?.avatar}
|
source={currentUser?.avatar}
|
||||||
size={36}
|
size={36}
|
||||||
name={currentUser?.nickname || currentUser?.username}
|
name={currentUser?.nickname || currentUser?.username}
|
||||||
/>
|
/>
|
||||||
|
</View>
|
||||||
)}
|
)}
|
||||||
</View>
|
</View>
|
||||||
|
</View>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -664,9 +717,24 @@ const styles = StyleSheet.create({
|
|||||||
padding: spacing.md,
|
padding: spacing.md,
|
||||||
paddingBottom: spacing.xl,
|
paddingBottom: spacing.xl,
|
||||||
},
|
},
|
||||||
|
timeContainer: {
|
||||||
|
alignItems: 'center',
|
||||||
|
marginVertical: spacing.md,
|
||||||
|
},
|
||||||
|
timeText: {
|
||||||
|
color: '#8E8E93',
|
||||||
|
fontSize: 12,
|
||||||
|
backgroundColor: 'rgba(142, 142, 147, 0.12)',
|
||||||
|
paddingHorizontal: spacing.md,
|
||||||
|
paddingVertical: 6,
|
||||||
|
borderRadius: 14,
|
||||||
|
fontWeight: '600',
|
||||||
|
overflow: 'hidden',
|
||||||
|
letterSpacing: 0.3,
|
||||||
|
},
|
||||||
messageRow: {
|
messageRow: {
|
||||||
flexDirection: 'row',
|
flexDirection: 'row',
|
||||||
alignItems: 'flex-end',
|
alignItems: 'flex-start',
|
||||||
marginBottom: spacing.md,
|
marginBottom: spacing.md,
|
||||||
maxWidth: screenWidth * 0.7,
|
maxWidth: screenWidth * 0.7,
|
||||||
},
|
},
|
||||||
@@ -677,6 +745,9 @@ const styles = StyleSheet.create({
|
|||||||
alignSelf: 'flex-end',
|
alignSelf: 'flex-end',
|
||||||
justifyContent: 'flex-end',
|
justifyContent: 'flex-end',
|
||||||
},
|
},
|
||||||
|
avatarContainer: {
|
||||||
|
marginTop: 0,
|
||||||
|
},
|
||||||
messageBubble: {
|
messageBubble: {
|
||||||
maxWidth: screenWidth * 0.5,
|
maxWidth: screenWidth * 0.5,
|
||||||
paddingHorizontal: spacing.md,
|
paddingHorizontal: spacing.md,
|
||||||
@@ -693,10 +764,15 @@ const styles = StyleSheet.create({
|
|||||||
borderBottomLeftRadius: 4,
|
borderBottomLeftRadius: 4,
|
||||||
...shadows.sm,
|
...shadows.sm,
|
||||||
},
|
},
|
||||||
|
messageContent: {
|
||||||
|
maxWidth: screenWidth * 0.5,
|
||||||
|
alignItems: 'flex-start',
|
||||||
|
},
|
||||||
senderName: {
|
senderName: {
|
||||||
fontSize: 12,
|
fontSize: 12,
|
||||||
color: '#999',
|
color: '#999',
|
||||||
marginBottom: 2,
|
marginBottom: 2,
|
||||||
|
marginLeft: 4,
|
||||||
},
|
},
|
||||||
messageText: {
|
messageText: {
|
||||||
fontSize: 15,
|
fontSize: 15,
|
||||||
|
|||||||
Reference in New Issue
Block a user