Update from local source

This commit is contained in:
Cola-Echo
2026-02-04 10:33:49 +08:00
parent 84dc04ef61
commit 1fd223930d
78 changed files with 28619 additions and 83 deletions

View File

@@ -0,0 +1,352 @@
/**
* 汇总检查弹窗模块
* @module ui/modals/summary-check
*/
import { getGlobalSettings, isMultiAIAvailable } from '@config/config-manager';
/**
* 显示汇总检查弹窗
* @param {string} summaryContent - 记忆摘要内容
* @param {string} editorContent - 剧情优化内容(可选)
* @returns {Promise<{action: 'confirm'|'regenerate'|'multi-regenerate'|'cancel', editedSummary?: string, editedEditor?: string}>} 用户操作结果
*/
export function showSummaryCheckModal(summaryContent, editorContent = "") {
return new Promise((resolve) => {
// 创建弹窗容器 - 无遮罩模式,允许与主界面交互
const modal = document.createElement("div");
modal.className = "mm-modal mm-modal-visible";
modal.style.zIndex = "999999";
modal.style.position = "fixed";
modal.style.top = "0";
modal.style.left = "0";
modal.style.right = "0";
modal.style.bottom = "0";
modal.style.background = "transparent";
modal.style.display = "flex";
modal.style.alignItems = "center";
modal.style.justifyContent = "center";
modal.style.pointerEvents = "none"; // 允许点击穿透到下层
// 应用当前主题
const settings = getGlobalSettings();
const theme = settings.theme || "default";
if (theme !== "default") {
modal.setAttribute("data-mm-theme", theme);
}
// 创建弹窗内容
const content = document.createElement("div");
content.className = "mm-modal-content mm-modal-large";
content.style.width = "100%";
content.style.maxWidth = "800px";
content.style.height = "80vh";
content.style.maxHeight = "80vh";
content.style.overflow = "hidden";
content.style.display = "flex";
content.style.flexDirection = "column";
content.style.background = "var(--mm-bg)";
content.style.borderRadius = "var(--mm-radius)";
content.style.boxShadow = "0 4px 20px rgba(0, 0, 0, 0.3)";
content.style.pointerEvents = "auto"; // 弹窗内容可交互
// 创建弹窗头部
const header = document.createElement("div");
header.className = "mm-modal-header";
header.style.display = "flex";
header.style.justifyContent = "space-between";
header.style.alignItems = "center";
header.style.padding = "15px 20px";
header.style.borderBottom = "1px solid var(--mm-border)";
header.style.flexShrink = "0";
const title = document.createElement("h4");
title.textContent = editorContent
? "汇总检查 - 记忆摘要 + 剧情优化"
: "汇总检查 - AI 生成的记忆摘要";
title.style.margin = "0";
title.style.fontSize = "16px";
title.style.color = "var(--mm-text)";
const closeBtn = document.createElement("button");
closeBtn.className = "mm-modal-close mm-btn mm-btn-icon";
closeBtn.innerHTML = `<i class="fa-solid fa-times"></i>`;
header.appendChild(title);
header.appendChild(closeBtn);
content.appendChild(header);
// 创建弹窗主体
const body = document.createElement("div");
body.className = "mm-modal-body";
body.style.flex = "1";
body.style.overflowY = "auto";
body.style.padding = "20px";
// 提示信息
const hint = document.createElement("div");
hint.style.marginBottom = "15px";
hint.style.padding = "10px 15px";
hint.style.background = "var(--mm-bg-secondary)";
hint.style.borderRadius = "var(--mm-radius)";
hint.style.fontSize = "13px";
hint.style.color = "var(--mm-text-muted)";
hint.innerHTML = `<i class="fa-solid fa-info-circle" style="margin-right: 8px; color: var(--mm-primary);"></i>
以下是将注入到对话中的内容。您可以直接编辑内容,然后选择确认发送或重新生成。`;
body.appendChild(hint);
// 记忆摘要内容区域
const summaryContainer = document.createElement("div");
summaryContainer.style.background = "var(--mm-bg-card)";
summaryContainer.style.borderRadius = "var(--mm-radius)";
summaryContainer.style.padding = "15px";
summaryContainer.style.border = "1px solid var(--mm-border)";
summaryContainer.style.marginBottom = editorContent ? "15px" : "0";
const summaryLabel = document.createElement("div");
summaryLabel.style.fontWeight = "bold";
summaryLabel.style.marginBottom = "10px";
summaryLabel.style.color = "var(--mm-primary)";
summaryLabel.innerHTML = `<i class="fa-solid fa-brain" style="margin-right: 8px;"></i>记忆摘要内容`;
summaryContainer.appendChild(summaryLabel);
// 创建可调整高度的容器
const resizableContainer = document.createElement("div");
resizableContainer.style.position = "relative";
resizableContainer.style.minHeight = "150px";
// 使用 textarea 替代 div支持编辑
const summaryText = document.createElement("textarea");
summaryText.style.width = "100%";
summaryText.style.boxSizing = "border-box";
summaryText.style.whiteSpace = "pre-wrap";
summaryText.style.wordBreak = "break-word";
summaryText.style.fontSize = "14px";
summaryText.style.lineHeight = "1.6";
summaryText.style.color = "var(--mm-text)";
summaryText.style.height = editorContent ? "200px" : "300px";
summaryText.style.minHeight = "100px";
summaryText.style.maxHeight = "none";
summaryText.style.overflowY = "auto";
summaryText.style.padding = "10px";
summaryText.style.background = "var(--mm-bg-secondary)";
summaryText.style.borderRadius = "4px 4px 0 0";
summaryText.style.resize = "none";
summaryText.style.border = "1px solid var(--mm-border)";
summaryText.style.fontFamily = "inherit";
summaryText.value = summaryContent || "(无内容)";
resizableContainer.appendChild(summaryText);
// 创建拖动手柄(使用统一的 CSS 类)
const resizeHandle = document.createElement("div");
resizeHandle.className = "mm-resize-handle";
resizableContainer.appendChild(resizeHandle);
// 拖动调整高度逻辑
let isResizing = false;
let startY = 0;
let startHeight = 0;
resizeHandle.addEventListener("mousedown", (e) => {
isResizing = true;
startY = e.clientY;
startHeight = summaryText.offsetHeight;
document.body.style.cursor = "ns-resize";
document.body.style.userSelect = "none";
e.preventDefault();
});
document.addEventListener("mousemove", (e) => {
if (!isResizing) return;
const deltaY = e.clientY - startY;
const newHeight = Math.max(100, startHeight + deltaY);
summaryText.style.height = newHeight + "px";
});
document.addEventListener("mouseup", () => {
if (isResizing) {
isResizing = false;
document.body.style.cursor = "";
document.body.style.userSelect = "";
}
});
summaryContainer.appendChild(resizableContainer);
body.appendChild(summaryContainer);
// 剧情优化内容的 textarea 引用(在条件块外声明以便后续访问)
let editorTextarea = null;
// 如果有剧情优化内容,添加 Editor 区域
if (editorContent) {
const editorContainer = document.createElement("div");
editorContainer.style.background = "var(--mm-bg-card)";
editorContainer.style.borderRadius = "var(--mm-radius)";
editorContainer.style.padding = "15px";
editorContainer.style.border = "1px solid var(--mm-border)";
editorContainer.style.borderLeftColor = "#9d7cd8"; // 紫色边框标识
editorContainer.style.borderLeftWidth = "3px";
const editorLabel = document.createElement("div");
editorLabel.style.fontWeight = "bold";
editorLabel.style.marginBottom = "10px";
editorLabel.style.color = "#9d7cd8";
editorLabel.innerHTML = `<i class="fa-solid fa-wand-magic-sparkles" style="margin-right: 8px;"></i>剧情优化内容 (Editor)`;
editorContainer.appendChild(editorLabel);
// 创建可调整高度的容器
const editorResizableContainer = document.createElement("div");
editorResizableContainer.style.position = "relative";
editorResizableContainer.style.minHeight = "100px";
// 使用 textarea 替代 div支持编辑
editorTextarea = document.createElement("textarea");
editorTextarea.style.width = "100%";
editorTextarea.style.boxSizing = "border-box";
editorTextarea.style.whiteSpace = "pre-wrap";
editorTextarea.style.wordBreak = "break-word";
editorTextarea.style.fontSize = "14px";
editorTextarea.style.lineHeight = "1.6";
editorTextarea.style.color = "var(--mm-text)";
editorTextarea.style.height = "150px";
editorTextarea.style.minHeight = "80px";
editorTextarea.style.maxHeight = "none";
editorTextarea.style.overflowY = "auto";
editorTextarea.style.padding = "10px";
editorTextarea.style.background = "var(--mm-bg-secondary)";
editorTextarea.style.borderRadius = "4px 4px 0 0";
editorTextarea.style.resize = "none";
editorTextarea.style.border = "1px solid var(--mm-border)";
editorTextarea.style.fontFamily = "inherit";
editorTextarea.value = editorContent;
editorResizableContainer.appendChild(editorTextarea);
// 创建拖动手柄
const editorResizeHandle = document.createElement("div");
editorResizeHandle.className = "mm-resize-handle";
editorResizableContainer.appendChild(editorResizeHandle);
// 拖动调整高度逻辑
let isEditorResizing = false;
let editorStartY = 0;
let editorStartHeight = 0;
editorResizeHandle.addEventListener("mousedown", (e) => {
isEditorResizing = true;
editorStartY = e.clientY;
editorStartHeight = editorTextarea.offsetHeight;
document.body.style.cursor = "ns-resize";
document.body.style.userSelect = "none";
e.preventDefault();
});
document.addEventListener("mousemove", (e) => {
if (!isEditorResizing) return;
const deltaY = e.clientY - editorStartY;
const newHeight = Math.max(80, editorStartHeight + deltaY);
editorTextarea.style.height = newHeight + "px";
});
document.addEventListener("mouseup", () => {
if (isEditorResizing) {
isEditorResizing = false;
document.body.style.cursor = "";
document.body.style.userSelect = "";
}
});
editorContainer.appendChild(editorResizableContainer);
body.appendChild(editorContainer);
}
content.appendChild(body);
// 创建弹窗底部按钮
const footer = document.createElement("div");
footer.className = "mm-modal-footer";
footer.style.display = "flex";
footer.style.justifyContent = "flex-end";
footer.style.gap = "10px";
footer.style.padding = "15px 20px";
footer.style.borderTop = "1px solid var(--mm-border)";
footer.style.flexShrink = "0";
const cancelBtn = document.createElement("button");
cancelBtn.className = "mm-btn mm-btn-secondary";
cancelBtn.innerHTML = `<i class="fa-solid fa-xmark" style="margin-right: 6px;"></i>取消发送`;
const regenerateBtn = document.createElement("button");
regenerateBtn.className = "mm-btn mm-btn-secondary";
regenerateBtn.innerHTML = `<i class="fa-solid fa-rotate" style="margin-right: 6px;"></i>重新生成`;
// 多AI生成按钮 - 仅在功能可用时显示
let multiAIBtn = null;
if (isMultiAIAvailable()) {
multiAIBtn = document.createElement("button");
multiAIBtn.className = "mm-btn mm-btn-secondary";
multiAIBtn.style.background = "linear-gradient(135deg, #667eea 0%, #764ba2 100%)";
multiAIBtn.style.color = "#fff";
multiAIBtn.style.border = "none";
multiAIBtn.innerHTML = `<i class="fa-solid fa-robot" style="margin-right: 6px;"></i>多AI生成`;
multiAIBtn.title = "使用多个AI并发生成回复然后选择其中一个";
}
const confirmBtn = document.createElement("button");
confirmBtn.className = "mm-btn mm-btn-primary";
confirmBtn.innerHTML = `<i class="fa-solid fa-check" style="margin-right: 6px;"></i>确认发送`;
footer.appendChild(cancelBtn);
footer.appendChild(regenerateBtn);
if (multiAIBtn) {
footer.appendChild(multiAIBtn);
}
footer.appendChild(confirmBtn);
content.appendChild(footer);
modal.appendChild(content);
document.body.appendChild(modal);
const cleanup = () => {
document.body.removeChild(modal);
};
// 确认发送 - 返回编辑后的内容
confirmBtn.addEventListener("click", () => {
const editedSummary = summaryText.value;
const editedEditor = editorTextarea ? editorTextarea.value : "";
cleanup();
resolve({
action: "confirm",
editedSummary,
editedEditor
});
});
// 重新生成
regenerateBtn.addEventListener("click", () => {
cleanup();
resolve({ action: "regenerate" });
});
// 多AI生成
if (multiAIBtn) {
multiAIBtn.addEventListener("click", () => {
cleanup();
resolve({ action: "multi-regenerate" });
});
}
// 取消发送
cancelBtn.addEventListener("click", () => {
cleanup();
resolve({ action: "cancel" });
});
// 关闭按钮
closeBtn.addEventListener("click", () => {
cleanup();
resolve({ action: "cancel" });
});
});
}