From d1b6ee84bc335c194a8099dbdfa97e75c701cd16 Mon Sep 17 00:00:00 2001 From: rgthree Date: Sat, 18 May 2024 00:10:20 -0400 Subject: [PATCH] Add image data in civitai lora image previews. For #223 --- src_web/comfyui/dialog_info.ts | 137 ++++++++++++++-------- src_web/common/css/dialog_model_info.scss | 63 +++++++++- src_web/common/media/svgs.ts | 60 ++++------ web/comfyui/dialog_info.js | 62 +++++----- web/common/css/dialog_model_info.css | 59 +++++++++- web/common/media/svgs.js | 60 ++++------ 6 files changed, 276 insertions(+), 165 deletions(-) diff --git a/src_web/comfyui/dialog_info.ts b/src_web/comfyui/dialog_info.ts index f996cea..fcc505c 100644 --- a/src_web/comfyui/dialog_info.ts +++ b/src_web/comfyui/dialog_info.ts @@ -8,7 +8,13 @@ import { query, setAttributes, } from "rgthree/common/utils_dom.js"; -import { logoCivitai, link, pencilColored, diskColored, dotdotdot } from "rgthree/common/media/svgs.js"; +import { + logoCivitai, + link, + pencilColored, + diskColored, + dotdotdot, +} from "rgthree/common/media/svgs.js"; import { RgthreeModelInfo } from "typings/rgthree.js"; import { SERVICE as MODEL_INFO_SERVICE } from "rgthree/common/model_info_service.js"; import { rgthree } from "./rgthree.js"; @@ -156,19 +162,20 @@ export class RgthreeInfoDialog extends RgthreeDialog { const civitaiLink = info.links?.find((i) => i.includes("civitai.com/models")); const html = ` @@ -203,22 +210,31 @@ export class RgthreeInfoDialog extends RgthreeDialog { "name", )} - ${!info.baseModelFile && !info.baseModelFile ? '' : infoTableRow( - "Base Model", - (info.baseModel || "") + (info.baseModelFile ? ` (${info.baseModelFile})` : ""), - )} + ${ + !info.baseModelFile && !info.baseModelFile + ? "" + : infoTableRow( + "Base Model", + (info.baseModel || "") + (info.baseModelFile ? ` (${info.baseModelFile})` : ""), + ) + } - ${!info.trainedWords?.length ? '' : infoTableRow( - "Trained Words", - getTrainedWordsMarkup(info.trainedWords) ?? "", - "Trained words from the metadata and/or civitai. Click to select for copy.", - )} + ${ + !info.trainedWords?.length + ? "" + : infoTableRow( + "Trained Words", + getTrainedWordsMarkup(info.trainedWords) ?? "", + "Trained words from the metadata and/or civitai. Click to select for copy.", + ) + } - ${!info.raw?.metadata.ss_clip_skip || info.raw?.metadata.ss_clip_skip == 'None' ? '' : infoTableRow( - "Clip Skip", - info.raw?.metadata.ss_clip_skip - )} + ${ + !info.raw?.metadata.ss_clip_skip || info.raw?.metadata.ss_clip_skip == "None" + ? "" + : infoTableRow("Clip Skip", info.raw?.metadata.ss_clip_skip) + } ${infoTableRow( "Strength Min", info.strengthMin ?? "", @@ -253,33 +269,40 @@ export class RgthreeInfoDialog extends RgthreeDialog { ?.map( (img) => `
  • - - +
    + +
    ${imgInfoField( + "", + img.civitaiUrl + ? `civitai${link}` + : undefined, + )}${imgInfoField("seed", img.seed)}${imgInfoField("steps", img.steps)}${imgInfoField("cfg", img.cfg)}${imgInfoField("sampler", img.sampler)}${imgInfoField("model", img.model)}${imgInfoField("positive", img.positive)}${imgInfoField("negative", img.negative)}
    +
  • `, ) .join("") ?? "" @@ -299,7 +322,9 @@ export class RgthreeInfoDialog extends RgthreeDialog { label: "Open API JSON", callback: async (e: PointerEvent) => { if (this.modelInfo?.file) { - window.open(`rgthree/api/loras/info?file=${encodeURIComponent(this.modelInfo.file)}`); + window.open( + `rgthree/api/loras/info?file=${encodeURIComponent(this.modelInfo.file)}`, + ); } }, }, @@ -307,9 +332,13 @@ export class RgthreeInfoDialog extends RgthreeDialog { label: "Clear all local info", callback: async (e: PointerEvent) => { if (this.modelInfo?.file) { - this.modelInfo = await MODEL_INFO_SERVICE.clearLoraFetchedData(this.modelInfo.file); + this.modelInfo = await MODEL_INFO_SERVICE.clearLoraFetchedData( + this.modelInfo.file, + ); this.setContent(this.getInfoContent()); - this.setTitle(this.modelInfo?.["name"] || this.modelInfo?.["file"] || "Unknown"); + this.setTitle( + this.modelInfo?.["name"] || this.modelInfo?.["file"] || "Unknown", + ); } }, }, @@ -389,3 +418,7 @@ function saveEditableRow(info: RgthreeModelInfo, tr: HTMLElement, saving = true) appendChildren(empty(td), [$el("span", { text: newValue })]); return modified; } + +function imgInfoField(label: string, value?: string | number) { + return value != null ? `${label ? `` : ""}${value}` : ""; +} diff --git a/src_web/common/css/dialog_model_info.scss b/src_web/common/css/dialog_model_info.scss index ad4d902..fdf00cd 100644 --- a/src_web/common/css/dialog_model_info.scss +++ b/src_web/common/css/dialog_model_info.scss @@ -304,7 +304,68 @@ justify-content: center; flex-direction: column; overflow: hidden; - padding: 8px; + padding: 0; + margin: 6px; + font-size: 0; + position: relative; + + figure { + margin: 0; + position: static; + + figcaption { + position: absolute; + left: 0; + width: 100%; + bottom: 0; + padding: 12px; + font-size: 12px; + background: rgba(0,0,0,0.85); + opacity: 0; + transform: translateY(50px); + transition: all 0.25s ease-in-out; + + > span { + display: inline-block; + padding: 2px 4px; + margin: 2px; + border-radius: 2px; + border: 1px solid rgba(255,255,255,0.2); + word-break: break-word; + + label { + display: inline; + padding: 0; + margin: 0; + opacity: 0.5; + pointer-events: none; + user-select: none; + } + a { + color: inherit; + text-decoration: underline; + &:hover { + text-decoration: none; + } + + svg { + height: 10px; + margin-left: 4px; + fill: currentColor; + } + } + } + &:empty { + &::before {content: 'No data.'} + text-align: center; + } + } + } + + &:hover figure figcaption { + opacity: 1; + transform: translateY(0px); + } .rgthree-info-table { width: calc(100% - 16px); diff --git a/src_web/common/media/svgs.ts b/src_web/common/media/svgs.ts index 05e6bab..8543639 100644 --- a/src_web/common/media/svgs.ts +++ b/src_web/common/media/svgs.ts @@ -2,46 +2,39 @@ import { createElement as $el } from "../utils_dom.js"; // Some svg repo : https://www.svgrepo.com/svg/326731/open-outline -export const logoRgthree = ` -
  • ${info.type || ""}
  • ${info.baseModel || ""}
  • - ${''} + ${""} @@ -161,12 +161,18 @@ export class RgthreeInfoDialog extends RgthreeDialog { ${infoTableRow("Name", info.name || ((_k = (_j = info.raw) === null || _j === void 0 ? void 0 : _j.metadata) === null || _k === void 0 ? void 0 : _k.ss_output_name) || "", "The name for display.", "name")} - ${!info.baseModelFile && !info.baseModelFile ? '' : infoTableRow("Base Model", (info.baseModel || "") + (info.baseModelFile ? ` (${info.baseModelFile})` : ""))} + ${!info.baseModelFile && !info.baseModelFile + ? "" + : infoTableRow("Base Model", (info.baseModel || "") + (info.baseModelFile ? ` (${info.baseModelFile})` : ""))} - ${!((_l = info.trainedWords) === null || _l === void 0 ? void 0 : _l.length) ? '' : infoTableRow("Trained Words", (_m = getTrainedWordsMarkup(info.trainedWords)) !== null && _m !== void 0 ? _m : "", "Trained words from the metadata and/or civitai. Click to select for copy.")} + ${!((_l = info.trainedWords) === null || _l === void 0 ? void 0 : _l.length) + ? "" + : infoTableRow("Trained Words", (_m = getTrainedWordsMarkup(info.trainedWords)) !== null && _m !== void 0 ? _m : "", "Trained words from the metadata and/or civitai. Click to select for copy.")} - ${!((_o = info.raw) === null || _o === void 0 ? void 0 : _o.metadata.ss_clip_skip) || ((_p = info.raw) === null || _p === void 0 ? void 0 : _p.metadata.ss_clip_skip) == 'None' ? '' : infoTableRow("Clip Skip", (_q = info.raw) === null || _q === void 0 ? void 0 : _q.metadata.ss_clip_skip)} + ${!((_o = info.raw) === null || _o === void 0 ? void 0 : _o.metadata.ss_clip_skip) || ((_p = info.raw) === null || _p === void 0 ? void 0 : _p.metadata.ss_clip_skip) == "None" + ? "" + : infoTableRow("Clip Skip", (_q = info.raw) === null || _q === void 0 ? void 0 : _q.metadata.ss_clip_skip)} ${infoTableRow("Strength Min", (_r = info.strengthMin) !== null && _r !== void 0 ? _r : "", "The recommended minimum strength, In the Power Lora Loader node, strength will signal when it is below this threshold.", "strengthMin")} ${infoTableRow("Strength Max", (_s = info.strengthMax) !== null && _s !== void 0 ? _s : "", "The recommended maximum strength. In the Power Lora Loader node, strength will signal when it is above this threshold.", "strengthMax")} ${""} @@ -174,33 +180,24 @@ export class RgthreeInfoDialog extends RgthreeDialog {
    - `; const div = $el("div", { html }); if (rgthree.isDevMode()) { @@ -284,3 +281,6 @@ function saveEditableRow(info, tr, saving = true) { appendChildren(empty(td), [$el("span", { text: newValue })]); return modified; } +function imgInfoField(label, value) { + return value != null ? `${label ? `` : ""}${value}` : ""; +} diff --git a/web/common/css/dialog_model_info.css b/web/common/css/dialog_model_info.css index e76d14f..6a9e822 100644 --- a/web/common/css/dialog_model_info.css +++ b/web/common/css/dialog_model_info.css @@ -256,7 +256,64 @@ justify-content: center; flex-direction: column; overflow: hidden; - padding: 8px; + padding: 0; + margin: 6px; + font-size: 0; + position: relative; +} +.rgthree-info-dialog .rgthree-info-images > li figure { + margin: 0; + position: static; +} +.rgthree-info-dialog .rgthree-info-images > li figure figcaption { + position: absolute; + left: 0; + width: 100%; + bottom: 0; + padding: 12px; + font-size: 12px; + background: rgba(0, 0, 0, 0.85); + opacity: 0; + transform: translateY(50px); + transition: all 0.25s ease-in-out; +} +.rgthree-info-dialog .rgthree-info-images > li figure figcaption > span { + display: inline-block; + padding: 2px 4px; + margin: 2px; + border-radius: 2px; + border: 1px solid rgba(255, 255, 255, 0.2); + word-break: break-word; +} +.rgthree-info-dialog .rgthree-info-images > li figure figcaption > span label { + display: inline; + padding: 0; + margin: 0; + opacity: 0.5; + pointer-events: none; + user-select: none; +} +.rgthree-info-dialog .rgthree-info-images > li figure figcaption > span a { + color: inherit; + text-decoration: underline; +} +.rgthree-info-dialog .rgthree-info-images > li figure figcaption > span a:hover { + text-decoration: none; +} +.rgthree-info-dialog .rgthree-info-images > li figure figcaption > span a svg { + height: 10px; + margin-left: 4px; + fill: currentColor; +} +.rgthree-info-dialog .rgthree-info-images > li figure figcaption:empty { + text-align: center; +} +.rgthree-info-dialog .rgthree-info-images > li figure figcaption:empty::before { + content: "No data."; +} +.rgthree-info-dialog .rgthree-info-images > li:hover figure figcaption { + opacity: 1; + transform: translateY(0px); } .rgthree-info-dialog .rgthree-info-images > li .rgthree-info-table { width: calc(100% - 16px); diff --git a/web/common/media/svgs.js b/web/common/media/svgs.js index a537a7e..eff1a71 100644 --- a/web/common/media/svgs.js +++ b/web/common/media/svgs.js @@ -1,38 +1,31 @@ import { createElement as $el } from "../utils_dom.js"; -export const logoRgthree = ` -