diff --git a/.eslintrc.json b/.eslintrc.json
index 7ea7b8dae..53691dbd9 100644
--- a/.eslintrc.json
+++ b/.eslintrc.json
@@ -90,6 +90,8 @@
"getENActiveTab": "readonly",
"quickApplyStyle": "readonly",
"quickSaveStyle": "readonly",
+ "setupExtraNetworks": "readonly",
+ "showNetworks": "readonly",
// from python
"localization": "readonly",
// progressbar.js
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 9e5d830cc..bb56efec5 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,14 +1,10 @@
# Change Log for SD.Next
-## Update for 2024-11-01
+## Update for 2024-11-02
-Smaller release just 3 days after the last one, but with some important fixes and improvements.
+Smaller release just few days after the last one, but with some important fixes and improvements.
This release can be considered an LTS release before we kick off the next round of major updates.
-- XYZ grid:
- - optional per-image time benchmark info
-- UI:
- - add additional [hotkeys](https://github.com/vladmandic/automatic/wiki/Hotkeys)
- Docs:
- add built-in [changelog](https://github.com/vladmandic/automatic/blob/master/CHANGELOG.md) search
since changelog is the best up-to-date source of info
@@ -21,6 +17,13 @@ This release can be considered an LTS release before we kick off the next round
- SD3: all-in-one safetensors
- *examples*: [large](https://civitai.com/models/882666/sd35-large-google-flan?modelVersionId=1003031), [medium](https://civitai.com/models/900327)
- *note*: enable *bnb* on-the-fly quantization for even bigger gains
+- UI:
+ - add additional [hotkeys](https://github.com/vladmandic/automatic/wiki/Hotkeys)
+ - add show networks on startup setting
+ - better mapping of networks previews
+ - optimize networks display load
+- XYZ grid:
+ - optional per-image time benchmark info
- CLI:
- refactor command line params
run `webui.sh`/`webui.bat` with `--help` to see all options
@@ -28,7 +31,7 @@ This release can be considered an LTS release before we kick off the next round
- Repo: move screenshots to GH pages
- Update requirements
- Fixes:
- - custom watermark add alphablending
+ - custom watermark add alphablending
- detailer min/max size as fractions of image size
- ipadapter load on-demand
- ipadapter face use correct yolo model
@@ -38,6 +41,8 @@ This release can be considered an LTS release before we kick off the next round
- fix lora enum logging on windows
- fix xyz grid with batch count
- fix vqa models ignoring hfcache folder setting
+ - fix network height in standard vs modern ui
+ - fix k-diff enum on startup
- move downloads of some auxillary models to hfcache instead of models folder
## Update for 2024-10-29
diff --git a/html/previews.json b/html/previews.json
new file mode 100644
index 000000000..3e4bc3d41
--- /dev/null
+++ b/html/previews.json
@@ -0,0 +1,11 @@
+{
+ "stabilityai--stable-diffusion-3-medium-diffusers": "models/Reference/stabilityai--stable-diffusion-3.jpg",
+ "stabilityai--stable-diffusion-3.5-medium": "models/Reference/stabilityai--stable-diffusion-3_5.jpg",
+ "stabilityai--stable-diffusion-3.5-large": "models/Reference/stabilityai--stable-diffusion-3_5.jpg",
+ "Disty0--FLUX.1-dev-qint8": "models/Reference/black-forest-labs--FLUX.1-dev.jpg",
+ "Disty0--FLUX.1-dev-qint4": "models/Reference/black-forest-labs--FLUX.1-dev.jpg",
+ "sayakpaul--flux.1-dev-nf4": "models/Reference/black-forest-labs--FLUX.1-dev.jpg",
+ "THUDM--CogVideoX-2b": "models/Reference/THUDM--CogView3-Plus-3B.jpg",
+ "THUDM--CogVideoX-5b": "models/Reference/THUDM--CogView3-Plus-3B.jpg",
+ "THUDM--CogVideoX-5b-I2V": "models/Reference/THUDM--CogView3-Plus-3B.jpg"
+}
diff --git a/javascript/extraNetworks.js b/javascript/extraNetworks.js
index 032ee4999..9a33baa86 100644
--- a/javascript/extraNetworks.js
+++ b/javascript/extraNetworks.js
@@ -375,6 +375,7 @@ function setupExtraNetworksForTab(tabname) {
if (!tabs) return;
// buttons
+ const btnShow = gradioApp().getElementById(`${tabname}_extra_networks_btn`);
const btnRefresh = gradioApp().getElementById(`${tabname}_extra_refresh`);
const btnScan = gradioApp().getElementById(`${tabname}_extra_scan`);
const btnSave = gradioApp().getElementById(`${tabname}_extra_save`);
@@ -448,50 +449,69 @@ function setupExtraNetworksForTab(tabname) {
// en style
if (!en) return;
+ let lastView;
+ let heightInitialized = false;
const intersectionObserver = new IntersectionObserver((entries) => {
- for (const el of Array.from(gradioApp().querySelectorAll('.extra-networks-page'))) {
- el.style.height = `${window.opts.extra_networks_height}vh`;
- el.parentElement.style.width = '-webkit-fill-available';
+ if (!heightInitialized) {
+ heightInitialized = true;
+ let h = 0;
+ const target = window.opts.extra_networks_card_cover === 'sidebar' ? 0 : window.opts.extra_networks_height;
+ if (window.opts.theme_type === 'Standard') h = target > 0 ? target : 55;
+ else h = target > 0 ? target : 87;
+ for (const el of Array.from(gradioApp().getElementById(`${tabname}_extra_tabs`).querySelectorAll('.extra-networks-page'))) {
+ if (h > 0) el.style.height = `${h}vh`;
+ el.parentElement.style.width = '-webkit-fill-available';
+ }
}
- if (entries[0].intersectionRatio > 0) {
- refreshENpage();
- // sortExtraNetworks('fixed');
- if (window.opts.extra_networks_card_cover === 'cover') {
- en.style.transition = '';
- en.style.zIndex = 100;
- en.style.top = '13em';
- en.style.position = 'absolute';
- en.style.right = 'unset';
- en.style.width = 'unset';
- en.style.height = 'unset';
- gradioApp().getElementById(`${tabname}_settings`).parentNode.style.width = 'unset';
- } else if (window.opts.extra_networks_card_cover === 'sidebar') {
- en.style.zIndex = 100;
- en.style.position = 'absolute';
- en.style.right = '0';
- en.style.top = '13em';
- en.style.height = 'auto';
- en.style.transition = 'width 0.3s ease';
- en.style.width = `${window.opts.extra_networks_sidebar_width}vw`;
- gradioApp().getElementById(`${tabname}_settings`).parentNode.style.width = `${100 - 2 - window.opts.extra_networks_sidebar_width}vw`;
+ if (lastView !== entries[0].intersectionRatio > 0) {
+ lastView = entries[0].intersectionRatio > 0;
+ if (lastView) {
+ refreshENpage();
+ // sortExtraNetworks('fixed');
+ if (window.opts.extra_networks_card_cover === 'cover') {
+ en.style.position = 'absolute';
+ en.style.height = 'unset';
+ en.style.width = 'unset';
+ en.style.right = 'unset';
+ en.style.top = '13em';
+ en.style.transition = '';
+ en.style.zIndex = 100;
+ gradioApp().getElementById(`${tabname}_settings`).parentNode.style.width = 'unset';
+ } else if (window.opts.extra_networks_card_cover === 'sidebar') {
+ en.style.position = 'absolute';
+ en.style.height = 'auto';
+ en.style.width = `${window.opts.extra_networks_sidebar_width}vw`;
+ en.style.right = '0';
+ en.style.top = '13em';
+ en.style.transition = 'width 0.3s ease';
+ en.style.zIndex = 100;
+ gradioApp().getElementById(`${tabname}_settings`).parentNode.style.width = `${100 - 2 - window.opts.extra_networks_sidebar_width}vw`;
+ } else {
+ en.style.position = 'relative';
+ en.style.height = 'unset';
+ en.style.width = 'unset';
+ en.style.right = 'unset';
+ en.style.top = 0;
+ en.style.transition = '';
+ en.style.zIndex = 0;
+ gradioApp().getElementById(`${tabname}_settings`).parentNode.style.width = 'unset';
+ }
} else {
- en.style.transition = '';
- en.style.zIndex = 0;
- en.style.top = 0;
- en.style.position = 'relative';
- en.style.right = 'unset';
- en.style.width = 'unset';
- en.style.height = 'unset';
+ if (window.opts.extra_networks_card_cover === 'sidebar') en.style.width = 0;
gradioApp().getElementById(`${tabname}_settings`).parentNode.style.width = 'unset';
}
- } else {
- if (window.opts.extra_networks_card_cover === 'sidebar') en.style.width = 0;
- gradioApp().getElementById(`${tabname}_settings`).parentNode.style.width = 'unset';
}
});
intersectionObserver.observe(en); // monitor visibility
}
+async function showNetworks() {
+ for (const tabname of ['txt2img', 'img2img', 'control']) {
+ if (window.opts.extra_networks_show) gradioApp().getElementById(`${tabname}_extra_networks_btn`).click();
+ }
+ log('showNetworks');
+}
+
async function setupExtraNetworks() {
setupExtraNetworksForTab('txt2img');
setupExtraNetworksForTab('img2img');
diff --git a/javascript/loader.js b/javascript/loader.js
index a8fadeb92..f3c7fe60f 100644
--- a/javascript/loader.js
+++ b/javascript/loader.js
@@ -27,7 +27,7 @@ async function preloadImages() {
async function createSplash() {
const dark = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches;
log('createSplash', { theme: dark ? 'dark' : 'light' });
- const num = Math.floor(11 * Math.random());
+ const num = Math.floor(9.99 * Math.random());
const splash = `
diff --git a/javascript/sdnext.css b/javascript/sdnext.css
index 1b2a6b3c8..d412d966f 100644
--- a/javascript/sdnext.css
+++ b/javascript/sdnext.css
@@ -203,7 +203,7 @@ table.settings-value-table td { padding: 0.4em; border: 1px solid #ccc; max-widt
#extensions .date { opacity: 0.85; font-size: var(--text-sm); }
/* extra networks */
-#txt2img_extra_networks, #img2img_extra_networks, #control_extra_networks { width: 0; }
+.extra_networks_root { width: 0; position: absolute; height: auto; right: 0; top: 13em; z-index: 100; } /* default is sidebar view */
.extra-networks { background: var(--background-color); padding: var(--block-label-padding); }
.extra-networks > div { margin: 0; border-bottom: none !important; gap: 0.3em 0; }
.extra-networks .second-line { display: flex; width: -moz-available; width: -webkit-fill-available; gap: 0.3em; box-shadow: var(--input-shadow); }
diff --git a/javascript/startup.js b/javascript/startup.js
index 637a8d15e..51e1800fc 100644
--- a/javascript/startup.js
+++ b/javascript/startup.js
@@ -32,6 +32,7 @@ async function initStartup() {
removeSplash();
// post startup tasks that may take longer but are not critical
+ showNetworks();
setHints();
applyStyles();
initIndexDB();
diff --git a/modules/shared.py b/modules/shared.py
index 342b5222c..c58110214 100644
--- a/modules/shared.py
+++ b/modules/shared.py
@@ -877,8 +877,9 @@ options_templates.update(options_section(('interrogate', "Interrogate"), {
}))
options_templates.update(options_section(('extra_networks', "Networks"), {
- "extra_networks_sep1": OptionInfo("
Extra networks UI
", "", gr.HTML),
- "extra_networks": OptionInfo(["All"], "Networks", gr.Dropdown, lambda: {"multiselect":True, "choices": ['All'] + [en.title for en in extra_networks]}),
+ "extra_networks_sep1": OptionInfo("
Networks UI
", "", gr.HTML),
+ "extra_networks_show": OptionInfo(True, "UI show on startup"),
+ "extra_networks": OptionInfo(["All"], "Available networks", gr.Dropdown, lambda: {"multiselect":True, "choices": ['All'] + [en.title for en in extra_networks]}),
"extra_networks_sort": OptionInfo("Default", "Sort order", gr.Dropdown, {"choices": ['Default', 'Name [A-Z]', 'Name [Z-A]', 'Date [Newest]', 'Date [Oldest]', 'Size [Largest]', 'Size [Smallest]']}),
"extra_networks_view": OptionInfo("gallery", "UI view", gr.Radio, {"choices": ["gallery", "list"]}),
"extra_networks_card_cover": OptionInfo("sidebar", "UI position", gr.Radio, {"choices": ["cover", "inline", "sidebar"]}),
@@ -888,13 +889,18 @@ options_templates.update(options_section(('extra_networks', "Networks"), {
"extra_networks_card_square": OptionInfo(True, "UI disable variable aspect ratio"),
"extra_networks_fetch": OptionInfo(True, "UI fetch network info on mouse-over"),
"extra_networks_card_fit": OptionInfo("cover", "UI image contain method", gr.Radio, {"choices": ["contain", "cover", "fill"], "visible": False}),
- "extra_networks_sep2": OptionInfo("
Extra networks general
", "", gr.HTML),
- "extra_network_reference": OptionInfo(False, "Use reference values when available", gr.Checkbox),
"extra_network_skip_indexing": OptionInfo(False, "Build info on first access", gr.Checkbox),
- "extra_networks_default_multiplier": OptionInfo(1.0, "Default strength", gr.Slider, {"minimum": 0.0, "maximum": 2.0, "step": 0.01}),
+
+ "extra_networks_model_sep": OptionInfo("
Models
", "", gr.HTML),
+ "extra_network_reference": OptionInfo(False, "Use reference values when available", gr.Checkbox),
+ "extra_networks_embed_sep": OptionInfo("
Embeddings
", "", gr.HTML),
"diffusers_convert_embed": OptionInfo(False, "Auto-convert SD 1.5 embeddings to SDXL ", gr.Checkbox, {"visible": native}),
- "extra_networks_sep3": OptionInfo("
Extra networks settings
", "", gr.HTML),
+ "extra_networks_styles_sep": OptionInfo("
Styles
", "", gr.HTML),
"extra_networks_styles": OptionInfo(True, "Show built-in styles"),
+ "extra_networks_wildcard_sep": OptionInfo("
Wildcards
", "", gr.HTML),
+ "wildcards_enabled": OptionInfo(True, "Enable file wildcards support"),
+ "extra_networks_lora_sep": OptionInfo("
LoRA
", "", gr.HTML),
+ "extra_networks_default_multiplier": OptionInfo(1.0, "Default strength", gr.Slider, {"minimum": 0.0, "maximum": 2.0, "step": 0.01}),
"lora_preferred_name": OptionInfo("filename", "LoRA preferred name", gr.Radio, {"choices": ["filename", "alias"]}),
"lora_add_hashes_to_infotext": OptionInfo(False, "LoRA add hash info"),
"lora_force_diffusers": OptionInfo(False if not cmd_opts.use_openvino else True, "LoRA force loading of all models using Diffusers"),
@@ -905,9 +911,9 @@ options_templates.update(options_section(('extra_networks', "Networks"), {
"lora_quant": OptionInfo("NF4","LoRA precision in quantized models", gr.Radio, {"choices": ["NF4", "FP4"]}),
"lora_functional": OptionInfo(False, "Use Kohya method for handling multiple LoRA", gr.Checkbox, { "visible": False }),
"lora_load_gpu": OptionInfo(True if not cmd_opts.lowvram else False, "Load LoRA directly to GPU"),
- "hypernetwork_enabled": OptionInfo(False, "Enable Hypernetwork support"),
+
+ "hypernetwork_enabled": OptionInfo(False, "Enable Hypernetwork support", gr.Checkbox, {"visible": False}),
"sd_hypernetwork": OptionInfo("None", "Add hypernetwork to prompt", gr.Dropdown, { "choices": ["None"], "visible": False }),
- "wildcards_enabled": OptionInfo(True, "Enable file wildcards support"),
}))
options_templates.update(options_section((None, "Hidden options"), {
diff --git a/modules/ui_control.py b/modules/ui_control.py
index 4d7c59bee..fccda2167 100644
--- a/modules/ui_control.py
+++ b/modules/ui_control.py
@@ -152,7 +152,7 @@ def create_ui(_blocks: gr.Blocks=None):
with gr.Row():
override_settings = ui_common.create_override_inputs('control')
- with gr.Row(variant='compact', elem_id="control_extra_networks", visible=False) as extra_networks_ui:
+ with gr.Row(variant='compact', elem_id="control_extra_networks", elem_classes=["extra_networks_root"], visible=False) as extra_networks_ui:
from modules import timer, ui_extra_networks
extra_networks_ui = ui_extra_networks.create_ui(extra_networks_ui, btn_extra, 'control', skip_indexing=shared.opts.extra_network_skip_indexing)
timer.startup.record('ui-networks')
diff --git a/modules/ui_extra_networks.py b/modules/ui_extra_networks.py
index 58fb463a9..323f4830f 100644
--- a/modules/ui_extra_networks.py
+++ b/modules/ui_extra_networks.py
@@ -50,6 +50,7 @@ card_list = '''
'''
+preview_map = None
def init_api(app):
@@ -350,6 +351,9 @@ class ExtraNetworksPage:
return self.link_preview(preview_file)
def update_all_previews(self, items):
+ global preview_map # pylint: disable=global-statement
+ if preview_map is None:
+ preview_map = shared.readfile('html/previews.json', silent=True)
t0 = time.time()
reference_path = os.path.abspath(os.path.join('models', 'Reference'))
possible_paths = list(set([os.path.dirname(item['filename']) for item in items] + [reference_path]))
@@ -378,8 +382,14 @@ class ExtraNetworksPage:
self.missing_thumbs.append(all_previews[file_idx])
item['preview'] = self.link_preview(all_previews[file_idx])
break
+ if item.get('preview', None) is None:
+ found = preview_map.get(base, None)
+ if found is not None:
+ item['preview'] = self.link_preview(found)
+ debug(f'EN mapped-preview: {item["name"]}={found}')
if item.get('preview', None) is None:
item['preview'] = self.link_preview('html/card-no-preview.png')
+ debug(f'EN missing-preview: {item["name"]}')
self.preview_time += time.time() - t0
diff --git a/modules/ui_img2img.py b/modules/ui_img2img.py
index 44f48c3c6..4cb8e4c18 100644
--- a/modules/ui_img2img.py
+++ b/modules/ui_img2img.py
@@ -41,7 +41,7 @@ def create_ui():
img2img_prompt, img2img_prompt_styles, img2img_negative_prompt, img2img_submit, img2img_reprocess, img2img_paste, img2img_extra_networks_button, img2img_token_counter, img2img_token_button, img2img_negative_token_counter, img2img_negative_token_button = ui_sections.create_toprow(is_img2img=True, id_part="img2img")
img2img_prompt_img = gr.File(label="", elem_id="img2img_prompt_image", file_count="single", type="binary", visible=False)
- with gr.Row(variant='compact', elem_id="img2img_extra_networks", visible=False) as extra_networks_ui:
+ with gr.Row(variant='compact', elem_id="img2img_extra_networks", elem_classes=["extra_networks_root"], visible=False) as extra_networks_ui:
from modules import ui_extra_networks
extra_networks_ui_img2img = ui_extra_networks.create_ui(extra_networks_ui, img2img_extra_networks_button, 'img2img', skip_indexing=shared.opts.extra_network_skip_indexing)
timer.startup.record('ui-networks')
diff --git a/modules/ui_txt2img.py b/modules/ui_txt2img.py
index ece8829c5..e2886e901 100644
--- a/modules/ui_txt2img.py
+++ b/modules/ui_txt2img.py
@@ -25,7 +25,7 @@ def create_ui():
txt_prompt_img = gr.File(label="", elem_id="txt2img_prompt_image", file_count="single", type="binary", visible=False)
txt_prompt_img.change(fn=modules.images.image_data, inputs=[txt_prompt_img], outputs=[txt2img_prompt, txt_prompt_img])
- with gr.Row(variant='compact', elem_id="txt2img_extra_networks", visible=False) as extra_networks_ui:
+ with gr.Row(variant='compact', elem_id="txt2img_extra_networks", elem_classes=["extra_networks_root"], visible=False) as extra_networks_ui:
from modules import ui_extra_networks
extra_networks_ui = ui_extra_networks.create_ui(extra_networks_ui, txt2img_extra_networks_button, 'txt2img', skip_indexing=shared.opts.extra_network_skip_indexing)
timer.startup.record('ui-networks')
diff --git a/wiki b/wiki
index a64e3776f..b36c2e1a4 160000
--- a/wiki
+++ b/wiki
@@ -1 +1 @@
-Subproject commit a64e3776fd357ccf85fa751a0efc65fead72c02a
+Subproject commit b36c2e1a4cb85338f20061639d4130255d10bf48