Files
JasonHoku-ComfyUI-Ultimate-…/resources/template.html
T

357 lines
16 KiB
HTML

<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
<style>
/* INJECTED CSS */
__CSS_CONTENT__
</style>
</head>
<body>
<!-- COMPACT SINGLE-LINE HEADER -->
<div id="header">
<button class="session-popup-btn" onclick="toggleSessionPopup()" title="Session Management">
SESSION
</button>
<button class="filter-popup-btn" onclick="toggleFiltersPopup()" title="Open Filters & Info">
FILTERS
</button>
<div style="flex-grow: 1;"></div>
<div class="meta-box">
<input type="text" inputmode="numeric" id="goto-input" min="1" placeholder="Go to # "
title="Jump to image number (press Enter)" style="width: 50px;">
</div>
<div class="meta-box">
<span class="meta-label">Cols</span>
<input type="text" inputmode="numeric" id="col-count" min="0" placeholder="Auto"
title="Set grid columns (0 = Auto)">
</div>
<div class="meta-box">
<span class="meta-label">Sort</span>
<select id="sort-select" class="sort-select" onchange="changeSort()">
<option value="oldest">Oldest</option>
<option value="newest">Newest</option>
<option value="fastest">Fastest</option>
<option value="favorited">Favorited</option>
<option value="model">Model</option>
<option value="prompt">Prompt</option>
<option value="cfg">CFG</option>
<option value="denoise">Denoise</option>
<option value="lora">LoRA</option>
<option value="sampler">Sampler</option>
</select>
</div>
<button class="action-btn" onclick="resetZoom()" title="Reset Zoom (0)">⊙</button>
<button class="fs-btn" onclick="toggleFullscreen()" title="Toggle Fullscreen">⛶</button>
</div>
<div id="filters-popup" class="filters-popup" style="display: none;">
<div class="filters-popup-header">
<h3>Filters & Info</h3>
<button class="close-popup-btn" onclick="toggleFiltersPopup()">✕</button>
</div>
<div class="filters-popup-content">
<!-- SEARCH FILTER SECTION -->
<div class="popup-section">
<div class="popup-section-title">SEARCH FILTER</div>
<div class="search-filter-container">
<div class="search-filter-row">
<select id="search-filter-type" class="search-filter-select">
<option value="">Select filter type...</option>
<option value="model">Model</option>
<option value="positive">Positive Prompt</option>
<option value="negative">Negative Prompt</option>
<option value="sampler">Sampler</option>
<option value="scheduler">Scheduler</option>
<option value="lora">LoRA</option>
</select>
<input type="text" id="search-filter-input" class="search-filter-input"
placeholder="Enter search term..." onkeypress="if(event.key==='Enter') addSearchFilter()">
<button class="search-filter-add-btn" onclick="addSearchFilter()">ADD</button>
</div>
<div id="active-search-filters" class="active-search-filters"></div>
</div>
</div>
<!-- Meta Info Section -->
<!-- Filters Section -->
<div class="popup-section">
<div class="popup-section-title">FILTERS <span
style="font-size: 9px; color: #555; font-weight: normal;">(Shift+Click to isolate)</span></div>
<br />
<div class="filter-row">
<span class="filter-label">Model</span>
<div id="filter-model" class="filter-buttons-container"></div>
</div>
<div class="filter-row">
<span class="filter-label">Positive Prompt</span>
<div id="filter-positive" class="filter-buttons-container"></div>
</div>
<div class="filter-row">
<span class="filter-label">Negative Prompt</span>
<div id="filter-negative" class="filter-buttons-container"></div>
</div>
<div class="filter-row">
<span class="filter-label">Sampler</span>
<div id="filter-sampler" class="filter-buttons-container"></div>
</div>
<div class="filter-row">
<span class="filter-label">Scheduler</span>
<div id="filter-scheduler" class="filter-buttons-container"></div>
</div>
<div class="filter-row">
<span class="filter-label">Denoise</span>
<div id="filter-denoise" class="filter-buttons-container"></div>
</div>
<div class="filter-row">
<span class="filter-label">LoRA</span>
<div id="filter-lora" class="filter-buttons-container"></div>
</div>
<div class="filter-row">
<span class="filter-label">Size</span>
<div id="filter-size" class="filter-buttons-container"></div>
</div>
<div class="filter-row">
<span class="filter-label">Seed</span>
<div id="filter-seed" class="filter-buttons-container"></div>
</div>
</div>
</div>
</div>
<!-- Overlay for popup -->
<div id="filters-overlay" class="filters-overlay" onclick="toggleFiltersPopup()" style="display: none;"></div>
<!-- SESSION POPUP PANEL -->
<div id="session-popup" class="session-dropdown" style="display: none;">
<div class="session-dropdown-content">
<input id="session-input" class="session-name-input" type="text" value="__TITLE__"
placeholder="Session name...">
<div class="session-actions">
<button class="session-action-btn save-btn" onclick="saveState()">SAVE</button>
<button class="session-action-btn load-btn" onclick="loadSession()">LOAD</button>
</div>
<!-- NEW: Export Favorites Section -->
<div style="border-top: 1px solid #333; margin-top: 12px; padding-top: 12px;">
<button class="session-action-btn"
style="background: #ff6b35; width: 100%; font-size: 11px; padding: 10px;"
onclick="exportFavorites()" title="Export favorited images to benchmark_favorites folder">
📦 COPY FAVORITES TO BENCHMARK FAVORITES FOLDER
</button>
<div style="margin-top: 8px; display: flex; align-items: center; gap: 6px;">
<input type="checkbox" checked id="pack-metadata-checkbox"
style="width: 14px; height: 14px; cursor: pointer;">
<label for="pack-metadata-checkbox"
style="font-size: 10px; color: #999; cursor: pointer; user-select: none;">
Pack metadata into copied favorites (for CivitAI)
</label>
</div>
<div style="margin-top: 8px; display: flex; align-items: center; gap: 6px;">
<input type="checkbox" id="organize-by-prompt-checkbox"
style="width: 14px; height: 14px; cursor: pointer;">
<label for="organize-by-prompt-checkbox"
style="font-size: 10px; color: #999; cursor: pointer; user-select: none;">
Organize into separate folders by prompt (Prompt1, Prompt2, etc.)
</label>
</div>
<div id="export-status" style="margin-top: 8px; font-size: 10px; color: #666; min-height: 16px;"></div>
</div>
</div>
</div>
<div id="viewport">
<div id="canvas">
<div class="grid" id="grid"></div>
</div>
</div>
<!-- MOBILE NAVIGATION BUTTONS -->
<button id="mobile-nav-up" class="mobile-nav-btn mobile-nav-up" onclick="scrollUpOneRow()" title="Scroll Up">
▲
</button>
<button id="mobile-nav-down" class="mobile-nav-btn mobile-nav-down" onclick="scrollDownOneRow()"
title="Scroll Down">
▼
</button>
<div class="json-container">
<!-- Button row -->
<div style="display: flex; gap: 0;">
<button id="json-btn-good" class="json-view-btn" onclick="viewGoodJSON()"
title="Click to view accepted configs JSON">
View Configs (0)
</button>
<button id="json-btn-favorite" class="json-view-btn" onclick="viewFavoritedJSON()"
title="Click to view favorited configs JSON">
View Favorited (0)
</button>
<button id="json-btn-bad" class="json-view-btn" onclick="viewRejectedJSON()"
title="Click to view rejected configs JSON">
View Rejected (0)
</button>
</div>
<!-- Hidden JSON display areas (shown when button is clicked) -->
<div id="json-bar-good" class="json-bar" style="display: none;" title="ACCEPTED CONFIGS (Click to select)"
onclick="selectJSON('json-bar-good')">[]</div>
<div id="json-bar-favorite" class="json-bar" style="display: none;" title="FAVORITED CONFIGS (Click to select)"
onclick="selectJSON('json-bar-favorite')">[]</div>
<div id="json-bar-bad" class="json-bar" style="display: none;" title="REJECTED CONFIGS (Click to select)"
onclick="selectJSON('json-bar-bad')">[]</div>
</div>
<div id="modal">
<div class="modal-main">
<div class="preview"><img id="m-img" src=""></div>
<div class="controls">
<h2 style="margin:0 0 10px 0; color:#fff;">Revise & Generate</h2>
<div class="field"><label>Model</label><input id="f-model" disabled style="opacity:0.6;"></div>
<div class="field"><label>Seed</label><input id="f-seed" type="number" disabled style="opacity:0.6;">
</div>
<div class="field"><label>Positive Prompt</label><textarea id="f-pos" rows="3"
style="background:#000; border:1px solid #333; color:#fff; padding:8px; font-size:12px; font-family:inherit; resize:vertical;"></textarea>
</div>
<div class="field"><label>Negative Prompt</label><textarea id="f-neg" rows="2"
style="background:#000; border:1px solid #333; color:#fff; padding:8px; font-size:12px; font-family:inherit; resize:vertical;"></textarea>
</div>
<div style="border-top:1px solid #333; margin:10px 0; padding-top:10px;">
<div style="font-size:11px; color:#666; margin-bottom:8px;">ADJUST PARAMETERS:</div>
</div>
<div class="field"><label>Sampler</label><input id="f-smp"></div>
<div class="field"><label>Scheduler</label><input id="f-sch"></div>
<div class="field"><label>Steps</label><input id="f-stp" type="number"></div>
<div class="field"><label>CFG</label><input id="f-cfg" type="number" step="0.5"></div>
<div class="field"><label>Denoise</label><input id="f-den" type="number" step="0.05"></div>
<div class="field"><label>LoRA</label><input id="f-lor"></div>
<div style="margin-top:auto; display:flex; gap:10px;">
<button class="action-btn"
style="flex:2; background:var(--accent); color:#000; border:none; height:36px; font-weight:800"
onclick="triggerGen(this)">GENERATE NEW</button>
<button class="action-btn" style="flex:1" onclick="closeM()">CANCEL</button>
</div>
</div>
</div>
<div class="reel-wrap">
<div style="font-size:10px; font-weight:bold; color:#666;">RELATED VARIANTS</div>
<div class="reel" id="reel"></div>
</div>
</div>
<script>
// INJECTED DATA
const TARGET_NODE_ID = "__NODE_ID__";
let fullManifest = __JSON_DATA__;
// INJECTED LOGIC
__JS_CONTENT__
</script>
<style>
/* Default behavior: The button is visible */
.gh-hide-on-mobile {
display: block;
}
/* CONDITION 1: Hide if screen is narrower than 768px (Mobile/Tablets) */
@media (max-width: 768px) {
.gh-hide-on-mobile {
display: none !important;
}
}
/* CONDITION 2: Hide if screen is in Portrait Mode (Taller than it is wide) */
@media (orientation: portrait) {
.gh-hide-on-mobile {
display: none !important;
}
}
</style>
<div class="gh-hide-on-mobile" style="position: absolute; top: 2px; left: 50%; transform: translateX(-50%); z-index: 999;">
<a href="https://github.com/JasonHoku/ComfyUI-Ultimate-Auto-Sampler-Config-Grid-Testing-Suite" target="_blank"
style="
display: inline-flex;
align-items: center;
gap: 6px;
background-color: #313131;
border: 1px solid rgba(27, 31, 35, 0.15);
border-radius: 6px;
color: #e6e6e6;
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Helvetica, Arial, sans-serif;
font-size: 14px;
font-weight: 600;
line-height: 1;
padding: 3px 10px;
line-height: 20px;
text-decoration: none;
white-space: nowrap;
" onmouseover="this.style.backgroundColor='#747474'" onmouseout="this.style.backgroundColor='#313131'">
<svg height="20" viewBox="0 0 16 16" width="20" style="fill: currentColor; opacity: 0.7;">
<path
d="M8 0C3.58 0 0 3.58 0 8c0 3.54 2.29 6.53 5.47 7.59.4.07.55-.17.55-.38 0-.19-.01-.82-.01-1.49-2.01.37-2.53-.49-2.69-.94-.09-.23-.48-.94-.82-1.13-.28-.15-.68-.52-.01-.53.63-.01 1.08.58 1.23.82.72 1.21 1.87.87 2.33.66.07-.52.28-.87.51-1.07-1.78-.2-3.64-.89-3.64-3.95 0-.87.31-1.59.82-2.15-.08-.2-.36-1.02.08-2.12 0 0 .67-.21 2.2.82.64-.18 1.32-.27 2-.27.68 0 1.36.09 2 .27 1.53-1.04 2.2-.82 2.2-.82.44 1.1.16 1.92.08 2.12.51.56.82 1.27.82 2.15 0 3.07-1.87 3.75-3.65 3.95.29.25.54.73.54 1.48 0 1.07-.01 1.93-.01 2.2 0 .21.15.46.55.38A8.013 8.013 0 0016 8c0-4.42-3.58-8-8-8z">
</path>
</svg>
<span>Star</span>
<span id="gh-star-count" style="
background-color: rgba(27, 31, 35, 0.08);
padding: 2px 6px;
border-radius: 10px;
font-size: 12px;
display: none; /* Hidden until loaded */
"></span>
</a>
</div>
<script>
(async function () {
try {
const repo = 'JasonHoku/ComfyUI-Ultimate-Auto-Sampler-Config-Grid-Testing-Suite';
const response = await fetch(`https://api.github.com/repos/${repo}`);
if (response.ok) {
const data = await response.json();
const countSpan = document.getElementById('gh-star-count');
// Format number (e.g. 1500 -> 1.5k) if needed, or just show raw
countSpan.textContent = data.stargazers_count;
countSpan.style.display = 'inline-block'; // Show it now that we have data
}
} catch (e) {
console.log('Could not fetch GitHub stars');
}
})();
</script>
</body>
</html>