import { renderExtensionTemplateAsync } from "/scripts/extensions.js"; import { POPUP_TYPE, Popup } from "/scripts/popup.js"; import { makeDraggable } from './draggable.js'; import { sectionTitles, conditionalBlocks, presetSettingsPath } from './config.js'; import * as state from './prese_state.js'; import { bindEvents } from './prese_events.js'; let settingsOrb = null; let globalCollapseState = {}; export function renderPresetManager(context) { const presetManager = state.getPresetManager(); const managerHtml = `
`; context.find('#preset-manager-container').html(managerHtml); const select = context.find('#preset-select'); select.empty(); for (const presetName in presetManager.presets) { const option = $('').val(presetName).text(presetName); if (presetName === presetManager.activePreset) { option.prop('selected', true); } select.append(option); } } export function renderEditor(context) { const container = context.find('#prompt-editor-container'); const currentPresets = state.getCurrentPresets(); const currentMixedOrder = state.getCurrentMixedOrder(); if (!container.length) { console.error("Amily2 [renderEditor]: Could not find #prompt-editor-container."); return; } const openSections = new Set(); container.find('.prompt-section').each(function() { const sectionKey = $(this).data('section'); const content = $(this).find('.collapsible-content'); if (content.is(':visible')) { openSections.add(sectionKey); } }); container.empty(); for (const sectionKey in sectionTitles) { const sectionTitle = sectionTitles[sectionKey]; const prompts = currentPresets[sectionKey] || []; const order = currentMixedOrder[sectionKey] || []; const sectionHtml = $(`

${sectionTitle}

`); const listContainer = sectionHtml.find('.mixed-list'); order.forEach((item, orderIndex) => { let itemHtml; if (item.type === 'prompt') { const prompt = prompts[item.index]; if (prompt) { itemHtml = createMixedPromptItemHtml(prompt, item.index, orderIndex, sectionKey); } } else if (item.type === 'conditional') { const block = conditionalBlocks[sectionKey]?.find(b => b.id === item.id); if (block) { itemHtml = createMixedConditionalItemHtml(block, orderIndex, sectionKey); } } if (itemHtml) { listContainer.append(itemHtml); } }); container.append(sectionHtml); } setTimeout(() => { container.find('.prompt-section').each(function() { const sectionKey = $(this).data('section'); const contentElement = $(this).find('.collapsible-content'); const iconElement = $(this).find('.collapse-icon'); const isExpanded = globalCollapseState[sectionKey] === true || openSections.has(sectionKey); if (isExpanded) { contentElement.show(); iconElement.text('▼'); } else { contentElement.hide(); iconElement.text('▶'); } }); }, 0); bindEvents(context); } function createMixedPromptItemHtml(prompt, promptIndex, orderIndex, sectionKey) { return `
⋮⋮
`; } function createMixedConditionalItemHtml(block, orderIndex, sectionKey) { return `
⋮⋮ 条件块 --- ${block.name} ---
${block.description}
`; } export function toggleSettingsOrb() { if (settingsOrb && settingsOrb.length > 0) { settingsOrb.remove(); settingsOrb = null; toastr.info('提示词链编辑器已关闭。'); } else { settingsOrb = $(`
`); settingsOrb.css({ position: 'fixed', top: '85%', left: '50%', transform: 'translate(-50%, -50%)', width: '50px', height: '50px', backgroundColor: 'var(--primary-color)', color: 'white', borderRadius: '50%', display: 'flex', justifyContent: 'center', alignItems: 'center', cursor: 'grab', zIndex: '9998', boxShadow: '0 4px 12px rgba(0,0,0,0.3)' }); settingsOrb.html(''); $('body').append(settingsOrb); makeDraggable(settingsOrb, showPresetSettings, 'amily2_settingsOrb_pos'); toastr.info('提示词链编辑器已开启。'); } } async function showPresetSettings() { const template = $(await renderExtensionTemplateAsync(presetSettingsPath, 'prese-settings')); renderPresetManager(template); renderEditor(template); const popup = new Popup(template, POPUP_TYPE.TEXT, 'Amily2 提示词链编辑器', { wide: true, large: true, okButton: '关闭', cancelButton: false, }); await popup.show(); } export function addPresetSettingsButton() { const button = document.createElement('div'); button.id = 'amily2-preset-settings-button'; button.classList.add('list-group-item', 'flex-container', 'flexGap5', 'interactable'); button.innerHTML = `Amily2 提示词链`; button.addEventListener('click', toggleSettingsOrb); const extensionsMenu = document.getElementById('extensionsMenu'); if (extensionsMenu && !document.getElementById(button.id)) { extensionsMenu.appendChild(button); } } export function getGlobalCollapseState() { return globalCollapseState; }