diff --git a/css/main.css b/css/main.css index 009b7c0a..913576c5 100644 --- a/css/main.css +++ b/css/main.css @@ -735,7 +735,30 @@ audio { .hover-element { position: relative; - font-size: 24px; + padding-top: 4px; +} + +#hover-element-button { + display: flex; + align-items: center; + justify-content: center; + width: 32px; + height: 32px; + border-radius: 0.5rem; + cursor: pointer; + color: gray; +} + +#hover-element-button:hover { + background-color: var(--background-fill-secondary); +} + +#hover-element-button svg { + color: inherit; +} + +.dark #hover-element-button:hover { + background-color: var(--selected-item-color-dark); } .hover-menu { @@ -743,27 +766,40 @@ audio { position: absolute; bottom: 100%; left: 0; - box-shadow: 0 2px 12px rgb(0 0 0 / 15%); - border-radius: 0.5rem; + background: white; + border: 1px solid rgba(0, 0, 0, 0.1); + box-shadow: 0 4px 16px rgb(0 0 0 / 12%), 0 1px 3px rgb(0 0 0 / 8%); + border-radius: 0.75rem; z-index: 10000; min-width: 330px; flex-direction: column; - overflow: hidden; + padding: 4px; +} + +.hover-menu::before { + content: ''; + position: absolute; + top: 100%; + left: 0; + width: 100%; + height: 8px; +} + +.hover-menu > * { + border: none !important; + box-shadow: none !important; } .hover-menu button { width: 100%; - background: white !important; - border-radius: 0 !important; + background: transparent !important; + border: none !important; + border-radius: 0.5rem !important; justify-content: space-between; margin: 0 !important; height: 36px; - border-color: transparent !important; - transition: background-color 0.15s ease; -} - -.hover-menu button:not(#clear-history-confirm) { - border-bottom: 0 !important; + font-weight: 500; + box-shadow: none !important; } .hover-menu button:hover { @@ -775,19 +811,26 @@ audio { } #show-controls { - background-color: white; - border-color: transparent !important; + background-color: transparent; + border: none !important; height: 36px; - border-radius: 0; - border-bottom: 0 !important; + border-radius: 0.5rem; padding-top: 3px; padding-left: 4px; display: flex; font-weight: normal; } +#show-controls:hover { + background-color: #dbeafe; +} + .dark #show-controls { - background-color: var(--darker-gray); + background-color: transparent; +} + +.dark #show-controls:hover { + background-color: var(--selected-item-color-dark); } #show-controls label { @@ -797,12 +840,12 @@ audio { width: 100%; padding-right: 12px; gap: 10px; - font-weight: 600; + font-weight: 500; color: var(--button-secondary-text-color); } #show-controls label input { - margin-top: 4px; + margin-top: 5px; } .transparent-substring { @@ -817,6 +860,7 @@ audio { min-width: 0 !important; display: flex; flex-direction: column-reverse; + padding-left: 12px; padding-right: 20px; padding-bottom: 3px; flex-grow: 0 !important; @@ -1208,9 +1252,14 @@ audio { color: #9ca3af; } +.dark .hover-menu { + background: var(--darker-gray); + border-color: transparent; + box-shadow: 0 4px 16px rgb(0 0 0 / 40%); +} + .dark .hover-menu button { - border-color: var(--border-color-primary); - background-color: var(--darker-gray) !important; + background-color: transparent !important; } .dark #chat-controls, diff --git a/js/main.js b/js/main.js index cba4c903..918c85c1 100644 --- a/js/main.js +++ b/js/main.js @@ -309,18 +309,19 @@ for (let i = 0; i < slimDropdownElements.length; i++) { // https://github.com/SillyTavern/SillyTavern/blob/6c8bd06308c69d51e2eb174541792a870a83d2d6/public/script.js //------------------------------------------------ var buttonsInChat = document.querySelectorAll("#chat-tab #chat-buttons button, #chat-tab #chat-buttons #show-controls"); +var hoverContainer = document.getElementById("gr-hover-container"); var button = document.getElementById("hover-element-button"); var menu = document.getElementById("hover-menu"); var istouchscreen = (navigator.maxTouchPoints > 0) || "ontouchstart" in document.documentElement; function showMenu() { - menu.style.display = "flex"; // Show the menu + menu.style.display = "flex"; } function hideMenu() { - menu.style.display = "none"; // Hide the menu + menu.style.display = "none"; if (!istouchscreen) { - document.querySelector("#chat-input textarea").focus(); // Focus on the chat input + document.querySelector("#chat-input textarea").focus(); } } @@ -329,7 +330,6 @@ if (buttonsInChat.length > 0) { const thisButton = buttonsInChat[i]; menu.appendChild(thisButton); - // Only apply transformations to button elements if (thisButton.tagName.toLowerCase() === "button") { thisButton.addEventListener("click", () => { hideMenu(); @@ -339,7 +339,6 @@ if (buttonsInChat.length > 0) { const matches = buttonText.match(/(\(.*?\))/); if (matches && matches.length > 1) { - // Apply the transparent-substring class to the matched substring const substring = matches[1]; const newText = buttonText.replace(substring, ` ${substring.slice(1, -1)}`); thisButton.innerHTML = newText; @@ -348,16 +347,19 @@ if (buttonsInChat.length > 0) { } } -function isMouseOverButtonOrMenu() { - return menu.matches(":hover") || button.matches(":hover"); -} +var menuInteracting = false; -button.addEventListener("mouseenter", function () { +hoverContainer.addEventListener("mouseenter", function () { if (!istouchscreen) { showMenu(); } }); +hoverContainer.addEventListener("mousedown", function () { + menuInteracting = true; + setTimeout(function () { menuInteracting = false; }, 300); +}); + button.addEventListener("click", function () { if (menu.style.display === "flex") { hideMenu(); @@ -367,24 +369,20 @@ button.addEventListener("click", function () { } }); -// Delay to prevent menu hiding when the mouse leaves the button or menu -function delayedHideMenu() { - setTimeout(function () { - if (!isMouseOverButtonOrMenu()) { - hideMenu(); - } - }, 100); -} - -// Add event listener for mouseleave on the button -button.addEventListener("mouseleave", delayedHideMenu); -// Add event listener for mouseleave on the menu -menu.addEventListener("mouseleave", delayedHideMenu); +hoverContainer.addEventListener("mouseleave", function () { + if (!istouchscreen) { + setTimeout(function () { + if (!hoverContainer.matches(":hover") && !menu.matches(":hover")) { + hideMenu(); + } + }, 50); + } +}); // Add event listener for click anywhere in the document document.addEventListener("click", function (event) { // Check if the click is outside the button/menu and the menu is visible - if (!isMouseOverButtonOrMenu() && menu.style.display === "flex") { + if (!menuInteracting && !event.target.closest("#gr-hover-container") && menu.style.display === "flex") { hideMenu(); } diff --git a/modules/ui_chat.py b/modules/ui_chat.py index 10d05f65..d9652253 100644 --- a/modules/ui_chat.py +++ b/modules/ui_chat.py @@ -52,7 +52,7 @@ def create_ui(): shared.gradio['html_display'] = gr.HTML(value=chat_html_wrapper({'internal': [], 'visible': [], 'metadata': {}}, '', '', 'chat', 'cai-chat', '')['html'], visible=True) with gr.Row(elem_id="chat-input-row"): with gr.Column(scale=1, elem_id='gr-hover-container'): - gr.HTML(value='
', elem_id='gr-hover') + gr.HTML(value='
', elem_id='gr-hover') with gr.Column(scale=10, elem_id='chat-input-container'): shared.gradio['textbox'] = gr.MultimodalTextbox(label='', placeholder='Send a message', file_types=['text', '.pdf', 'image'], file_count="multiple", elem_id='chat-input', elem_classes=['add_scrollbar'])