312 lines
7.6 KiB
JavaScript
312 lines
7.6 KiB
JavaScript
import { api } from "/scripts/api.js";
|
||
import { app } from "/scripts/app.js";
|
||
|
||
// forked from pysssss's imageFeed.js
|
||
|
||
const styles = {
|
||
lighbox: {
|
||
position: "fixed",
|
||
top: 0,
|
||
left: 0,
|
||
width: "100vw",
|
||
height: "100vh",
|
||
background: "rgba(0,0,0,0.5)",
|
||
display: "none",
|
||
justifyContent: "center",
|
||
alignItems: "center",
|
||
zIndex: 999,
|
||
},
|
||
lightboxBtn: (extra) => ({
|
||
position: "absolute",
|
||
top: "50%",
|
||
background: "none",
|
||
border: "none",
|
||
color: "#fff",
|
||
zIndex: 9999999,
|
||
fontSize: "30px",
|
||
cursor: "pointer",
|
||
pointerEvents: "bounding-box",
|
||
...extra,
|
||
})
|
||
,
|
||
img_list: {
|
||
|
||
minHeight: "30px",
|
||
maxHeight: "300px",
|
||
width: "100vw",
|
||
position: "absolute",
|
||
bottom: 0,
|
||
zIndex: 9999999,
|
||
background: "#333",
|
||
overflow: "auto",
|
||
}
|
||
}
|
||
|
||
let currentImageIndex = 0;
|
||
const imageUrls = [];
|
||
|
||
let image_menu = null
|
||
|
||
app.registerExtension({
|
||
name: "mtb.ImageFeed",
|
||
setup: async () => {
|
||
// - HTML & CSS
|
||
//- lightbox
|
||
const lightboxContainer = document.createElement("div");
|
||
Object.assign(lightboxContainer.style, styles.lighbox);
|
||
|
||
const lightboxImage = document.createElement("img");
|
||
Object.assign(lightboxImage.style, {
|
||
maxHeight: "100%",
|
||
maxWidth: "100%",
|
||
borderRadius: "5px",
|
||
});
|
||
|
||
// previous and next buttons
|
||
const lightboxPrevBtn = document.createElement("button");
|
||
const lightboxNextBtn = document.createElement("button");
|
||
|
||
lightboxPrevBtn.textContent = "❮";
|
||
lightboxNextBtn.textContent = "❯";
|
||
|
||
Object.assign(lightboxPrevBtn.style, styles.lightboxBtn({ left: "0%" }));
|
||
Object.assign(lightboxNextBtn.style, styles.lightboxBtn({ right: "0%" }));
|
||
|
||
// close button
|
||
const lightboxCloseBtn = document.createElement("button");
|
||
Object.assign(lightboxCloseBtn.style, styles.lightboxBtn({ right: "0", top: "0" }));
|
||
lightboxCloseBtn.textContent = "❌";
|
||
|
||
const lightboxButtons = document.createElement("div");
|
||
Object.assign(lightboxButtons.style, {
|
||
position: "absolute",
|
||
top: "0%",
|
||
right: "0%",
|
||
// transform: "translate(50%, -50%)",
|
||
height: "100%",
|
||
width: "100%",
|
||
background: "none",
|
||
border: "none",
|
||
color: "#fff",
|
||
fontSize: "30px",
|
||
cursor: "pointer",
|
||
pointerEvents: "none",
|
||
});
|
||
|
||
lightboxButtons.append(lightboxPrevBtn, lightboxNextBtn, lightboxCloseBtn);
|
||
lightboxContainer.append(lightboxButtons, lightboxImage);
|
||
|
||
//- image list
|
||
const imageListContainer = document.createElement("div");
|
||
Object.assign(imageListContainer.style, styles.img_list);
|
||
|
||
|
||
const createImgListBtn = (text, style) => {
|
||
const btn = document.createElement("button");
|
||
btn.type = "button";
|
||
btn.textContent = text;
|
||
Object.assign(btn.style, {
|
||
...style,
|
||
border: "none",
|
||
color: "#fff",
|
||
background: "none",
|
||
height: "20px",
|
||
cursor: "pointer",
|
||
position: "absolute",
|
||
top: "5px",
|
||
fontSize: "12px",
|
||
lineHeight: "12px",
|
||
});
|
||
imageListContainer.append(btn);
|
||
return btn;
|
||
}
|
||
const showBtn = document.createElement("button");
|
||
const closeBtn = createImgListBtn("❌", {
|
||
width: "20px",
|
||
textIndent: "-4px",
|
||
right: "5px",
|
||
});
|
||
const loadButton = createImgListBtn("Load Session History", {
|
||
right: "90px",
|
||
});
|
||
const clearButton = createImgListBtn("Clear", {
|
||
right: "30px",
|
||
});
|
||
|
||
|
||
//- tools popup button
|
||
showBtn.classList.add("comfy-settings-btn");
|
||
Object.assign(showBtn.style, {
|
||
right: "16px",
|
||
cursor: "pointer",
|
||
display: "none",
|
||
});
|
||
|
||
//- append to DOM
|
||
document.body.append(imageListContainer);
|
||
|
||
|
||
showBtn.textContent = "🖼️";
|
||
showBtn.onclick = () => {
|
||
imageListContainer.style.display = "block";
|
||
showBtn.style.display = "none";
|
||
};
|
||
document.querySelector(".comfy-settings-btn").after(showBtn);
|
||
document.querySelector(".comfy-settings-btn").after(lightboxContainer);
|
||
|
||
|
||
|
||
// for (const { output } of history) {
|
||
// if (output?.images) {
|
||
// for (const src of output.images) {
|
||
// const img = document.createElement("img");
|
||
// const but = document.createElement("button");
|
||
|
||
//- callbacks
|
||
closeBtn.onclick = () => {
|
||
imageListContainer.style.display = "none";
|
||
showBtn.style.display = "unset";
|
||
};
|
||
|
||
clearButton.onclick = () => {
|
||
imageListContainer.replaceChildren(closeBtn, clearButton, loadButton);
|
||
}
|
||
|
||
lightboxNextBtn.onclick = () => {
|
||
currentImageIndex = (currentImageIndex + 1) % imageUrls.length;
|
||
const imageUrl = imageUrls[currentImageIndex];
|
||
lightboxImage.src = imageUrl;
|
||
};
|
||
|
||
// Modify the lightboxPrevBtn onclick callback
|
||
lightboxPrevBtn.onclick = () => {
|
||
currentImageIndex = (currentImageIndex - 1 + imageUrls.length) % imageUrls.length;
|
||
const imageUrl = imageUrls[currentImageIndex];
|
||
lightboxImage.src = imageUrl;
|
||
};
|
||
|
||
|
||
lightboxCloseBtn.onclick = () => {
|
||
lightboxContainer.style.display = "none";
|
||
};
|
||
lightboxImage.onclick = lightboxNextBtn.onclick;
|
||
/**
|
||
* This is the function that creates the image buttons for the image list
|
||
* They are wrapped in a button so that they can be clicked and open
|
||
* the image in the lightbox.
|
||
* @param {*} src
|
||
*/
|
||
const createImageBtn = (src) => {
|
||
console.debug(`making image ${src.filename}`);
|
||
const img = document.createElement("img");
|
||
const but = document.createElement("button");
|
||
|
||
Object.assign(but.style, {
|
||
height: "120px",
|
||
width: "120px",
|
||
});
|
||
Object.assign(img.style, {
|
||
width: "100%",
|
||
height: "100%",
|
||
objectFit: "scale-down",
|
||
});
|
||
|
||
img.src = `/view?filename=${encodeURIComponent(src.filename)}&type=${src.type}&subfolder=${encodeURIComponent(
|
||
src.subfolder
|
||
)}`;
|
||
|
||
imageUrls.push(img.src);
|
||
|
||
console.debug(img.src)
|
||
|
||
but.onclick = () => {
|
||
lightboxContainer.style.display = "flex";
|
||
// add the same image to the lightbox
|
||
lightboxImage.src = img.src;
|
||
// lighboxContainer.replaceChildren(lightboxButtons, img);
|
||
|
||
};
|
||
|
||
// add right click menu
|
||
but.addEventListener("contextmenu", (e) => {
|
||
e.preventDefault();
|
||
|
||
if (image_menu) {
|
||
image_menu.remove();
|
||
}
|
||
|
||
image_menu = document.createElement("div");
|
||
Object.assign(image_menu.style, {
|
||
position: "absolute",
|
||
top: `${e.clientY}px`,
|
||
left: `${e.clientX}px`,
|
||
background: "#333",
|
||
color: "#fff",
|
||
padding: "5px",
|
||
borderRadius: "5px",
|
||
zIndex: 999,
|
||
});
|
||
const load_img = document.createElement("button");
|
||
load_img.textContent = "Load";
|
||
load_img.onclick = () => {
|
||
app.handleFile(img.src)
|
||
|
||
}
|
||
|
||
image_menu.appendChild(load_img)
|
||
document.body.appendChild(image_menu)
|
||
})
|
||
|
||
but.append(img)
|
||
imageListContainer.prepend(but)
|
||
};
|
||
|
||
|
||
loadButton.onclick = async () => {
|
||
const all_history = await api.getHistory();
|
||
for (const history of all_history.History) {
|
||
if (history.outputs) {
|
||
for (const key of Object.keys(history.outputs)) {
|
||
console.debug(key)
|
||
for (const im of history.outputs[key].images) {
|
||
console.debug(im)
|
||
createImageBtn(im)
|
||
}
|
||
}
|
||
// for (const src of outputs.outputs.images) {
|
||
// console.debug(src)
|
||
// makeImage(`${src.subfolder}/${src.filename}`)
|
||
// }
|
||
}
|
||
}
|
||
}
|
||
|
||
///////-------
|
||
|
||
// const all_history = await api.getHistory()
|
||
// for (const history of all_history.History) {
|
||
// if (history.outputs) {
|
||
// for (const key of Object.keys(history.outputs)) {
|
||
// for (const im of history.outputs[key].images) {
|
||
// makeImage(im)
|
||
// }
|
||
// }
|
||
// // for (const src of outputs.outputs.images) {
|
||
// // console.debug(src)
|
||
// // makeImage(`${src.subfolder}/${src.filename}`)
|
||
// // }
|
||
// }
|
||
// }
|
||
|
||
//- Hook into the API
|
||
api.addEventListener("executed", ({ detail }) => {
|
||
if (detail?.output?.images) {
|
||
for (const src of detail.output.images) {
|
||
console.debug(`Adding ${src} to image feed`)
|
||
createImageBtn(src)
|
||
}
|
||
}
|
||
})
|
||
}
|
||
})
|