From 31c1139b32612aa760be30bafeabfd092fb182a3 Mon Sep 17 00:00:00 2001 From: Will Miao <13051207myq@gmail.com> Date: Tue, 18 Feb 2025 00:02:12 +0800 Subject: [PATCH] Add context menu checkpoint --- static/css/base.css | 4 +- static/css/components/menu.css | 42 ++++++++++++ static/css/style.css | 1 + static/js/components/ContextMenu.js | 88 ++++++++++++++++++++++++++ static/js/main.js | 2 + templates/components/context_menu.html | 21 ++++++ templates/loras.html | 1 + 7 files changed, 157 insertions(+), 2 deletions(-) create mode 100644 static/css/components/menu.css create mode 100644 static/js/components/ContextMenu.js create mode 100644 templates/components/context_menu.html diff --git a/static/css/base.css b/static/css/base.css index 263b4e4e..448f696a 100644 --- a/static/css/base.css +++ b/static/css/base.css @@ -31,7 +31,7 @@ html { /* Color System */ --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-text: oklch(95% 0.02 256); --lora-error: oklch(75% 0.32 29); @@ -59,7 +59,7 @@ html { --border-color: #404040; --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-text: oklch(98% 0.02 256); } diff --git a/static/css/components/menu.css b/static/css/components/menu.css new file mode 100644 index 00000000..819cfe72 --- /dev/null +++ b/static/css/components/menu.css @@ -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; +} \ No newline at end of file diff --git a/static/css/style.css b/static/css/style.css index f4e7eae8..a0a79844 100644 --- a/static/css/style.css +++ b/static/css/style.css @@ -9,6 +9,7 @@ @import 'components/modal.css'; @import 'components/toast.css'; @import 'components/loading.css'; +@import 'components/menu.css'; .initialization-notice { display: flex; diff --git a/static/js/components/ContextMenu.js b/static/js/components/ContextMenu.js new file mode 100644 index 00000000..eafc2162 --- /dev/null +++ b/static/js/components/ContextMenu.js @@ -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; + } +} \ No newline at end of file diff --git a/static/js/main.js b/static/js/main.js index e4866bf4..9a2989ec 100644 --- a/static/js/main.js +++ b/static/js/main.js @@ -22,6 +22,7 @@ import { showDeleteModal, confirmDelete, closeDeleteModal } from './utils/modalU import { SearchManager } from './utils/search.js'; import { DownloadManager } from './managers/DownloadManager.js'; import { SettingsManager, toggleApiKeyVisibility } from './managers/SettingsManager.js'; +import { LoraContextMenu } from './components/ContextMenu.js'; // Export all functions that need global access window.loadMoreLoras = loadMoreLoras; @@ -56,6 +57,7 @@ document.addEventListener('DOMContentLoaded', () => { initFolderTagsVisibility(); initBackToTop(); window.searchManager = new SearchManager(); + new LoraContextMenu(); }); // Initialize event listeners diff --git a/templates/components/context_menu.html b/templates/components/context_menu.html new file mode 100644 index 00000000..43b2451a --- /dev/null +++ b/templates/components/context_menu.html @@ -0,0 +1,21 @@ +
\ No newline at end of file diff --git a/templates/loras.html b/templates/loras.html index 30976dad..47a92488 100644 --- a/templates/loras.html +++ b/templates/loras.html @@ -58,6 +58,7 @@ {% include 'components/modals.html' %} {% include 'components/loading.html' %} + {% include 'components/context_menu.html' %}