diff options
-rw-r--r-- | CHANGELOG.md | 14 | ||||
-rw-r--r-- | extensions-builtin/Lora/ui_extra_networks_lora.py | 4 | ||||
-rw-r--r-- | extensions-builtin/canvas-zoom-and-pan/javascript/zoom.js | 171 | ||||
-rw-r--r-- | extensions-builtin/canvas-zoom-and-pan/scripts/hotkey_config.py | 10 | ||||
-rw-r--r-- | extensions-builtin/canvas-zoom-and-pan/style.css | 63 | ||||
-rw-r--r-- | html/extra-networks-card.html | 2 | ||||
-rw-r--r-- | javascript/extraNetworks.js | 50 | ||||
-rw-r--r-- | modules/launch_utils.py | 8 | ||||
-rw-r--r-- | modules/processing.py | 3 | ||||
-rw-r--r-- | modules/ui.py | 1 | ||||
-rw-r--r-- | modules/ui_extra_networks.py | 18 | ||||
-rw-r--r-- | modules/ui_extra_networks_checkpoints.py | 4 | ||||
-rw-r--r-- | modules/ui_extra_networks_hypernets.py | 4 | ||||
-rw-r--r-- | modules/ui_extra_networks_textual_inversion.py | 4 | ||||
-rw-r--r-- | style.css | 14 | ||||
-rw-r--r-- | webui.py | 4 | ||||
-rwxr-xr-x | webui.sh | 2 |
17 files changed, 342 insertions, 34 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md index 6c6ab5e3..c3c57fe0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,17 @@ +## 1.3.1
+
+### Features:
+ * revert default cross attention optimization to Doggettx
+
+### Bug Fixes:
+ * fix bug: LoRA don't apply on dropdown list sd_lora
+ * fix png info always added even if setting is not enabled
+ * fix some fields not applying in xyz plot
+ * fix "hires. fix" prompt sharing same labels with txt2img_prompt
+ * fix lora hashes not being added properly to infotex if there is only one lora
+ * fix --use-cpu failing to work properly at startup
+ * make --disable-opt-split-attention command line option work again
+
## 1.3.0
### Features:
diff --git a/extensions-builtin/Lora/ui_extra_networks_lora.py b/extensions-builtin/Lora/ui_extra_networks_lora.py index 259e99ac..da49790b 100644 --- a/extensions-builtin/Lora/ui_extra_networks_lora.py +++ b/extensions-builtin/Lora/ui_extra_networks_lora.py @@ -13,7 +13,7 @@ class ExtraNetworksPageLora(ui_extra_networks.ExtraNetworksPage): lora.list_available_loras()
def list_items(self):
- for name, lora_on_disk in lora.available_loras.items():
+ for index, (name, lora_on_disk) in enumerate(lora.available_loras.items()):
path, ext = os.path.splitext(lora_on_disk.filename)
alias = lora_on_disk.get_alias()
@@ -27,6 +27,8 @@ class ExtraNetworksPageLora(ui_extra_networks.ExtraNetworksPage): "prompt": json.dumps(f"<lora:{alias}:") + " + opts.extra_networks_default_multiplier + " + json.dumps(">"),
"local_preview": f"{path}.{shared.opts.samples_format}",
"metadata": json.dumps(lora_on_disk.metadata, indent=4) if lora_on_disk.metadata else None,
+ "sort_keys": {'default': index, **self.get_sort_keys(lora_on_disk.filename)},
+
}
def allowed_directories_for_previews(self):
diff --git a/extensions-builtin/canvas-zoom-and-pan/javascript/zoom.js b/extensions-builtin/canvas-zoom-and-pan/javascript/zoom.js index f555960d..41d9ddf4 100644 --- a/extensions-builtin/canvas-zoom-and-pan/javascript/zoom.js +++ b/extensions-builtin/canvas-zoom-and-pan/javascript/zoom.js @@ -14,13 +14,73 @@ function getActiveTab(elements, all = false) { } } +// Wait until opts loaded +async function waitForOpts() { + return new Promise(resolve => { + const checkInterval = setInterval(() => { + if (window.opts && Object.keys(window.opts).length !== 0) { + clearInterval(checkInterval); + resolve(window.opts); + } + }, 100); + }); +} + +// Check is hotkey valid +function isSingleLetter(value) { + return ( + typeof value === "string" && value.length === 1 && /[a-z]/i.test(value) + ); +} + +// Create hotkeyConfig from opts +function createHotkeyConfig(defaultHotkeysConfig, hotkeysConfigOpts) { + const result = {}; + const usedKeys = new Set(); + + for (const key in defaultHotkeysConfig) { + if (typeof hotkeysConfigOpts[key] === "boolean") { + result[key] = hotkeysConfigOpts[key]; + continue; + } + if ( + hotkeysConfigOpts[key] && + isSingleLetter(hotkeysConfigOpts[key]) && + !usedKeys.has(hotkeysConfigOpts[key].toUpperCase()) + ) { + // If the property passed the test and has not yet been used, add 'Key' before it and save it + result[key] = "Key" + hotkeysConfigOpts[key].toUpperCase(); + usedKeys.add(hotkeysConfigOpts[key].toUpperCase()); + } else { + // If the property does not pass the test or has already been used, we keep the default value + console.error( + `Hotkey: ${hotkeysConfigOpts[key]} for ${key} is repeated and conflicts with another hotkey or is not 1 letter. The default hotkey is used: ${defaultHotkeysConfig[key][3]}` + ); + result[key] = defaultHotkeysConfig[key]; + } + } + + return result; +} + +// Main onUiLoaded(async() => { - const hotkeysConfig = { - resetZoom: "KeyR", - fitToScreen: "KeyS", - moveKey: "KeyF", - overlap: "KeyO" + const hotkeysConfigOpts = await waitForOpts(); + + // Default config + const defaultHotkeysConfig = { + canvas_hotkey_reset: "KeyR", + canvas_hotkey_fullscreen: "KeyS", + canvas_hotkey_move: "KeyF", + canvas_hotkey_overlap: "KeyO", + canvas_show_tooltip: true, + canvas_swap_controls: false }; + // swap the actions for ctr + wheel and shift + wheel + const hotkeysConfig = createHotkeyConfig( + defaultHotkeysConfig, + hotkeysConfigOpts + ); let isMoving = false; let mouseX, mouseY; @@ -48,6 +108,68 @@ onUiLoaded(async() => { let [zoomLevel, panX, panY] = [1, 0, 0]; let fullScreenMode = false; + // Create tooltip + function createTooltip() { + const toolTipElemnt = + targetElement.querySelector(".image-container"); + const tooltip = document.createElement("div"); + tooltip.className = "tooltip"; + + // Creating an item of information + const info = document.createElement("i"); + info.className = "tooltip-info"; + info.textContent = ""; + + // Create a container for the contents of the tooltip + const tooltipContent = document.createElement("div"); + tooltipContent.className = "tooltip-content"; + + // Add info about hotkets + const zoomKey = hotkeysConfig.canvas_swap_controls ? "Ctrl" : "Shift"; + const adjustKey = hotkeysConfig.canvas_swap_controls ? "Shift" : "Ctrl"; + + const hotkeys = [ + {key: `${zoomKey} + wheel`, action: "Zoom canvas"}, + {key: `${adjustKey} + wheel`, action: "Adjust brush size"}, + { + key: hotkeysConfig.canvas_hotkey_reset.charAt( + hotkeysConfig.canvas_hotkey_reset.length - 1 + ), + action: "Reset zoom" + }, + { + key: hotkeysConfig.canvas_hotkey_fullscreen.charAt( + hotkeysConfig.canvas_hotkey_fullscreen.length - 1 + ), + action: "Fullscreen mode" + }, + { + key: hotkeysConfig.canvas_hotkey_move.charAt( + hotkeysConfig.canvas_hotkey_move.length - 1 + ), + action: "Move canvas" + } + ]; + hotkeys.forEach(function(hotkey) { + const p = document.createElement("p"); + p.innerHTML = + "<b>" + hotkey.key + "</b>" + " - " + hotkey.action; + tooltipContent.appendChild(p); + }); + + // Add information and content elements to the tooltip element + tooltip.appendChild(info); + tooltip.appendChild(tooltipContent); + + // Add a hint element to the target element + toolTipElemnt.appendChild(tooltip); + } + + //Show tool tip if setting enable + if (hotkeysConfig.canvas_show_tooltip) { + createTooltip(); + } + // In the course of research, it was found that the tag img is very harmful when zooming and creates white canvases. This hack allows you to almost never think about this problem, it has no effect on webui. function fixCanvas() { const activeTab = getActiveTab(elements).textContent.trim(); @@ -159,7 +281,10 @@ onUiLoaded(async() => { // Change the zoom level based on user interaction function changeZoomLevel(operation, e) { - if (e.shiftKey) { + if ( + (!hotkeysConfig.canvas_swap_controls && e.shiftKey) || + (hotkeysConfig.canvas_swap_controls && e.ctrlKey) + ) { e.preventDefault(); let zoomPosX, zoomPosY; @@ -262,7 +387,8 @@ onUiLoaded(async() => { targetElement.style.transform = `translate(${0}px, ${0}px) scale(${1})`; // Get scrollbar width to right-align the image - const scrollbarWidth = window.innerWidth - document.documentElement.clientWidth; + const scrollbarWidth = + window.innerWidth - document.documentElement.clientWidth; // Get element and screen dimensions const elementWidth = targetElement.offsetWidth; @@ -312,10 +438,9 @@ onUiLoaded(async() => { // Handle keydown events function handleKeyDown(event) { const hotkeyActions = { - [hotkeysConfig.resetZoom]: resetZoom, - [hotkeysConfig.overlap]: toggleOverlap, - [hotkeysConfig.fitToScreen]: fitToScreen - // [hotkeysConfig.moveKey] : moveCanvas, + [hotkeysConfig.canvas_hotkey_reset]: resetZoom, + [hotkeysConfig.canvas_hotkey_overlap]: toggleOverlap, + [hotkeysConfig.canvas_hotkey_fullscreen]: fitToScreen }; const action = hotkeyActions[event.code]; @@ -369,7 +494,11 @@ onUiLoaded(async() => { changeZoomLevel(operation, e); // Handle brush size adjustment with ctrl key pressed - if (e.ctrlKey || e.metaKey) { + if ( + (hotkeysConfig.canvas_swap_controls && e.shiftKey) || + (!hotkeysConfig.canvas_swap_controls && + (e.ctrlKey || e.metaKey)) + ) { e.preventDefault(); // Increase or decrease brush size based on scroll direction @@ -377,20 +506,19 @@ onUiLoaded(async() => { } }); - /** - * Handle the move event for pan functionality. Updates the panX and panY variables and applies the new transform to the target element. - * @param {MouseEvent} e - The mouse event. - */ + // Handle the move event for pan functionality. Updates the panX and panY variables and applies the new transform to the target element. function handleMoveKeyDown(e) { - if (e.code === hotkeysConfig.moveKey) { - if (!e.ctrlKey && !e.metaKey) { + if (e.code === hotkeysConfig.canvas_hotkey_move) { + if (!e.ctrlKey && !e.metaKey && isKeyDownHandlerAttached) { + e.preventDefault(); + document.activeElement.blur(); isMoving = true; } } } function handleMoveKeyUp(e) { - if (e.code === hotkeysConfig.moveKey) { + if (e.code === hotkeysConfig.canvas_hotkey_move) { isMoving = false; } } @@ -422,6 +550,11 @@ onUiLoaded(async() => { } } + // Prevents sticking to the mouse + window.onblur = function() { + isMoving = false; + }; + gradioApp().addEventListener("mousemove", handleMoveByKey); } diff --git a/extensions-builtin/canvas-zoom-and-pan/scripts/hotkey_config.py b/extensions-builtin/canvas-zoom-and-pan/scripts/hotkey_config.py new file mode 100644 index 00000000..d83e14da --- /dev/null +++ b/extensions-builtin/canvas-zoom-and-pan/scripts/hotkey_config.py @@ -0,0 +1,10 @@ +from modules import shared + +shared.options_templates.update(shared.options_section(('canvas_hotkey', "Canvas Hotkeys"), { + "canvas_hotkey_move": shared.OptionInfo("F", "Moving the canvas"), + "canvas_hotkey_fullscreen": shared.OptionInfo("S", "Fullscreen Mode, maximizes the picture so that it fits into the screen and stretches it to its full width "), + "canvas_hotkey_reset": shared.OptionInfo("R", "Reset zoom and canvas positon"), + "canvas_hotkey_overlap": shared.OptionInfo("O", "Toggle overlap ( Technical button, neededs for testing )"), + "canvas_show_tooltip": shared.OptionInfo(True, "Enable tooltip on the canvas"), + "canvas_swap_controls": shared.OptionInfo(False, "Swap hotkey combinations for Zoom and Adjust brush resize"), +})) diff --git a/extensions-builtin/canvas-zoom-and-pan/style.css b/extensions-builtin/canvas-zoom-and-pan/style.css new file mode 100644 index 00000000..5b131d50 --- /dev/null +++ b/extensions-builtin/canvas-zoom-and-pan/style.css @@ -0,0 +1,63 @@ +.tooltip-info { + position: absolute; + top: 10px; + left: 10px; + cursor: help; + background-color: rgba(0, 0, 0, 0.3); + width: 20px; + height: 20px; + border-radius: 50%; + display: flex; + align-items: center; + justify-content: center; + flex-direction: column; + + z-index: 100; +} + +.tooltip-info::after { + content: ''; + display: block; + width: 2px; + height: 7px; + background-color: white; + margin-top: 2px; +} + +.tooltip-info::before { + content: ''; + display: block; + width: 2px; + height: 2px; + background-color: white; +} + +.tooltip-content { + display: none; + background-color: #f9f9f9; + color: #333; + border: 1px solid #ddd; + padding: 15px; + position: absolute; + top: 40px; + left: 10px; + width: 250px; + font-size: 16px; + opacity: 0; + border-radius: 8px; + box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2); + + z-index: 100; +} + +.tooltip:hover .tooltip-content { + display: block; + animation: fadeIn 0.5s; + opacity: 1; +} + +@keyframes fadeIn { + from {opacity: 0;} + to {opacity: 1;} +} + diff --git a/html/extra-networks-card.html b/html/extra-networks-card.html index 2b32e712..68a84c3a 100644 --- a/html/extra-networks-card.html +++ b/html/extra-networks-card.html @@ -1,4 +1,4 @@ -<div class='card' style={style} onclick={card_clicked}> +<div class='card' style={style} onclick={card_clicked} {sort_keys}> {background_image} {metadata_button} <div class='actions'> diff --git a/javascript/extraNetworks.js b/javascript/extraNetworks.js index aafe0a00..b87bca3e 100644 --- a/javascript/extraNetworks.js +++ b/javascript/extraNetworks.js @@ -3,10 +3,17 @@ function setupExtraNetworksForTab(tabname) { var tabs = gradioApp().querySelector('#' + tabname + '_extra_tabs > div'); var search = gradioApp().querySelector('#' + tabname + '_extra_search textarea'); + var sort = gradioApp().getElementById(tabname + '_extra_sort'); + var sortOrder = gradioApp().getElementById(tabname + '_extra_sortorder'); var refresh = gradioApp().getElementById(tabname + '_extra_refresh'); search.classList.add('search'); + sort.classList.add('sort'); + sortOrder.classList.add('sortorder'); + sort.dataset.sortkey = 'sortDefault'; tabs.appendChild(search); + tabs.appendChild(sort); + tabs.appendChild(sortOrder); tabs.appendChild(refresh); var applyFilter = function() { @@ -26,8 +33,51 @@ function setupExtraNetworksForTab(tabname) { }); }; + var applySort = function() { + var reverse = sortOrder.classList.contains("sortReverse"); + var sortKey = sort.querySelector("input").value.toLowerCase().replace("sort", "").replaceAll(" ", "_").replace(/_+$/, "").trim(); + sortKey = sortKey ? "sort" + sortKey.charAt(0).toUpperCase() + sortKey.slice(1) : ""; + var sortKeyStore = sortKey ? sortKey + (reverse ? "Reverse" : "") : ""; + if (!sortKey || sortKeyStore == sort.dataset.sortkey) { + return; + } + + sort.dataset.sortkey = sortKeyStore; + + var cards = gradioApp().querySelectorAll('#' + tabname + '_extra_tabs div.card'); + cards.forEach(function(card) { + card.originalParentElement = card.parentElement; + }); + var sortedCards = Array.from(cards); + sortedCards.sort(function(cardA, cardB) { + var a = cardA.dataset[sortKey]; + var b = cardB.dataset[sortKey]; + if (!isNaN(a) && !isNaN(b)) { + return parseInt(a) - parseInt(b); + } + + return (a < b ? -1 : (a > b ? 1 : 0)); + }); + if (reverse) { + sortedCards.reverse(); + } + cards.forEach(function(card) { + card.remove(); + }); + sortedCards.forEach(function(card) { + card.originalParentElement.appendChild(card); + }); + }; + search.addEventListener("input", applyFilter); applyFilter(); + ["change", "blur", "click"].forEach(function(evt) { + sort.querySelector("input").addEventListener(evt, applySort); + }); + sortOrder.addEventListener("click", function() { + sortOrder.classList.toggle("sortReverse"); + applySort(); + }); extraNetworksApplyFilter[tabname] = applyFilter; } diff --git a/modules/launch_utils.py b/modules/launch_utils.py index 6e9bb770..0c8c4db0 100644 --- a/modules/launch_utils.py +++ b/modules/launch_utils.py @@ -68,7 +68,13 @@ def git_tag(): try:
return subprocess.check_output([git, "describe", "--tags"], shell=False, encoding='utf8').strip()
except Exception:
- return "<none>"
+ try:
+ from pathlib import Path
+ changelog_md = Path(__file__).parent.parent / "CHANGELOG.md"
+ with changelog_md.open(encoding="utf-8") as file:
+ return next((line.strip() for line in file if line.strip()), "<none>")
+ except Exception:
+ return "<none>"
def run(command, desc=None, errdesc=None, custom_env=None, live: bool = default_command_live) -> str:
diff --git a/modules/processing.py b/modules/processing.py index baa9b278..362ab4c2 100644 --- a/modules/processing.py +++ b/modules/processing.py @@ -595,8 +595,7 @@ def process_images(p: StableDiffusionProcessing) -> Processed: try:
# if no checkpoint override or the override checkpoint can't be found, remove override entry and load opts checkpoint
- override_checkpoint = p.override_settings.get('sd_model_checkpoint')
- if override_checkpoint is not None and sd_models.checkpoint_alisases.get(override_checkpoint) is None:
+ if sd_models.checkpoint_alisases.get(p.override_settings.get('sd_model_checkpoint')) is None:
p.override_settings.pop('sd_model_checkpoint', None)
sd_models.reload_model_weights()
diff --git a/modules/ui.py b/modules/ui.py index b7459f08..988b2003 100644 --- a/modules/ui.py +++ b/modules/ui.py @@ -79,6 +79,7 @@ extra_networks_symbol = '\U0001F3B4' # 🎴 switch_values_symbol = '\U000021C5' # ⇅
restore_progress_symbol = '\U0001F300' # 🌀
detect_image_size_symbol = '\U0001F4D0' # 📐
+up_down_symbol = '\u2195\ufe0f' # ↕️
def plaintext_to_html(text):
diff --git a/modules/ui_extra_networks.py b/modules/ui_extra_networks.py index 19fbaae5..a7d3bc79 100644 --- a/modules/ui_extra_networks.py +++ b/modules/ui_extra_networks.py @@ -4,6 +4,7 @@ from pathlib import Path from modules import shared
from modules.images import read_info_from_image, save_image_with_geninfo
+from modules.ui import up_down_symbol
import gradio as gr
import json
import html
@@ -185,6 +186,8 @@ class ExtraNetworksPage: if search_only and shared.opts.extra_networks_hidden_models == "Never":
return ""
+ sort_keys = " ".join([html.escape(f'data-sort-{k}={v}') for k, v in item.get("sort_keys", {}).items()]).strip()
+
args = {
"background_image": background_image,
"style": f"'display: none; {height}{width}'",
@@ -198,10 +201,23 @@ class ExtraNetworksPage: "search_term": item.get("search_term", ""),
"metadata_button": metadata_button,
"search_only": " search_only" if search_only else "",
+ "sort_keys": sort_keys,
}
return self.card_page.format(**args)
+ def get_sort_keys(self, path):
+ """
+ List of default keys used for sorting in the UI.
+ """
+ pth = Path(path)
+ stat = pth.stat()
+ return {
+ "date_created": int(stat.st_ctime or 0),
+ "date_modified": int(stat.st_mtime or 0),
+ "name": pth.name.lower(),
+ }
+
def find_preview(self, path):
"""
Find a preview PNG for a given path (without extension) and call link_preview on it.
@@ -296,6 +312,8 @@ def create_ui(container, button, tabname): page_elem.change(fn=lambda: None, _js='function(){applyExtraNetworkFilter(' + json.dumps(tabname) + '); return []}', inputs=[], outputs=[])
gr.Textbox('', show_label=False, elem_id=tabname+"_extra_search", placeholder="Search...", visible=False)
+ gr.Dropdown(choices=['Default Sort', 'Date Created', 'Date Modified', 'Name'], value='Default Sort', elem_id=tabname+"_extra_sort", multiselect=False, visible=False, show_label=False, interactive=True)
+ gr.Button(up_down_symbol, elem_id=tabname+"_extra_sortorder")
button_refresh = gr.Button('Refresh', elem_id=tabname+"_extra_refresh")
ui.button_save_preview = gr.Button('Save preview', elem_id=tabname+"_save_preview", visible=False)
diff --git a/modules/ui_extra_networks_checkpoints.py b/modules/ui_extra_networks_checkpoints.py index a17aa9c9..8b9ab71b 100644 --- a/modules/ui_extra_networks_checkpoints.py +++ b/modules/ui_extra_networks_checkpoints.py @@ -14,7 +14,7 @@ class ExtraNetworksPageCheckpoints(ui_extra_networks.ExtraNetworksPage): def list_items(self):
checkpoint: sd_models.CheckpointInfo
- for name, checkpoint in sd_models.checkpoints_list.items():
+ for index, (name, checkpoint) in enumerate(sd_models.checkpoints_list.items()):
path, ext = os.path.splitext(checkpoint.filename)
yield {
"name": checkpoint.name_for_extra,
@@ -24,6 +24,8 @@ class ExtraNetworksPageCheckpoints(ui_extra_networks.ExtraNetworksPage): "search_term": self.search_terms_from_path(checkpoint.filename) + " " + (checkpoint.sha256 or ""),
"onclick": '"' + html.escape(f"""return selectCheckpoint({json.dumps(name)})""") + '"',
"local_preview": f"{path}.{shared.opts.samples_format}",
+ "sort_keys": {'default': index, **self.get_sort_keys(checkpoint.filename)},
+
}
def allowed_directories_for_previews(self):
diff --git a/modules/ui_extra_networks_hypernets.py b/modules/ui_extra_networks_hypernets.py index 6187e000..7c19b532 100644 --- a/modules/ui_extra_networks_hypernets.py +++ b/modules/ui_extra_networks_hypernets.py @@ -12,7 +12,7 @@ class ExtraNetworksPageHypernetworks(ui_extra_networks.ExtraNetworksPage): shared.reload_hypernetworks()
def list_items(self):
- for name, path in shared.hypernetworks.items():
+ for index, (name, path) in enumerate(shared.hypernetworks.items()):
path, ext = os.path.splitext(path)
yield {
@@ -23,6 +23,8 @@ class ExtraNetworksPageHypernetworks(ui_extra_networks.ExtraNetworksPage): "search_term": self.search_terms_from_path(path),
"prompt": json.dumps(f"<hypernet:{name}:") + " + opts.extra_networks_default_multiplier + " + json.dumps(">"),
"local_preview": f"{path}.preview.{shared.opts.samples_format}",
+ "sort_keys": {'default': index, **self.get_sort_keys(path + ext)},
+
}
def allowed_directories_for_previews(self):
diff --git a/modules/ui_extra_networks_textual_inversion.py b/modules/ui_extra_networks_textual_inversion.py index 6944d559..58a61c55 100644 --- a/modules/ui_extra_networks_textual_inversion.py +++ b/modules/ui_extra_networks_textual_inversion.py @@ -13,7 +13,7 @@ class ExtraNetworksPageTextualInversion(ui_extra_networks.ExtraNetworksPage): sd_hijack.model_hijack.embedding_db.load_textual_inversion_embeddings(force_reload=True)
def list_items(self):
- for embedding in sd_hijack.model_hijack.embedding_db.word_embeddings.values():
+ for index, embedding in enumerate(sd_hijack.model_hijack.embedding_db.word_embeddings.values()):
path, ext = os.path.splitext(embedding.filename)
yield {
"name": embedding.name,
@@ -23,6 +23,8 @@ class ExtraNetworksPageTextualInversion(ui_extra_networks.ExtraNetworksPage): "search_term": self.search_terms_from_path(embedding.filename),
"prompt": json.dumps(embedding.name),
"local_preview": f"{path}.preview.{shared.opts.samples_format}",
+ "sort_keys": {'default': index, **self.get_sort_keys(embedding.filename)},
+
}
def allowed_directories_for_previews(self):
@@ -734,12 +734,22 @@ footer { .extra-network-subdirs button{
margin: 0 0.15em;
}
-.extra-networks .tab-nav .search{
+.extra-networks .tab-nav .search,
+.extra-networks .tab-nav .sort,
+.extra-networks .tab-nav .sortorder{
display: inline-block;
- max-width: 16em;
margin: 0.3em;
align-self: center;
+}
+
+.extra-networks .tab-nav .search {
width: 16em;
+ max-width: 16em;
+}
+
+.extra-networks .tab-nav .sort {
+ width: 12em;
+ max-width: 12em;
}
#txt2img_extra_view, #img2img_extra_view {
@@ -469,10 +469,6 @@ def webui(): startup_timer.record("scripts unloaded callback")
initialize_rest(reload_script_modules=True)
- modules.script_callbacks.on_list_optimizers(modules.sd_hijack_optimizations.list_optimizers)
- modules.sd_hijack.list_optimizers()
- startup_timer.record("scripts list_optimizers")
-
if __name__ == "__main__":
if cmd_opts.nowebui:
@@ -112,7 +112,7 @@ then fi # Check prerequisites -gpu_info=$(lspci 2>/dev/null | grep VGA) +gpu_info=$(lspci 2>/dev/null | grep -E "VGA|Display") case "$gpu_info" in *"Navi 1"*|*"Navi 2"*) export HSA_OVERRIDE_GFX_VERSION=10.3.0 ;; |