Files
ComfyAssets-ComfyUI_PromptM…/web/js/image-helpers.js
T
Vito Sansevero 4ab0214f09 fix: address gallery auto-tag review images by path, not digest id
The gallery review flow builds its list from /prompt_manager/images/output,
whose id is a 16-hex path digest, but posted it as image_id to
autotag/single, so the server looked up a database row and every request
404ed. autotagSingleBody (pure, tested) now sends path for output-folder
entries and keeps image_id for database rows, which the admin review flow
(/images/all) still uses.
2026-10-08 18:01:34 -07:00

96 lines
3.9 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**
* Pure helpers for image entries rendered by the admin and gallery pages.
*
* Image rows come from the database (`width`, `height`, `file_size` are stored
* from a POST body and may be strings) or from the output-folder scan (`id` is
* a path digest, `path` is the file). Everything these helpers return for HTML
* is already escaped, so callers can drop it into text or a quoted attribute.
*
* Loadable in the browser (window.ImageHelpers) and in Node for tests.
*/
(function (root) {
"use strict";
const escapeHtml =
typeof module !== "undefined" && module.exports
? require("./html-escape.js").escapeHtml
: root.escapeHtml;
const UNKNOWN_SIZE = "Unknown size";
/**
* "640×480 | 1.2 MB" for a card body or a viewer caption, escaped.
*
* @param {{width?: unknown, height?: unknown, file_size?: unknown}|null|undefined} image
* @param {{formatFileSize?: (bytes: number) => string, separator?: string}} [options]
* @returns {string} escaped text; "Unknown size" when a dimension is missing
*/
function formatImageCaption(image, { formatFileSize, separator = " | " } = {}) {
const entry = image || {};
const parts = [];
if (entry.width && entry.height) {
parts.push(`${escapeHtml(entry.width)}×${escapeHtml(entry.height)}`);
} else {
parts.push(UNKNOWN_SIZE);
}
const bytes = Number(entry.file_size);
if (formatFileSize && Number.isFinite(bytes) && bytes > 0) {
parts.push(escapeHtml(formatFileSize(bytes)));
}
return parts.join(escapeHtml(separator));
}
/**
* A complete standalone page showing a workflow as pretty-printed JSON.
* Written into a blank same-origin window, so the JSON must not be able
* to close the <pre> and inject markup.
*
* @param {unknown} workflow
* @returns {string} HTML document
*/
function workflowDocumentHtml(workflow) {
const json = escapeHtml(JSON.stringify(workflow, null, 2));
return [
"<!DOCTYPE html>",
"<html>",
"<head><meta charset=\"utf-8\"><title>ComfyUI Workflow Data</title></head>",
"<body style=\"background: #111; color: #fff; font-family: monospace; padding: 20px;\">",
"<h2>ComfyUI Workflow JSON</h2>",
`<pre style="background: #222; padding: 15px; border-radius: 5px; overflow: auto;">${json}</pre>`,
"</body>",
"</html>",
].join("\n");
}
/**
* Body for POST /prompt_manager/autotag/single.
*
* Database rows (admin review, /images/all) have an integer id the server
* looks up; output-folder entries (gallery review, /images/output) have a
* path digest as id, which would 404, so those are addressed by path.
*
* @param {{id?: unknown, path?: unknown}} image
* @param {{modelType: string, generalThreshold?: number, characterThreshold?: number, prompt?: string}} settings
* @returns {object} JSON-serialisable request body
*/
function autotagSingleBody(image, settings) {
const entry = image || {};
const target =
typeof entry.path === "string" && entry.path && !Number.isInteger(entry.id)
? { path: entry.path }
: { image_id: entry.id };
const modelType = String(settings.modelType || "");
const params = modelType.startsWith("wd14")
? {
general_threshold: settings.generalThreshold,
character_threshold: settings.characterThreshold,
}
: { prompt: settings.prompt };
return { ...target, model_type: modelType, ...params };
}
const api = { formatImageCaption, workflowDocumentHtml, autotagSingleBody };
if (typeof module !== "undefined" && module.exports) module.exports = api;
else root.ImageHelpers = api;
})(typeof window !== "undefined" ? window : globalThis);