diff --git a/js/AvatarPreview.js b/js/AvatarPreview.js index 37c71ec..d0a0f93 100644 --- a/js/AvatarPreview.js +++ b/js/AvatarPreview.js @@ -20,6 +20,7 @@ import { initModel } from "./onnx.js"; // import { uploadSegments } from "./LayerEditor.js"; const workflowList = [ + "idle_avatar_(trigger)", "Auto_segment_workflow", "BronyaZaychik_(ChinaDress)", "BronyaZaychik_(Default_Silverwing)", @@ -28,6 +29,7 @@ const workflowList = [ "BronyaZaychikLora_withhand", "SilverWolf_(Default)", "SilverWolf_(Maid)", + "SilverWolfLora_withhand", ]; function editSegment(stage) { diff --git a/js/LayerEditor.js b/js/LayerEditor.js index e6d2951..09809b9 100644 --- a/js/LayerEditor.js +++ b/js/LayerEditor.js @@ -15,6 +15,7 @@ import { embeddings, embeddingID, alertDialog, + allImagePrompts, } from "./state.js"; import { van } from "./van.js"; import vision from "https://cdn.jsdelivr.net/npm/@mediapipe/tasks-vision@0.10.3"; @@ -410,6 +411,15 @@ export function LayerEditor() { console.log("close"); showImageEditor.val = false; await uploadSegments(); + + // allImagePrompts.val = [ + // ...allImagePrompts.val, + // { + // version: "v" + allImagePrompts.val.length, + // prompt: imagePromptsMulti.val, + // }, + // ]; + // api.fetchApi("/segments_order", { // method: "POST", // body: JSON.stringify({ @@ -461,7 +471,7 @@ export function LayerEditor() { div( { class: - "hidden w-full flex justify-center absolute top-0 left-0 right-0 items-center", + "hidden w-full justify-center absolute top-0 left-0 right-0 items-center", }, button( { diff --git a/js/SideBar.js b/js/SideBar.js index ec5836a..44d21d2 100644 --- a/js/SideBar.js +++ b/js/SideBar.js @@ -5,6 +5,7 @@ import { imagePromptsMulti, targetNode, showImageEditor, + allImagePrompts, } from "./state.js"; import { van } from "./van.js"; const { @@ -61,196 +62,229 @@ export function SideBar() { const layer_to_delete = van.state(""); return div( - { - class: - "ml-2 z-100 w-fit flex-col flex justify-center absolute top-0 left-0 bottom-0 items-start gap-2", - }, - () => { - const layers = Object.entries(imagePromptsMulti.val); - return ul( - { - class: "menu bg-base-200 w-56 rounded-box text-base-content ", - }, - button({ - onclick: () => { - const layers = Object.entries(imagePromptsMulti.val); - layers.map(([key, value]) => { - imagePrompts.val = []; - imagePromptsMulti.val[key] = []; - }); - drawSegment([]); - updateImagePrompts(); + div( + { + class: + "ml-2 z-100 w-fit flex-col flex justify-center absolute top-0 left-0 bottom-0 items-start gap-2", + }, + () => { + const layers = Object.entries(imagePromptsMulti.val); + return ul( + { + class: "menu bg-base-200 w-56 rounded-box text-base-content ", }, - class: "btn btn-ghost normal-case flex", - }, "Clear ALL"), - layers.length === 0 ? li(a("Empty layer")) : null, - ...layers.map(([key, value]) => { - return li( - a( - { - class: () => - `normal-case text-start items-start flex items-center justify-between ${ - selectedLayer.val === key ? "active" : "" - }`, - onclick: () => { - selectedLayer.val = key; - imagePrompts.val = imagePromptsMulti.val[key]; - drawSegment(getClicks()); - }, - }, - key, - div( - {}, - button( - { - class: - "btn btn-circle btn-xs btn-ghost group hover:text-red-500", - onclick: (e) => { - console.log("clear"); - e.preventDefault(); - e.stopPropagation(); - imagePrompts.val = []; - imagePromptsMulti.val[key] = []; - drawSegment([]); - updateImagePrompts(); - }, - }, - span({ - class: "iconify", - "data-icon": "ant-design:clear-outlined", - "data-inline": "false", - }) - ), - button( - { - class: - "btn btn-circle btn-xs btn-ghost group hover:text-red-500", - onclick: (e) => { - console.log("delete"); - e.preventDefault(); - e.stopPropagation(); - layer_to_delete.val = key; - setTimeout(() => { - delete_layer_dialog.showModal(); - }, 0); - }, - }, - span({ - class: "iconify", - "data-icon": "ic:baseline-delete", - "data-inline": "false", - }) - ) - ) - ) - ); - }), - div({ class: "divider !py-0 my-0" }), - li( - a( + button( { - class: "flex items-center justify-between", onclick: () => { - my_modal_3.showModal(); - }, - }, - "New Layer", - span({ - class: "iconify", - "data-icon": "ic:outline-plus", - "data-inline": "false", - }) - ) - ) - ); - }, - () => - ConfirmDialog( - { - id: "delete_layer_dialog", - title: "Delete Layer: " + layer_to_delete.val, - onsubmit: () => { - imagePromptsMulti.val = Object.fromEntries( - Object.entries(imagePromptsMulti.val).filter( - ([key, value]) => key !== layer_to_delete.val - ) - ); - console.log(imagePromptsMulti.val); - if (selectedLayer.val === layer_to_delete.val) { - // Select another layer if there is one - if (Object.keys(imagePromptsMulti.val).length > 0) { - selectedLayer.val = Object.keys(imagePromptsMulti.val)[0]; - imagePrompts.val = imagePromptsMulti.val[selectedLayer.val]; - } else { - selectedLayer.val = ""; - imagePrompts.val = []; - } - } - targetNode.val.graph.change(); - updateImagePrompts(); - delete_layer_dialog.close(); - }, - }, - p("Are you sure you want to delete this layer?") - ), - () => - dialog( - { id: "my_modal_3", class: "modal" }, - div( - { class: "modal-box text-base-content" }, - form( - { - class: "gap-2 flex flex-col", - method: "dialog", - onsubmit: (e) => { - console.log("add new layer"); - e.preventDefault(); - const inputText = e.target.elements[1].value; - imagePromptsMulti.val = { - ...imagePromptsMulti.val, - [inputText]: [], - }; - console.log(inputText, imagePromptsMulti.val); - my_modal_3.close(); - e.target.elements[1].value = ""; - - selectedLayer.val = inputText; - imagePrompts.val = imagePromptsMulti.val[inputText]; - drawSegment(getClicks()); + layers.map(([key, value]) => { + imagePrompts.val = []; + imagePromptsMulti.val[key] = []; + }); + drawSegment([]); updateImagePrompts(); }, + class: "btn btn-ghost normal-case flex", }, - button( + "Clear ALL" + ), + layers.length === 0 ? li(a("Empty layer")) : null, + ...layers.map(([key, value]) => { + return li( + a( + { + class: () => + `normal-case text-start items-start flex items-center justify-between ${ + selectedLayer.val === key ? "active" : "" + }`, + onclick: () => { + selectedLayer.val = key; + imagePrompts.val = imagePromptsMulti.val[key]; + drawSegment(getClicks()); + }, + }, + key, + div( + {}, + button( + { + class: + "btn btn-circle btn-xs btn-ghost group hover:text-red-500", + onclick: (e) => { + console.log("clear"); + e.preventDefault(); + e.stopPropagation(); + imagePrompts.val = []; + imagePromptsMulti.val[key] = []; + drawSegment([]); + updateImagePrompts(); + }, + }, + span({ + class: "iconify", + "data-icon": "ant-design:clear-outlined", + "data-inline": "false", + }) + ), + button( + { + class: + "btn btn-circle btn-xs btn-ghost group hover:text-red-500", + onclick: (e) => { + console.log("delete"); + e.preventDefault(); + e.stopPropagation(); + layer_to_delete.val = key; + setTimeout(() => { + delete_layer_dialog.showModal(); + }, 0); + }, + }, + span({ + class: "iconify", + "data-icon": "ic:baseline-delete", + "data-inline": "false", + }) + ) + ) + ) + ); + }), + div({ class: "divider !py-0 my-0" }), + li( + a( { - type: "button", - class: "btn btn-sm btn-circle btn-ghost absolute right-2 top-2", - onclick: (e) => { - e.stopPropagation(); - my_modal_3.close(); + class: "flex items-center justify-between", + onclick: () => { + my_modal_3.showModal(); }, }, - "✕" - ), - h3( - { class: "font-bold text-lg text-base-content" }, - "Add new layer!" - ), - input({ - type: "text", - placeholder: "Type here", - class: "input input-bordered w-full", - autofocus: true, - }), - button( + "New Layer", + span({ + class: "iconify", + "data-icon": "ic:outline-plus", + "data-inline": "false", + }) + ) + ) + ); + }, + () => + ConfirmDialog( + { + id: "delete_layer_dialog", + title: "Delete Layer: " + layer_to_delete.val, + onsubmit: () => { + imagePromptsMulti.val = Object.fromEntries( + Object.entries(imagePromptsMulti.val).filter( + ([key, value]) => key !== layer_to_delete.val + ) + ); + console.log(imagePromptsMulti.val); + if (selectedLayer.val === layer_to_delete.val) { + // Select another layer if there is one + if (Object.keys(imagePromptsMulti.val).length > 0) { + selectedLayer.val = Object.keys(imagePromptsMulti.val)[0]; + imagePrompts.val = imagePromptsMulti.val[selectedLayer.val]; + } else { + selectedLayer.val = ""; + imagePrompts.val = []; + } + } + targetNode.val.graph.change(); + updateImagePrompts(); + delete_layer_dialog.close(); + }, + }, + p("Are you sure you want to delete this layer?") + ), + () => + dialog( + { id: "my_modal_3", class: "modal" }, + div( + { class: "modal-box text-base-content" }, + form( { - type: "submit", - class: "btn btn-sm btn-ghost place-self-end", + class: "gap-2 flex flex-col", + method: "dialog", + onsubmit: (e) => { + console.log("add new layer"); + e.preventDefault(); + const inputText = e.target.elements[1].value; + imagePromptsMulti.val = { + ...imagePromptsMulti.val, + [inputText]: [], + }; + console.log(inputText, imagePromptsMulti.val); + my_modal_3.close(); + e.target.elements[1].value = ""; + + selectedLayer.val = inputText; + imagePrompts.val = imagePromptsMulti.val[inputText]; + drawSegment(getClicks()); + updateImagePrompts(); + }, }, - "Confirm" + button( + { + type: "button", + class: + "btn btn-sm btn-circle btn-ghost absolute right-2 top-2", + onclick: (e) => { + e.stopPropagation(); + my_modal_3.close(); + }, + }, + "✕" + ), + h3( + { class: "font-bold text-lg text-base-content" }, + "Add new layer!" + ), + input({ + type: "text", + placeholder: "Type here", + class: "input input-bordered w-full", + autofocus: true, + }), + button( + { + type: "submit", + class: "btn btn-sm btn-ghost place-self-end", + }, + "Confirm" + ) ) ) ) - ) + ), + // div( + // { + // class: + // "ml-2 z-100 w-fit flex-col flex justify-center absolute top-0 right-0 bottom-0 items-start gap-2 bg-transparent", + // }, + // () => { + // return ul( + // { + // class: "menu bg-base-200 w-56 rounded-box text-base-content ", + // }, + // ...allImagePrompts.val.map((e) => + // button( + // { + // class: + // "normal-case text-start flex items-center justify-center", + // onclick: async () => { + // imagePromptsMulti.val = e.prompt; + // imagePrompts.val = imagePromptsMulti.val[selectedLayer.val]; + // drawSegment(getClicks()); + // updateImagePrompts() + // }, + // }, + // e.version + // ) + // ) + // ); + // } + // ) ); } diff --git a/js/index.js b/js/index.js index 8cef05b..d217964 100644 --- a/js/index.js +++ b/js/index.js @@ -27,6 +27,7 @@ import "https://code.iconify.design/3/3.1.0/iconify.min.js"; import { autoSegment, drawSegment, getClicks, segmented } from "./LayerEditor.js"; import { infoDialog } from "./dialog.js"; import { sharedAvatarLink } from "./AvatarPreview.js"; +import { updateImagePrompts } from './LayerEditor.js'; export const generatedImages = {}; @@ -351,6 +352,7 @@ function showMyImageEditor(node) { embeddings.val = tensor; if (enableAutoSegment.val && !segmented.val) await autoSegment(); drawSegment(getClicks()); + updateImagePrompts() }); targetNode.val = node; }) diff --git a/js/state.js b/js/state.js index a5016d7..88593c2 100644 --- a/js/state.js +++ b/js/state.js @@ -47,6 +47,9 @@ export const imageContainerSize = van.state({ /** @type {State} */ export const imagePrompts = van.state([]); +export const allImagePrompts = van.state([{}]); + + /** @type {State>} */ export const imagePromptsMulti = van.state({}); diff --git a/js/tw-styles.css b/js/tw-styles.css index d343eef..4ee263a 100644 --- a/js/tw-styles.css +++ b/js/tw-styles.css @@ -2614,6 +2614,10 @@ details.collapse summary::-webkit-details-marker{ background-color: rgb(255 255 255 / var(--tw-bg-opacity)); } +.bg-transparent{ + background-color: transparent; +} + .bg-opacity-50{ --tw-bg-opacity: 0.5; }