diff --git a/modules/button-collapse.js b/modules/button-collapse.js
deleted file mode 100644
index 94aed2a..0000000
--- a/modules/button-collapse.js
+++ /dev/null
@@ -1,257 +0,0 @@
-let stylesInjected = false;
-
-const SELECTORS = {
- chat: '#chat',
- messages: '.mes',
- mesButtons: '.mes_block .mes_buttons',
- buttons: '.memory-button, .dynamic-prompt-analysis-btn, .mes_history_preview',
- collapse: '.xiaobaix-collapse-btn',
-};
-
-const XPOS_KEY = 'xiaobaix_x_btn_position';
-const getXBtnPosition = () => {
- try {
- return (
- window?.extension_settings?.LittleWhiteBox?.xBtnPosition ||
- localStorage.getItem(XPOS_KEY) ||
- 'name-left'
- );
- } catch {
- return 'name-left';
- }
-};
-
-const injectStyles = () => {
- if (stylesInjected) return;
- const css = `
-.mes_block .mes_buttons{align-items:center}
-.xiaobaix-collapse-btn{
-position:relative;display:inline-flex;width:32px;height:32px;justify-content:center;align-items:center;
-border-radius:50%;background:var(--SmartThemeBlurTintColor);cursor:pointer;
-box-shadow:inset 0 0 15px rgba(0,0,0,.6),0 2px 8px rgba(0,0,0,.2);
-transition:opacity .15s ease,transform .15s ease}
-.xiaobaix-xstack{position:relative;display:inline-flex;align-items:center;justify-content:center;pointer-events:none}
-.xiaobaix-xstack span{
-position:absolute;font:italic 900 20px 'Arial Black',sans-serif;letter-spacing:-2px;transform:scaleX(.8);
-text-shadow:0 0 10px rgba(255,255,255,.5),0 0 20px rgba(100,200,255,.3);color:#fff}
-.xiaobaix-xstack span:nth-child(1){color:rgba(255,255,255,.1);transform:scaleX(.8) translateX(-8px);text-shadow:none}
-.xiaobaix-xstack span:nth-child(2){color:rgba(255,255,255,.2);transform:scaleX(.8) translateX(-4px);text-shadow:none}
-.xiaobaix-xstack span:nth-child(3){color:rgba(255,255,255,.4);transform:scaleX(.8) translateX(-2px);text-shadow:none}
-.xiaobaix-sub-container{display:none;position:absolute;right:38px;border-radius:8px;padding:4px;gap:8px;pointer-events:auto}
-.xiaobaix-collapse-btn.open .xiaobaix-sub-container{display:flex;background:var(--SmartThemeBlurTintColor)}
-.xiaobaix-collapse-btn.open,.xiaobaix-collapse-btn.open ~ *{pointer-events:auto!important}
-.mes_block .mes_buttons.xiaobaix-expanded{width:150px}
-.xiaobaix-sub-container,.xiaobaix-sub-container *{pointer-events:auto!important}
-.xiaobaix-sub-container .memory-button,.xiaobaix-sub-container .dynamic-prompt-analysis-btn,.xiaobaix-sub-container .mes_history_preview{opacity:1!important;filter:none!important}
-.xiaobaix-sub-container.dir-right{left:38px;right:auto;z-index:1000;margin-top:2px}
-`;
- const style = document.createElement('style');
- style.textContent = css;
- document.head.appendChild(style);
- stylesInjected = true;
-};
-
-const createCollapseButton = (dirRight) => {
- injectStyles();
- const btn = document.createElement('div');
- btn.className = 'mes_btn xiaobaix-collapse-btn';
- btn.innerHTML = `
-
XXXX
-
- `;
- const sub = btn.lastElementChild;
-
- ['click','pointerdown','pointerup'].forEach(t => {
- sub.addEventListener(t, e => e.stopPropagation(), { passive: true });
- });
-
- btn.addEventListener('click', (e) => {
- e.preventDefault(); e.stopPropagation();
- const open = btn.classList.toggle('open');
- const mesButtons = btn.closest(SELECTORS.mesButtons);
- if (mesButtons) mesButtons.classList.toggle('xiaobaix-expanded', open);
- });
-
- return btn;
-};
-
-const findInsertPoint = (messageEl) => {
- return messageEl.querySelector(
- '.ch_name.flex-container.justifySpaceBetween .flex-container.flex1.alignitemscenter,' +
- '.ch_name.flex-container.justifySpaceBetween .flex-container.flex1.alignItemsCenter'
- );
-};
-
-const ensureCollapseForMessage = (messageEl, pos) => {
- const mesButtons = messageEl.querySelector(SELECTORS.mesButtons);
- if (!mesButtons) return null;
-
- let collapseBtn = messageEl.querySelector(SELECTORS.collapse);
- const dirRight = pos === 'edit-right';
-
- if (!collapseBtn) collapseBtn = createCollapseButton(dirRight);
- else collapseBtn.querySelector('.xiaobaix-sub-container')?.classList.toggle('dir-right', dirRight);
-
- if (dirRight) {
- const container = findInsertPoint(messageEl);
- if (!container) return null;
- if (collapseBtn.parentNode !== container) container.appendChild(collapseBtn);
- } else {
- if (mesButtons.lastElementChild !== collapseBtn) mesButtons.appendChild(collapseBtn);
- }
- return collapseBtn;
-};
-
-let processed = new WeakSet();
-let io = null;
-let mo = null;
-let queue = [];
-let rafScheduled = false;
-
-const processOneMessage = (message) => {
- if (!message || processed.has(message)) return;
-
- const mesButtons = message.querySelector(SELECTORS.mesButtons);
- if (!mesButtons) { processed.add(message); return; }
-
- const pos = getXBtnPosition();
- if (pos === 'edit-right' && !findInsertPoint(message)) { processed.add(message); return; }
-
- const targetBtns = mesButtons.querySelectorAll(SELECTORS.buttons);
- if (!targetBtns.length) { processed.add(message); return; }
-
- const collapseBtn = ensureCollapseForMessage(message, pos);
- if (!collapseBtn) { processed.add(message); return; }
-
- const sub = collapseBtn.querySelector('.xiaobaix-sub-container');
- const frag = document.createDocumentFragment();
- targetBtns.forEach(b => frag.appendChild(b));
- sub.appendChild(frag);
-
- processed.add(message);
-};
-
-const ensureIO = () => {
- if (io) return io;
- io = new IntersectionObserver((entries) => {
- for (const e of entries) {
- if (!e.isIntersecting) continue;
- processOneMessage(e.target);
- io.unobserve(e.target);
- }
- }, {
- root: document.querySelector(SELECTORS.chat) || null,
- rootMargin: '200px 0px',
- threshold: 0
- });
- return io;
-};
-
-const observeVisibility = (nodes) => {
- const obs = ensureIO();
- nodes.forEach(n => { if (n && !processed.has(n)) obs.observe(n); });
-};
-
-const hookMutations = () => {
- const chat = document.querySelector(SELECTORS.chat);
- if (!chat) return;
-
- if (!mo) {
- mo = new MutationObserver((muts) => {
- for (const m of muts) {
- m.addedNodes && m.addedNodes.forEach(n => {
- if (n.nodeType !== 1) return;
- const el = n;
- if (el.matches?.(SELECTORS.messages)) queue.push(el);
- else el.querySelectorAll?.(SELECTORS.messages)?.forEach(mes => queue.push(mes));
- });
- }
- if (!rafScheduled && queue.length) {
- rafScheduled = true;
- requestAnimationFrame(() => {
- observeVisibility(queue);
- queue = [];
- rafScheduled = false;
- });
- }
- });
- }
- mo.observe(chat, { childList: true, subtree: true });
-};
-
-const processExistingVisible = () => {
- const all = document.querySelectorAll(`${SELECTORS.chat} ${SELECTORS.messages}`);
- if (!all.length) return;
- const unprocessed = [];
- all.forEach(n => { if (!processed.has(n)) unprocessed.push(n); });
- if (unprocessed.length) observeVisibility(unprocessed);
-};
-
-const initButtonCollapse = () => {
- injectStyles();
- hookMutations();
- processExistingVisible();
- if (window && window['registerModuleCleanup']) {
- try { window['registerModuleCleanup']('buttonCollapse', cleanup); } catch {}
- }
-};
-
-const processButtonCollapse = () => {
- processExistingVisible();
-};
-
-const registerButtonToSubContainer = (messageId, buttonEl) => {
- if (!buttonEl) return false;
- const message = document.querySelector(`${SELECTORS.chat} ${SELECTORS.messages}[mesid="${messageId}"]`);
- if (!message) return false;
-
- processOneMessage(message);
-
- const pos = getXBtnPosition();
- const collapseBtn = message.querySelector(SELECTORS.collapse) || ensureCollapseForMessage(message, pos);
- if (!collapseBtn) return false;
-
- const sub = collapseBtn.querySelector('.xiaobaix-sub-container');
- sub.appendChild(buttonEl);
- buttonEl.style.pointerEvents = 'auto';
- buttonEl.style.opacity = '1';
- return true;
-};
-
-const cleanup = () => {
- io?.disconnect(); io = null;
- mo?.disconnect(); mo = null;
- queue = [];
- rafScheduled = false;
-
- document.querySelectorAll(SELECTORS.collapse).forEach(btn => {
- const sub = btn.querySelector('.xiaobaix-sub-container');
- const message = btn.closest(SELECTORS.messages) || btn.closest('.mes');
- const mesButtons = message?.querySelector(SELECTORS.mesButtons) || message?.querySelector('.mes_buttons');
- if (sub && mesButtons) {
- mesButtons.classList.remove('xiaobaix-expanded');
- const frag = document.createDocumentFragment();
- while (sub.firstChild) frag.appendChild(sub.firstChild);
- mesButtons.appendChild(frag);
- }
- btn.remove();
- });
-
- processed = new WeakSet();
-};
-
-if (typeof window !== 'undefined') {
- Object.assign(window, {
- initButtonCollapse,
- cleanupButtonCollapse: cleanup,
- registerButtonToSubContainer,
- processButtonCollapse,
- });
-
- document.addEventListener('xiaobaixEnabledChanged', (e) => {
- const en = e && e.detail && e.detail.enabled;
- if (!en) cleanup();
- });
-}
-
-export { initButtonCollapse, cleanup, registerButtonToSubContainer, processButtonCollapse };