${visibleSources
.map(
(source) => `
${
SOURCE_LABELS[source] || source
}
`,
)
.join("")}
`;
const header = card.querySelector(".mm-collapse-header");
header.addEventListener("click", () => {
card.classList.toggle("expanded");
const arrow = card.querySelector(".mm-collapse-arrow");
if (arrow) {
arrow.classList.toggle(
"fa-chevron-up",
card.classList.contains("expanded"),
);
arrow.classList.toggle(
"fa-chevron-down",
!card.classList.contains("expanded"),
);
}
});
container.appendChild(card);
initFlowSourceDrag(card.querySelector(".mm-flow-source-list"));
});
}
function initFlowSourceDrag(listContainer) {
if (!listContainer) return;
let draggedItem = null;
listContainer
.querySelectorAll(".mm-flow-source-item")
.forEach((item) => {
item.addEventListener("dragstart", (e) => {
draggedItem = item;
item.classList.add("mm-dragging");
e.dataTransfer.effectAllowed = "move";
});
item.addEventListener("dragend", () => {
item.classList.remove("mm-dragging");
draggedItem = null;
listContainer
.querySelectorAll(".mm-flow-source-item")
.forEach((i) => {
i.classList.remove(
"mm-drag-over-top",
"mm-drag-over-bottom",
);
});
// 拖拽结束后自动保存
autoSaveFlowConfig();
});
item.addEventListener("dragover", (e) => {
e.preventDefault();
if (!draggedItem || draggedItem === item) return;
const rect = item.getBoundingClientRect();
const midY = rect.top + rect.height / 2;
item.classList.remove(
"mm-drag-over-top",
"mm-drag-over-bottom",
);
item.classList.add(
e.clientY < midY
? "mm-drag-over-top"
: "mm-drag-over-bottom",
);
});
item.addEventListener("dragleave", () => {
item.classList.remove(
"mm-drag-over-top",
"mm-drag-over-bottom",
);
});
item.addEventListener("drop", (e) => {
e.preventDefault();
if (!draggedItem || draggedItem === item) return;
const rect = item.getBoundingClientRect();
if (e.clientY < rect.top + rect.height / 2) {
listContainer.insertBefore(draggedItem, item);
} else {
listContainer.insertBefore(
draggedItem,
item.nextSibling,
);
}
item.classList.remove(
"mm-drag-over-top",
"mm-drag-over-bottom",
);
});
});
}
// 自动保存流程配置(静默保存,不关闭弹窗)
function autoSaveFlowConfig() {
const container = document.getElementById("mm-flow-config-list");
if (!container) return;
const newOrder = {};
container.querySelectorAll(".mm-flow-source-list").forEach((list) => {
const category = list.dataset.category;
const sources = [];
// 1. 始终将jailbreak放在最顶部(即使在界面上隐藏)
sources.push("jailbreak");
// 2. 添加界面上可见的其他来源
list.querySelectorAll(".mm-flow-source-item").forEach((item) => {
sources.push(item.dataset.source);
});
if (sources.length > 0) {
newOrder[category] = sources;
}
});
const settings = getGlobalSettings();
settings.promptPartsOrder = newOrder;
updateGlobalSettings(settings);
Logger.debug("[流程配置] 已自动保存来源排序配置");
}
function saveFlowConfig() {
const container = document.getElementById("mm-flow-config-list");
if (!container) return;
const newOrder = {};
container.querySelectorAll(".mm-flow-source-list").forEach((list) => {
const category = list.dataset.category;
const sources = [];
// 1. 始终将jailbreak放在最顶部(即使在界面上隐藏)
sources.push("jailbreak");
// 2. 添加界面上可见的其他来源
list.querySelectorAll(".mm-flow-source-item").forEach((item) => {
sources.push(item.dataset.source);
});
if (sources.length > 0) {
newOrder[category] = sources;
}
});
const settings = getGlobalSettings();
settings.promptPartsOrder = newOrder;
updateGlobalSettings(settings);
Logger.log("[流程配置] 已保存来源排序配置", newOrder);
// 视觉反馈:显示保存成功提示
const saveBtn = document.getElementById("mm-flow-config-save");
if (saveBtn) {
const originalText = saveBtn.innerHTML;
saveBtn.innerHTML = '