From 82d93fe5a8373c39863b63d1e8181ebcaea8eae6 Mon Sep 17 00:00:00 2001 From: CalamitousFelicitousness Date: Fri, 1 Aug 2025 12:00:58 +0100 Subject: [PATCH 1/3] Update setHints.js with longHint --- javascript/setHints.js | 95 ++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 92 insertions(+), 3 deletions(-) diff --git a/javascript/setHints.js b/javascript/setHints.js index 086367a6e..e135f16d4 100644 --- a/javascript/setHints.js +++ b/javascript/setHints.js @@ -9,6 +9,8 @@ const localeData = { type: 2, hint: null, btn: null, + expandTimeout: null, // New property for expansion timeout + currentElement: null, // Track current element for expansion }; async function cycleLocale() { @@ -44,20 +46,103 @@ async function tooltipCreate() { if (window.opts.tooltips === 'UI tooltips') localeData.type = 2; } +async function expandTooltip(element, longHint) { + if (localeData.currentElement === element && localeData.hint.classList.contains('tooltip-show')) { + // Hide the progress ring + const ring = localeData.hint.querySelector('.tooltip-progress-ring'); + if (ring) { + ring.style.opacity = '0'; + } + + // Expand the container + localeData.hint.classList.add('tooltip-expanded'); + + // After container starts expanding, reveal the long content + setTimeout(() => { + const longContent = localeData.hint.querySelector('.long-content'); + if (longContent) { + longContent.classList.add('show'); + } + }, 100); + } +} + async function tooltipShow(e) { + // Clear any existing expansion timeout + if (localeData.expandTimeout) { + clearTimeout(localeData.expandTimeout); + localeData.expandTimeout = null; + } + + // Remove expanded class and reset current element + localeData.hint.classList.remove('tooltip-expanded'); + localeData.currentElement = e.target; + if (e.target.dataset.hint) { + // Create progress ring SVG + const progressRing = ` +
+ + + + +
+ `; + + // Set up the complete content structure from the start + let content = ` +
+ ${e.target.textContent} + ${e.target.dataset.longHint ? progressRing : ''} +
+
+ ${e.target.dataset.hint} + `; + + // Add long content if available, but keep it hidden + if (e.target.dataset.longHint) { + content += `
${e.target.dataset.longHint}
`; + } + + localeData.hint.innerHTML = content; localeData.hint.classList.add('tooltip-show'); - localeData.hint.innerHTML = `${e.target.textContent}
${e.target.dataset.hint}`; + if (e.clientX > window.innerWidth / 2) { localeData.hint.classList.add('tooltip-left'); } else { localeData.hint.classList.remove('tooltip-left'); } + + // Set up expansion timer if long hint is available + if (e.target.dataset.longHint) { + // Start progress ring animation + const ring = localeData.hint.querySelector('.tooltip-progress-ring'); + const ringProgress = localeData.hint.querySelector('.ring-progress'); + + if (ring && ringProgress) { + // Show the ring and start animation + setTimeout(() => { + ring.classList.add('active'); + ringProgress.classList.add('animate'); + }, 100); + } + + localeData.expandTimeout = setTimeout(() => { + expandTooltip(e.target, e.target.dataset.longHint); + }, 3000); + } } } async function tooltipHide(e) { - localeData.hint.classList.remove('tooltip-show'); + // Clear expansion timeout when hiding + if (localeData.expandTimeout) { + clearTimeout(localeData.expandTimeout); + localeData.expandTimeout = null; + } + + localeData.hint.classList.remove('tooltip-show', 'tooltip-expanded'); + localeData.currentElement = null; } async function validateHints(json, elements) { @@ -85,7 +170,7 @@ async function addMissingHints(json, missingHints) { json.missing = []; for (const h of missingHints.sort()) { if (h.length <= 1) continue; - json.missing.push({ id: '', label: h, localized: '', hint: h }); + json.missing.push({ id: '', label: h, localized: '', hint: h, longHint: '' }); // Add longHint property } log('missing hints', missingHints); log('added missing hints:', { missing: json.missing }); @@ -192,6 +277,10 @@ async function setHints(analyze = false) { el.title = found.hint; } else if (localeData.type === 2) { el.dataset.hint = found.hint; + // Set long hint if available + if (found.longHint && found.longHint.length > 0) { + el.dataset.longHint = found.longHint; + } el.addEventListener('mouseover', tooltipShow); el.addEventListener('mouseout', tooltipHide); } else { From 2ea059d0552ea4d786a24589d4f1ed7828f44f63 Mon Sep 17 00:00:00 2001 From: CalamitousFelicitousness Date: Fri, 1 Aug 2025 12:01:50 +0100 Subject: [PATCH 2/3] Update sdnext.css --- javascript/sdnext.css | 97 ++++++++++++++++++++++++++++++++++++------- 1 file changed, 81 insertions(+), 16 deletions(-) diff --git a/javascript/sdnext.css b/javascript/sdnext.css index af5b39464..6e3141897 100644 --- a/javascript/sdnext.css +++ b/javascript/sdnext.css @@ -602,21 +602,97 @@ div#extras_scale_to_tab div.form { display: block; font-size: var(--text-xs); min-height: 1.3em; + max-width: 40em; opacity: 0; padding: 0.5em; pointer-events: none; position: fixed; right: 1em; top: 1em; - transition: opacity 0.2s ease-in; + transition: opacity 0.2s ease-in, width 0.4s ease-in-out; width: 22em; z-index: 999; + overflow: visible; } .tooltip-show { opacity: 0.9; } +.tooltip-expanded { + width: 32em; +} + +.tooltip .separator { + display: block; + height: 1px; + background: linear-gradient(to right, transparent, var(--button-primary-border-color), transparent); + margin: 0.5em 0; + opacity: 0.6; +} + +.tooltip .long-content { + opacity: 0; + max-height: 0; + overflow: hidden; + transition: opacity 0.3s ease-in, max-height 0.3s ease-in-out; +} + +.tooltip .long-content.show { + opacity: 1; + max-height: 50em; +} + +.tooltip-header { + position: relative; + display: flex; + align-items: center; + justify-content: space-between; +} + +.tooltip-progress-ring { + position: absolute; + right: 0; + top: 50%; + transform: translateY(-50%); + width: 1.2em; + height: 1.2em; + opacity: 0; + transition: opacity 0.2s ease-in; + flex-shrink: 0; +} + +.tooltip-progress-ring.active { + opacity: 0.8; +} + +.tooltip-progress-ring svg { + width: 100%; + height: 100%; + transform: rotate(-90deg); +} + +.tooltip-progress-ring .ring-background { + fill: none; + stroke: var(--button-primary-border-color); + stroke-width: 2; + opacity: 0.3; +} + +.tooltip-progress-ring .ring-progress { + fill: none; + stroke: var(--body-text-color); + stroke-width: 2; + stroke-linecap: round; + stroke-dasharray: 31.4; /* Circumference of circle with radius 5 (2πr = 2π×5 ≈ 31.4) */ + stroke-dashoffset: 31.4; + transition: stroke-dashoffset 3s linear; +} + +.tooltip-progress-ring .ring-progress.animate { + stroke-dashoffset: 0; +} + .toolbutton-selected { background: var(--background-fill-primary) !important; } @@ -680,19 +756,8 @@ div#extras_scale_to_tab div.form { #quicksettings>button { align-self: end; - height: 1.3em; - margin: 0em 0.7em 0.3em -0.5em; - line-height: 1em; - background-color: var(--background-fill-primary); -} - -#quicksettings>button:hover { - background-color: var(--button-cancel-border-color-hover); -} - -button#quicksettings_reset { - position: absolute; - right: 0; + margin-bottom: 6px; + padding: 0 1em 0 0; } #settings { @@ -1648,7 +1713,7 @@ div:has(>#tab-gallery-folders) { cursor: cell; padding: 8px; background-color: var(--input-background-fill); - border-radius: var(--radius-lg); + border-radius: var(--sd-border-radius); max-width: 100%; } @@ -1660,7 +1725,7 @@ div:has(>#tab-gallery-folders) { display: inline-block; transition: transform 0.2s ease-in-out; flex-shrink: 0; - color: var(--block-title-text-color); + color: var(--sd-input-text-color); } .gallery-separator-name { From df924d291b23cb7e5ac54f75e4088cbd1815fe5d Mon Sep 17 00:00:00 2001 From: CalamitousFelicitousness Date: Fri, 1 Aug 2025 18:35:36 +0100 Subject: [PATCH 3/3] Update sdnext.css Amended in response to comments by @vladmandic on 01/08/2025. --- javascript/sdnext.css | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/javascript/sdnext.css b/javascript/sdnext.css index 6e3141897..4ac257c89 100644 --- a/javascript/sdnext.css +++ b/javascript/sdnext.css @@ -609,7 +609,7 @@ div#extras_scale_to_tab div.form { position: fixed; right: 1em; top: 1em; - transition: opacity 0.2s ease-in, width 0.4s ease-in-out; + transition: opacity 0.2s ease-in; width: 22em; z-index: 999; overflow: visible; @@ -1713,7 +1713,7 @@ div:has(>#tab-gallery-folders) { cursor: cell; padding: 8px; background-color: var(--input-background-fill); - border-radius: var(--sd-border-radius); + border-radius: var(--radius-lg); max-width: 100%; } @@ -1725,7 +1725,7 @@ div:has(>#tab-gallery-folders) { display: inline-block; transition: transform 0.2s ease-in-out; flex-shrink: 0; - color: var(--sd-input-text-color); + color: var(--block-title-text-color); } .gallery-separator-name {