add new file

This commit is contained in:
NyaFuP
2025-07-15 20:50:53 +09:00
parent 8ad0d806e9
commit 6dbfad1be0
2 changed files with 133 additions and 1 deletions
+16 -1
View File
@@ -55,11 +55,20 @@
/* Image Grid */
.nf-image-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(var(--min-column-width, 150px), 1fr));
gap: 8px;
grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
flex: 1; /* Take up remaining space */
overflow-y: auto;
min-height: 0; /* Allow shrinking */
align-items: start;
}
/* Smart grid layout that adapts to content and window size */
.nf-image-grid.smart-grid-layout {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(var(--min-column-width, 150px), 1fr));
gap: 8px;
align-items: start;
}
.nf-image-container {
@@ -70,6 +79,12 @@
transition: border-color 0.2s;
}
/* Responsive image containers */
.nf-image-grid.smart-grid-layout .nf-image-container {
width: 100%;
max-width: 100%;
}
.nf-image-container:hover {
border-color: #70a0d0;
}
+117
View File
@@ -22,6 +22,9 @@ export class NFPreviewDialog {
// Apply max width setting
this.applyMaxWidthSetting();
// Setup Queue Prompt keybinding integration
this.setupQueuePromptIntegration();
}
loadCSS() {
@@ -57,6 +60,55 @@ export class NFPreviewDialog {
document.head.appendChild(style);
}
setupQueuePromptIntegration() {
// Listen for Queue Prompt keybinding events
document.addEventListener('keydown', (event) => {
// Check if it's Ctrl+Enter (Queue Prompt) or Ctrl+Shift+Enter (Queue Prompt to Front)
if (event.ctrlKey && event.key === 'Enter') {
// Only handle if preview dialog is visible
if (this.isVisible()) {
console.log('NF Preview Dialog: Queue Prompt keybinding detected - stopping dialog and allowing queue to proceed');
// Stop the dialog processing immediately
this.stopDialogForQueue();
// Allow the event to propagate to ComfyUI's queue system
// Do not prevent default - let ComfyUI handle the queue
}
}
});
// Also listen for programmatic queue events via API
api.addEventListener("status", (event) => {
const status = event.detail;
// If queue is starting and dialog is visible, stop the dialog
if (status && status.exec_info && status.exec_info.queue_remaining > 0) {
if (this.isVisible()) {
console.log('NF Preview Dialog: Queue started programmatically - stopping dialog');
this.stopDialogForQueue();
}
}
});
}
stopDialogForQueue() {
// Stop countdown immediately
this.stopCountdown();
console.log('NF Preview Dialog: Stopping dialog processing for queue');
// Send cancellation response to backend (empty selection, cancelled=true)
this.sendSelection([], true);
// Hide the dialog
this.hide();
}
isVisible() {
return this.window && !this.window.classList.contains('hidden');
}
show(data) {
console.log("NF Preview Dialog: Showing review dialog", data);
@@ -177,6 +229,11 @@ export class NFPreviewDialog {
renderImages() {
this.imageGrid.innerHTML = '';
// Counter for loaded images to determine layout
let loadedImages = 0;
let landscapeCount = 0;
let portraitCount = 0;
this.images.forEach((imageInfo, index) => {
const container = document.createElement('div');
container.className = 'nf-image-container';
@@ -188,6 +245,23 @@ export class NFPreviewDialog {
img.src = this.getImageUrl(imageInfo);
img.alt = `Image ${index + 1}`;
// Check image aspect ratio when loaded
img.onload = () => {
loadedImages++;
const aspectRatio = img.naturalWidth / img.naturalHeight;
if (aspectRatio > 1.1) { // Landscape (wider than tall)
landscapeCount++;
} else if (aspectRatio < 0.9) { // Portrait (taller than wide)
portraitCount++;
}
// When all images are loaded, determine layout
if (loadedImages === this.images.length) {
this.applyImageLayout(landscapeCount, portraitCount);
}
};
const overlay = document.createElement('div');
overlay.className = 'nf-image-overlay';
overlay.textContent = index + 1;
@@ -198,6 +272,27 @@ export class NFPreviewDialog {
});
}
applyImageLayout(landscapeCount, portraitCount) {
// Always use smart grid layout that adapts to window size
this.imageGrid.className = 'nf-image-grid smart-grid-layout';
// Set CSS custom properties for dynamic grid sizing
const dialogWidth = this.window.offsetWidth - 48; // Account for padding
const isLandscapeDominant = landscapeCount > portraitCount;
if (isLandscapeDominant) {
// For landscape images, use slightly wider columns but still allow multiple columns
const minColumnWidth = Math.max(200, Math.min(300, dialogWidth / 2)); // 200-300px, max 2 columns typically
this.imageGrid.style.setProperty('--min-column-width', `${minColumnWidth}px`);
console.log('NF Preview Dialog: Using smart grid layout optimized for landscape images, min width:', minColumnWidth);
} else {
// For portrait/square images, use standard grid sizing
const minColumnWidth = Math.max(120, Math.min(200, dialogWidth / 3)); // 120-200px, allow up to 3-4 columns
this.imageGrid.style.setProperty('--min-column-width', `${minColumnWidth}px`);
console.log('NF Preview Dialog: Using smart grid layout optimized for portrait/square images, min width:', minColumnWidth);
}
}
getImageUrl(imageInfo) {
return `/view?filename=${encodeURIComponent(imageInfo.filename)}&type=${imageInfo.type}&subfolder=${encodeURIComponent(imageInfo.subfolder || '')}`;
}
@@ -397,6 +492,28 @@ export class NFPreviewDialog {
if (rememberPosition) {
this.saveSize(width, height);
}
// Recalculate grid layout for new window size
if (this.imageGrid && this.imageGrid.children.length > 0) {
// Get current aspect ratio distribution
let landscapeCount = 0;
let portraitCount = 0;
for (let container of this.imageGrid.children) {
const img = container.querySelector('img');
if (img && img.naturalWidth && img.naturalHeight) {
const aspectRatio = img.naturalWidth / img.naturalHeight;
if (aspectRatio > 1.1) {
landscapeCount++;
} else if (aspectRatio < 0.9) {
portraitCount++;
}
}
}
this.applyImageLayout(landscapeCount, portraitCount);
}
console.log("NF Preview Dialog: Window resized to", width, height);
}
}