diff --git a/js/imageFeed.js b/js/imageFeed.js index 0b000f8..4e6a473 100644 --- a/js/imageFeed.js +++ b/js/imageFeed.js @@ -9,27 +9,29 @@ $el("style", { .pysssss-image-feed { position: absolute; background: #333; - overflow: auto; z-index: 99; font-family: sans-serif; font-size: 12px; + display: flex; + flex-direction: column; } .pysssss-image-feed--top, .pysssss-image-feed--bottom { width: 100vw; min-height: 30px; - max-height: var(--max-size, 200px); + max-height: calc(var(--max-size, 20) * 1vh); } .pysssss-image-feed--top { top: 0; } .pysssss-image-feed--bottom { bottom: 0; + flex-direction: column-reverse; } .pysssss-image-feed--left, .pysssss-image-feed--right { top: 0; height: 100vh; - min-width: 30px; - max-width: var(--max-size, 200px); + min-width: 200px; + max-width: calc(var(--max-size, 10) * 1vw); } .pysssss-image-feed--left { left: 0; @@ -37,17 +39,54 @@ $el("style", { .pysssss-image-feed--right { right: 0; } + + .pysssss-image-feed--left .pysssss-image-feed-menu, .pysssss-image-feed--right .pysssss-image-feed-menu { + flex-direction: column; + } + .pysssss-image-feed-menu { - position: sticky; - top: 0; - height: 0px; + position: relative; + flex: 0 1 min-content; display: flex; gap: 5px; - padding: 5px 5px 0 5px; + padding: 5px; + justify-content: space-between; + } + .pysssss-image-feed-btn-group { + align-items: stretch; + display: flex; + gap: .5rem; + flex: 0 1 fit-content; + justify-content: flex-end; } .pysssss-image-feed-btn { - cursor: pointer; + background-color:#666666; + border-radius:5px; + border:1px solid #ffffff; + color:#ffffff; + cursor:pointer; + display:inline-block; + flex: 0 1 fit-content; + text-decoration:none; } + .pysssss-image-feed-btn.sizing-btn:checked { + filter: invert(); + } + .pysssss-image-feed-btn.clear-btn { + padding: 5px 20px; + } + .pysssss-image-feed-btn.hide-btn { + padding: 5px; + aspect-ratio: 1 / 1; + } + .pysssss-image-feed-btn:hover { + background-color:#3d3d3d; + } + .pysssss-image-feed-btn:active { + position:relative; + top:1px; + } + .pysssss-image-feed-menu section { border-radius: 5px; background: rgba(0,0,0,0.6); @@ -55,21 +94,75 @@ $el("style", { display: flex; gap: 5px; align-items: center; + position: relative; } - .pysssss-image-feed-menu section * { - display: none; + .pysssss-image-feed-menu section span { + white-space: nowrap; } - .pysssss-image-feed-menu section:hover * { - display: initial; + .pysssss-image-feed-menu section input { + flex: 1 1 100%; + background: rgba(0,0,0,0.6); + border-radius: 5px; + overflow: hidden; + z-index: 100; } + + .sizing-menu { + position: relative; + } + + .size-controls-flyout { + position: absolute; + transform: scaleX(0%); + transition: 200ms ease-out; + transition-delay: 500ms; + z-index: 101; + width: 300px; + } + + .sizing-menu:hover .size-controls-flyout { + transform: scale(1, 1); + transition: 200ms linear; + transition-delay: 0; + } + .pysssss-image-feed--bottom .size-controls-flyout { + transform: scale(1,0); + transform-origin: bottom; + bottom: 0; + left: 0; + } + .pysssss-image-feed--top .size-controls-flyout { + transform: scale(1,0); + transform-origin: top; + top: 0; + left: 0; + } + .pysssss-image-feed--left .size-controls-flyout { + transform: scale(0, 1); + transform-origin: left; + top: 0; + left: 0; + } + .pysssss-image-feed--right .size-controls-flyout { + transform: scale(0, 1); + transform-origin: right; + top: 0; + right: 0; + } + .pysssss-image-feed-menu > * { min-height: 24px; } .pysssss-image-feed-list { + flex: 1 1 auto; + overflow-y: auto; display: grid; align-items: center; justify-content: center; - grid-template-columns: repeat( auto-fit, minmax(var(--img-sz), 1fr) ); + gap: 4px; + grid-auto-rows: min-content; + grid-template-columns: repeat(var(--img-sz, 3), 1fr); + transition: 100ms linear; } .pysssss-image-feed-list div { text-align: center; @@ -77,7 +170,7 @@ $el("style", { .pysssss-image-feed-list img { object-fit: var(--img-fit, contain); max-width: 100%; - max-height: var(--max-size); + max-height: calc(var(--max-size) * 1vh); } .pysssss-image-feed-list img:hover { filter: brightness(1.2); @@ -189,7 +282,12 @@ app.registerExtension({ }, }); - const hideButton = $el("button.pysssss-image-feed-btn", { + const clearButton = $el("button.pysssss-image-feed-btn.clear-btn", { + textContent: "Clear", + onclick: () => imageList.replaceChildren(), + }); + + const hideButton = $el("button.pysssss-image-feed-btn.hide-btn", { textContent: "❌", onclick: () => { imageFeed.style.display = "none"; @@ -200,64 +298,64 @@ app.registerExtension({ imageFeed.append( $el("div.pysssss-image-feed-menu", [ - $el( - "section", - { - textContent: "Feed Size...", - }, - [ - $el("input", { - type: "range", - style: { width: "100px" }, - min: 10, - max: 80, - oninput: (e) => { - e.target.parentElement.title = `Controls the maximum size of the image feed panel (${e.target.value}vh)`; - imageFeed.style.setProperty("--max-size", e.target.value + "vh"); - saveVal("FeedSize", e.target.value); - }, - $: (el) => { - requestAnimationFrame(() => { - el.value = getVal("FeedSize", 25); - el.oninput({ target: el }); - }); - }, - }), - ] - ), - $el( - "section", - { - textContent: "Image Size...", - style: { - marginRight: "auto", - }, - }, - [ - $el("input", { - type: "range", - style: { width: "100px" }, - min: 5, - max: 100, - oninput: (e) => { - e.target.parentElement.title = `Controls the maximum size images in the feed (${e.target.value}vw)`; - imageFeed.style.setProperty("--img-sz", e.target.value + "vw"); - saveVal("ImageSize", e.target.value); - }, - $: (el) => { - requestAnimationFrame(() => { - el.value = getVal("ImageSize", 25); - el.oninput({ target: el }); - }); - }, - }), - ] - ), - $el("button.pysssss-image-feed-btn", { - textContent: "Clear", - onclick: () => imageList.replaceChildren(), - }), - hideButton, + $el("section.sizing-menu", {}, [ + $el('label.size-control-handle', { textContent: '↹ Resize Feed' }), + $el('div.size-controls-flyout', {}, [ + $el( + "section.size-control.feed-size-control", + {}, + [ + $el("span", { + textContent: "Feed Size...", + }), + $el("input", { + type: "range", + min: 10, + max: 80, + oninput: (e) => { + e.target.parentElement.title = `Controls the maximum size of the image feed panel (${e.target.value}vh)`; + imageFeed.style.setProperty("--max-size", e.target.value); + saveVal("FeedSize", e.target.value); + }, + $: (el) => { + requestAnimationFrame(() => { + el.value = getVal("FeedSize", 25); + el.oninput({ target: el }); + }); + }, + }), + ] + ), + $el( + "section.size-control.image-size-control", + {}, + [ + $el("span", { textContent: "Image Size...", }), + $el("input", { + type: "range", + min: 1, + max: 10, + step: 1, + oninput: (e) => { + e.target.parentElement.title = `Controls the maximum size images in the feed (${e.target.value} columns)`; + imageFeed.style.setProperty("--img-sz", e.target.value); + saveVal("ImageSize", e.target.value); + }, + $: (el) => { + requestAnimationFrame(() => { + el.value = getVal("ImageSize", 4); + el.oninput({ target: el }); + }); + }, + }), + ] + ), + ]) + ]), + $el("div.pysssss-image-feed-btn-group", {}, [ + clearButton, + hideButton, + ]), ]), imageList ); @@ -275,9 +373,8 @@ app.registerExtension({ api.addEventListener("executed", ({ detail }) => { if (detail?.output?.images) { for (const src of detail.output.images) { - const href = `/view?filename=${encodeURIComponent(src.filename)}&type=${ - src.type - }&subfolder=${encodeURIComponent(src.subfolder)}&t=${+new Date()}`; + const href = `/view?filename=${encodeURIComponent(src.filename)}&type=${src.type + }&subfolder=${encodeURIComponent(src.subfolder)}&t=${+new Date()}`; const method = feedDirection.value === "newest first" ? "prepend" : "append"; imageList[method](