// 消息处理模块
import { renderMarkdown } from './markdown.js';
import { highlightCodeBlocks } from './highlight.js';
import { scrollToBottom } from './dom-utils.js';

export function addMessage(chatArea, role, markdownContent) {
    if (!chatArea) return null;

    const messageEl = document.createElement('div');
    messageEl.className = `message ${role}`;

    const contentEl = document.createElement('div');
    contentEl.className = 'message-content markdown-body';
    contentEl.innerHTML = renderMarkdown(markdownContent || '');

    // 添加操作栏 (复制 & 删除)
    const actionRow = document.createElement('div');
    actionRow.className = 'message-actions';

    const copyBtn = document.createElement('button');
    copyBtn.className = 'btn-copy-markdown';
    copyBtn.title = '复制原始内容';
    copyBtn.innerHTML = '<svg viewBox="0 0 24 24" width="14" height="14" stroke="currentColor" stroke-width="2" fill="none" stroke-linecap="round" stroke-linejoin="round"><rect x="9" y="9" width="13" height="13" rx="2" ry="2"></rect><path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"></path></svg>';

    const rawContent = document.createElement('div');
    rawContent.className = 'raw-markdown';
    rawContent.style.display = 'none';
    rawContent.textContent = markdownContent || '';

    const deleteBtn = document.createElement('button');
    deleteBtn.className = 'btn-delete-message';
    deleteBtn.title = '删除消息';
    deleteBtn.innerHTML = '<svg viewBox="0 0 24 24" width="14" height="14" stroke="currentColor" stroke-width="2" fill="none" stroke-linecap="round" stroke-linejoin="round"><polyline points="3 6 5 6 21 6"></polyline><path d="M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2"></path></svg>';

    actionRow.appendChild(copyBtn);
    actionRow.appendChild(rawContent);
    actionRow.appendChild(deleteBtn);

    contentEl.appendChild(actionRow);

    const timestamp = document.createElement('div');
    timestamp.className = 'timestamp';
    timestamp.textContent = new Date().toLocaleString();
    contentEl.appendChild(timestamp);

    const avatarEl = document.createElement('div');
    avatarEl.className = 'avatar';
    avatarEl.textContent = role === 'user' ? '👤' : (role === 'assistant' ? '🤖' : '⚠');

    messageEl.appendChild(contentEl);
    messageEl.appendChild(avatarEl);

    chatArea.appendChild(messageEl);

    // 异步高亮代码块(不阻塞)
    highlightCodeBlocks(contentEl).catch(err => {
        console.warn('代码高亮失败:', err);
    });
    scrollToBottom(chatArea);
    return contentEl;
}

⚠⚠    以下内容为AI分析的结果,请根据实际情况进行判断。

这是一个聊天应用中的消息处理模块,主要功能是创建和渲染聊天消息。让我详细解释一下代码的结构和功能:

模块导入

import { renderMarkdown } from './markdown.js';
import { highlightCodeBlocks } from './highlight.js';
import { scrollToBottom } from './dom-utils.js';

导入了三个工具模块:

  • renderMarkdown: 将Markdown文本转换为HTML
  • highlightCodeBlocks: 代码块语法高亮
  • scrollToBottom: 滚动到聊天区域底部

主要函数 addMessage

参数

  • chatArea: 聊天区域的DOM元素
  • role: 消息角色('user'用户、'assistant'助手等)
  • markdownContent: Markdown格式的消息内容

功能实现

  1. 创建消息容器

    const messageEl = document.createElement('div');
    messageEl.className = `message ${role}`;
    

    创建带有角色样式的消息容器

  2. 渲染消息内容

    const contentEl = document.createElement('div');
    contentEl.className = 'message-content markdown-body';
    contentEl.innerHTML = renderMarkdown(markdownContent || '');
    

    将Markdown内容转换为HTML并渲染

  3. 添加操作按钮

    • 复制按钮: 带有复制图标的SVG,用于复制原始Markdown内容
    • 隐藏的原始内容: 存储原始Markdown文本,供复制功能使用
    • 删除按钮: 带有垃圾桶图标的SVG,用于删除消息
  4. 添加时间戳

    const timestamp = document.createElement('div');
    timestamp.className = 'timestamp';
    timestamp.textContent = new Date().toLocaleString();
    

    显示消息创建的时间

  5. 添加头像

    const avatarEl = document.createElement('div');
    avatarEl.className = 'avatar';
    avatarEl.textContent = role === 'user' ? '👤' : (role === 'assistant' ? '🤖' : '⚠');
    

    根据角色显示不同的emoji头像

  6. 组装和渲染

    • 将所有元素组装到消息容器中
    • 添加到聊天区域
    • 异步执行代码高亮(不阻塞主线程)
    • 滚动到底部显示最新消息

特点

  • 模块化设计: 功能分离,易于维护
  • 异步处理: 代码高亮异步执行,不影响用户体验
  • 错误处理: 对代码高亮失败进行捕获和警告
  • 用户体验: 自动滚动到底部,显示时间戳和操作按钮
  • 灵活性: 支持不同角色的消息,带有相应的样式和头像

这个模块为聊天应用提供了完整的消息展示功能,支持Markdown渲染、代码高亮、消息操作等特性。

评论加载中...