correctionBug

This commit is contained in:
Bouletto
2025-08-25 15:44:54 +02:00
parent 63615112dc
commit 1256b22331
2 changed files with 54 additions and 81 deletions
+16 -13
View File
@@ -1,5 +1,5 @@
# -*- coding: utf-8 -*-
# DAO_master - Folder File Pro
# DAO_master - Folder File Pro (v4.1)
import os
import io
@@ -80,7 +80,7 @@ class FInfo:
mtime: float
# --------------------------------------------------------------------------------------
# Helpers (même pipeline que l'UI)
# Helpers
def _norm_exts(exts: str) -> List[str]:
if not exts:
@@ -208,7 +208,7 @@ def _open_in_explorer(target: str) -> None:
subprocess.Popen(["xdg-open", target], close_fds=True)
# --------------------------------------------------------------------------------------
# HTTP endpoints (si serveur dispo)
# HTTP endpoints
if HAVE_SERVER:
@PromptServer.instance.routes.get("/folder_file_pro/list")
@@ -304,7 +304,7 @@ if HAVE_SERVER:
return web.Response(status=404)
try:
img = Image.open(filepath)
# Si alpha -> PNG, sinon JPEG
# alpha -> PNG, sinon JPEG
has_alpha = (img.mode == "RGBA") or (img.mode == "P" and "transparency" in img.info)
img = img.convert("RGBA") if has_alpha else img.convert("RGB")
img.thumbnail([320, 320], Image.LANCZOS)
@@ -365,8 +365,10 @@ class FolderFilePro:
"regex_ignore_case": ("BOOLEAN", {"default": True}),
"sort_by": (["name", "mtime", "size"], {"default": "name"}),
"descending": ("BOOLEAN", {"default": False}),
# Sélection
"seed_mode": (["manual", "fixed", "increment", "decrement", "randomize"], {"default": "manual"}),
"seed": ("INT", {"default": 0, "min": -2147483648, "max": 2147483647}),
"index": ("INT", {"default": 0, "min": 0, "max": 1_000_000_000}),
}
}
@@ -378,7 +380,7 @@ class FolderFilePro:
def pick(self, directory: str, extensions: str,
name_regex: str, regex_mode: str, regex_ignore_case: bool,
sort_by: str, descending: bool,
seed_mode: str, seed: int):
seed_mode: str, seed: int, index: int):
exts = _norm_exts(extensions)
files = _list_files_current_dir(directory, exts)
@@ -392,16 +394,17 @@ class FolderFilePro:
n = len(files)
sm = (seed_mode or "manual").lower()
if sm == "randomize":
idx = random.Random(int(seed)).randrange(n)
if sm == "manual":
sel = max(0, min(int(index), n - 1))
elif sm == "randomize":
sel = random.Random(int(seed) & 0xFFFFFFFF).randrange(n)
elif sm == "decrement":
sel = (int(seed) - 1) % n
else:
try:
idx = int(seed)
except Exception:
idx = 0
idx %= n
# fixed / increment → même base (Comfy ne fournit pas de hook post-run ici)
sel = int(seed) % n
chosen = files[idx]
chosen = files[sel]
files_json = json.dumps(
[{"name": f.name, "path": f.path, "size": f.size, "mtime": f.mtime} for f in files],
+38 -68
View File
@@ -1,7 +1,8 @@
"use strict";
// DAO_master — Folder File Pro UI (v4.0)
// - Folder icon from web/ico_dossier.png (non déformée)
// DAO_master — Folder File Pro UI (v4.1)
// - Icône dossier PNG /web/ico_dossier.png non déformée
// - Grid/List, scroll fiable, double-clic, type-to-select, Explorer
// - Clic sur un fichier => seed_mode = "manual" + mise à jour de l'index (aligné Python)
import { app } from "/scripts/app.js";
import { api } from "/scripts/api.js";
@@ -41,10 +42,10 @@ function ensureLightbox() {
});
}
/* ---------- Icône dossier PNG depuis /web ---------- */
/* ---------- Icône dossier ---------- */
const FFP_FOLDER_URL = new URL("./ico_dossier.png", import.meta.url).href;
/* ---------- Badge d'extension pour non-images ---------- */
/* ---------- Badge d'extension ---------- */
function extBadge(ext) {
if (!ext) ext = ".file";
if (ext[0] !== ".") ext = "." + ext;
@@ -52,7 +53,7 @@ function extBadge(ext) {
}
app.registerExtension({
name: "DAO_master.FolderFilePro.UI.v4_0",
name: "DAO_master.FolderFilePro.UI.v4_1",
async beforeRegisterNodeDef(nodeType, nodeData) {
if (!nodeData || nodeData.name !== "Folder File Pro") return;
@@ -69,8 +70,10 @@ app.registerExtension({
const wReIC = this.widgets.find((w) => w.name === "regex_ignore_case");
const wSort = this.widgets.find((w) => w.name === "sort_by");
const wDesc = this.widgets.find((w) => w.name === "descending");
const wIdx = this.widgets.find((w) => w.name === "index");
if (wIdx) wIdx.hidden = true;
const wSeedMode = this.widgets.find((w) => w.name === "seed_mode");
const wSeed = this.widgets.find((w) => w.name === "seed");
const wIndex = this.widgets.find((w) => w.name === "index");
if (wIndex) wIndex.hidden = true;
/* --------- UI DOM --------- */
const root = document.createElement("div");
@@ -81,7 +84,6 @@ app.registerExtension({
.ffp-input,.ffp-btn,.ffp-select{background:#333;color:#ccc;border:1px solid #555;border-radius:6px;padding:6px 8px;font-size:12px}
.ffp-input{flex:1 1 auto;min-width:240px}
/* conteneur résultats → occupe tout l'espace disponible; min-height:0 pour activer le scroll */
.ffp-grid{flex:1 1 auto;min-height:0;overflow-y:auto;background:#222;border-radius:10px;padding:10px;
display:grid;grid-template-columns:repeat(auto-fill,minmax(180px,1fr));gap:10px}
.ffp-grid.ffp-list{display:block}
@@ -91,14 +93,13 @@ app.registerExtension({
.ffp-card.selected{border-color:#00ffc9}
.ffp-media{display:flex;align-items:center;justify-content:center;height:150px;border-radius:10px 10px 0 0;background:#1b1b1b;overflow:hidden;color:#bbb;font-size:22px}
.ffp-media img{max-width:100%;max-height:100%;object-fit:contain;image-rendering:auto}
.ffp-media img{max-width:100%;max-height:100%;object-fit:contain}
/* taille conforme Local_Image_Gallery (Grid ~72px haut) */
/* taille proche de Local_Image_Gallery (≈72px de haut) */
.ffp-media .ffp-folder-img{max-height:72px;max-width:96px;width:auto;height:auto}
.ffp-info{padding:8px 10px;font-size:12px;word-break:break-all;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}
/* List mode */
.ffp-grid.ffp-list .ffp-card{flex-direction:row;align-items:center;padding:6px 8px;margin-bottom:6px}
.ffp-grid.ffp-list .ffp-media{width:52px;height:52px;border-radius:8px;margin-right:10px}
.ffp-grid.ffp-list .ffp-media .ffp-folder-img{max-height:40px;max-width:56px}
@@ -157,8 +158,12 @@ app.registerExtension({
card.classList.add("selected");
selectedPath = card.dataset.path || null;
if (scroll) card.scrollIntoView({ block: "nearest" });
if (updateIndex && card.dataset.type === "file")
if (updateIndex && card.dataset.type === "file") {
// IMPORTANT : aligner le moteur Python sur la sélection
if (wSeedMode) wSeedMode.value = "manual";
resolveAndSelect.call(this, selectedPath);
this.setDirtyCanvas(true, true);
}
}
function selectByIndex(idx) {
const list = cardsArray();
@@ -187,40 +192,21 @@ app.registerExtension({
}
function fileHTML(f) {
if (f.type === "image") {
const src =
"/folder_file_pro/thumbnail?filepath=" +
encodeURIComponent(f.path);
const src = "/folder_file_pro/thumbnail?filepath=" + encodeURIComponent(f.path);
return (
'<div class="ffp-media"><img loading="lazy" src="' +
src +
'" /></div><div class="ffp-info" title="' +
f.name +
'">' +
f.name +
"</div>"
'<div class="ffp-media"><img loading="lazy" src="' + src +
'" /></div><div class="ffp-info" title="' + f.name + '">' + f.name + "</div>"
);
} else if (f.type === "svg") {
const src =
"/folder_file_pro/view?filepath=" +
encodeURIComponent(f.path);
const src = "/folder_file_pro/view?filepath=" + encodeURIComponent(f.path);
return (
'<div class="ffp-media"><img loading="lazy" src="' +
src +
'" /></div><div class="ffp-info" title="' +
f.name +
'">' +
f.name +
"</div>"
'<div class="ffp-media"><img loading="lazy" src="' + src +
'" /></div><div class="ffp-info" title="' + f.name + '">' + f.name + "</div>"
);
} else {
return (
'<div class="ffp-media">' +
extBadge(f.ext || ".file") +
'</div><div class="ffp-info" title="' +
f.name +
'">' +
f.name +
"</div>"
'<div class="ffp-media">' + extBadge(f.ext || ".file") +
'</div><div class="ffp-info" title="' + f.name + '">' + f.name + "</div>"
);
}
}
@@ -258,9 +244,7 @@ app.registerExtension({
pathInput.value = curDir;
parentDir = data.parent_directory || null;
upBtn.disabled = !parentDir;
countLbl.textContent = data.total_count
? String(data.total_count) + " fichier(s)"
: "";
countLbl.textContent = data.total_count ? String(data.total_count) + " fichier(s)" : "";
grid.classList.toggle("ffp-list", curView === "list");
@@ -286,10 +270,7 @@ app.registerExtension({
const sameView = curView === prevView;
if (!sameDir || !sameView || forceResetScroll) grid.scrollTop = 0;
else {
const maxScroll = Math.max(
0,
grid.scrollHeight - grid.clientHeight
);
const maxScroll = Math.max(0, grid.scrollHeight - grid.clientHeight);
grid.scrollTop = Math.min(prevScroll, maxScroll);
}
lastDir = curDir;
@@ -298,10 +279,7 @@ app.registerExtension({
grid.focus();
});
} catch (e) {
grid.innerHTML =
'<p style="color:#ff7777;padding:8px">' +
(e.message || String(e)) +
"</p>";
grid.innerHTML = '<p style="color:#ff7777;padding:8px">' + (e.message || String(e)) + "</p>";
lastDir = String(wDir ? wDir.value : "");
lastView = viewSel.value;
forceResetScroll = false;
@@ -325,13 +303,11 @@ app.registerExtension({
regex_ic: String(!!(wReIC && wReIC.value)),
path: String(targetPath),
}).toString();
const res = await api.fetchApi(
"/folder_file_pro/resolve_index?" + params
);
const res = await api.fetchApi("/folder_file_pro/resolve_index?" + params);
const data = await res.json();
const idxW = this.widgets.find((w) => w.name === "index");
if (idxW && data.index >= 0) {
idxW.value = data.index;
if (data && typeof data.index === "number" && data.index >= 0) {
const idxW = this.widgets.find((w) => w.name === "index");
if (idxW) idxW.value = data.index;
this.setDirtyCanvas(true, true);
}
} catch (e) {
@@ -368,15 +344,11 @@ app.registerExtension({
v.pause();
a.pause();
if (isImg) {
i.src =
"/folder_file_pro/view?filepath=" + encodeURIComponent(p);
i.src = "/folder_file_pro/view?filepath=" + encodeURIComponent(p);
i.style.display = "block";
lb.style.display = "flex";
} else {
window.open(
"/folder_file_pro/view?filepath=" + encodeURIComponent(p),
"_blank"
);
window.open("/folder_file_pro/view?filepath=" + encodeURIComponent(p), "_blank");
}
});
@@ -401,8 +373,7 @@ app.registerExtension({
}
}
grid.addEventListener("keydown", (e) => {
const tag =
(document.activeElement && document.activeElement.tagName) || "";
const tag = (document.activeElement && document.activeElement.tagName) || "";
if (tag === "INPUT" || tag === "SELECT" || tag === "TEXTAREA") return;
if (e.key.length === 1 && !e.ctrlKey && !e.metaKey && !e.altKey) {
handleType.call(this, e.key);
@@ -420,7 +391,7 @@ app.registerExtension({
}
});
// relier widgets aux refresh
// refresh auto quand un widget change
function rewire(w) {
if (!w) return;
const prev = w.callback;
@@ -451,8 +422,7 @@ app.registerExtension({
fetchList();
};
exploreBtn.onclick = async () => {
const toOpen =
(selectedPath || (wDir ? wDir.value : "") || "").toString();
const toOpen = (selectedPath || (wDir ? wDir.value : "") || "").toString();
if (!toOpen) return;
try {
await api.fetchApi("/folder_file_pro/open_explorer", {
@@ -485,4 +455,4 @@ app.registerExtension({
},
});
console.log("[DAO_master] Folder File Pro UI v4.0 loaded");
console.log("[DAO_master] Folder File Pro UI v4.1 loaded");