Files
ComfyUI-Lora-Manager/static/js/components/ContextMenu.js

101 lines
3.5 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { refreshSingleLoraMetadata } from '../api/loraApi.js';
export class LoraContextMenu {
constructor() {
this.menu = document.getElementById('loraContextMenu');
this.currentCard = null;
this.init();
}
init() {
document.addEventListener('click', () => this.hideMenu());
document.addEventListener('contextmenu', (e) => {
const card = e.target.closest('.lora-card');
if (!card) {
this.hideMenu();
return;
}
e.preventDefault();
this.showMenu(e.clientX, e.clientY, card);
});
this.menu.addEventListener('click', (e) => {
const menuItem = e.target.closest('.context-menu-item');
if (!menuItem || !this.currentCard) return;
const action = menuItem.dataset.action;
if (!action) return;
switch(action) {
case 'detail':
// Trigger the main card click which shows the modal
this.currentCard.click();
break;
case 'civitai':
// Only trigger if the card is from civitai
if (this.currentCard.dataset.from_civitai === 'true') {
if (this.currentCard.dataset.meta === '{}') {
showToast('Please fetch metadata from CivitAI first', 'info');
} else {
this.currentCard.querySelector('.fa-globe')?.click();
}
} else {
showToast('No CivitAI information available', 'info');
}
break;
case 'copyname':
this.currentCard.querySelector('.fa-copy')?.click();
break;
case 'preview':
this.currentCard.querySelector('.fa-image')?.click();
break;
case 'delete':
this.currentCard.querySelector('.fa-trash')?.click();
break;
case 'move':
moveManager.showMoveModal(this.currentCard.dataset.filepath);
break;
case 'refresh-metadata':
refreshSingleLoraMetadata(this.currentCard.dataset.filepath);
break;
}
this.hideMenu();
});
}
showMenu(x, y, card) {
this.currentCard = card;
this.menu.style.display = 'block';
// 获取菜单尺寸
const menuRect = this.menu.getBoundingClientRect();
// 获取视口尺寸
const viewportWidth = document.documentElement.clientWidth;
const viewportHeight = document.documentElement.clientHeight;
// 计算最终位置 - 使用 clientX/Y不需要考虑滚动偏移
let finalX = x;
let finalY = y;
// 确保菜单不会超出右侧边界
if (x + menuRect.width > viewportWidth) {
finalX = x - menuRect.width;
}
// 确保菜单不会超出底部边界
if (y + menuRect.height > viewportHeight) {
finalY = y - menuRect.height;
}
// 直接设置位置,因为 position: fixed 是相对于视口定位的
this.menu.style.left = `${finalX}px`;
this.menu.style.top = `${finalY}px`;
}
hideMenu() {
this.menu.style.display = 'none';
this.currentCard = null;
}
}