diff --git a/html/extra-networks-pane.html b/html/extra-networks-pane.html
new file mode 100644
index 000000000..93bad698d
--- /dev/null
+++ b/html/extra-networks-pane.html
@@ -0,0 +1,11 @@
+
+ {subdirs_html}
+
+
+
+ {tree_html}
+
+
+ {items_html}
+
+
\ No newline at end of file
diff --git a/html/extra-networks-tree-directory.html b/html/extra-networks-tree-directory.html
new file mode 100644
index 000000000..cec155886
--- /dev/null
+++ b/html/extra-networks-tree-directory.html
@@ -0,0 +1,4 @@
+
+{folder_name}
+{content}
+
\ No newline at end of file
diff --git a/html/extra-networks-tree-file.html b/html/extra-networks-tree-file.html
new file mode 100644
index 000000000..8b1378917
--- /dev/null
+++ b/html/extra-networks-tree-file.html
@@ -0,0 +1 @@
+
diff --git a/javascript/extraNetworks.js b/javascript/extraNetworks.js
index 40309d557..33f45c8e4 100644
--- a/javascript/extraNetworks.js
+++ b/javascript/extraNetworks.js
@@ -253,6 +253,28 @@ function saveCardPreview(event, tabname, filename) {
event.preventDefault();
}
+function extraNetworksFolderClick(event, tabs_id) {
+ var els = document.querySelectorAll(".folder-item-summary.selected");
+ [...els].forEach(el => {
+ el.classList.remove("selected");
+ });
+ event.target.classList.add("selected");
+
+ var searchTextArea = gradioApp().querySelector("#" + tabs_id + ' > label > textarea');
+ var text = event.target.classList.contains("search-all") ? "" : event.target.firstChild.textContent.trim();
+ searchTextArea.value = text;
+ updateInput(searchTextArea);
+
+ if (event.target.parentElement.open) {
+ // before close
+ console.log("closed");
+ } else {
+ // before open
+ console.log("opened");
+ //console.log("Opened:", event.target.parentElement);
+ }
+}
+
function extraNetworksSearchButton(tabs_id, event) {
var searchTextarea = gradioApp().querySelector("#" + tabs_id + ' > label > textarea');
var button = event.target;
diff --git a/modules/shared_options.py b/modules/shared_options.py
index e698c2649..d2e86ff10 100644
--- a/modules/shared_options.py
+++ b/modules/shared_options.py
@@ -238,7 +238,6 @@ options_templates.update(options_section(('extra_networks', "Extra Networks", "s
"extra_networks_dir_button_function": OptionInfo(False, "Add a '/' to the beginning of directory buttons").info("Buttons will display the contents of the selected directory without acting as a search filter."),
"extra_networks_hidden_models": OptionInfo("When searched", "Show cards for models in hidden directories", gr.Radio, {"choices": ["Always", "When searched", "Never"]}).info('"When searched" option will only show the item when the search string has 4 characters or more'),
"extra_networks_default_multiplier": OptionInfo(1.0, "Default multiplier for extra networks", gr.Slider, {"minimum": 0.0, "maximum": 2.0, "step": 0.01}),
- "extra_networks_tree_view": OptionInfo(False, "Show extra networks using a directory tree view.").needs_reload_ui(),
"extra_networks_card_width": OptionInfo(0, "Card width for Extra Networks").info("in pixels"),
"extra_networks_card_height": OptionInfo(0, "Card height for Extra Networks").info("in pixels"),
"extra_networks_card_text_scale": OptionInfo(1.0, "Card text scale", gr.Slider, {"minimum": 0.0, "maximum": 2.0, "step": 0.01}).info("1 = original size"),
diff --git a/modules/ui_extra_networks.py b/modules/ui_extra_networks.py
index ab484a5dc..6318594fa 100644
--- a/modules/ui_extra_networks.py
+++ b/modules/ui_extra_networks.py
@@ -73,10 +73,11 @@ def get_tree(paths: Union[str, list[str]], items: dict[str, ExtraNetworksItem])
# the value can be an empty dict if the directory is empty. We want these
# placeholders for empty dirs so we can inform the user later.
for path in paths:
+ short_path = os.path.basename(path)
# Wrap the path in a list since that is what the `_get_tree` expects.
- res[path] = _get_tree([path])
- if res[path]:
- res[path] = res[path][os.path.basename(path)]
+ res[short_path] = _get_tree([path])
+ if res[short_path]:
+ res[short_path] = res[short_path][os.path.basename(path)]
return res
@@ -153,10 +154,9 @@ class ExtraNetworksPage:
self.title = title
self.name = title.lower()
self.id_page = self.name.replace(" ", "_")
- if shared.opts.extra_networks_tree_view:
- self.card_page = shared.html("extra-networks-card-minimal.html")
- else:
- self.card_page = shared.html("extra-networks-card.html")
+ self.extra_networks_pane_template = shared.html("extra-networks-pane.html")
+ self.card_page_template = shared.html("extra-networks-card.html")
+ self.card_page_minimal_template = shared.html("extra-networks-card-minimal.html")
self.allow_prompt = True
self.allow_negative_prompt = False
self.metadata = {}
@@ -182,15 +182,14 @@ class ExtraNetworksPage:
def search_terms_from_path(self, filename, possible_directories=None):
abspath = os.path.abspath(filename)
-
for parentdir in (possible_directories if possible_directories is not None else self.allowed_directories_for_previews()):
- parentdir = os.path.abspath(parentdir)
+ parentdir = os.path.dirname(os.path.abspath(parentdir))
if abspath.startswith(parentdir):
- return abspath[len(parentdir):].replace('\\', '/')
+ return os.path.relpath(abspath, parentdir)
return ""
- def create_item_html(self, tabname: str, item: dict) -> str:
+ def create_item_html(self, tabname: str, item: dict, template: Optional[str] = None) -> str:
"""Generates HTML for a single ExtraNetworks Item
Args:
@@ -265,7 +264,10 @@ class ExtraNetworksPage:
"tabname": quote_js(tabname),
}
- return self.card_page.format(**args)
+ if template:
+ return template.format(**args)
+ else:
+ return self.card_page.format(**args)
def create_tree_view_html(self, tabname: str) -> str:
"""Generates HTML for displaying folders in a tree view.
@@ -276,53 +278,67 @@ class ExtraNetworksPage:
Returns:
HTML string generated for this tree view.
"""
- self_name_id = self.name.replace(" ", "_")
- res = f"
"
-
- self.metadata = {}
- self.items = {x["name"]: x for x in self.list_items()}
+ res = f""
+ # Generate HTML for the tree.
roots = self.allowed_directories_for_previews()
tree_items = {v["filename"]: ExtraNetworksItem(v) for v in self.items.values()}
tree = get_tree([os.path.abspath(x) for x in roots], items=tree_items)
if not tree:
- return res + "
"
# Add each root directory to the tree.
for k, v in sorted(tree.items(), key=lambda x: shared.natural_sort_key(x[0])):
# If root is empty, append the "disabled" attribute to the template details tag.
- res += dir_template.format("open" if v else "open disabled", k, _build_tree(v))
+ res += "
"
+ res += dir_template.format(
+ **{
+ "attributes": "open" if v else "open",
+ "tabname": tabname,
+ "folder_name": k,
+ "content": _build_tree(v),
+ }
+ )
+ res += "
"
res += "
"
- res += ""
return res
- def create_card_view_html(self, tabname):
- items_html = ""
- self.metadata = {}
+ def create_subdirs_html(self, tabname):
subdirs = {}
for parentdir in [os.path.abspath(x) for x in self.allowed_directories_for_previews()]:
@@ -355,43 +371,53 @@ class ExtraNetworksPage:
subdirs = {"": 1, **subdirs}
subdirs_html_template = (
- "