Merge branch 'dev' into feat/filter-sampler-upscaler-choices

This commit is contained in:
Vladimir Mandic
2026-09-13 07:41:53 +02:00
committed by GitHub
99 changed files with 2858 additions and 394 deletions
+19 -11
View File
@@ -108,19 +108,27 @@ export const xnEngine: XnEngine = {
this.lora = new XnIndex(items);
}
// Embeddings: {loaded: [...], skipped: [...]}
const embData = await this.fetchJson('/embeddings') as Record<string, unknown> | null;
if (embData && typeof embData === 'object') {
const loaded = Array.isArray(embData.loaded) ? embData.loaded : [];
this.embed = new XnIndex(loaded.map((name) => ({ name: String(name) })));
if (window.opts.diffusers_enable_embed) {
const embData = await this.fetchJson('/embeddings') as Record<string, unknown> | null;
if (embData && typeof embData === 'object') {
const loaded = Array.isArray(embData.loaded) ? embData.loaded : [];
this.embed = new XnIndex(loaded.map((name) => ({ name: String(name) })));
}
} else {
this.embed = new XnIndex([]);
}
// Wildcards: [{name}, ...]
const wcData = await this.fetchJson('/wildcards');
if (Array.isArray(wcData)) {
this.wildcard = new XnIndex(
wcData
.filter((w) => typeof w === 'object' && w && 'name' in w && typeof w.name === 'string')
.map((w) => ({ name: w.name })),
);
if (window.opts.wildcards_enabled) {
const wcData = await this.fetchJson('/wildcards');
if (Array.isArray(wcData)) {
this.wildcard = new XnIndex(
wcData
.filter((w) => typeof w === 'object' && w && 'name' in w && typeof w.name === 'string')
.map((w) => ({ name: w.name })),
);
}
} else {
this.wildcard = new XnIndex([]);
}
log('autoComplete', {
xnLoaded: true,
+2 -1
View File
@@ -1,4 +1,5 @@
@font-face { font-family: 'NotoSans'; font-display: swap; font-style: normal; font-weight: 100; src: local('NotoSansNerd'), url('fonts/notosans-nerdfont-regular.ttf') }
@font-face { font-family: 'Ubuntu'; font-display: swap; font-style: normal; font-weight: 100; src: local('Ubuntu'), url('fonts/ubuntu-nerdfont.ttf') }
/* toolbutton */
.gradio-button.tool { max-width: min-content; min-width: min-content !important; align-self: end; font-size: 1.4em; color: var(--body-text-color) !important; }
@@ -32,7 +33,7 @@
/* fullpage image viewer */
#lightboxModal { display: none; position: fixed; z-index: 1001; left: 0; top: 0; width: 100%; height: 100%; overflow: auto; background-color: rgba(20, 20, 20, 0.75); backdrop-filter: blur(6px);
user-select: none; -webkit-user-select: none; flex-direction: row; font-family: 'NotoSans'; }
user-select: none; -webkit-user-select: none; flex-direction: row; font-family: 'Ubuntu'; }
.modalControls { display: flex; justify-content: space-evenly; background-color: transparent; position: absolute; width: 99%; z-index: 1; }
.modalControls:hover { background-color: #50505050; }
.modalControls span { color: white; font-size: 2em; font-weight: bold; cursor: pointer; filter: grayscale(100%); }
+10 -3
View File
@@ -5,6 +5,13 @@
font-weight: 100;
src: local('NotoSansNerd'), url('fonts/notosans-nerdfont-regular.ttf');
}
@font-face {
font-display: swap;
font-family: 'Ubuntu';
font-style: normal;
font-weight: 100;
src: local('Ubuntu'), url('fonts/ubuntu-nerdfont.ttf');
}
:root {
--card-size: 160px;
@@ -72,7 +79,7 @@
--sd-tooltip-text-color: var(--sd-input-background-color);
--sd-body-font: 'IBM Plex Mono', monospace;
--sd-text-font: 'IBM Plex Mono', monospace;
--sd-button-font: 'NotoSans', sans-serif;
--sd-button-font: 'Ubuntu', sans-serif;
--sd-image-fit: scale-down;
--sd-panel-min-width: 256px;
--sd-grid-image-size: 150px;
@@ -289,12 +296,12 @@ input::-webkit-outer-spin-button, input::-webkit-inner-spin-button {
.gradio-dropdown .token {
overflow-x: hidden;
padding: var(--spacing-xs) !important;
font-family: 'NotoSans', var(--font);
font-family: 'Ubuntu', var(--font);
}
.gradio-dropdown .wrap input,
.gradio-dropdown input {
font-family: 'NotoSans', var(--font);
font-family: 'Ubuntu', var(--font);
}
.gradio-html {
+49 -20
View File
@@ -10051,6 +10051,7 @@ var ignoreElements = ["logMonitorData", "logWarnings", "logErrors", "tooltip-con
var ignoreElementsSet = new Set(ignoreElements);
var ignoreClasses = ["wrap"];
var mutationTimer;
var mutationTS;
var validMutations = [];
async function mutationCallback(mutations) {
if (mutations.length <= 0) return;
@@ -10064,7 +10065,10 @@ async function mutationCallback(mutations) {
if (validMutations.length < 1) return;
if (mutationTimer) clearTimeout(mutationTimer);
mutationTimer = setTimeout(async () => {
const ts = Date.now() - mutationTS;
if (!executedOnLoaded && ts > 1e3) log("onUiLoaded delayed", { ts, prompts: anyPromptExists() });
if (!executedOnLoaded && anyPromptExists()) {
log("onUiLoaded", ts);
executedOnLoaded = true;
executeCallbacks(uiLoadedCallbacks);
}
@@ -10083,6 +10087,7 @@ async function mutationCallback(mutations) {
}
document.addEventListener("DOMContentLoaded", () => {
log("DOMContentLoaded");
mutationTS = Date.now();
gradioObserver = new MutationObserver(mutationCallback);
gradioObserver.observe(gradioApp(), { childList: true, subtree: true, attributes: false });
});
@@ -10403,7 +10408,7 @@ function readCardTags(el2, tags) {
textarea.value = new_prompt;
updateInput(textarea);
};
if (tags.length === 0) return;
if (!tags || tags.length === 0) return;
const cardTags = tags.split("|");
if (!cardTags || cardTags.length === 0) return;
const tagsEl = el2.getElementsByClassName("tags")[0];
@@ -12556,7 +12561,7 @@ var ConnectionMonitorState = class _ConnectionMonitorState {
else return;
}
this.element.dataset.hint = this.toHTML();
this.element.style.backgroundColor = this.online ? "var(--sd-main-accent-color)" : "var(--color-error)";
this.element.style.background = this.online ? "var(--sd-main-accent-color)" : "var(--color-error)";
}
};
async function updateIndicator(online, data = {}, msg) {
@@ -13569,7 +13574,7 @@ Resolution: ${this.width} x ${this.height}`;
}
}
};
let ok2 = true;
let ok = true;
if (cachedData?.img) {
img.src = cachedData.img;
this.exif = cachedData.exif;
@@ -13582,7 +13587,7 @@ Resolution: ${this.width} x ${this.height}`;
try {
const json = await delayFetchThumb(this.src, this.#signal);
if (!json) {
ok2 = false;
ok = false;
pb.stats.failed = (pb.stats.failed || 0) + 1;
} else {
img.src = json.data;
@@ -13617,7 +13622,7 @@ Resolution: ${this.width} x ${this.height}`;
pb.stats.callback = (pb.stats.callback || 0) + Math.round(performance.now() - t0);
if (this.#signal.aborted) return;
galleryHashes.add(this.hash);
if (!ok2) return;
if (!ok) return;
img.onclick = () => {
setGallerySelectionByElement(this, { send: true });
};
@@ -14754,16 +14759,24 @@ var xnEngine = {
}
this.lora = new XnIndex(items);
}
const embData = await this.fetchJson("/embeddings");
if (embData && typeof embData === "object") {
const loaded = Array.isArray(embData.loaded) ? embData.loaded : [];
this.embed = new XnIndex(loaded.map((name) => ({ name: String(name) })));
if (window.opts.diffusers_enable_embed) {
const embData = await this.fetchJson("/embeddings");
if (embData && typeof embData === "object") {
const loaded = Array.isArray(embData.loaded) ? embData.loaded : [];
this.embed = new XnIndex(loaded.map((name) => ({ name: String(name) })));
}
} else {
this.embed = new XnIndex([]);
}
const wcData = await this.fetchJson("/wildcards");
if (Array.isArray(wcData)) {
this.wildcard = new XnIndex(
wcData.filter((w) => typeof w === "object" && w && "name" in w && typeof w.name === "string").map((w) => ({ name: w.name }))
);
if (window.opts.wildcards_enabled) {
const wcData = await this.fetchJson("/wildcards");
if (Array.isArray(wcData)) {
this.wildcard = new XnIndex(
wcData.filter((w) => typeof w === "object" && w && "name" in w && typeof w.name === "string").map((w) => ({ name: w.name }))
);
}
} else {
this.wildcard = new XnIndex([]);
}
log("autoComplete", {
xnLoaded: true,
@@ -16086,8 +16099,8 @@ async function createSplash() {
<div id="splashLog" class="splash-log" style="position: fixed; bottom: 0; text-align: left; padding: 8vh 8px 8px 8px; font-size: 12px; width: 100%; background: linear-gradient(0deg, darkslategray, transparent); opacity: 50%;"></div>
</div>`;
document.body.insertAdjacentHTML("beforeend", splash);
const ok2 = await preloadImages();
if (!ok2) {
const ok = await preloadImages();
if (!ok) {
removeSplash();
return;
}
@@ -16106,6 +16119,15 @@ async function createSplash() {
if (motdEl) motdEl.innerHTML = clean;
}).catch((err) => error(`getMOTD: ${err}`));
log("loadGradioUi");
const splashMonitor = setInterval(() => {
const splashVisible = !!document.getElementById("splash");
if (splashVisible) {
log("splashVisible", { visible: true, elapsed: Math.round(performance.now() - appStartTime) });
} else {
log("splashVisible", { visible: false, elapsed: Math.round(performance.now() - appStartTime) });
clearInterval(splashMonitor);
}
}, 5e3);
}
window.onload = createSplash;
@@ -16124,23 +16146,27 @@ function addLegacyNotice() {
window.api = "/sdapi/v1";
window.subpath = "";
var startupPromises = [];
var ok = false;
var optsReady = false;
var initialized = false;
async function waitForOpts() {
const t0 = performance.now();
let t1 = performance.now();
while (true) {
if (t1 - t0 > 12e4) {
if (t1 - t0 > 6e4) {
log("waitForOpts timeout");
break;
}
if (window.opts && Object.keys(window.opts).length > 0) {
ok = window.opts.theme_type === "Modern" ? "uiux_separator_appearance" in window.opts : true;
if (ok) {
optsReady = window.opts.theme_type === "Modern" ? "uiux_separator_appearance" in window.opts : true;
if (optsReady) {
log("waitForOpts", Math.round(t1 - t0));
timer("waitForOpts", t1 - t0);
break;
}
}
if (t1 - t0 > 15e3) {
log("waitForOpts delayed", Math.round(t1 - t0));
}
await sleep(100);
t1 = performance.now();
}
@@ -16159,6 +16185,8 @@ async function updateSubpath() {
log("API", { url: window.api });
}
async function initStartup() {
if (initialized) return;
initialized = true;
const t0 = performance.now();
log("initGradio", Math.round(t0 - appStartTime));
timer("initGradio", t0 - appStartTime);
@@ -16202,6 +16230,7 @@ async function initStartup() {
}
onUiLoaded(initStartup);
onUiReady(() => log("uiReady"));
window.initStartup = initStartup;
// ui/extensions.ts
function extensions_apply(_extensionsDisabledList, _extensionsUpdateList, disableAll) {
+3 -3
View File
File diff suppressed because one or more lines are too long
+1 -1
View File
@@ -103,7 +103,7 @@ function readCardTags(el, tags) {
updateInput(textarea);
};
if (tags.length === 0) return;
if (!tags || tags.length === 0) return;
const cardTags = tags.split('|');
if (!cardTags || cardTags.length === 0) return;
const tagsEl = el.getElementsByClassName('tags')[0];
+1
View File
@@ -325,6 +325,7 @@ class SimpleProgressBar {
}
update(loaded, max) {
// log('galleryUpdate', { loaded, max });
this.#progress.style.width = `${Math.floor((loaded / max) * 100)}%`;
this.#text.textContent = `${loaded}/${max}`;
if (!this.#visible) {
+1
View File
@@ -23,6 +23,7 @@ declare global {
// state objects
api: string; // ui/startup.ts
subpath: string; // ui/startup.ts
initStartup?: () => void; // ui/startup.ts
opts: Record<string, any>; // ui/ui.ts
localization?: Record<string, any>; // ui/ui.ts
titles?: Record<string, any>; // ui/ui.ts
+3
View File
@@ -34,6 +34,9 @@ function forceLogin() {
document.body.appendChild(form);
const status = form.querySelector('#loginStatus');
if (!status) {
console.error('forceLogin', 'loginStatus element not found');
}
form.addEventListener('submit', (event) => {
event.preventDefault();
+10
View File
@@ -112,6 +112,16 @@ async function createSplash() {
.catch((err) => error(`getMOTD: ${err}`));
log('loadGradioUi');
const splashMonitor = setInterval(() => {
const splashVisible = !!document.getElementById('splash');
if (splashVisible) {
log('splashVisible', { visible: true, elapsed: Math.round(performance.now() - appStartTime) });
} else {
log('splashVisible', { visible: false, elapsed: Math.round(performance.now() - appStartTime) });
clearInterval(splashMonitor);
}
}, 5000);
}
window.onload = createSplash;
+1 -1
View File
@@ -65,7 +65,7 @@ export class ConnectionMonitorState {
else return;
}
this.element.dataset.hint = this.toHTML();
this.element.style.backgroundColor = this.online ? 'var(--sd-main-accent-color)' : 'var(--color-error)';
this.element.style.background = this.online ? 'var(--sd-main-accent-color)' : 'var(--color-error)';
}
}
+6 -1
View File
@@ -139,6 +139,7 @@ const ignoreElementsSet = new Set(ignoreElements);
const ignoreClasses = ['wrap'];
let mutationTimer: ReturnType<typeof setTimeout> | undefined;
let mutationTS: number | undefined;
let validMutations = [];
async function mutationCallback(mutations) {
@@ -152,9 +153,12 @@ async function mutationCallback(mutations) {
}
if (validMutations.length < 1) return;
if (mutationTimer) clearTimeout(mutationTimer);
if (mutationTimer) clearTimeout(mutationTimer); // bounce
mutationTimer = setTimeout(async () => {
const ts = Date.now() - mutationTS;
if (!executedOnLoaded && (ts > 1000)) log('onUiLoaded delayed', { ts, prompts: anyPromptExists() });
if (!executedOnLoaded && anyPromptExists()) { // execute once
log('onUiLoaded', ts);
executedOnLoaded = true;
executeCallbacks(uiLoadedCallbacks);
}
@@ -174,6 +178,7 @@ async function mutationCallback(mutations) {
document.addEventListener('DOMContentLoaded', () => {
log('DOMContentLoaded');
mutationTS = Date.now();
gradioObserver = new MutationObserver(mutationCallback);
gradioObserver.observe(gradioApp(), { childList: true, subtree: true, attributes: false });
});
+13 -5
View File
@@ -27,25 +27,29 @@ window.api = '/sdapi/v1';
window.subpath = '';
const startupPromises: Promise<unknown>[] = [];
let ok = false;
let optsReady = false;
let initialized = false;
async function waitForOpts() {
// make sure all of the ui is ready and options are loaded
const t0 = performance.now();
let t1 = performance.now();
while (true) {
if (t1 - t0 > 120000) {
if (t1 - t0 > 60000) {
log('waitForOpts timeout');
break;
}
if (window.opts && Object.keys(window.opts).length > 0) {
ok = window.opts.theme_type === 'Modern' ? 'uiux_separator_appearance' in window.opts : true;
if (ok) {
optsReady = (window.opts.theme_type === 'Modern') ? 'uiux_separator_appearance' in window.opts : true;
if (optsReady) {
log('waitForOpts', Math.round(t1 - t0));
timer('waitForOpts', t1 - t0);
break;
}
}
if (t1 - t0 > 15000) {
log('waitForOpts delayed', Math.round(t1 - t0));
}
await sleep(100);
t1 = performance.now();
}
@@ -66,7 +70,9 @@ async function updateSubpath() {
log('API', { url: window.api });
}
async function initStartup() {
export async function initStartup() {
if (initialized) return;
initialized = true;
const t0 = performance.now();
log('initGradio', Math.round(t0 - appStartTime));
timer('initGradio', t0 - appStartTime);
@@ -126,6 +132,8 @@ async function initStartup() {
onUiLoaded(initStartup);
onUiReady(() => log('uiReady'));
window.initStartup = initStartup;
// onAfterUiUpdate(() => log('evt onAfterUiUpdate'));
// onUiLoaded(() => log('evt onUiLoaded'));
// onOptionsChanged(() => log('evt onOptionsChanged'));