mirror of
https://github.com/willmiao/ComfyUI-Lora-Manager.git
synced 2026-03-25 07:05:43 -03:00
Add context menu checkpoint
This commit is contained in:
@@ -31,7 +31,7 @@ html {
|
|||||||
|
|
||||||
/* Color System */
|
/* Color System */
|
||||||
--lora-accent: oklch(68% 0.28 256);
|
--lora-accent: oklch(68% 0.28 256);
|
||||||
--lora-surface: oklch(100% 0 0 / 0.95);
|
--lora-surface: oklch(100% 0 0 / 0.98);
|
||||||
--lora-border: oklch(90% 0.02 256 / 0.15);
|
--lora-border: oklch(90% 0.02 256 / 0.15);
|
||||||
--lora-text: oklch(95% 0.02 256);
|
--lora-text: oklch(95% 0.02 256);
|
||||||
--lora-error: oklch(75% 0.32 29);
|
--lora-error: oklch(75% 0.32 29);
|
||||||
@@ -59,7 +59,7 @@ html {
|
|||||||
--border-color: #404040;
|
--border-color: #404040;
|
||||||
|
|
||||||
--lora-accent: oklch(68% 0.28 256);
|
--lora-accent: oklch(68% 0.28 256);
|
||||||
--lora-surface: oklch(25% 0.02 256 / 0.85);
|
--lora-surface: oklch(25% 0.02 256 / 0.98);
|
||||||
--lora-border: oklch(90% 0.02 256 / 0.15);
|
--lora-border: oklch(90% 0.02 256 / 0.15);
|
||||||
--lora-text: oklch(98% 0.02 256);
|
--lora-text: oklch(98% 0.02 256);
|
||||||
}
|
}
|
||||||
|
|||||||
42
static/css/components/menu.css
Normal file
42
static/css/components/menu.css
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
.context-menu {
|
||||||
|
position: fixed;
|
||||||
|
background: var(--lora-surface);
|
||||||
|
border: 1px solid var(--border-color);
|
||||||
|
border-radius: var(--border-radius-xs);
|
||||||
|
padding: 4px 0;
|
||||||
|
min-width: 180px;
|
||||||
|
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.2);
|
||||||
|
z-index: 1000;
|
||||||
|
display: none;
|
||||||
|
backdrop-filter: blur(10px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.context-menu-item {
|
||||||
|
padding: 8px 12px;
|
||||||
|
cursor: pointer;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 8px;
|
||||||
|
color: var(--text-color);
|
||||||
|
background: var(--lora-surface);
|
||||||
|
}
|
||||||
|
|
||||||
|
.context-menu-item:hover {
|
||||||
|
background-color: var(--lora-accent);
|
||||||
|
color: var(--lora-text);
|
||||||
|
}
|
||||||
|
|
||||||
|
.context-menu-separator {
|
||||||
|
height: 1px;
|
||||||
|
background-color: var(--border-color);
|
||||||
|
margin: 4px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.context-menu-item.delete-item {
|
||||||
|
color: var(--danger-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.context-menu-item i {
|
||||||
|
width: 16px;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
@@ -9,6 +9,7 @@
|
|||||||
@import 'components/modal.css';
|
@import 'components/modal.css';
|
||||||
@import 'components/toast.css';
|
@import 'components/toast.css';
|
||||||
@import 'components/loading.css';
|
@import 'components/loading.css';
|
||||||
|
@import 'components/menu.css';
|
||||||
|
|
||||||
.initialization-notice {
|
.initialization-notice {
|
||||||
display: flex;
|
display: flex;
|
||||||
|
|||||||
88
static/js/components/ContextMenu.js
Normal file
88
static/js/components/ContextMenu.js
Normal file
@@ -0,0 +1,88 @@
|
|||||||
|
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 action = e.target.closest('.context-menu-item')?.dataset.action;
|
||||||
|
if (!action || !this.currentCard) return;
|
||||||
|
|
||||||
|
switch(action) {
|
||||||
|
case 'detail':
|
||||||
|
this.currentCard.querySelector('.info-button').click();
|
||||||
|
break;
|
||||||
|
case 'civitai':
|
||||||
|
this.currentCard.querySelector('.civitai-button').click();
|
||||||
|
break;
|
||||||
|
case 'copyname':
|
||||||
|
this.currentCard.querySelector('.copy-button').click();
|
||||||
|
break;
|
||||||
|
case 'preview':
|
||||||
|
this.currentCard.querySelector('.preview-button').click();
|
||||||
|
break;
|
||||||
|
case 'delete':
|
||||||
|
this.currentCard.querySelector('.delete-button').click();
|
||||||
|
break;
|
||||||
|
case 'move':
|
||||||
|
// To be implemented
|
||||||
|
console.log('Move to folder feature coming soon');
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.hideMenu();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
showMenu(x, y, card) {
|
||||||
|
this.currentCard = card;
|
||||||
|
this.menu.style.display = 'block';
|
||||||
|
|
||||||
|
// 使用客户端坐标,考虑滚动位置
|
||||||
|
const scrollY = window.scrollY || window.pageYOffset;
|
||||||
|
const scrollX = window.scrollX || window.pageXOffset;
|
||||||
|
|
||||||
|
// 获取菜单尺寸
|
||||||
|
const menuRect = this.menu.getBoundingClientRect();
|
||||||
|
|
||||||
|
// 获取视口尺寸
|
||||||
|
const viewportWidth = document.documentElement.clientWidth;
|
||||||
|
const viewportHeight = document.documentElement.clientHeight;
|
||||||
|
|
||||||
|
// 根据鼠标位置和菜单尺寸计算最终位置
|
||||||
|
let finalX = x;
|
||||||
|
let finalY = y;
|
||||||
|
|
||||||
|
// 确保菜单不会超出右侧边界
|
||||||
|
if (x + menuRect.width > viewportWidth) {
|
||||||
|
finalX = x - menuRect.width;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 确保菜单不会超出底部边界
|
||||||
|
if (y + menuRect.height > viewportHeight) {
|
||||||
|
finalY = y - menuRect.height;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 设置菜单位置,考虑滚动偏移
|
||||||
|
this.menu.style.left = `${finalX + scrollX}px`;
|
||||||
|
this.menu.style.top = `${finalY + scrollY}px`;
|
||||||
|
}
|
||||||
|
|
||||||
|
hideMenu() {
|
||||||
|
this.menu.style.display = 'none';
|
||||||
|
this.currentCard = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -22,6 +22,7 @@ import { showDeleteModal, confirmDelete, closeDeleteModal } from './utils/modalU
|
|||||||
import { SearchManager } from './utils/search.js';
|
import { SearchManager } from './utils/search.js';
|
||||||
import { DownloadManager } from './managers/DownloadManager.js';
|
import { DownloadManager } from './managers/DownloadManager.js';
|
||||||
import { SettingsManager, toggleApiKeyVisibility } from './managers/SettingsManager.js';
|
import { SettingsManager, toggleApiKeyVisibility } from './managers/SettingsManager.js';
|
||||||
|
import { LoraContextMenu } from './components/ContextMenu.js';
|
||||||
|
|
||||||
// Export all functions that need global access
|
// Export all functions that need global access
|
||||||
window.loadMoreLoras = loadMoreLoras;
|
window.loadMoreLoras = loadMoreLoras;
|
||||||
@@ -56,6 +57,7 @@ document.addEventListener('DOMContentLoaded', () => {
|
|||||||
initFolderTagsVisibility();
|
initFolderTagsVisibility();
|
||||||
initBackToTop();
|
initBackToTop();
|
||||||
window.searchManager = new SearchManager();
|
window.searchManager = new SearchManager();
|
||||||
|
new LoraContextMenu();
|
||||||
});
|
});
|
||||||
|
|
||||||
// Initialize event listeners
|
// Initialize event listeners
|
||||||
|
|||||||
21
templates/components/context_menu.html
Normal file
21
templates/components/context_menu.html
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
<div id="loraContextMenu" class="context-menu">
|
||||||
|
<div class="context-menu-item" data-action="detail">
|
||||||
|
<i class="fas fa-info-circle"></i> Show Details
|
||||||
|
</div>
|
||||||
|
<div class="context-menu-item" data-action="civitai">
|
||||||
|
<i class="fas fa-external-link-alt"></i> View on Civitai
|
||||||
|
</div>
|
||||||
|
<div class="context-menu-item" data-action="copyname">
|
||||||
|
<i class="fas fa-copy"></i> Copy Model Name
|
||||||
|
</div>
|
||||||
|
<div class="context-menu-item" data-action="preview">
|
||||||
|
<i class="fas fa-image"></i> Replace Preview
|
||||||
|
</div>
|
||||||
|
<div class="context-menu-separator"></div>
|
||||||
|
<div class="context-menu-item" data-action="move">
|
||||||
|
<i class="fas fa-folder-open"></i> Move to Folder
|
||||||
|
</div>
|
||||||
|
<div class="context-menu-item delete-item" data-action="delete">
|
||||||
|
<i class="fas fa-trash"></i> Delete Model
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
@@ -58,6 +58,7 @@
|
|||||||
|
|
||||||
{% include 'components/modals.html' %}
|
{% include 'components/modals.html' %}
|
||||||
{% include 'components/loading.html' %}
|
{% include 'components/loading.html' %}
|
||||||
|
{% include 'components/context_menu.html' %}
|
||||||
|
|
||||||
<div class="container">
|
<div class="container">
|
||||||
{% if is_initializing %}
|
{% if is_initializing %}
|
||||||
|
|||||||
Reference in New Issue
Block a user