62 lines
1.5 KiB
JavaScript
62 lines
1.5 KiB
JavaScript
/**
|
|
* 瞬态消息管理器
|
|
*
|
|
* 瞬态消息只保留最新一条,新状态覆盖旧状态,不会堆积在聊天历史中。
|
|
*/
|
|
import { escapeHtml } from '../utils.js';
|
|
import { getChatMessages, scrollToBottom } from './renderer.js';
|
|
|
|
/**
|
|
* 当前活跃的瞬态消息 DOM 引用
|
|
*/
|
|
let ephemeralState = {
|
|
wrapper: null,
|
|
bubble: null,
|
|
};
|
|
|
|
/**
|
|
* 显示瞬态状态消息
|
|
*
|
|
* 同一时刻只保留一条状态消息,调用此函数会更新已有消息或创建新消息。
|
|
*
|
|
* @param {string} text - 状态文本
|
|
* @param {string} [type='processing'] - 消息类型
|
|
*/
|
|
export function showStatus(text, type) {
|
|
const chatMessages = getChatMessages();
|
|
if (!chatMessages) return;
|
|
|
|
if (ephemeralState.bubble) {
|
|
ephemeralState.bubble.textContent = escapeHtml(text);
|
|
ephemeralState.bubble.className = 'chat-bubble ' + (type || 'processing');
|
|
scrollToBottom();
|
|
return;
|
|
}
|
|
|
|
const wrapper = document.createElement('div');
|
|
wrapper.className = 'chat-message';
|
|
wrapper.innerHTML = `
|
|
<div class="ai-avatar"><img src="/static/icon/agent.svg" alt=""></div>
|
|
<div class="chat-bubble ${type || 'processing'}">${escapeHtml(text)}</div>
|
|
`;
|
|
chatMessages.appendChild(wrapper);
|
|
scrollToBottom();
|
|
|
|
ephemeralState = {
|
|
wrapper,
|
|
bubble: wrapper.querySelector('.chat-bubble'),
|
|
};
|
|
}
|
|
|
|
/**
|
|
* 清除瞬态状态消息
|
|
*/
|
|
export function clearStatus() {
|
|
if (ephemeralState.wrapper) {
|
|
ephemeralState.wrapper.remove();
|
|
}
|
|
ephemeralState = {
|
|
wrapper: null,
|
|
bubble: null,
|
|
};
|
|
} |