Skip to content

Commit abf3711

Browse files
committed
Add nsfw level filtering and view more previews/metadata
1 parent 73dfdc6 commit abf3711

File tree

3 files changed

+96
-13
lines changed

3 files changed

+96
-13
lines changed

web/js/common/modelInfoDialog.css

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,21 @@
9494
bottom: 10px;
9595
right: 10px;
9696
}
97+
.pysssss-preview button+button {
98+
bottom: 34px;
99+
}
100+
101+
.pysssss-preview button.pysssss-preview-nav {
102+
bottom: unset;
103+
right: 30px;
104+
top: 10px;
105+
font-size: 14px;
106+
line-height: 14px;
107+
}
108+
109+
.pysssss-preview button.pysssss-preview-nav+.pysssss-preview-nav {
110+
right: 10px;
111+
}
97112
.pysssss-model-notes {
98113
background-color: rgba(0, 0, 0, 0.25);
99114
padding: 5px;

web/js/common/modelInfoDialog.js

Lines changed: 59 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,10 @@ class MetadataDialog extends ComfyDialog {
1515
$el(
1616
"div",
1717
Object.keys(metadata).map((k) =>
18-
$el("div", [$el("label", { textContent: k }), $el("span", { textContent: metadata[k] })])
18+
$el("div", [
19+
$el("label", { textContent: k }),
20+
$el("span", { textContent: typeof metadata[k] === "object" ? JSON.stringify(metadata[k]) : metadata[k] }),
21+
])
1922
)
2023
)
2124
);
@@ -146,13 +149,10 @@ export class ModelInfoDialog extends ComfyDialog {
146149
if (textarea) {
147150
this.customNotes = textarea.value;
148151

149-
const resp = await api.fetchApi(
150-
"/pysssss/metadata/notes/" + encodeURIComponent(`${this.type}/${this.name}`),
151-
{
152-
method: "POST",
153-
body: this.customNotes,
154-
}
155-
);
152+
const resp = await api.fetchApi("/pysssss/metadata/notes/" + encodeURIComponent(`${this.type}/${this.name}`), {
153+
method: "POST",
154+
body: this.customNotes,
155+
});
156156

157157
if (resp.status !== 200) {
158158
console.error(resp);
@@ -255,11 +255,24 @@ export class ModelInfoDialog extends ComfyDialog {
255255
})
256256
);
257257

258-
const preview = info.images.find((i) => i.type === "image");
259-
if (preview) {
260-
this.img.src = preview.url;
258+
const allPreviews = info.images?.filter((i) => i.type === "image");
259+
const previews = allPreviews?.filter((i) => i.nsfwLevel <= ModelInfoDialog.nsfwLevel);
260+
if (previews?.length) {
261+
let previewIndex = 0;
262+
let preview;
263+
const updatePreview = () => {
264+
preview = previews[previewIndex];
265+
this.img.src = preview.url;
266+
};
267+
268+
updatePreview();
261269
this.img.style.display = "";
262270

271+
this.img.title = `${previews.length} previews.`;
272+
if (allPreviews.length !== previews.length) {
273+
this.img.title += ` ${allPreviews.length - previews.length} images hidden due to NSFW level.`;
274+
}
275+
263276
this.imgSave = $el("button", {
264277
textContent: "Use as preview",
265278
parent: this.imgWrapper,
@@ -299,6 +312,41 @@ export class ModelInfoDialog extends ComfyDialog {
299312
app.refreshComboInNodes();
300313
},
301314
});
315+
316+
$el("button", {
317+
textContent: "Show metadata",
318+
parent: this.imgWrapper,
319+
onclick: async () => {
320+
if (preview.meta && Object.keys(preview.meta).length) {
321+
new MetadataDialog().show(preview.meta);
322+
} else {
323+
alert("No image metadata found");
324+
}
325+
},
326+
});
327+
328+
const addNavButton = (icon, direction) => {
329+
$el("button.pysssss-preview-nav", {
330+
textContent: icon,
331+
parent: this.imgWrapper,
332+
onclick: async () => {
333+
previewIndex += direction;
334+
if (previewIndex < 0) {
335+
previewIndex = previews.length - 1;
336+
} else if (previewIndex >= previews.length) {
337+
previewIndex = 0;
338+
}
339+
updatePreview();
340+
},
341+
});
342+
};
343+
344+
if (previews.length > 1) {
345+
addNavButton("‹", -1);
346+
addNavButton("›", 1);
347+
}
348+
} else if (info.images?.length) {
349+
$el("span", { style: { opacity: 0.6 }, textContent: "⚠️ All images hidden due to NSFW level setting.", parent: this.imgWrapper });
302350
}
303351

304352
return info;

web/js/modelInfo.js

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,14 @@ import { $el } from "../../../scripts/ui.js";
44
import { ModelInfoDialog } from "./common/modelInfoDialog.js";
55

66
const MAX_TAGS = 500;
7+
const NsfwLevel = {
8+
PG: 1,
9+
PG13: 2,
10+
R: 4,
11+
X: 8,
12+
XXX: 16,
13+
Blocked: 32,
14+
};
715

816
export class LoraInfoDialog extends ModelInfoDialog {
917
getTagFrequency() {
@@ -79,8 +87,8 @@ export class LoraInfoDialog extends ModelInfoDialog {
7987

8088
addTags() {
8189
let tags = this.getTagFrequency();
82-
if(!tags?.length) {
83-
tags = this.metadata["modelspec.tags"]?.split(",").map(t => [t.trim(), 1]);
90+
if (!tags?.length) {
91+
tags = this.metadata["modelspec.tags"]?.split(",").map((t) => [t.trim(), 1]);
8492
}
8593
let hasMore;
8694
if (tags?.length) {
@@ -376,6 +384,18 @@ app.registerExtension({
376384
"Checkpoint",
377385
["CheckpointLoader.ckpt_name", "CheckpointLoaderSimple", "CheckpointLoader|pysssss", "Efficient Loader", "Eff. Loader SDXL"].join(",")
378386
);
387+
388+
app.ui.settings.addSetting({
389+
id: `pysssss.ModelInfo.NsfwLevel`,
390+
name: `🐍 Model Info - Image Preview Max NSFW Level`,
391+
type: "combo",
392+
defaultValue: "PG13",
393+
options: Object.keys(NsfwLevel),
394+
tooltip: `Hides preview images that are tagged as a higher NSFW level`,
395+
onChange(value) {
396+
ModelInfoDialog.nsfwLevel = NsfwLevel[value] ?? NsfwLevel.PG;
397+
},
398+
});
379399
},
380400
beforeRegisterNodeDef(nodeType) {
381401
const getExtraMenuOptions = nodeType.prototype.getExtraMenuOptions;

0 commit comments

Comments
 (0)