From 0a73687556c64881e65bb325b1da5494e3ea9066 Mon Sep 17 00:00:00 2001 From: Victor Seiji Hariki Date: Mon, 12 Dec 2022 18:25:32 -0300 Subject: [PATCH 1/3] add prompt history as suggested in #87 Signed-off-by: Victor Seiji Hariki --- css/index.css | 231 +++++++++++++++++++++++++++++++++++- index.html | 37 ++++-- js/index.js | 67 ----------- js/initalize/ui.populate.js | 16 ++- js/lib/events.js | 5 + js/lib/util.js | 27 +++++ js/prompt.js | 189 +++++++++++++++++++++++++++++ js/ui/tool/dream.js | 2 + res/icons/history.svg | 6 + res/icons/library.svg | 7 ++ res/icons/minus-square.svg | 5 + res/icons/minus.svg | 4 + res/icons/plus-square.svg | 6 + res/icons/plus.svg | 5 + 14 files changed, 526 insertions(+), 81 deletions(-) create mode 100644 js/lib/events.js create mode 100644 js/prompt.js create mode 100644 res/icons/history.svg create mode 100644 res/icons/library.svg create mode 100644 res/icons/minus-square.svg create mode 100644 res/icons/minus.svg create mode 100644 res/icons/plus-square.svg create mode 100644 res/icons/plus.svg diff --git a/css/index.css b/css/index.css index f8c634e..3a36855 100644 --- a/css/index.css +++ b/css/index.css @@ -331,13 +331,48 @@ input#host { /* Prompt Fields */ +.content.prompt { + display: flex; + align-items: stretch; +} + +.content.prompt > .inputs { + width: 200px; +} + div.prompt-wrapper { + display: flex; + + width: calc(100%); + overflow: visible; } -div.prompt-wrapper > textarea { +div.prompt-wrapper > * { + flex-shrink: 0; +} + +div.prompt-wrapper textarea { margin: 0; - padding: 0; + + border-radius: 0; + + border: none; + + z-index: 1; +} + +div.prompt-wrapper:not(:first-child) textarea { + border-top: 1px solid black; +} + +div.prompt-wrapper > textarea { + box-sizing: border-box; + width: calc(100% - 20px); + + padding: 2px; + + transition-duration: 200ms; resize: vertical; } @@ -346,6 +381,198 @@ div.prompt-wrapper > textarea:focus { width: 700px; } +div.prompt-wrapper > .prompt-indicator { + display: flex; + + cursor: help; + + width: 20px; +} + +div.prompt-wrapper:first-child > .prompt-indicator { + border-top-left-radius: 5px; +} + +div.prompt-wrapper:last-child > .prompt-indicator { + border-bottom-left-radius: 5px; +} + +div.prompt-wrapper > .prompt-indicator.positive { + background-color: #484; +} + +div.prompt-wrapper > .prompt-indicator.negative { + background-color: #844; +} +div.prompt-wrapper > .prompt-indicator.styles { + background-color: #448; +} + +div.prompt-wrapper > .prompt-indicator::after { + content: ""; + display: block; + margin: auto; + + width: 16px; + height: 16px; + + background-color: var(--c-text); + + mask-size: contain; + -webkit-mask-size: contain; +} + +div.prompt-wrapper > .prompt-indicator.positive::after { + mask-image: url("/res/icons/plus-square.svg"); + -webkit-mask-image: url("/res/icons/plus-square.svg"); +} + +div.prompt-wrapper > .prompt-indicator.negative::after { + mask-image: url("/res/icons/minus-square.svg"); + -webkit-mask-image: url("/res/icons/minus-square.svg"); +} + +div.prompt-wrapper > .prompt-indicator.styles::after { + mask-image: url("/res/icons/library.svg"); + -webkit-mask-image: url("/res/icons/library.svg"); +} + +.prompt-history-wrapper { + position: relative; + + flex-shrink: 0; + + width: 20px; +} + +.prompt-history-container { + display: flex; + + position: absolute; + + top: 0; + left: 0; + + height: 100%; +} + +#prompt-history { + width: 0px; + height: 100%; + + transition-duration: 200ms; + + background-color: #1e1e50; +} + +#prompt-history.expanded { + width: 300px; +} + +#prompt-history .entry { + display: flex; + align-items: stretch; + justify-content: stretch; + + border: 1px #fff3; + + height: 25px; +} + +#prompt-history.expanded .entry > button { + padding: 2px; + padding-left: 5px; +} + +#prompt-history .entry > button { + flex: 1; + + cursor: pointer; + + margin: 0; + border: 0; + padding: 0; + + color: var(--c-text); + + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + + transition-duration: 100ms; +} + +#prompt-history .entry:hover > button:not(:hover) { + flex-grow: 0; + flex-shrink: 1; + flex-basis: 20%; + width: 20%; +} + +#prompt-history .entry > button.prompt { + background-color: #484; +} + +#prompt-history .entry > button.negative { + background-color: #844; +} + +#prompt-history .entry > button.styles { + background-color: #448; +} + +#prompt-history .entry > button:hover { + filter: brightness(115%); + backdrop-filter: brightness(115%); +} + +#prompt-history .entry > button:active { + filter: brightness(150%); + backdrop-filter: brightness(150%); +} + +button.prompt-history-btn { + cursor: pointer; + + border-radius: 0; + + border-top-right-radius: 5px; + border-bottom-right-radius: 5px; + + background-color: #1e1e50; + + margin: 0; + padding: 0; + border: 0; + + width: 20px; +} + +button.prompt-history-btn::after { + content: ""; + display: block; + margin: auto; + + width: 16px; + height: 16px; + + background-color: var(--c-text); + + mask-size: contain; + -webkit-mask-size: contain; + + mask-image: url("/res/icons/history.svg"); + -webkit-mask-image: url("/res/icons/history.svg"); +} + +button.prompt-history-btn:hover { + filter: brightness(115%); +} + +button.prompt-history-btn:active { + filter: brightness(150%); +} + /* Style Field */ select > .style-select-option { position: relative; diff --git a/index.html b/index.html index 77f031d..5e2a5c2 100644 --- a/index.html +++ b/index.html @@ -51,19 +51,31 @@ -
- -
-
- +
+
+
+
+ +
+
+
+ +
+
+
+
+
- -
- +
+
+
+ +
- -
-
-
+
From f63bbafe0f9333c0de4e31c0c8ea2aa818013601 Mon Sep 17 00:00:00 2001 From: Victor Seiji Hariki Date: Mon, 12 Dec 2022 18:49:53 -0300 Subject: [PATCH 3/3] add cancel button to future generations Signed-off-by: Victor Seiji Hariki --- css/ui/tool/dream.css | 2 +- js/ui/tool/dream.js | 51 +++++++++++++++++++++++++++++-------------- 2 files changed, 36 insertions(+), 17 deletions(-) diff --git a/css/ui/tool/dream.css b/css/ui/tool/dream.css index 784ed59..b0ac86e 100644 --- a/css/ui/tool/dream.css +++ b/css/ui/tool/dream.css @@ -1,3 +1,3 @@ -.dream-interrupt-btn { +.dream-stop-btn { width: 100px; } diff --git a/js/ui/tool/dream.js b/js/ui/tool/dream.js index bc96c3d..5bf1baf 100644 --- a/js/ui/tool/dream.js +++ b/js/ui/tool/dream.js @@ -129,10 +129,35 @@ const _generate = async ( if (generationAreas.has(areaid)) return; generationAreas.add(areaid); + // Makes an element in a location + const makeElement = (type, x, y) => { + const el = document.createElement(type); + el.style.position = "absolute"; + el.style.left = `${x - imageCollection.inputOffset.x}px`; + el.style.top = `${y - imageCollection.inputOffset.y}px`; + + // We can use the input element to add interactible html elements in the world + imageCollection.inputElement.appendChild(el); + + return el; + }; + // Await for queue + let cancelled = false; const waitQueue = async () => { const stopQueueMarchingAnts = march(bb, {style: "#AAF"}); + // Add cancel Button + const cancelButton = makeElement("button", bb.x + bb.w - 100, bb.y + bb.h); + cancelButton.classList.add("dream-stop-btn"); + cancelButton.textContent = "Cancel"; + cancelButton.addEventListener("click", () => { + cancelled = true; + imageCollection.inputElement.removeChild(cancelButton); + stopQueueMarchingAnts(); + }); + imageCollection.inputElement.appendChild(cancelButton); + let qPromise = null; let qResolve = null; await new Promise((finish) => { @@ -151,8 +176,10 @@ const _generate = async ( finish(); } }); - - stopQueueMarchingAnts(); + if (!cancelled) { + imageCollection.inputElement.removeChild(cancelButton); + stopQueueMarchingAnts(); + } return {promise: qPromise, resolve: qResolve}; }; @@ -167,30 +194,22 @@ const _generate = async ( const initialQ = await waitQueue(); + if (cancelled) { + nextQueue(initialQ); + return; + } + // Images to select through let at = 0; /** @type {Array} */ const images = [null]; /** @type {HTMLDivElement} */ let imageSelectMenu = null; - // Layer for the images const layer = imageCollection.registerLayer(null, { after: maskPaintLayer, }); - const makeElement = (type, x, y) => { - const el = document.createElement(type); - el.style.position = "absolute"; - el.style.left = `${x - imageCollection.inputOffset.x}px`; - el.style.top = `${y - imageCollection.inputOffset.y}px`; - - // We can use the input element to add interactible html elements in the world - imageCollection.inputElement.appendChild(el); - - return el; - }; - const redraw = (url = images[at]) => { if (url === null) layer.ctx.clearRect(0, 0, layer.canvas.width, layer.canvas.height); @@ -216,7 +235,7 @@ const _generate = async ( // Add Interrupt Button const interruptButton = makeElement("button", bb.x + bb.w - 100, bb.y + bb.h); - interruptButton.classList.add("dream-interrupt-btn"); + interruptButton.classList.add("dream-stop-btn"); interruptButton.textContent = "Interrupt"; interruptButton.addEventListener("click", () => { fetch(`${host}${url}interrupt`, {method: "POST"});