mirror of
https://github.com/vladmandic/automatic
synced 2026-09-19 09:14:35 +02:00
fix gallery, update js logging, add en caching
This commit is contained in:
+6
-1
@@ -32,12 +32,15 @@
|
||||
"no-useless-escape":"off",
|
||||
"object-curly-newline":"off",
|
||||
"prefer-rest-params":"off",
|
||||
"prefer-destructuring":"off",
|
||||
"radix":"off"
|
||||
},
|
||||
"globals": {
|
||||
// asssets
|
||||
"panzoom": "readonly",
|
||||
//script.js
|
||||
"log": "readonly",
|
||||
"debug": "readonly",
|
||||
"gradioApp": "readonly",
|
||||
"executeCallbacks": "readonly",
|
||||
"onAfterUiUpdate": "readonly",
|
||||
@@ -65,7 +68,9 @@
|
||||
"create_submit_args": "readonly",
|
||||
"restart_reload": "readonly",
|
||||
"updateInput": "readonly",
|
||||
//extraNetworks.js
|
||||
// settings.js
|
||||
"register_drag_drop": "readonly",
|
||||
//extraNetworks.js
|
||||
"requestGet": "readonly",
|
||||
"popup": "readonly",
|
||||
// from python
|
||||
|
||||
+5
-2
@@ -1,10 +1,9 @@
|
||||
# Change Log for SD.Next
|
||||
|
||||
## Update for 2023-08-26
|
||||
## Update for 2023-08-29
|
||||
|
||||
- general:
|
||||
- all system and image paths are now relative by default
|
||||
- fix extra networks previews
|
||||
- add settings validation when performing load/save
|
||||
- settings tab in ui now shows settings that are changed from default values
|
||||
- settings tab switch to compact view
|
||||
@@ -20,6 +19,10 @@
|
||||
enable with `--use-openvino`
|
||||
thanks @disty0
|
||||
- add model **precompile** option (when model compile is enbled)
|
||||
- **extra network** folder info caching
|
||||
results in much faster startup when you have large number of extra networks
|
||||
- fix extra networks previews
|
||||
- fix gradio gallery
|
||||
|
||||
## Update for 2023-08-20
|
||||
|
||||
|
||||
@@ -119,7 +119,6 @@ Below is partial list of all available parameters, run `webui --help` for the fu
|
||||
|
||||
SD.Next comes with several extensions pre-installed:
|
||||
|
||||
- [Dynamic Thresholding](https://github.com/mcmonkeyprojects/sd-dynamic-thresholding)
|
||||
- [ControlNet](https://github.com/Mikubill/sd-webui-controlnet)
|
||||
- [Agent Scheduler](https://github.com/ArtVentureX/sd-webui-agent-scheduler)
|
||||
- [Multi-Diffusion Tiled Diffusion and VAE](https://github.com/pkuliyi2015/multidiffusion-upscaler-for-automatic1111)
|
||||
|
||||
@@ -103,7 +103,6 @@ svg.feather.feather-image, .feather .feather-image { display: none }
|
||||
#txt2img_cfg_scale { min-width: 200px; }
|
||||
#txt2img_checkboxes, #img2img_checkboxes { background-color: transparent; }
|
||||
#txt2img_checkboxes, #img2img_checkboxes { margin-bottom: 0.2em; }
|
||||
#txt2img_gallery, #img2img_gallery, #extras_gallery { padding: 0; margin: 0; object-fit: contain; box-shadow: none; min-height: 0; }
|
||||
#txt2img_actions_column, #img2img_actions_column { flex-flow: wrap; justify-content: space-between; }
|
||||
#txt2img_enqueue_wrapper, #img2img_enqueue_wrapper { min-width: unset; width: 48%; }
|
||||
#txt2img_generate_box, #img2img_generate_box { min-width: unset; width: 48%; }
|
||||
|
||||
@@ -62,9 +62,9 @@ const contextMenuInit = () => {
|
||||
});
|
||||
}
|
||||
|
||||
function addContextMenuEventListener() {
|
||||
async function addContextMenuEventListener() {
|
||||
if (eventListenerApplied) return;
|
||||
console.log('initContextMenu');
|
||||
log('initContextMenu');
|
||||
gradioApp().addEventListener('click', (e) => {
|
||||
if (!e.isTrusted) return;
|
||||
const oldMenu = gradioApp().querySelector('#context-menu');
|
||||
|
||||
@@ -6,7 +6,7 @@ function extensions_apply(extensions_disabled_list, extensions_update_list, disa
|
||||
if (x.name.startsWith('update_') && x.checked) update.push(x.name.substring(7));
|
||||
});
|
||||
restart_reload();
|
||||
console.log('Extensions apply:', { disable, update });
|
||||
log('Extensions apply:', { disable, update });
|
||||
return [JSON.stringify(disable), JSON.stringify(update), disable_all];
|
||||
}
|
||||
|
||||
@@ -16,7 +16,7 @@ function extensions_check(info, extensions_disabled_list, search_text, sort_colu
|
||||
if (x.name.startsWith('enable_') && !x.checked) disable.push(x.name.substring(7));
|
||||
});
|
||||
const id = randomId();
|
||||
console.log('Extensions check:', { disable });
|
||||
log('Extensions check:', { disable });
|
||||
return [id, JSON.stringify(disable), search_text, sort_column];
|
||||
}
|
||||
|
||||
@@ -27,7 +27,7 @@ function install_extension(button, url) {
|
||||
const textarea = gradioApp().querySelector('#extension_to_install textarea');
|
||||
textarea.value = url;
|
||||
updateInput(textarea);
|
||||
console.log('Extension install:', { url });
|
||||
log('Extension install:', { url });
|
||||
gradioApp().querySelector('#install_extension_button').click();
|
||||
}
|
||||
|
||||
@@ -38,7 +38,7 @@ function uninstall_extension(button, url) {
|
||||
const textarea = gradioApp().querySelector('#extension_to_install textarea');
|
||||
textarea.value = url;
|
||||
updateInput(textarea);
|
||||
console.log('Extension uninstall:', { url });
|
||||
log('Extension uninstall:', { url });
|
||||
gradioApp().querySelector('#uninstall_extension_button').click();
|
||||
}
|
||||
|
||||
@@ -48,6 +48,6 @@ function update_extension(button, url) {
|
||||
const textarea = gradioApp().querySelector('#extension_to_install textarea');
|
||||
textarea.value = url;
|
||||
updateInput(textarea);
|
||||
console.log('Extension update:', { url });
|
||||
log('Extension update:', { url });
|
||||
gradioApp().querySelector('#update_extension_button').click();
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@ function attachGalleryListeners(tab_name) {
|
||||
const gallery = gradioApp().querySelector(`#${tab_name}_gallery`);
|
||||
if (!gallery) return null;
|
||||
gallery.addEventListener('click', () => setTimeout(() => {
|
||||
console.log('galleryItemSelected:', tab_name);
|
||||
log('galleryItemSelected:', tab_name);
|
||||
gradioApp().getElementById(`${tab_name}_generation_info_button`)?.click();
|
||||
}, 500));
|
||||
gallery?.addEventListener('keydown', (e) => {
|
||||
@@ -36,7 +36,7 @@ function initiGenerationParams() {
|
||||
if (txt2img_gallery && img2img_gallery) generationParamsInitialized = true;
|
||||
else return;
|
||||
modalObserver.observe(modal, { attributes: true, attributeFilter: ['style'] });
|
||||
console.log('initGenerationParams');
|
||||
log('initGenerationParams');
|
||||
}
|
||||
|
||||
onAfterUiUpdate(initiGenerationParams);
|
||||
|
||||
@@ -3,7 +3,7 @@ let dragDropInitialized = false;
|
||||
async function initDragDrop() {
|
||||
if (dragDropInitialized) return;
|
||||
dragDropInitialized = true;
|
||||
console.log('initDragDrop');
|
||||
log('initDragDrop');
|
||||
window.addEventListener('drop', (e) => {
|
||||
const target = e.composedPath()[0];
|
||||
if (!target.placeholder) return;
|
||||
@@ -18,7 +18,7 @@ async function initDragDrop() {
|
||||
if (fileInput) {
|
||||
fileInput.files = files;
|
||||
fileInput.dispatchEvent(new Event('change'));
|
||||
console.log('dropEvent');
|
||||
log('dropEvent');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -134,7 +134,7 @@ function galleryClickEventHandler(event) {
|
||||
}
|
||||
}
|
||||
|
||||
function initImageViewer() {
|
||||
async function initImageViewer() {
|
||||
// Each tab has its own gradio-gallery
|
||||
const galleryPreviews = gradioApp().querySelectorAll('.gradio-gallery > div.preview');
|
||||
if (galleryPreviews.length > 0) {
|
||||
@@ -241,7 +241,7 @@ function initImageViewer() {
|
||||
modalControls.appendChild(modalClose);
|
||||
|
||||
gradioApp().appendChild(modal);
|
||||
console.log('initImageViewer');
|
||||
log('initImageViewer');
|
||||
}
|
||||
|
||||
onAfterUiUpdate(initImageViewer);
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
const appStartTime = performance.now();
|
||||
|
||||
async function preloadImages() {
|
||||
const dark = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches;
|
||||
const imagePromises = [];
|
||||
@@ -24,7 +26,7 @@ async function preloadImages() {
|
||||
|
||||
async function createSplash() {
|
||||
const dark = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches;
|
||||
console.log('createSplash', { theme: dark ? 'dark' : 'light' });
|
||||
log('createSplash', { theme: dark ? 'dark' : 'light' });
|
||||
const num = Math.floor(11 * Math.random());
|
||||
const splash = `
|
||||
<div id="splash" class="splash" style="background: ${dark ? 'black' : 'white'}">
|
||||
@@ -38,8 +40,8 @@ async function createSplash() {
|
||||
async function removeSplash() {
|
||||
const splash = document.getElementById('splash');
|
||||
if (splash) splash.remove();
|
||||
console.log('removeSplash');
|
||||
console.log('startupTime', Math.round(performance.now() - appStartTime) / 1000);
|
||||
log('removeSplash');
|
||||
log('startupTime', Math.round(performance.now() - appStartTime) / 1000);
|
||||
}
|
||||
|
||||
window.onload = createSplash;
|
||||
|
||||
@@ -52,7 +52,7 @@ async function initLogMonitor() {
|
||||
`;
|
||||
el.style.display = 'none';
|
||||
logMonitor();
|
||||
console.log('initLogMonitor');
|
||||
log('initLogMonitor');
|
||||
}
|
||||
|
||||
onAfterUiUpdate(initLogMonitor);
|
||||
|
||||
@@ -26,7 +26,7 @@ function initNotifications() {
|
||||
parent.focus();
|
||||
this.close();
|
||||
};
|
||||
console.log('sendNotification');
|
||||
log('sendNotification');
|
||||
}
|
||||
|
||||
onAfterUiUpdate(initNotifications);
|
||||
|
||||
@@ -1017,7 +1017,7 @@ function autoRun() {
|
||||
return;
|
||||
}
|
||||
var options = collectOptions(panzoomScript);
|
||||
console.log(options);
|
||||
log(options);
|
||||
window[globalName] = createPanZoom(el, options);
|
||||
}
|
||||
|
||||
|
||||
@@ -103,7 +103,7 @@ function requestProgress(id_task, progressEl, galleryEl, atEnd = null, onProgres
|
||||
};
|
||||
|
||||
const done = () => {
|
||||
console.debug('taskEnd:', id_task);
|
||||
debug('taskEnd:', id_task);
|
||||
localStorage.removeItem('task');
|
||||
setProgress();
|
||||
if (parentGallery && livePreview) parentGallery.removeChild(livePreview);
|
||||
|
||||
+11
-1
@@ -1,4 +1,14 @@
|
||||
const appStartTime = performance.now();
|
||||
const log = (...msg) => {
|
||||
const dt = new Date();
|
||||
const ts = `${dt.getHours().toString().padStart(2, '0')}:${dt.getMinutes().toString().padStart(2, '0')}:${dt.getSeconds().toString().padStart(2, '0')}.${dt.getMilliseconds().toString().padStart(3, '0')}`;
|
||||
console.log(ts, ...msg); // eslint-disable-line no-console
|
||||
};
|
||||
|
||||
const debug = (...msg) => {
|
||||
const dt = new Date();
|
||||
const ts = `${dt.getHours().toString().padStart(2, '0')}:${dt.getMinutes().toString().padStart(2, '0')}:${dt.getSeconds().toString().padStart(2, '0')}.${dt.getMilliseconds().toString().padStart(3, '0')}`;
|
||||
console.debug(ts, ...msg); // eslint-disable-line no-console
|
||||
};
|
||||
|
||||
function gradioApp() {
|
||||
const elems = document.getElementsByTagName('gradio-app');
|
||||
|
||||
@@ -31,19 +31,19 @@ async function tooltipHide(e) {
|
||||
async function validateHints(elements, data) {
|
||||
let original = elements.map((e) => e.textContent.toLowerCase().trim()).sort((a, b) => a > b);
|
||||
original = [...new Set(original)];
|
||||
console.log('all hints:', original);
|
||||
console.log('hints-differences', { elements: original.length, hints: data.length });
|
||||
log('all hints:', original);
|
||||
log('hints-differences', { elements: original.length, hints: data.length });
|
||||
const current = data.map((e) => e.label.toLowerCase().trim()).sort((a, b) => a > b);
|
||||
let missing = [];
|
||||
for (let i = 0; i < original.length; i++) {
|
||||
if (!current.includes(original[i])) missing.push(original[i]);
|
||||
}
|
||||
console.log('missing in locale:', missing);
|
||||
log('missing in locale:', missing);
|
||||
missing = [];
|
||||
for (let i = 0; i < current.length; i++) {
|
||||
if (!original.includes(current[i])) missing.push(current[i]);
|
||||
}
|
||||
console.log('in locale but not ui:', missing);
|
||||
log('in locale but not ui:', missing);
|
||||
}
|
||||
|
||||
async function setHints() {
|
||||
@@ -84,7 +84,7 @@ async function setHints() {
|
||||
}
|
||||
}
|
||||
const t1 = performance.now();
|
||||
console.log('setHints', { type: localeData.type, elements: elements.length, localized, hints, data: localeData.data.length, time: t1 - t0 });
|
||||
log('setHints', { type: localeData.type, elements: elements.length, localized, hints, data: localeData.data.length, time: t1 - t0 });
|
||||
removeSplash();
|
||||
// validateHints(elements, localeData.data)
|
||||
}
|
||||
|
||||
+16
-20
@@ -1,10 +1,9 @@
|
||||
let opts_metadata = {};
|
||||
const opts_tabs = {};
|
||||
|
||||
const monitoredOpts = [
|
||||
{ sd_model_checkpoint: null },
|
||||
{
|
||||
sd_backend: () => {
|
||||
gradioApp().getElementById('refresh_sd_model_checkpoint')?.click();
|
||||
},
|
||||
},
|
||||
{ sd_backend: () => gradioApp().getElementById('refresh_sd_model_checkpoint')?.click() },
|
||||
];
|
||||
|
||||
function updateOpts(json_string) {
|
||||
@@ -13,7 +12,7 @@ function updateOpts(json_string) {
|
||||
const key = Object.keys(op)[0];
|
||||
const callback = op[key];
|
||||
if (opts[key] && opts[key] !== settings_data.values[key]) {
|
||||
console.log('updateOpts', key, opts[key], settings_data.values[key]);
|
||||
log('updateOpts', key, opts[key], settings_data.values[key]);
|
||||
if (callback) callback();
|
||||
}
|
||||
}
|
||||
@@ -31,9 +30,7 @@ function updateOpts(json_string) {
|
||||
function showAllSettings() {
|
||||
// Try to ensure that the show all settings tab is opened by clicking on its tab button
|
||||
const tab_dirty_indicator = gradioApp().getElementById('modification_indicator_show_all_pages');
|
||||
if (tab_dirty_indicator && tab_dirty_indicator.nextSibling) {
|
||||
tab_dirty_indicator.nextSibling.click();
|
||||
}
|
||||
if (tab_dirty_indicator && tab_dirty_indicator.nextSibling) tab_dirty_indicator.nextSibling.click();
|
||||
gradioApp().querySelectorAll('#settings > .tab-content > .tabitem').forEach((elem) => {
|
||||
if (elem.id === 'settings_tab_licenses' || elem.id === 'settings_show_all_pages') return;
|
||||
elem.style.display = 'block';
|
||||
@@ -42,17 +39,16 @@ function showAllSettings() {
|
||||
|
||||
function markIfModified(setting_name, value) {
|
||||
const elem = gradioApp().getElementById(`modification_indicator_${setting_name}`);
|
||||
if (elem == null) return;
|
||||
// Use JSON.stringify to compare nested objects (e.g. arrays for checkbox-groups)
|
||||
const previous_value_json = JSON.stringify(opts[setting_name]);
|
||||
const changed_value = JSON.stringify(value) !== previous_value_json;
|
||||
if (changed_value) elem.title = `click to revert to previous value: ${previous_value_json}`;
|
||||
|
||||
const is_unsaved = opts_metadata[setting_name].is_stored;
|
||||
if (is_unsaved) elem.title = 'custom value';
|
||||
elem.disabled = !(is_unsaved || changed_value);
|
||||
if (!elem) return;
|
||||
const previous_value = JSON.stringify(opts[setting_name]);
|
||||
const current_value = JSON.stringify(value);
|
||||
const changed_value = previous_value !== current_value;
|
||||
if (changed_value) elem.title = `click to revert to previous value: ${previous_value}`;
|
||||
const is_stored = opts_metadata[setting_name].is_stored;
|
||||
if (is_stored) elem.title = 'custom value';
|
||||
elem.disabled = !changed_value && !is_stored;
|
||||
elem.classList.toggle('changed', changed_value);
|
||||
elem.classList.toggle('unsaved', is_unsaved);
|
||||
elem.classList.toggle('saved', is_stored);
|
||||
|
||||
const { tab_name } = opts_metadata[setting_name];
|
||||
if (!opts_tabs[tab_name].changed) opts_tabs[tab_name].changed = new Set();
|
||||
@@ -67,7 +63,7 @@ function markIfModified(setting_name, value) {
|
||||
tab_nav_indicator.disabled = (changed_items.size === 0) && (unsaved.size === 0);
|
||||
tab_nav_indicator.title = '';
|
||||
tab_nav_indicator.classList.toggle('changed', changed_items.size > 0);
|
||||
tab_nav_indicator.classList.toggle('unsaved', saved.size > 0);
|
||||
tab_nav_indicator.classList.toggle('saved', saved.size > 0);
|
||||
if (changed_items.size > 0) tab_nav_indicator.title += `click to reset ${changed_items.size} unapplied changes in this tab\n`;
|
||||
if (saved.size > 0) tab_nav_indicator.title += `${saved.size} custom values\n${unsaved.size} default values}`;
|
||||
}
|
||||
|
||||
@@ -67,8 +67,6 @@ button.custom-button{
|
||||
.performance { font-size: 0.85em; color: #444; }
|
||||
.performance p { display: inline-block; color: var(--body-text-color-subdued) !important }
|
||||
.performance .time { margin-right: 0; }
|
||||
@media screen and (min-width: 2500px) { #txt2img_gallery, #img2img_gallery { min-height: 768px; } }
|
||||
#txt2img_gallery img, #img2img_gallery img, #extras_gallery img { object-fit: scale-down; width: -webkit-fill-available !important; }
|
||||
#txt2img_footer, #img2img_footer, #extras_footer { height: fit-content; }
|
||||
#txt2img_footer, #img2img_footer { height: fit-content; display: none; }
|
||||
#txt2img_generate_box, #img2img_generate_box { gap: 0.5em; flex-wrap: wrap-reverse; height: fit-content; }
|
||||
@@ -133,7 +131,7 @@ div#extras_scale_to_tab div.form{ flex-direction: row; }
|
||||
#settings .dirtyable.hidden { display: none; }
|
||||
#settings .modification-indicator { height: 1.2em; border-radius: 1em !important; padding: 0; width: 0; margin-right: 0.5em; }
|
||||
#settings .modification-indicator:disabled { visibility: hidden; }
|
||||
#settings .modification-indicator.unsaved { background: var(--color-accent-soft); width: 4px; }
|
||||
#settings .modification-indicator.saved { background: var(--color-accent-soft); width: 4px; }
|
||||
#settings .modification-indicator.changed { background: var(--color-accent); width: 4px; }
|
||||
#settings .modification-indicator.changed.unsaved { background-image: linear-gradient(var(--color-accent) 25%, var(--color-accent-soft) 75%); width: 4px; }
|
||||
#settings_result { margin: 0 1.2em; }
|
||||
|
||||
+15
-18
@@ -7,8 +7,6 @@ let img2img_textarea;
|
||||
const wait_time = 800;
|
||||
const token_timeouts = {};
|
||||
let uiLoaded = false;
|
||||
let opts_metadata = {};
|
||||
const opts_tabs = {};
|
||||
|
||||
function rememberGallerySelection(name) {
|
||||
// dummy
|
||||
@@ -27,7 +25,7 @@ function update_token_counter(button_id) {
|
||||
function clip_gallery_urls(gallery) {
|
||||
const files = gallery.map((v) => v.data);
|
||||
navigator.clipboard.writeText(JSON.stringify(files)).then(
|
||||
() => console.log('clipboard:', files),
|
||||
() => log('clipboard:', files),
|
||||
(err) => console.error('clipboard:', files, err),
|
||||
);
|
||||
}
|
||||
@@ -146,7 +144,7 @@ function clearGallery(tabname) {
|
||||
}
|
||||
|
||||
function submit(...args) {
|
||||
console.log('submitTxt');
|
||||
log('submitTxt');
|
||||
clearGallery('txt2img');
|
||||
const id = randomId();
|
||||
requestProgress(id, null, gradioApp().getElementById('txt2img_gallery'));
|
||||
@@ -156,7 +154,7 @@ function submit(...args) {
|
||||
}
|
||||
|
||||
function submit_img2img(...args) {
|
||||
console.log('submitImg');
|
||||
log('submitImg');
|
||||
clearGallery('img2img');
|
||||
const id = randomId();
|
||||
requestProgress(id, null, gradioApp().getElementById('img2img_gallery'));
|
||||
@@ -167,7 +165,7 @@ function submit_img2img(...args) {
|
||||
}
|
||||
|
||||
function submit_postprocessing(...args) {
|
||||
console.log('SubmitExtras');
|
||||
log('SubmitExtras');
|
||||
clearGallery('extras');
|
||||
return args;
|
||||
}
|
||||
@@ -227,7 +225,7 @@ function register_drag_drop() {
|
||||
evt.preventDefault();
|
||||
evt.dataTransfer.dropEffect = 'copy';
|
||||
for (const f of evt.dataTransfer.files) {
|
||||
console.log('QuickSettingsDrop', f);
|
||||
log('QuickSettingsDrop', f);
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -259,13 +257,13 @@ function sortUIElements() {
|
||||
|
||||
const scriptsImg = gradioApp().getElementById('scripts_alwayson_img2img').children;
|
||||
for (const el of Array.from(scriptsImg)) el.style.order = find(el, tabsOrder);
|
||||
console.log('sortUIElements');
|
||||
log('sortUIElements');
|
||||
}
|
||||
|
||||
onAfterUiUpdate(async () => {
|
||||
let promptsInitialized = false;
|
||||
|
||||
function registerTextarea(id, id_counter, id_button) {
|
||||
async function registerTextarea(id, id_counter, id_button) {
|
||||
const prompt = gradioApp().getElementById(id);
|
||||
if (!prompt) return;
|
||||
const counter = gradioApp().getElementById(id_counter);
|
||||
@@ -275,7 +273,7 @@ onAfterUiUpdate(async () => {
|
||||
prompt.parentElement.style.position = 'relative';
|
||||
promptTokecountUpdateFuncs[id] = () => { update_token_counter(id_button); };
|
||||
localTextarea.addEventListener('input', promptTokecountUpdateFuncs[id]);
|
||||
if (!promptsInitialized) console.log('initPrompts')
|
||||
if (!promptsInitialized) log('initPrompts');
|
||||
promptsInitialized = true;
|
||||
}
|
||||
|
||||
@@ -378,16 +376,15 @@ async function preview_theme() {
|
||||
}
|
||||
}
|
||||
|
||||
function reconnectUI() {
|
||||
async function reconnectUI() {
|
||||
const gallery = gradioApp().getElementById('txt2img_gallery');
|
||||
if (!gallery) return;
|
||||
const task_id = localStorage.getItem('task');
|
||||
const api_logo = Array.from(gradioApp().querySelectorAll('img')).filter((el) => el?.src?.endsWith('api-logo.svg'));
|
||||
if (api_logo.length > 0) api_logo[0].remove();
|
||||
|
||||
const gallery = gradioApp().getElementById('txt2img_gallery');
|
||||
const task_id = localStorage.getItem('task');
|
||||
if (!gallery) return;
|
||||
clearInterval(start_check); // eslint-disable-line no-use-before-define
|
||||
if (task_id) {
|
||||
console.debug('task check:', task_id);
|
||||
debug('task check:', task_id);
|
||||
requestProgress(task_id, null, gallery, null, null, true);
|
||||
}
|
||||
uiLoaded = true;
|
||||
@@ -411,7 +408,7 @@ function reconnectUI() {
|
||||
};
|
||||
const sd_model_observer = new MutationObserver(sd_model_callback);
|
||||
sd_model_observer.observe(sd_model, { attributes: true, childList: true, subtree: true });
|
||||
console.log('reconnectUI');
|
||||
log('reconnectUI');
|
||||
}
|
||||
|
||||
const start_check = setInterval(reconnectUI, 50);
|
||||
const start_check = setInterval(reconnectUI, 100);
|
||||
|
||||
+1
-8
@@ -551,9 +551,6 @@ def save_image(image, path, basename, seed=None, prompt=None, extension='jpg', i
|
||||
file_decoration = shared.opts.samples_filename_pattern
|
||||
else:
|
||||
file_decoration = "[seq]-[prompt_words]"
|
||||
# add_number = shared.opts.save_images_add_number or file_decoration == ''
|
||||
# if file_decoration != "" and add_number:
|
||||
# file_decoration = f"-{file_decoration}"
|
||||
file_decoration = namegen.apply(file_decoration) + suffix
|
||||
if shared.opts.save_images_add_number:
|
||||
if '[seq]' not in file_decoration:
|
||||
@@ -578,10 +575,7 @@ def save_image(image, path, basename, seed=None, prompt=None, extension='jpg', i
|
||||
params = script_callbacks.ImageSaveParams(image, p, fullfn, pnginfo)
|
||||
script_callbacks.before_image_saved_callback(params)
|
||||
exifinfo = params.pnginfo.get('UserComment', '')
|
||||
if len(exifinfo) > 0:
|
||||
exifinfo = exifinfo + ', ' + params.pnginfo.get(pnginfo_section_name, '')
|
||||
else:
|
||||
exifinfo = params.pnginfo.get(pnginfo_section_name, '')
|
||||
exifinfo = (exifinfo + ', ' if len(exifinfo) > 0 else '') + params.pnginfo.get(pnginfo_section_name, '')
|
||||
filename, extension = os.path.splitext(params.filename)
|
||||
if hasattr(os, 'statvfs'):
|
||||
max_name_len = os.statvfs(path).f_namemax
|
||||
@@ -591,7 +585,6 @@ def save_image(image, path, basename, seed=None, prompt=None, extension='jpg', i
|
||||
|
||||
save_queue.put((params.image, filename, extension, params, exifinfo, txt_fullfn)) # actual save is executed in a thread that polls data from queue
|
||||
save_queue.join()
|
||||
# atomically_save_image(params.image, filename, extension, params, exifinfo, txt_fullfn)
|
||||
|
||||
params.image.already_saved_as = params.filename
|
||||
script_callbacks.image_saved_callback(params)
|
||||
|
||||
@@ -498,7 +498,8 @@ def create_infotext(p: StableDiffusionProcessing, all_prompts, all_seeds, all_su
|
||||
generation_params.update(p.extra_generation_params)
|
||||
generation_params_text = ", ".join([k if k == v else f'{k}: {generation_parameters_copypaste.quote(v)}' for k, v in generation_params.items() if v is not None])
|
||||
negative_prompt_text = f"\nNegative prompt: {all_negative_prompts[index]}" if all_negative_prompts[index] else ""
|
||||
return f"{all_prompts[index]}{negative_prompt_text}\n{generation_params_text}".strip()
|
||||
infotext = f"{all_prompts[index]}{negative_prompt_text}\n{generation_params_text}".strip()
|
||||
return infotext
|
||||
|
||||
|
||||
"""
|
||||
@@ -776,19 +777,19 @@ def process_images_inner(p: StableDiffusionProcessing) -> Processed:
|
||||
p.ops.append('color')
|
||||
image = apply_color_correction(p.color_corrections[i], image)
|
||||
image = apply_overlay(image, p.paste_to, i, p.overlay_images)
|
||||
if shared.opts.samples_save and not p.do_not_save_samples:
|
||||
images.save_image(image, p.outpath_samples, "", p.seeds[i], p.prompts[i], shared.opts.samples_format, info=infotext(i), p=p)
|
||||
text = infotext(i)
|
||||
infotexts.append(text)
|
||||
image.info["parameters"] = text
|
||||
output_images.append(image)
|
||||
if shared.opts.samples_save and not p.do_not_save_samples:
|
||||
images.save_image(image, p.outpath_samples, "", p.seeds[i], p.prompts[i], shared.opts.samples_format, info=text, p=p)
|
||||
if hasattr(p, 'mask_for_overlay') and p.mask_for_overlay and any([shared.opts.save_mask, shared.opts.save_mask_composite, shared.opts.return_mask, shared.opts.return_mask_composite]):
|
||||
image_mask = p.mask_for_overlay.convert('RGB')
|
||||
image_mask_composite = Image.composite(image.convert('RGBA').convert('RGBa'), Image.new('RGBa', image.size), images.resize_image(3, p.mask_for_overlay, image.width, image.height).convert('L')).convert('RGBA')
|
||||
if shared.opts.save_mask:
|
||||
images.save_image(image_mask, p.outpath_samples, "", p.seeds[i], p.prompts[i], shared.opts.samples_format, info=infotext(i), p=p, suffix="-mask")
|
||||
images.save_image(image_mask, p.outpath_samples, "", p.seeds[i], p.prompts[i], shared.opts.samples_format, info=text, p=p, suffix="-mask")
|
||||
if shared.opts.save_mask_composite:
|
||||
images.save_image(image_mask_composite, p.outpath_samples, "", p.seeds[i], p.prompts[i], shared.opts.samples_format, info=infotext(i), p=p, suffix="-mask-composite")
|
||||
images.save_image(image_mask_composite, p.outpath_samples, "", p.seeds[i], p.prompts[i], shared.opts.samples_format, info=text, p=p, suffix="-mask-composite")
|
||||
if shared.opts.return_mask:
|
||||
output_images.append(image_mask)
|
||||
if shared.opts.return_mask_composite:
|
||||
|
||||
@@ -215,13 +215,13 @@ def model_hash(filename):
|
||||
try:
|
||||
with open(filename, "rb") as file:
|
||||
import hashlib
|
||||
t0 = time.time()
|
||||
# t0 = time.time()
|
||||
m = hashlib.sha256()
|
||||
file.seek(0x100000)
|
||||
m.update(file.read(0x10000))
|
||||
shorthash = m.hexdigest()[0:8]
|
||||
t1 = time.time()
|
||||
shared.log.debug(f'Calculating short hash: {filename} hash={shorthash} time={(t1-t0):.2f}')
|
||||
# t1 = time.time()
|
||||
# shared.log.debug(f'Calculating short hash: {filename} hash={shorthash} time={(t1-t0):.2f}')
|
||||
return shorthash
|
||||
except FileNotFoundError:
|
||||
return 'NOFILE'
|
||||
|
||||
+3
-3
@@ -280,7 +280,7 @@ def disable_extensions():
|
||||
else:
|
||||
opts.data['disabled_extensions'] = [x for x in opts.disabled_extensions if x != 'Lora']
|
||||
if backend == Backend.DIFFUSERS:
|
||||
for ext in ['sd-webui-controlnet', 'sd-dynamic-thresholding', 'multidiffusion-upscaler-for-automatic1111', 'a1111-sd-webui-lycoris']:
|
||||
for ext in ['sd-webui-controlnet', 'multidiffusion-upscaler-for-automatic1111', 'a1111-sd-webui-lycoris']:
|
||||
if ext not in opts.disabled_extensions:
|
||||
log.warning(f'Diffusers disabling uncompatible extension: {ext}')
|
||||
opts.data['disabled_extensions'].append(ext)
|
||||
@@ -385,7 +385,7 @@ options_templates.update(options_section(('cuda', "Compute Settings"), {
|
||||
"upcast_sampling": OptionInfo(True if sys.platform == "darwin" else False, "Enable upcast sampling"),
|
||||
"upcast_attn": OptionInfo(False, "Enable upcast cross attention layer"),
|
||||
"cuda_cast_unet": OptionInfo(False, "Use fixed UNet precision"),
|
||||
"disable_nan_check": OptionInfo(True, "Disable NaN check in produced images/latent spaces"),
|
||||
"disable_nan_check": OptionInfo(True, "Disable NaN check in produced images/latent spaces", gr.Checkbox, {"visible": False}),
|
||||
"rollback_vae": OptionInfo(False, "Attempt VAE roll back when produced NaN values (experimental)"),
|
||||
"opt_channelslast": OptionInfo(False, "Use channels last as torch memory format "),
|
||||
"cudnn_benchmark": OptionInfo(False, "Enable full-depth cuDNN benchmark feature"),
|
||||
@@ -399,7 +399,7 @@ options_templates.update(options_section(('cuda', "Compute Settings"), {
|
||||
"cuda_compile_verbose": OptionInfo(False, "Model compile verbose mode"),
|
||||
"cuda_compile_errors": OptionInfo(True, "Model compile suppress errors"),
|
||||
"ipex_optimize": OptionInfo(True if devices.backend == "ipex" else False, "Enable IPEX Optimize for Intel GPUs"),
|
||||
"directml_memory_provider": OptionInfo(default_memory_provider, '[DirectML] Memory stats provider', gr.Dropdown, lambda: {"choices": memory_providers}),
|
||||
"directml_memory_provider": OptionInfo(default_memory_provider, 'DirectML memory stats provider', gr.Dropdown, lambda: {"choices": memory_providers}),
|
||||
}))
|
||||
|
||||
options_templates.update(options_section(('diffusers', "Diffusers Settings"), {
|
||||
|
||||
@@ -82,8 +82,8 @@ def save_files(js_data, images, html_info, index):
|
||||
self.prompt = getattr(self, 'prompt', None) or getattr(self, 'Prompt', None)
|
||||
self.all_seeds = getattr(self, 'all_seeds', [self.seed])
|
||||
self.all_prompts = getattr(self, 'all_prompts', [self.prompt])
|
||||
self.infotext = html_info
|
||||
self.infotexts = getattr(self, 'infotexts', [html_info])
|
||||
self.infotext = self.infotexts[0] if len(self.infotexts) > 0 else html_info
|
||||
self.index_of_first_image = getattr(self, 'index_of_first_image', 0)
|
||||
try:
|
||||
data = json.loads(js_data)
|
||||
@@ -164,7 +164,8 @@ def create_output_panel(tabname, outdir):
|
||||
|
||||
with gr.Column(variant='panel', elem_id=f"{tabname}_results"):
|
||||
with gr.Group(elem_id=f"{tabname}_gallery_container"):
|
||||
result_gallery = gr.Gallery(value=[], label='Output', show_label=False, elem_id=f"{tabname}_gallery", elem_classes="logo").style(preview=False, container=False, columns=[1,2,3,4,5,6]) # <576px, <768px, <992px, <1200px, <1400px, >1400px
|
||||
# columns are for <576px, <768px, <992px, <1200px, <1400px, >1400px
|
||||
result_gallery = gr.Gallery(value=[], label='Output', show_label=False, show_download_button=True, elem_id=f"{tabname}_gallery", container=False, preview=True, columns=[1,2,3,4,5,6], object_fit='scale-down')
|
||||
|
||||
with gr.Column(elem_id=f"{tabname}_footer", elem_classes="gallery_footer"):
|
||||
with gr.Row(elem_id=f"image_buttons_{tabname}", elem_classes="image-buttons"):
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import re
|
||||
import time
|
||||
import json
|
||||
import html
|
||||
import os.path
|
||||
@@ -14,10 +15,23 @@ from modules.ui_components import ToolButton
|
||||
|
||||
extra_pages = []
|
||||
allowed_dirs = set()
|
||||
dir_cache = {}
|
||||
|
||||
refresh_symbol = '\U0001f504' # 🔄
|
||||
close_symbol = '\U0000274C' # ❌
|
||||
|
||||
|
||||
def listdir(path):
|
||||
if path in dir_cache and os.path.getmtime(path) == dir_cache[path][0]:
|
||||
return dir_cache[path][1]
|
||||
else:
|
||||
dir_cache[path] = (
|
||||
os.path.getmtime(path),
|
||||
[os.path.join(path, f) for f in os.listdir(path)]
|
||||
)
|
||||
return dir_cache[path][1]
|
||||
|
||||
|
||||
def register_page(page):
|
||||
"""registers extra networks page for the UI; recommend doing it in on_before_ui() callback for extensions"""
|
||||
extra_pages.append(page)
|
||||
@@ -125,7 +139,7 @@ class ExtraNetworksPage:
|
||||
return ""
|
||||
|
||||
def is_empty(self, folder):
|
||||
for f in os.listdir(folder):
|
||||
for f in listdir(folder):
|
||||
_fn, ext = os.path.splitext(f)
|
||||
if ext.lower() in ['.ckpt', '.safetensors', '.pt'] or os.path.isdir(os.path.join(folder, f)):
|
||||
return False
|
||||
@@ -154,6 +168,7 @@ class ExtraNetworksPage:
|
||||
self.missing_thumbs.clear()
|
||||
|
||||
def create_html(self, tabname, skip = False):
|
||||
t0 = time.time()
|
||||
self_name_id = self.name.replace(" ", "_")
|
||||
if skip:
|
||||
return f"<div id='{tabname}_{self_name_id}_subdirs' class='extra-network-subdirs'></div><div id='{tabname}_{self_name_id}_cards' class='extra-network-cards'>Extra network page not ready<br>Click refresh to try again</div>"
|
||||
@@ -199,7 +214,8 @@ class ExtraNetworksPage:
|
||||
res = f"<div id='{tabname}_{self_name_id}_subdirs' class='extra-network-subdirs'>{subdirs_html}</div><div id='{tabname}_{self_name_id}_cards' class='extra-network-cards'>{self.html}</div>"
|
||||
else:
|
||||
return ''
|
||||
shared.log.debug(f'Extra networks: {self.name} items={len(self.items)} subdirs={len(subdirs)}')
|
||||
t1 = time.time()
|
||||
shared.log.debug(f'Extra networks: {self.name} items={len(self.items)} subdirs={len(subdirs)} time={round(t1-t0, 2)}')
|
||||
threading.Thread(target=self.create_thumb).start()
|
||||
return res
|
||||
except Exception as e:
|
||||
@@ -240,7 +256,6 @@ class ExtraNetworksPage:
|
||||
args['title'] += f'\nAlias: {item["alias"]}'
|
||||
if item.get("tags", None) is not None:
|
||||
args['title'] += f'\nTags: {", ".join(tags)}'
|
||||
#self.card.format(**args)
|
||||
return self.card.format(**args)
|
||||
except Exception as e:
|
||||
shared.log.error(f'Extra networks item error: page={tabname} item={item["name"]} {e}')
|
||||
@@ -248,16 +263,20 @@ class ExtraNetworksPage:
|
||||
|
||||
def find_preview(self, path):
|
||||
preview_extensions = ["jpg", "jpeg", "png", "webp", "tiff", "jp2"]
|
||||
files = listdir(os.path.dirname(path))
|
||||
for file in [f'{path}{mid}{ext}' for ext in preview_extensions for mid in ['.thumb.', '.preview.', '.']]:
|
||||
if os.path.exists(file):
|
||||
# if os.path.exists(file):
|
||||
if file in files:
|
||||
if '.thumb.' not in file:
|
||||
self.missing_thumbs.append(file)
|
||||
return self.link_preview(file)
|
||||
return self.link_preview('html/card-no-preview.png')
|
||||
|
||||
def find_description(self, path):
|
||||
files = listdir(os.path.dirname(path))
|
||||
for file in [f"{path}.txt", f"{path}.description.txt"]:
|
||||
if os.path.exists(file):
|
||||
# if os.path.exists(file):
|
||||
if file in files:
|
||||
try:
|
||||
with open(file, "r", encoding="utf-8", errors="replace") as f:
|
||||
txt = f.read()
|
||||
@@ -269,8 +288,10 @@ class ExtraNetworksPage:
|
||||
|
||||
def find_info(self, path):
|
||||
basename, _ext = os.path.splitext(path)
|
||||
files = listdir(os.path.dirname(path))
|
||||
for file in [f"{path}.info", f"{path}.civitai.info", f"{basename}.info", f"{basename}.civitai.info"]:
|
||||
if os.path.exists(file):
|
||||
# if os.path.exists(file):
|
||||
if file in files:
|
||||
try:
|
||||
with open(file, "r", encoding="utf-8", errors="replace") as f:
|
||||
txt = f.read()
|
||||
@@ -278,8 +299,7 @@ class ExtraNetworksPage:
|
||||
return txt
|
||||
except OSError:
|
||||
pass
|
||||
return None
|
||||
|
||||
return None
|
||||
|
||||
|
||||
def initialize():
|
||||
|
||||
Reference in New Issue
Block a user