mirror of
https://github.com/Cola-Echo/memory-manager-concurrent.git
synced 2026-06-14 11:45:51 +00:00
fix: 优化进度面板移动端显示和拖拽功能
- 进度面板移动端默认定位改为左上角(参考剧情优化面板) - 修复移动端拖拽时面板消失的问题 - 使用 setProperty 设置 !important 内联样式覆盖CSS规则 - 拖拽开始时先固定当前位置防止跳变 - 移动端拖拽后保持用户自定义位置 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
115
index.js
115
index.js
@@ -3640,6 +3640,13 @@
|
|||||||
y: clientY - rect.top,
|
y: clientY - rect.top,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// 先将当前位置固定为内联样式(防止拖拽时位置跳变)
|
||||||
|
// 使用 setProperty 设置 !important,以覆盖移动端CSS中的 !important 规则
|
||||||
|
this.container.style.setProperty('left', `${rect.left}px`, 'important');
|
||||||
|
this.container.style.setProperty('top', `${rect.top}px`, 'important');
|
||||||
|
this.container.style.setProperty('right', 'auto', 'important');
|
||||||
|
this.container.style.setProperty('transform', 'none', 'important');
|
||||||
|
|
||||||
// 添加拖动样式
|
// 添加拖动样式
|
||||||
this.container.classList.add("mm-dragging");
|
this.container.classList.add("mm-dragging");
|
||||||
|
|
||||||
@@ -3676,10 +3683,10 @@
|
|||||||
newX = Math.max(0, Math.min(newX, maxX));
|
newX = Math.max(0, Math.min(newX, maxX));
|
||||||
newY = Math.max(0, Math.min(newY, maxY));
|
newY = Math.max(0, Math.min(newY, maxY));
|
||||||
|
|
||||||
// 应用位置(使用 left/top 而不是 transform)
|
// 应用位置(使用 setProperty 设置 !important,覆盖移动端CSS)
|
||||||
this.container.style.left = `${newX}px`;
|
this.container.style.setProperty('left', `${newX}px`, 'important');
|
||||||
this.container.style.top = `${newY}px`;
|
this.container.style.setProperty('top', `${newY}px`, 'important');
|
||||||
this.container.style.transform = "none";
|
this.container.style.setProperty('transform', 'none', 'important');
|
||||||
|
|
||||||
this.position = { x: newX, y: newY };
|
this.position = { x: newX, y: newY };
|
||||||
};
|
};
|
||||||
@@ -3694,9 +3701,15 @@
|
|||||||
document.removeEventListener("touchmove", onDragMove);
|
document.removeEventListener("touchmove", onDragMove);
|
||||||
document.removeEventListener("touchend", onDragEnd);
|
document.removeEventListener("touchend", onDragEnd);
|
||||||
|
|
||||||
// 保存位置
|
// 保存位置(如果有移动)
|
||||||
if (this.position) {
|
if (this.position && dragMoved) {
|
||||||
this.savePosition();
|
// 移动端:添加用户定位类让拖拽位置生效,但不保存到localStorage
|
||||||
|
// 桌面端:保存位置并添加用户定位类
|
||||||
|
if (window.innerWidth >= 768) {
|
||||||
|
this.savePosition();
|
||||||
|
}
|
||||||
|
// 移动端和桌面端都添加用户定位类,让拖拽后的位置生效
|
||||||
|
this.container.classList.add("mm-user-positioned");
|
||||||
}
|
}
|
||||||
|
|
||||||
// 判断是否为点击(短时间内没有移动)
|
// 判断是否为点击(短时间内没有移动)
|
||||||
@@ -3722,8 +3735,11 @@
|
|||||||
}, { passive: false });
|
}, { passive: false });
|
||||||
}
|
}
|
||||||
|
|
||||||
// 保存位置到 localStorage
|
// 保存位置到 localStorage(仅桌面端)
|
||||||
savePosition() {
|
savePosition() {
|
||||||
|
// 移动端不保存位置
|
||||||
|
if (window.innerWidth < 768) return;
|
||||||
|
|
||||||
if (this.position) {
|
if (this.position) {
|
||||||
localStorage.setItem(
|
localStorage.setItem(
|
||||||
"mm_progress_panel_position",
|
"mm_progress_panel_position",
|
||||||
@@ -3748,6 +3764,8 @@
|
|||||||
this.container.style.left = `${pos.x}px`;
|
this.container.style.left = `${pos.x}px`;
|
||||||
this.container.style.top = `${pos.y}px`;
|
this.container.style.top = `${pos.y}px`;
|
||||||
this.container.style.transform = "none";
|
this.container.style.transform = "none";
|
||||||
|
// 添加用户定位类,防止移动端 CSS 覆盖
|
||||||
|
this.container.classList.add("mm-user-positioned");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
@@ -3761,6 +3779,7 @@
|
|||||||
this.container.style.left = "50%";
|
this.container.style.left = "50%";
|
||||||
this.container.style.top = "80px";
|
this.container.style.top = "80px";
|
||||||
this.container.style.transform = "translateX(-50%)";
|
this.container.style.transform = "translateX(-50%)";
|
||||||
|
this.container.classList.remove("mm-user-positioned");
|
||||||
localStorage.removeItem("mm_progress_panel_position");
|
localStorage.removeItem("mm_progress_panel_position");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3777,13 +3796,53 @@
|
|||||||
this.hideTimeout = null;
|
this.hideTimeout = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 重置面板位置,让CSS初始定位生效
|
// 检查是否有保存的位置
|
||||||
if (this.container) {
|
if (this.container) {
|
||||||
this.container.style.left = "";
|
// 移动端(宽度小于768px)不使用保存的位置,始终使用CSS默认位置
|
||||||
this.container.style.top = "";
|
const isMobile = window.innerWidth < 768;
|
||||||
this.container.style.right = "";
|
|
||||||
this.container.style.bottom = "";
|
if (isMobile) {
|
||||||
this.container.style.transform = "";
|
// 移动端:清除所有内联样式,使用CSS默认定位
|
||||||
|
this.container.style.left = "";
|
||||||
|
this.container.style.top = "";
|
||||||
|
this.container.style.right = "";
|
||||||
|
this.container.style.bottom = "";
|
||||||
|
this.container.style.transform = "";
|
||||||
|
this.container.classList.remove("mm-user-positioned");
|
||||||
|
this.position = null;
|
||||||
|
} else {
|
||||||
|
// 桌面端:尝试使用保存的位置
|
||||||
|
const saved = localStorage.getItem("mm_progress_panel_position");
|
||||||
|
if (saved) {
|
||||||
|
try {
|
||||||
|
const pos = JSON.parse(saved);
|
||||||
|
requestAnimationFrame(() => {
|
||||||
|
const rect = this.container.getBoundingClientRect();
|
||||||
|
const maxX = window.innerWidth - Math.min(rect.width, 320);
|
||||||
|
const maxY = window.innerHeight - Math.min(rect.height, 100);
|
||||||
|
|
||||||
|
if (pos.x >= 0 && pos.x <= maxX && pos.y >= 0 && pos.y <= maxY) {
|
||||||
|
this.position = pos;
|
||||||
|
this.container.style.left = `${pos.x}px`;
|
||||||
|
this.container.style.top = `${pos.y}px`;
|
||||||
|
this.container.style.transform = "none";
|
||||||
|
this.container.classList.add("mm-user-positioned");
|
||||||
|
} else {
|
||||||
|
this.resetPosition();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} catch (e) {
|
||||||
|
// 解析失败
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
this.container.style.left = "";
|
||||||
|
this.container.style.top = "";
|
||||||
|
this.container.style.right = "";
|
||||||
|
this.container.style.bottom = "";
|
||||||
|
this.container.style.transform = "";
|
||||||
|
this.container.classList.remove("mm-user-positioned");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
this.isVisible = true;
|
this.isVisible = true;
|
||||||
@@ -6440,6 +6499,10 @@
|
|||||||
async function callSingleSummaryBookAI(panel, book, userMessage, context) {
|
async function callSingleSummaryBookAI(panel, book, userMessage, context) {
|
||||||
const bookName = book.name;
|
const bookName = book.name;
|
||||||
|
|
||||||
|
// 创建 AbortController 用于终止任务
|
||||||
|
const taskId = `search_${bookName}`;
|
||||||
|
const abortController = new AbortController();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
panel.setBookStatus(bookName, "loading", "调用AI中...");
|
panel.setBookStatus(bookName, "loading", "调用AI中...");
|
||||||
panel.addBookAIMessage(bookName, "正在调用历史事件回忆AI...");
|
panel.addBookAIMessage(bookName, "正在调用历史事件回忆AI...");
|
||||||
@@ -6467,20 +6530,21 @@
|
|||||||
const finalSystemPrompt = getJailbreakPrefix() + "\n\n" + baseSystemPrompt;
|
const finalSystemPrompt = getJailbreakPrefix() + "\n\n" + baseSystemPrompt;
|
||||||
const finalUserMessage = buildUserPrompt(userMessage);
|
const finalUserMessage = buildUserPrompt(userMessage);
|
||||||
|
|
||||||
// 添加到进度追踪
|
// 添加到进度追踪,并注册 AbortController
|
||||||
const taskId = `search_${bookName}`;
|
|
||||||
if (progressTracker) {
|
if (progressTracker) {
|
||||||
progressTracker.addTask(taskId, `搜索:${bookName}`, "search");
|
progressTracker.addTask(taskId, `搜索:${bookName}`, "search");
|
||||||
|
progressTracker.setTaskAbortController(taskId, abortController);
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// 调用AI
|
// 调用AI(传递 signal 以支持终止)
|
||||||
const response = await APIAdapter.callWithRetry(
|
const response = await APIAdapter.callWithRetry(
|
||||||
{ ...aiConfig, category: bookName, source: bookName, taskId: taskId },
|
{ ...aiConfig, category: bookName, source: bookName, taskId: taskId },
|
||||||
finalSystemPrompt,
|
finalSystemPrompt,
|
||||||
finalUserMessage,
|
finalUserMessage,
|
||||||
taskId,
|
taskId,
|
||||||
3
|
3,
|
||||||
|
abortController.signal
|
||||||
);
|
);
|
||||||
|
|
||||||
// 完成进度
|
// 完成进度
|
||||||
@@ -6506,12 +6570,19 @@
|
|||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
// 失败时也标记进度完成
|
// 失败时也标记进度完成
|
||||||
|
const isAborted = error.name === "AbortError";
|
||||||
if (progressTracker) {
|
if (progressTracker) {
|
||||||
progressTracker.completeTask(taskId, false, error.message);
|
progressTracker.completeTask(taskId, false, isAborted ? "已终止" : error.message);
|
||||||
|
}
|
||||||
|
if (isAborted) {
|
||||||
|
Logger.warn(`[交互式搜索] 总结世界书 "${bookName}" 已被终止`);
|
||||||
|
panel.setBookStatus(bookName, "error", "已终止");
|
||||||
|
panel.addBookSystemMessage(bookName, "搜索已被用户终止");
|
||||||
|
} else {
|
||||||
|
Logger.error(`[交互式搜索] 总结世界书 "${bookName}" AI调用失败:`, error.message);
|
||||||
|
panel.setBookStatus(bookName, "error", "失败");
|
||||||
|
panel.addBookSystemMessage(bookName, `AI调用失败: ${error.message}`);
|
||||||
}
|
}
|
||||||
Logger.error(`[交互式搜索] 总结世界书 "${bookName}" AI调用失败:`, error.message);
|
|
||||||
panel.setBookStatus(bookName, "error", "失败");
|
|
||||||
panel.addBookSystemMessage(bookName, `AI调用失败: ${error.message}`);
|
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
Logger.error(`[交互式搜索] 总结世界书 "${bookName}" 初始化失败:`, error.message);
|
Logger.error(`[交互式搜索] 总结世界书 "${bookName}" 初始化失败:`, error.message);
|
||||||
|
|||||||
51
style.css
51
style.css
@@ -3124,11 +3124,13 @@
|
|||||||
============================================================================ */
|
============================================================================ */
|
||||||
|
|
||||||
@media (max-width: 768px) {
|
@media (max-width: 768px) {
|
||||||
.mm-message-progress-panel {
|
/* 进度面板移动端基础定位(参考剧情优化面板,固定在左上角) */
|
||||||
|
.mm-message-progress-panel:not(.mm-dragging):not(.mm-user-positioned) {
|
||||||
width: calc(100vw - 32px);
|
width: calc(100vw - 32px);
|
||||||
max-width: 320px;
|
max-width: 320px;
|
||||||
left: 16px;
|
left: 16px;
|
||||||
top: 60px;
|
top: 60px;
|
||||||
|
right: auto;
|
||||||
transform: none;
|
transform: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3159,10 +3161,13 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
@media (max-width: 480px) {
|
@media (max-width: 480px) {
|
||||||
.mm-message-progress-panel {
|
/* 进度面板手机端基础定位(参考剧情优化面板,固定在左上角) */
|
||||||
|
.mm-message-progress-panel:not(.mm-dragging):not(.mm-user-positioned) {
|
||||||
width: calc(100vw - 24px);
|
width: calc(100vw - 24px);
|
||||||
left: 12px;
|
left: 8px;
|
||||||
top: 50px;
|
top: 60px;
|
||||||
|
right: auto;
|
||||||
|
transform: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.mm-msg-panel-header {
|
.mm-msg-panel-header {
|
||||||
@@ -6445,13 +6450,22 @@
|
|||||||
transform: none;
|
transform: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 进度面板 - 移动端安全定位 */
|
/* 进度面板 - 移动端安全定位(参考剧情优化面板,固定在左上角) */
|
||||||
.mm-message-progress-panel {
|
.mm-message-progress-panel:not(.mm-dragging):not(.mm-user-positioned) {
|
||||||
top: 10px !important;
|
top: 60px !important;
|
||||||
left: 50% !important;
|
left: 16px !important;
|
||||||
transform: translateX(-50%) !important;
|
right: auto !important;
|
||||||
|
transform: none !important;
|
||||||
max-height: 60vh !important;
|
max-height: 60vh !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* 用户手动拖动后,允许自定义位置 */
|
||||||
|
.mm-message-progress-panel.mm-user-positioned {
|
||||||
|
top: unset !important;
|
||||||
|
left: unset !important;
|
||||||
|
right: unset !important;
|
||||||
|
transform: none !important;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 手机适配 (480px) */
|
/* 手机适配 (480px) */
|
||||||
@@ -6558,16 +6572,25 @@
|
|||||||
transform: none;
|
transform: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 进度面板 - 手机端安全定位 */
|
/* 进度面板 - 手机端安全定位(参考剧情优化面板,固定在左上角) */
|
||||||
.mm-message-progress-panel {
|
.mm-message-progress-panel:not(.mm-dragging):not(.mm-user-positioned) {
|
||||||
top: 8px !important;
|
top: 60px !important;
|
||||||
left: 50% !important;
|
left: 8px !important;
|
||||||
transform: translateX(-50%) !important;
|
right: auto !important;
|
||||||
|
transform: none !important;
|
||||||
max-height: 55vh !important;
|
max-height: 55vh !important;
|
||||||
width: calc(100vw - 24px) !important;
|
width: calc(100vw - 24px) !important;
|
||||||
max-width: 300px !important;
|
max-width: 300px !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* 用户手动拖动后,允许自定义位置 */
|
||||||
|
.mm-message-progress-panel.mm-user-positioned {
|
||||||
|
top: unset !important;
|
||||||
|
left: unset !important;
|
||||||
|
right: unset !important;
|
||||||
|
transform: none !important;
|
||||||
|
}
|
||||||
|
|
||||||
/* 汇总检查弹窗(动态创建) */
|
/* 汇总检查弹窗(动态创建) */
|
||||||
.mm-modal.mm-modal-visible .mm-modal-content {
|
.mm-modal.mm-modal-visible .mm-modal-content {
|
||||||
width: calc(100vw - 16px) !important;
|
width: calc(100vw - 16px) !important;
|
||||||
|
|||||||
Reference in New Issue
Block a user