From f6d72ef0021f8cea7f2c1c6eba8469de00ca76cd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=A7=91=E6=9E=97=5FCyril=20Pilgrim?= Date: Thu, 5 Mar 2026 09:34:16 +0800 Subject: [PATCH] feat(ui): refine save button style and add ESC key listener to close manager Motivation: The save button's style was originally an overly bright gradient, making it feel out of place compared to the frosted glass aesthetics. Additionally, the user requested the ability to close the modal using the Escape key. Implementation: 1. Updated '.llm-pm-actions-right button:last-child' CSS to use a restrained translucent background similar to the sidebar items, keeping it cohesive with the glassmorphism design. 2. Added a global 'keydown' listener on 'Escape' inside 'ProviderManager.show()' which correctly triggers 'closeModal()' (also checking for unsaved changes) and automatically removes itself when closed. --- web/css/provider_manager.css | 13 +++++++------ web/js/provider_manager.js | 37 ++++++++++++++++++++++++++---------- 2 files changed, 34 insertions(+), 16 deletions(-) diff --git a/web/css/provider_manager.css b/web/css/provider_manager.css index 64bc1f8..69d049d 100644 --- a/web/css/provider_manager.css +++ b/web/css/provider_manager.css @@ -458,16 +458,17 @@ box-shadow: 0 0 16px var(--glass-accent-glow); } -/* Primary save button (last child) */ .llm-pm-actions-right button:last-child { - background: linear-gradient(135deg, var(--glass-accent), #8b5cf6) !important; - color: white !important; - border: none !important; - box-shadow: 0 4px 14px var(--glass-accent-glow); + background: rgba(255, 255, 255, 0.08) !important; + color: var(--glass-text-primary) !important; + border: 1px solid rgba(255, 255, 255, 0.15) !important; + box-shadow: 0 4px 12px rgba(0, 0, 0, 0.2), inset 0 1px 1px rgba(255, 255, 255, 0.1); } .llm-pm-actions-right button:last-child:hover { - box-shadow: 0 6px 20px rgba(99, 102, 241, 0.45); + background: rgba(255, 255, 255, 0.15) !important; + border-color: rgba(255, 255, 255, 0.25) !important; + box-shadow: 0 6px 16px rgba(0, 0, 0, 0.3), inset 0 1px 1px rgba(255, 255, 255, 0.2); transform: translateY(-1px); } diff --git a/web/js/provider_manager.js b/web/js/provider_manager.js index ce669ec..430980c 100644 --- a/web/js/provider_manager.js +++ b/web/js/provider_manager.js @@ -412,20 +412,37 @@ class ProviderManager { this.contentContainer = $el("div.llm-pm-content"); this.sidebarListContainer = $el("div.llm-pm-list"); + const closeModal = () => { + this.checkUnsaved(() => { + this.modal.style.display = "none"; + this.currentDraft = null; + if (this._escListener) { + window.removeEventListener("keydown", this._escListener); + this._escListener = null; + } + // Trigger full redraw of graph to apply changes + if (app.graph) { + app.graph.setDirtyCanvas(true); + } + }); + }; + const closeBtn = $el("span.llm-pm-close", { innerHTML: "×", - onclick: () => { - this.checkUnsaved(() => { - this.modal.style.display = "none"; - this.currentDraft = null; - // Trigger full redraw of graph to apply changes - if (app.graph) { - app.graph.setDirtyCanvas(true); - } - }); - } + onclick: closeModal }); + // Add ESC listener + this._escListener = (e) => { + if (e.key === "Escape" && this.modal && this.modal.style.display !== "none") { + // Ignore if there is another dialog overlay active (like unsaved changes prompt) + if (!document.querySelector(".llm-pm-prompt-overlay")) { + closeModal(); + } + } + }; + window.addEventListener("keydown", this._escListener); + const searchInput = $el("input", { type: "text", placeholder: t("search_placeholder"),