Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
S
Stable Diffusion Webui
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Locked Files
Issues
0
Issues
0
List
Boards
Labels
Service Desk
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Security & Compliance
Security & Compliance
Dependency List
License Compliance
Packages
Packages
List
Container Registry
Analytics
Analytics
CI / CD
Code Review
Insights
Issues
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
novelai-storage
Stable Diffusion Webui
Commits
4f962670
Commit
4f962670
authored
Jan 16, 2024
by
Sj-Si
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Finish cleanup.
parent
1fdc18e6
Changes
11
Show whitespace changes
Inline
Side-by-side
Showing
11 changed files
with
288 additions
and
168 deletions
+288
-168
html/extra-networks-card-minimal.html
html/extra-networks-card-minimal.html
+0
-4
html/extra-networks-card.html
html/extra-networks-card.html
+5
-5
html/extra-networks-edit-item-button.html
html/extra-networks-edit-item-button.html
+1
-1
html/extra-networks-metadata-button.html
html/extra-networks-metadata-button.html
+1
-1
html/extra-networks-pane.html
html/extra-networks-pane.html
+3
-3
html/extra-networks-tree-button.html
html/extra-networks-tree-button.html
+1
-2
html/extra-networks-tree.html
html/extra-networks-tree.html
+7
-7
javascript/extraNetworks.js
javascript/extraNetworks.js
+90
-80
modules/ui_extra_networks.py
modules/ui_extra_networks.py
+123
-39
modules/ui_extra_networks_user_metadata.py
modules/ui_extra_networks_user_metadata.py
+1
-1
style.css
style.css
+56
-25
No files found.
html/extra-networks-card-minimal.html
deleted
100644 → 0
View file @
1fdc18e6
<div
class=
"card-minimal"
onclick=
{card_clicked}
data-name=
"{name}"
>
<span
class=
"name"
>
{name}
</span>
<span
class=
"button-row"
>
{copy_path_button}{metadata_button}{edit_button}
</span>
</div>
html/extra-networks-card.html
View file @
4f962670
<div
class=
"card"
style=
{style}
onclick=
"{card_clicked}"
data-name=
"{name}"
{
sort_keys
}
>
<div
class=
"card"
style=
"{style}"
onclick=
"{card_clicked}"
data-name=
"{name}"
{
sort_keys
}
>
{background_image}
{background_image}
<div
class=
"button-row"
>
{copy_path_button}{metadata_button}{edit_button}
</div>
<div
class=
"button-row"
>
{copy_path_button}{metadata_button}{edit_button}
</div>
<div
class=
'actions'
>
<div
class=
"actions"
>
<div
class=
'additional'
>
{search_terms}
</div>
<div
class=
"additional"
>
{search_terms}
</div>
<span
class=
'name'
>
{name}
</span>
<span
class=
"name"
>
{name}
</span>
<span
class=
'description'
>
{description}
</span>
<span
class=
"description"
>
{description}
</span>
</div>
</div>
</div>
</div>
html/extra-networks-edit-item-button.html
View file @
4f962670
<div
class=
"edit-button card-button"
<div
class=
"edit-button card-button"
title=
"Edit metadata"
title=
"Edit metadata"
onclick=
"extraNetworksEditUserMetadata(event, '{tabname}', '{
page_id
}', '{name}')"
>
onclick=
"extraNetworksEditUserMetadata(event, '{tabname}', '{
extra_networks_tabname
}', '{name}')"
>
</div>
</div>
\ No newline at end of file
html/extra-networks-metadata-button.html
View file @
4f962670
<div
class=
"metadata-button card-button"
<div
class=
"metadata-button card-button"
title=
"Show internal metadata"
title=
"Show internal metadata"
onclick=
"extraNetworksRequestMetadata(event, '{
page_id
}', '{name}')"
>
onclick=
"extraNetworksRequestMetadata(event, '{
extra_networks_tabname
}', '{name}')"
>
</div>
</div>
\ No newline at end of file
html/extra-networks-pane.html
View file @
4f962670
<div
id=
'{tabname}_{
network_type_id
}_pane'
class=
'extra-network-pane'
>
<div
id=
'{tabname}_{
extra_networks_tabname
}_pane'
class=
'extra-network-pane'
>
<div
id=
'{tabname}_{
network_type_id
}_tree'
class=
'extra-network-tree'
>
<div
id=
'{tabname}_{
extra_networks_tabname
}_tree'
class=
'extra-network-tree'
>
{tree_html}
{tree_html}
</div>
</div>
<div
id=
'{tabname}_{
network_type_id
}_cards'
class=
'extra-network-cards'
>
<div
id=
'{tabname}_{
extra_networks_tabname
}_cards'
class=
'extra-network-cards'
>
{items_html}
{items_html}
</div>
</div>
</div>
</div>
\ No newline at end of file
html/extra-networks-tree-button.html
View file @
4f962670
<span
data-filterable-item-text
hidden
>
{search_terms}
</span>
<span
data-filterable-item-text
hidden
>
{search_terms}
</span>
<div
class=
"tree-list-content {subclass}"
<div
class=
"tree-list-content {subclass}"
expanded=
"false"
type=
"button"
type=
"button"
onclick=
"extraNetworksTreeOnClick(event, '{tabname}', '{
tab_id
}');{onclick_extra}"
onclick=
"extraNetworksTreeOnClick(event, '{tabname}', '{
extra_networks_tabname
}');{onclick_extra}"
data-path=
"{data_path}"
data-path=
"{data_path}"
data-hash=
"{data_hash}"
data-hash=
"{data_hash}"
>
>
...
...
html/extra-networks-tree.html
View file @
4f962670
...
@@ -2,36 +2,36 @@
...
@@ -2,36 +2,36 @@
<div
class=
"tree-list-controls"
>
<div
class=
"tree-list-controls"
>
<div
class=
"tree-list-search"
>
<div
class=
"tree-list-search"
>
<input
<input
id=
"{tabname}_{
tab_id
}_extra_search"
id=
"{tabname}_{
extra_networks_tabname
}_extra_search"
class=
"tree-list-search-text"
class=
"tree-list-search-text"
type=
"search"
type=
"search"
placeholder=
"Filter files"
placeholder=
"Filter files"
>
>
</div>
</div>
<div
<div
id=
"{tabname}_{
tab_id
}_extra_sort"
id=
"{tabname}_{
extra_networks_tabname
}_extra_sort"
class=
"tree-list-sort"
class=
"tree-list-sort"
data-sortmode=
"path"
data-sortmode=
"path"
data-sortkey=
"sortPath-Ascending-640"
data-sortkey=
"sortPath-Ascending-640"
title=
"Sort by path"
title=
"Sort by path"
onclick=
"extraNetworksTreeSortOnClick(event, '{tabname}', '{
tab_id
}');"
onclick=
"extraNetworksTreeSortOnClick(event, '{tabname}', '{
extra_networks_tabname
}');"
>
>
<i
class=
"tree-list-sort-icon"
></i>
<i
class=
"tree-list-sort-icon"
></i>
</div>
</div>
<div
<div
id=
"{tabname}_{
tab_id
}_extra_sort_dir"
id=
"{tabname}_{
extra_networks_tabname
}_extra_sort_dir"
class=
"tree-list-sort-dir"
class=
"tree-list-sort-dir"
data-sortdir=
"Ascending"
data-sortdir=
"Ascending"
title=
"Sort ascending"
title=
"Sort ascending"
onclick=
"extraNetworksTreeSortDirOnClick(event, '{tabname}', '{
tab_id
}');"
onclick=
"extraNetworksTreeSortDirOnClick(event, '{tabname}', '{
extra_networks_tabname
}');"
>
>
<i
class=
"tree-list-sort-dir-icon"
></i>
<i
class=
"tree-list-sort-dir-icon"
></i>
</div>
</div>
<div
<div
id=
"{tabname}_{
tab_id
}_extra_refresh"
id=
"{tabname}_{
extra_networks_tabname
}_extra_refresh"
class=
"tree-list-refresh"
class=
"tree-list-refresh"
title=
"Refresh page"
title=
"Refresh page"
onclick=
"extraNetworksTreeRefreshOnClick(event, '{tabname}', '{
tab_id
}');"
onclick=
"extraNetworksTreeRefreshOnClick(event, '{tabname}', '{
extra_networks_tabname
}');"
>
>
<i
class=
"tree-list-refresh-icon"
></i>
<i
class=
"tree-list-refresh-icon"
></i>
</div>
</div>
...
...
javascript/extraNetworks.js
View file @
4f962670
...
@@ -31,25 +31,15 @@ function setupExtraNetworksForTab(tabname) {
...
@@ -31,25 +31,15 @@ function setupExtraNetworksForTab(tabname) {
var
this_tab
=
gradioApp
().
querySelector
(
'
#
'
+
tabname
+
'
_extra_tabs
'
);
var
this_tab
=
gradioApp
().
querySelector
(
'
#
'
+
tabname
+
'
_extra_tabs
'
);
this_tab
.
classList
.
add
(
'
extra-networks
'
);
this_tab
.
classList
.
add
(
'
extra-networks
'
);
this_tab
.
querySelectorAll
(
"
:scope > [id^='
"
+
tabname
+
"
_']
"
).
forEach
(
function
(
elem
)
{
this_tab
.
querySelectorAll
(
"
:scope > [id^='
"
+
tabname
+
"
_']
"
).
forEach
(
function
(
elem
)
{
var
tab_id
=
elem
.
getAttribute
(
"
id
"
);
var
extra_networks_tabname
=
elem
.
id
;
var
search
=
gradioApp
().
querySelector
(
"
#
"
+
tab_id
+
"
_extra_search
"
);
var
search
=
gradioApp
().
querySelector
(
"
#
"
+
extra_networks_tabname
+
"
_extra_search
"
);
if
(
!
search
)
{
var
sort_mode
=
gradioApp
().
querySelector
(
"
#
"
+
extra_networks_tabname
+
"
_extra_sort
"
);
return
;
// `continue` doesn't work in `forEach` loops. This is equivalent.
var
sort_dir
=
gradioApp
().
querySelector
(
"
#
"
+
extra_networks_tabname
+
"
_extra_sort_dir
"
);
}
var
refresh
=
gradioApp
().
querySelector
(
"
#
"
+
extra_networks_tabname
+
"
_extra_refresh
"
);
var
sort
=
gradioApp
().
querySelector
(
"
#
"
+
tab_id
+
"
_extra_sort
"
);
if
(
!
sort
)
{
return
;
// `continue` doesn't work in `forEach` loops. This is equivalent.
}
var
sort_dir
=
gradioApp
().
querySelector
(
"
#
"
+
tab_id
+
"
_extra_sort_dir
"
);
// If any of the buttons above don't exist, we want to skip this iteration of the loop.
if
(
!
sort_dir
)
{
if
(
!
search
||
!
sort_mode
||
!
sort_dir
||
!
refresh
)
{
return
;
// `continue` doesn't work in `forEach` loops. This is equivalent.
return
;
// `return` is equivalent of `continue` but for forEach loops.
}
var
refresh
=
gradioApp
().
querySelector
(
"
#
"
+
tab_id
+
"
_extra_refresh
"
);
if
(
!
refresh
)
{
return
;
// `continue` doesn't work in `forEach` loops. This is equivalent.
}
}
var
applyFilter
=
function
()
{
var
applyFilter
=
function
()
{
...
@@ -78,14 +68,14 @@ function setupExtraNetworksForTab(tabname) {
...
@@ -78,14 +68,14 @@ function setupExtraNetworksForTab(tabname) {
var
cards
=
gradioApp
().
querySelectorAll
(
'
#
'
+
tabname
+
'
_extra_tabs div.card
'
);
var
cards
=
gradioApp
().
querySelectorAll
(
'
#
'
+
tabname
+
'
_extra_tabs div.card
'
);
var
reverse
=
sort_dir
.
dataset
.
sortdir
==
"
Descending
"
;
var
reverse
=
sort_dir
.
dataset
.
sortdir
==
"
Descending
"
;
var
sortKey
=
sort
.
dataset
.
sortmode
.
toLowerCase
().
replace
(
"
sort
"
,
""
).
replaceAll
(
"
"
,
"
_
"
).
replace
(
/_+$/
,
""
).
trim
()
||
"
name
"
;
var
sortKey
=
sort
_mode
.
dataset
.
sortmode
.
toLowerCase
().
replace
(
"
sort
"
,
""
).
replaceAll
(
"
"
,
"
_
"
).
replace
(
/_+$/
,
""
).
trim
()
||
"
name
"
;
sortKey
=
"
sort
"
+
sortKey
.
charAt
(
0
).
toUpperCase
()
+
sortKey
.
slice
(
1
);
sortKey
=
"
sort
"
+
sortKey
.
charAt
(
0
).
toUpperCase
()
+
sortKey
.
slice
(
1
);
var
sortKeyStore
=
sortKey
+
"
-
"
+
(
reverse
?
"
Descending
"
:
"
Ascending
"
)
+
"
-
"
+
cards
.
length
;
var
sortKeyStore
=
sortKey
+
"
-
"
+
(
reverse
?
"
Descending
"
:
"
Ascending
"
)
+
"
-
"
+
cards
.
length
;
if
(
sortKeyStore
==
sort
.
dataset
.
sortkey
)
{
if
(
sortKeyStore
==
sort
_mode
.
dataset
.
sortkey
)
{
return
;
return
;
}
}
sort
.
dataset
.
sortkey
=
sortKeyStore
;
sort
_mode
.
dataset
.
sortkey
=
sortKeyStore
;
cards
.
forEach
(
function
(
card
)
{
cards
.
forEach
(
function
(
card
)
{
card
.
originalParentElement
=
card
.
parentElement
;
card
.
originalParentElement
=
card
.
parentElement
;
...
@@ -115,8 +105,8 @@ function setupExtraNetworksForTab(tabname) {
...
@@ -115,8 +105,8 @@ function setupExtraNetworksForTab(tabname) {
applySort
();
applySort
();
applyFilter
();
applyFilter
();
extraNetworksApplySort
[
tab_id
]
=
applySort
;
extraNetworksApplySort
[
extra_networks_tabname
]
=
applySort
;
extraNetworksApplyFilter
[
tab_id
]
=
applyFilter
;
extraNetworksApplyFilter
[
extra_networks_tabname
]
=
applyFilter
;
});
});
registerPrompt
(
tabname
,
tabname
+
"
_prompt
"
);
registerPrompt
(
tabname
,
tabname
+
"
_prompt
"
);
...
@@ -148,14 +138,6 @@ function extraNetworksMovePromptToTab(tabname, id, showPrompt, showNegativePromp
...
@@ -148,14 +138,6 @@ function extraNetworksMovePromptToTab(tabname, id, showPrompt, showNegativePromp
}
}
}
}
function
clearSearch
(
tabname
)
{
// Clear search box.
var
tab_id
=
tabname
+
"
_extra_search
"
;
var
searchTextarea
=
gradioApp
().
querySelector
(
"
#
"
+
tab_id
+
'
> label > textarea
'
);
searchTextarea
.
value
=
""
;
updateInput
(
searchTextarea
);
}
function
extraNetworksUnrelatedTabSelected
(
tabname
)
{
// called from python when user selects an unrelated tab (generate)
function
extraNetworksUnrelatedTabSelected
(
tabname
)
{
// called from python when user selects an unrelated tab (generate)
extraNetworksMovePromptToTab
(
tabname
,
''
,
false
,
false
);
extraNetworksMovePromptToTab
(
tabname
,
''
,
false
,
false
);
...
@@ -264,22 +246,20 @@ function saveCardPreview(event, tabname, filename) {
...
@@ -264,22 +246,20 @@ function saveCardPreview(event, tabname, filename) {
event
.
preventDefault
();
event
.
preventDefault
();
}
}
function
extraNetworksTreeProcessFileClick
(
event
,
btn
,
tabname
,
tab_id
)
{
function
extraNetworksTreeProcessFileClick
(
event
,
btn
,
tabname
,
extra_networks_tabname
)
{
/**
/**
* Processes `onclick` events when user clicks on files in tree.
* Processes `onclick` events when user clicks on files in tree.
*
*
* @param event The generated event.
* @param event The generated event.
* @param btn The clicked `tree-list-item` button.
* @param btn The clicked `tree-list-item` button.
* @param tabname The name of the active tab in the sd webui. Ex: txt2img, img2img, etc.
* @param tabname The name of the active tab in the sd webui. Ex: txt2img, img2img, etc.
* @param
tab_id
The id of the active extraNetworks tab. Ex: lora, checkpoints, etc.
* @param
extra_networks_tabname
The id of the active extraNetworks tab. Ex: lora, checkpoints, etc.
*/
*/
var
par
=
btn
.
parentElement
;
// NOTE: Currently unused.
var
search_id
=
tabname
+
"
_
"
+
tab_id
+
"
_extra_search
"
;
return
;
var
type
=
par
.
getAttribute
(
"
data-tree-entry-type
"
);
var
path
=
btn
.
getAttribute
(
"
data-path
"
);
}
}
function
extraNetworksTreeProcessDirectoryClick
(
event
,
btn
,
tabname
,
tab_id
)
{
function
extraNetworksTreeProcessDirectoryClick
(
event
,
btn
,
tabname
,
extra_networks_tabname
)
{
/**
/**
* Processes `onclick` events when user clicks on directories in tree.
* Processes `onclick` events when user clicks on directories in tree.
*
*
...
@@ -292,7 +272,7 @@ function extraNetworksTreeProcessDirectoryClick(event, btn, tabname, tab_id) {
...
@@ -292,7 +272,7 @@ function extraNetworksTreeProcessDirectoryClick(event, btn, tabname, tab_id) {
* @param event The generated event.
* @param event The generated event.
* @param btn The clicked `tree-list-item` button.
* @param btn The clicked `tree-list-item` button.
* @param tabname The name of the active tab in the sd webui. Ex: txt2img, img2img, etc.
* @param tabname The name of the active tab in the sd webui. Ex: txt2img, img2img, etc.
* @param
tab_id
The id of the active extraNetworks tab. Ex: lora, checkpoints, etc.
* @param
extra_networks_tabname
The id of the active extraNetworks tab. Ex: lora, checkpoints, etc.
*/
*/
var
ul
=
btn
.
nextElementSibling
;
var
ul
=
btn
.
nextElementSibling
;
// This is the actual target that the user clicked on within the target button.
// This is the actual target that the user clicked on within the target button.
...
@@ -301,12 +281,12 @@ function extraNetworksTreeProcessDirectoryClick(event, btn, tabname, tab_id) {
...
@@ -301,12 +281,12 @@ function extraNetworksTreeProcessDirectoryClick(event, btn, tabname, tab_id) {
function
_expand_or_collapse
(
_ul
,
_btn
)
{
function
_expand_or_collapse
(
_ul
,
_btn
)
{
// Expands <ul> if it is collapsed, collapses otherwise. Updates button attributes.
// Expands <ul> if it is collapsed, collapses otherwise. Updates button attributes.
if
(
_ul
.
hasAttribute
(
"
data-
hidden
"
))
{
if
(
_ul
.
hasAttribute
(
"
hidden
"
))
{
_ul
.
removeAttribute
(
"
data-
hidden
"
);
_ul
.
removeAttribute
(
"
hidden
"
);
_btn
.
setAttribute
(
"
expanded
"
,
"
true
"
)
;
_btn
.
dataset
.
expanded
=
""
;
}
else
{
}
else
{
_ul
.
setAttribute
(
"
data-
hidden
"
,
""
);
_ul
.
setAttribute
(
"
hidden
"
,
""
);
_btn
.
setAttribute
(
"
expanded
"
,
"
false
"
)
;
delete
_btn
.
dataset
.
expanded
;
}
}
}
}
...
@@ -314,19 +294,19 @@ function extraNetworksTreeProcessDirectoryClick(event, btn, tabname, tab_id) {
...
@@ -314,19 +294,19 @@ function extraNetworksTreeProcessDirectoryClick(event, btn, tabname, tab_id) {
// Removes the `selected` attribute from all buttons.
// Removes the `selected` attribute from all buttons.
var
sels
=
document
.
querySelectorAll
(
"
div.tree-list-content
"
);
var
sels
=
document
.
querySelectorAll
(
"
div.tree-list-content
"
);
[...
sels
].
forEach
(
el
=>
{
[...
sels
].
forEach
(
el
=>
{
el
.
removeAttribute
(
"
selected
"
)
;
delete
el
.
dataset
.
selected
;
});
});
}
}
function
_select_button
(
_btn
)
{
function
_select_button
(
_btn
)
{
// Removes `selected` attribute from all buttons then adds to passed button.
// Removes `
data-
selected` attribute from all buttons then adds to passed button.
_remove_selected_from_all
();
_remove_selected_from_all
();
_btn
.
setAttribute
(
"
selected
"
,
""
)
;
_btn
.
dataset
.
selected
=
""
;
}
}
function
_update_search
(
_tabname
,
_
tab_id
,
_search_text
)
{
function
_update_search
(
_tabname
,
_
extra_networks_tabname
,
_search_text
)
{
// Update search input with select button's path.
// Update search input with select button's path.
var
search_input_elem
=
gradioApp
().
querySelector
(
"
#
"
+
tabname
+
"
_
"
+
tab_id
+
"
_extra_search
"
);
var
search_input_elem
=
gradioApp
().
querySelector
(
"
#
"
+
tabname
+
"
_
"
+
extra_networks_tabname
+
"
_extra_search
"
);
search_input_elem
.
value
=
_search_text
;
search_input_elem
.
value
=
_search_text
;
updateInput
(
search_input_elem
);
updateInput
(
search_input_elem
);
}
}
...
@@ -337,26 +317,26 @@ function extraNetworksTreeProcessDirectoryClick(event, btn, tabname, tab_id) {
...
@@ -337,26 +317,26 @@ function extraNetworksTreeProcessDirectoryClick(event, btn, tabname, tab_id) {
_expand_or_collapse
(
ul
,
btn
);
_expand_or_collapse
(
ul
,
btn
);
}
else
{
}
else
{
// User clicked anywhere else on the button.
// User clicked anywhere else on the button.
if
(
btn
.
hasAttribute
(
"
selected
"
)
&&
!
ul
.
hasAttribute
(
"
data-hidden
"
))
{
if
(
"
selected
"
in
btn
.
dataset
&&
!
(
ul
.
hasAttribute
(
"
hidden
"
)
))
{
// If folder is select and open, collapse and deselect button.
// If folder is select and open, collapse and deselect button.
_expand_or_collapse
(
ul
,
btn
);
_expand_or_collapse
(
ul
,
btn
);
btn
.
removeAttribute
(
"
selected
"
)
;
delete
btn
.
dataset
.
selected
;
_update_search
(
tabname
,
tab_id
,
""
);
_update_search
(
tabname
,
extra_networks_tabname
,
""
);
}
else
if
(
!
(
!
btn
.
hasAttribute
(
"
selected
"
)
&&
!
ul
.
hasAttribute
(
"
data-hidden
"
)))
{
}
else
if
(
!
(
!
(
"
selected
"
in
btn
.
dataset
)
&&
!
(
ul
.
hasAttribute
(
"
hidden
"
)
)))
{
// If folder is open and not selected, then we don't collapse; just select.
// If folder is open and not selected, then we don't collapse; just select.
// NOTE: Double inversion sucks but it is the clearest way to show the branching here.
// NOTE: Double inversion sucks but it is the clearest way to show the branching here.
_expand_or_collapse
(
ul
,
btn
);
_expand_or_collapse
(
ul
,
btn
);
_select_button
(
btn
,
tabname
,
tab_id
);
_select_button
(
btn
,
tabname
,
extra_networks_tabname
);
_update_search
(
tabname
,
tab_id
,
btn
.
getAttribute
(
"
data-path
"
)
);
_update_search
(
tabname
,
extra_networks_tabname
,
btn
.
dataset
.
path
);
}
else
{
}
else
{
// All other cases, just select the button.
// All other cases, just select the button.
_select_button
(
btn
,
tabname
,
tab_id
);
_select_button
(
btn
,
tabname
,
extra_networks_tabname
);
_update_search
(
tabname
,
tab_id
,
btn
.
getAttribute
(
"
data-path
"
)
);
_update_search
(
tabname
,
extra_networks_tabname
,
btn
.
dataset
.
path
);
}
}
}
}
}
}
function
extraNetworksTreeOnClick
(
event
,
tabname
,
tab_id
)
{
function
extraNetworksTreeOnClick
(
event
,
tabname
,
extra_networks_tabname
)
{
/**
/**
* Handles `onclick` events for buttons within an `extra-network-tree .tree-list--tree`.
* Handles `onclick` events for buttons within an `extra-network-tree .tree-list--tree`.
*
*
...
@@ -365,20 +345,30 @@ function extraNetworksTreeOnClick(event, tabname, tab_id) {
...
@@ -365,20 +345,30 @@ function extraNetworksTreeOnClick(event, tabname, tab_id) {
*
*
* @param event The generated event.
* @param event The generated event.
* @param tabname The name of the active tab in the sd webui. Ex: txt2img, img2img, etc.
* @param tabname The name of the active tab in the sd webui. Ex: txt2img, img2img, etc.
* @param
tab_id
The id of the active extraNetworks tab. Ex: lora, checkpoints, etc.
* @param
extra_networks_tabname
The id of the active extraNetworks tab. Ex: lora, checkpoints, etc.
*/
*/
var
btn
=
event
.
currentTarget
;
var
btn
=
event
.
currentTarget
;
var
par
=
btn
.
parentElement
;
var
par
=
btn
.
parentElement
;
if
(
par
.
getAttribute
(
"
data-tree-entry-type
"
)
===
"
file
"
)
{
if
(
par
.
dataset
.
treeEntryType
===
"
file
"
)
{
extraNetworksTreeProcessFileClick
(
event
,
btn
,
tabname
,
tab_id
);
extraNetworksTreeProcessFileClick
(
event
,
btn
,
tabname
,
extra_networks_tabname
);
}
else
{
}
else
{
extraNetworksTreeProcessDirectoryClick
(
event
,
btn
,
tabname
,
tab_id
);
extraNetworksTreeProcessDirectoryClick
(
event
,
btn
,
tabname
,
extra_networks_tabname
);
}
}
}
}
function
extraNetworksTreeSortOnClick
(
event
,
tabname
,
tab_id
)
{
function
extraNetworksTreeSortOnClick
(
event
,
tabname
,
extra_networks_tabname
)
{
/**
* Handles `onclick` events for the Sort Mode button.
*
* Modifies the data attributes of the Sort Mode button to cycle between
* various sorting modes.
*
* @param event The generated event.
* @param tabname The name of the active tab in the sd webui. Ex: txt2img, img2img, etc.
* @param extra_networks_tabname The id of the active extraNetworks tab. Ex: lora, checkpoints, etc.
*/
var
curr_mode
=
event
.
currentTarget
.
dataset
.
sortmode
;
var
curr_mode
=
event
.
currentTarget
.
dataset
.
sortmode
;
var
el_sort_dir
=
gradioApp
().
querySelector
(
"
#
"
+
tabname
+
"
_
"
+
tab_id
+
"
_extra_sort_dir
"
);
var
el_sort_dir
=
gradioApp
().
querySelector
(
"
#
"
+
tabname
+
"
_
"
+
extra_networks_tabname
+
"
_extra_sort_dir
"
);
var
sort_dir
=
el_sort_dir
.
dataset
.
sortdir
;
var
sort_dir
=
el_sort_dir
.
dataset
.
sortdir
;
if
(
curr_mode
==
"
path
"
)
{
if
(
curr_mode
==
"
path
"
)
{
event
.
currentTarget
.
dataset
.
sortmode
=
"
name
"
;
event
.
currentTarget
.
dataset
.
sortmode
=
"
name
"
;
...
@@ -397,23 +387,43 @@ function extraNetworksTreeSortOnClick(event, tabname, tab_id) {
...
@@ -397,23 +387,43 @@ function extraNetworksTreeSortOnClick(event, tabname, tab_id) {
event
.
currentTarget
.
dataset
.
sortkey
=
"
sortPath-
"
+
sort_dir
+
"
-640
"
;
event
.
currentTarget
.
dataset
.
sortkey
=
"
sortPath-
"
+
sort_dir
+
"
-640
"
;
event
.
currentTarget
.
setAttribute
(
"
title
"
,
"
Sort by path
"
);
event
.
currentTarget
.
setAttribute
(
"
title
"
,
"
Sort by path
"
);
}
}
applyExtraNetworkSort
(
tabname
+
"
_
"
+
tab_id
);
applyExtraNetworkSort
(
tabname
+
"
_
"
+
extra_networks_tabname
);
}
}
function
extraNetworksTreeSortDirOnClick
(
event
,
tabname
,
tab_id
)
{
function
extraNetworksTreeSortDirOnClick
(
event
,
tabname
,
extra_networks_tabname
)
{
var
curr_dir
=
event
.
currentTarget
.
getAttribute
(
"
data-sortdir
"
);
/**
if
(
curr_dir
==
"
Ascending
"
)
{
* Handles `onclick` events for the Sort Direction button.
*
* Modifies the data attributes of the Sort Direction button to cycle between
* ascending and descending sort directions.
*
* @param event The generated event.
* @param tabname The name of the active tab in the sd webui. Ex: txt2img, img2img, etc.
* @param extra_networks_tabname The id of the active extraNetworks tab. Ex: lora, checkpoints, etc.
*/
if
(
event
.
currentTarget
.
dataset
.
sortdir
==
"
Ascending
"
)
{
event
.
currentTarget
.
dataset
.
sortdir
=
"
Descending
"
;
event
.
currentTarget
.
dataset
.
sortdir
=
"
Descending
"
;
event
.
currentTarget
.
setAttribute
(
"
title
"
,
"
Sort descending
"
);
event
.
currentTarget
.
setAttribute
(
"
title
"
,
"
Sort descending
"
);
}
else
{
}
else
{
event
.
currentTarget
.
dataset
.
sortdir
=
"
Ascending
"
;
event
.
currentTarget
.
dataset
.
sortdir
=
"
Ascending
"
;
event
.
currentTarget
.
setAttribute
(
"
title
"
,
"
Sort ascending
"
);
event
.
currentTarget
.
setAttribute
(
"
title
"
,
"
Sort ascending
"
);
}
}
applyExtraNetworkSort
(
tabname
+
"
_
"
+
tab_id
);
applyExtraNetworkSort
(
tabname
+
"
_
"
+
extra_networks_tabname
);
}
}
function
extraNetworksTreeRefreshOnClick
(
event
,
tabname
,
tab_id
)
{
function
extraNetworksTreeRefreshOnClick
(
event
,
tabname
,
extra_networks_tabname
)
{
console
.
log
(
"
refresh clicked
"
);
/**
* Handles `onclick` events for the Refresh Page button.
*
* In order to actually call the python functions in `ui_extra_networks.py`
* to refresh the page, we created an empty gradio button in that file with an
* event handler that refreshes the page. So what this function here does
* is it manually raises a `click` event on that button.
*
* @param event The generated event.
* @param tabname The name of the active tab in the sd webui. Ex: txt2img, img2img, etc.
* @param extra_networks_tabname The id of the active extraNetworks tab. Ex: lora, checkpoints, etc.
*/
var
btn_refresh_internal
=
gradioApp
().
getElementById
(
tabname
+
"
_extra_refresh_internal
"
);
var
btn_refresh_internal
=
gradioApp
().
getElementById
(
tabname
+
"
_extra_refresh_internal
"
);
btn_refresh_internal
.
dispatchEvent
(
new
Event
(
"
click
"
));
btn_refresh_internal
.
dispatchEvent
(
new
Event
(
"
click
"
));
}
}
...
...
modules/ui_extra_networks.py
View file @
4f962670
...
@@ -155,7 +155,14 @@ class ExtraNetworksPage:
...
@@ -155,7 +155,14 @@ class ExtraNetworksPage:
def
__init__
(
self
,
title
):
def
__init__
(
self
,
title
):
self
.
title
=
title
self
.
title
=
title
self
.
name
=
title
.
lower
()
self
.
name
=
title
.
lower
()
self
.
id_page
=
self
.
name
.
replace
(
" "
,
"_"
)
# This is the actual name of the extra networks tab (not txt2img/img2img).
self
.
extra_networks_tabname
=
self
.
name
.
replace
(
" "
,
"_"
)
self
.
allow_prompt
=
True
self
.
allow_negative_prompt
=
False
self
.
metadata
=
{}
self
.
items
=
{}
self
.
lister
=
util
.
MassFileLister
()
# HTML Templates
self
.
pane_tpl
=
shared
.
html
(
"extra-networks-pane.html"
)
self
.
pane_tpl
=
shared
.
html
(
"extra-networks-pane.html"
)
self
.
tree_tpl
=
shared
.
html
(
"extra-networks-tree.html"
)
self
.
tree_tpl
=
shared
.
html
(
"extra-networks-tree.html"
)
self
.
card_tpl
=
shared
.
html
(
"extra-networks-card.html"
)
self
.
card_tpl
=
shared
.
html
(
"extra-networks-card.html"
)
...
@@ -163,11 +170,6 @@ class ExtraNetworksPage:
...
@@ -163,11 +170,6 @@ class ExtraNetworksPage:
self
.
btn_copy_path_tpl
=
shared
.
html
(
"extra-networks-copy-path-button.html"
)
self
.
btn_copy_path_tpl
=
shared
.
html
(
"extra-networks-copy-path-button.html"
)
self
.
btn_metadata_tpl
=
shared
.
html
(
"extra-networks-metadata-button.html"
)
self
.
btn_metadata_tpl
=
shared
.
html
(
"extra-networks-metadata-button.html"
)
self
.
btn_edit_item_tpl
=
shared
.
html
(
"extra-networks-edit-item-button.html"
)
self
.
btn_edit_item_tpl
=
shared
.
html
(
"extra-networks-edit-item-button.html"
)
self
.
allow_prompt
=
True
self
.
allow_negative_prompt
=
False
self
.
metadata
=
{}
self
.
items
=
{}
self
.
lister
=
util
.
MassFileLister
()
def
refresh
(
self
):
def
refresh
(
self
):
pass
pass
...
@@ -202,15 +204,17 @@ class ExtraNetworksPage:
...
@@ -202,15 +204,17 @@ class ExtraNetworksPage:
item
:
dict
,
item
:
dict
,
template
:
Optional
[
str
]
=
None
,
template
:
Optional
[
str
]
=
None
,
)
->
Union
[
str
,
dict
]:
)
->
Union
[
str
,
dict
]:
"""Generates HTML for a single ExtraNetworks Item
"""Generates HTML for a single ExtraNetworks Item
.
Args:
Args:
tabname: The name of the active tab.
tabname: The name of the active tab.
item: Dictionary containing item information.
item: Dictionary containing item information.
template: Optional template string to use.
Returns:
Returns:
HTML string generated for this item.
If a template is passed:
HTML string generated for this item.
Can be empty if the item is not meant to be shown.
Can be empty if the item is not meant to be shown.
If no template is passed: A dictionary containing the generated item's attributes.
"""
"""
metadata
=
item
.
get
(
"metadata"
)
metadata
=
item
.
get
(
"metadata"
)
if
metadata
:
if
metadata
:
...
@@ -244,14 +248,14 @@ class ExtraNetworksPage:
...
@@ -244,14 +248,14 @@ class ExtraNetworksPage:
if
metadata
:
if
metadata
:
btn_metadata
=
self
.
btn_metadata_tpl
.
format
(
btn_metadata
=
self
.
btn_metadata_tpl
.
format
(
**
{
**
{
"
page_id"
:
self
.
id_pag
e
,
"
extra_networks_tabname"
:
self
.
extra_networks_tabnam
e
,
"name"
:
html
.
escape
(
item
[
"name"
]),
"name"
:
html
.
escape
(
item
[
"name"
]),
}
}
)
)
btn_edit_item
=
self
.
btn_edit_item_tpl
.
format
(
btn_edit_item
=
self
.
btn_edit_item_tpl
.
format
(
**
{
**
{
"tabname"
:
tabname
,
"tabname"
:
tabname
,
"
page_id"
:
self
.
id_pag
e
,
"
extra_networks_tabname"
:
self
.
extra_networks_tabnam
e
,
"name"
:
html
.
escape
(
item
[
"name"
]),
"name"
:
html
.
escape
(
item
[
"name"
]),
}
}
)
)
...
@@ -307,9 +311,9 @@ class ExtraNetworksPage:
...
@@ -307,9 +311,9 @@ class ExtraNetworksPage:
"search_only"
:
" search_only"
if
search_only
else
""
,
"search_only"
:
" search_only"
if
search_only
else
""
,
"search_terms"
:
search_terms_html
,
"search_terms"
:
search_terms_html
,
"sort_keys"
:
sort_keys
,
"sort_keys"
:
sort_keys
,
"style"
:
f
"
'display: none; {height}{width}; font-size: {shared.opts.extra_networks_card_text_scale*100}
%
'
"
,
"style"
:
f
"
display: none; {height}{width}; font-size: {shared.opts.extra_networks_card_text_scale*100}
%
"
,
"tabname"
:
tabname
,
"tabname"
:
tabname
,
"
tab_id"
:
self
.
id_pag
e
,
"
extra_networks_tabname"
:
self
.
extra_networks_tabnam
e
,
}
}
if
template
:
if
template
:
...
@@ -317,7 +321,32 @@ class ExtraNetworksPage:
...
@@ -317,7 +321,32 @@ class ExtraNetworksPage:
else
:
else
:
return
args
return
args
def
create_tree_dir_item_html
(
self
,
tabname
:
str
,
dir_path
:
str
,
content
:
Optional
[
str
]
=
None
)
->
Optional
[
str
]:
def
create_tree_dir_item_html
(
self
,
tabname
:
str
,
dir_path
:
str
,
content
:
Optional
[
str
]
=
None
,
)
->
Optional
[
str
]:
"""Generates HTML for a directory item in the tree.
The generated HTML is of the format:
```html
<li class="tree-list-item tree-list-item--has-subitem">
<div class="tree-list-content tree-list-content-dir"></div>
<ul class="tree-list tree-list--subgroup">
{content}
</ul>
</li>
```
Args:
tabname: The name of the active tab.
dir_path: Path to the directory for this item.
content: Optional HTML string that will be wrapped by this <ul>.
Returns:
HTML formatted string.
"""
if
not
content
:
if
not
content
:
return
None
return
None
...
@@ -326,7 +355,7 @@ class ExtraNetworksPage:
...
@@ -326,7 +355,7 @@ class ExtraNetworksPage:
"search_terms"
:
""
,
"search_terms"
:
""
,
"subclass"
:
"tree-list-content-dir"
,
"subclass"
:
"tree-list-content-dir"
,
"tabname"
:
tabname
,
"tabname"
:
tabname
,
"
tab_id"
:
self
.
id_pag
e
,
"
extra_networks_tabname"
:
self
.
extra_networks_tabnam
e
,
"onclick_extra"
:
""
,
"onclick_extra"
:
""
,
"data_path"
:
dir_path
,
"data_path"
:
dir_path
,
"data_hash"
:
""
,
"data_hash"
:
""
,
...
@@ -337,10 +366,32 @@ class ExtraNetworksPage:
...
@@ -337,10 +366,32 @@ class ExtraNetworksPage:
"action_list_item_action_trailing"
:
""
,
"action_list_item_action_trailing"
:
""
,
}
}
)
)
ul
=
f
"<ul class='tree-list tree-list--subgroup' data-hidden>{content}</ul>"
ul
=
f
"<ul class='tree-list tree-list--subgroup' hidden>{content}</ul>"
return
f
"<li class='tree-list-item tree-list-item--has-subitem' data-tree-entry-type='dir'>{btn + ul}</li>"
return
(
"<li class='tree-list-item tree-list-item--has-subitem' data-tree-entry-type='dir'>"
f
"{btn + ul}"
"</li>"
)
def
create_tree_file_item_html
(
self
,
tabname
:
str
,
file_path
:
str
,
item
:
dict
)
->
str
:
"""Generates HTML for a file item in the tree.
The generated HTML is of the format:
```html
<li class="tree-list-item tree-list-item--subitem">
<span data-filterable-item-text hidden></span>
<div class="tree-list-content tree-list-content-file"></div>
</li>
```
Args:
tabname: The name of the active tab.
file_path: The path to the file for this item.
item: Dictionary containing the item information.
def
create_tree_file_item_html
(
self
,
tabname
:
str
,
item_name
:
str
,
item
:
dict
)
->
str
:
Returns:
HTML formatted string.
"""
item_html_args
=
self
.
create_item_html
(
tabname
,
item
)
item_html_args
=
self
.
create_item_html
(
tabname
,
item
)
action_buttons
=
""
.
join
(
action_buttons
=
""
.
join
(
[
[
...
@@ -355,9 +406,9 @@ class ExtraNetworksPage:
...
@@ -355,9 +406,9 @@ class ExtraNetworksPage:
"search_terms"
:
""
,
"search_terms"
:
""
,
"subclass"
:
"tree-list-content-file"
,
"subclass"
:
"tree-list-content-file"
,
"tabname"
:
tabname
,
"tabname"
:
tabname
,
"
tab_id"
:
self
.
id_pag
e
,
"
extra_networks_tabname"
:
self
.
extra_networks_tabnam
e
,
"onclick_extra"
:
item_html_args
[
"card_clicked"
],
"onclick_extra"
:
item_html_args
[
"card_clicked"
],
"data_path"
:
item_name
,
"data_path"
:
file_path
,
"data_hash"
:
item
[
"shorthash"
],
"data_hash"
:
item
[
"shorthash"
],
"action_list_item_action_leading"
:
"<i class='tree-list-item-action-chevron'></i>"
,
"action_list_item_action_leading"
:
"<i class='tree-list-item-action-chevron'></i>"
,
"action_list_item_visual_leading"
:
"🗎"
,
"action_list_item_visual_leading"
:
"🗎"
,
...
@@ -366,11 +417,17 @@ class ExtraNetworksPage:
...
@@ -366,11 +417,17 @@ class ExtraNetworksPage:
"action_list_item_action_trailing"
:
action_buttons
,
"action_list_item_action_trailing"
:
action_buttons
,
}
}
)
)
return
f
"<li class='tree-list-item tree-list-item--subitem' data-tree-entry-type='file'>{btn}</li>"
return
(
"<li class='tree-list-item tree-list-item--subitem' data-tree-entry-type='file'>"
f
"{btn}"
"</li>"
)
def
create_tree_view_html
(
self
,
tabname
:
str
)
->
str
:
def
create_tree_view_html
(
self
,
tabname
:
str
)
->
str
:
"""Generates HTML for displaying folders in a tree view.
"""Generates HTML for displaying folders in a tree view.
The generated HTML uses `extra-networks-tree.html` as a template.
Args:
Args:
tabname: The name of the active tab.
tabname: The name of the active tab.
...
@@ -379,7 +436,7 @@ class ExtraNetworksPage:
...
@@ -379,7 +436,7 @@ class ExtraNetworksPage:
"""
"""
res
=
""
res
=
""
#
Generate HTML for the tree
.
#
Setup the tree dictionary
.
roots
=
self
.
allowed_directories_for_previews
()
roots
=
self
.
allowed_directories_for_previews
()
tree_items
=
{
v
[
"filename"
]:
ExtraNetworksItem
(
v
)
for
v
in
self
.
items
.
values
()}
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
)
tree
=
get_tree
([
os
.
path
.
abspath
(
x
)
for
x
in
roots
],
items
=
tree_items
)
...
@@ -388,7 +445,17 @@ class ExtraNetworksPage:
...
@@ -388,7 +445,17 @@ class ExtraNetworksPage:
return
res
return
res
def
_build_tree
(
data
:
Optional
[
dict
[
str
,
ExtraNetworksItem
]]
=
None
)
->
Optional
[
str
]:
def
_build_tree
(
data
:
Optional
[
dict
[
str
,
ExtraNetworksItem
]]
=
None
)
->
Optional
[
str
]:
"""Recursively builds HTML for a tree."""
"""Recursively builds HTML for a tree.
Args:
data: Dictionary representing a directory tree. Can be NoneType.
Data keys should be absolute paths from the root and values
should be subdirectory trees or an ExtraNetworksItem.
Returns:
If data is not None: HTML string
Else: None
"""
if
not
data
:
if
not
data
:
return
None
return
None
...
@@ -402,25 +469,36 @@ class ExtraNetworksPage:
...
@@ -402,25 +469,36 @@ class ExtraNetworksPage:
else
:
else
:
_dir_li
.
append
(
self
.
create_tree_dir_item_html
(
tabname
,
k
,
_build_tree
(
v
)))
_dir_li
.
append
(
self
.
create_tree_dir_item_html
(
tabname
,
k
,
_build_tree
(
v
)))
# Directories should always be displayed before files.
# Directories should always be displayed before files
so we order them here
.
return
""
.
join
(
_dir_li
)
+
""
.
join
(
_file_li
)
return
""
.
join
(
_dir_li
)
+
""
.
join
(
_file_li
)
# Add each root directory to the tree.
# Add each root directory to the tree.
for
k
,
v
in
sorted
(
tree
.
items
(),
key
=
lambda
x
:
shared
.
natural_sort_key
(
x
[
0
])):
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.
item_html
=
self
.
create_tree_dir_item_html
(
tabname
,
k
,
_build_tree
(
v
))
item_html
=
self
.
create_tree_dir_item_html
(
tabname
,
k
,
_build_tree
(
v
))
if
item_html
:
# Only add non-empty entries to the tree.
if
item_html
is
not
None
:
res
+=
item_html
res
+=
item_html
return
self
.
tree_tpl
.
format
(
return
self
.
tree_tpl
.
format
(
**
{
**
{
"tabname"
:
tabname
,
"tabname"
:
tabname
,
"
tab_id"
:
self
.
id_pag
e
,
"
extra_networks_tabname"
:
self
.
extra_networks_tabnam
e
,
"tree"
:
f
"<ul class='tree-list tree-list--tree'>{res}</ul>"
"tree"
:
f
"<ul class='tree-list tree-list--tree'>{res}</ul>"
}
}
)
)
def
create_card_view_html
(
self
,
tabname
):
def
create_card_view_html
(
self
,
tabname
:
str
)
->
str
:
"""Generates HTML for the network Card View section for a tab.
This HTML goes into the `extra-networks-pane.html` <div> with
`id='{tabname}_{extra_networks_tabname}_cards`.
Args:
tabname: The name of the active tab.
Returns:
HTML formatted string.
"""
res
=
""
res
=
""
self
.
items
=
{
x
[
"name"
]:
x
for
x
in
self
.
list_items
()}
self
.
items
=
{
x
[
"name"
]:
x
for
x
in
self
.
list_items
()}
for
item
in
self
.
items
.
values
():
for
item
in
self
.
items
.
values
():
...
@@ -433,20 +511,26 @@ class ExtraNetworksPage:
...
@@ -433,20 +511,26 @@ class ExtraNetworksPage:
return
res
return
res
def
create_html
(
self
,
tabname
):
def
create_html
(
self
,
tabname
):
"""Generates an HTML string for the current pane.
The generated HTML uses `extra-networks-pane.html` as a template.
Args:
tabname: The name of the active tab.
Returns:
HTML formatted string.
"""
self
.
lister
.
reset
()
self
.
lister
.
reset
()
self
.
metadata
=
{}
self
.
metadata
=
{}
self
.
items
=
{
x
[
"name"
]:
x
for
x
in
self
.
list_items
()}
self
.
items
=
{
x
[
"name"
]:
x
for
x
in
self
.
list_items
()}
tree_view_html
=
self
.
create_tree_view_html
(
tabname
)
card_view_html
=
self
.
create_card_view_html
(
tabname
)
network_type_id
=
self
.
id_page
return
self
.
pane_tpl
.
format
(
return
self
.
pane_tpl
.
format
(
**
{
**
{
"tabname"
:
tabname
,
"tabname"
:
tabname
,
"
network_type_id"
:
network_type_id
,
"
extra_networks_tabname"
:
self
.
extra_networks_tabname
,
"tree_html"
:
tree_view_html
,
"tree_html"
:
self
.
create_tree_view_html
(
tabname
)
,
"items_html"
:
card_view_html
,
"items_html"
:
self
.
create_card_view_html
(
tabname
)
,
}
}
)
)
...
@@ -561,16 +645,16 @@ def create_ui(interface: gr.Blocks, unrelated_tabs, tabname):
...
@@ -561,16 +645,16 @@ def create_ui(interface: gr.Blocks, unrelated_tabs, tabname):
button_refresh
=
gr
.
Button
(
"Refresh"
,
elem_id
=
tabname
+
"_extra_refresh_internal"
,
visible
=
False
)
button_refresh
=
gr
.
Button
(
"Refresh"
,
elem_id
=
tabname
+
"_extra_refresh_internal"
,
visible
=
False
)
for
page
in
ui
.
stored_extra_pages
:
for
page
in
ui
.
stored_extra_pages
:
with
gr
.
Tab
(
page
.
title
,
elem_id
=
f
"{tabname}_{page.
id_pag
e}"
,
elem_classes
=
[
"extra-page"
])
as
tab
:
with
gr
.
Tab
(
page
.
title
,
elem_id
=
f
"{tabname}_{page.
extra_networks_tabnam
e}"
,
elem_classes
=
[
"extra-page"
])
as
tab
:
with
gr
.
Column
(
elem_id
=
f
"{tabname}_{page.
id_pag
e}_prompts"
,
elem_classes
=
[
"extra-page-prompts"
]):
with
gr
.
Column
(
elem_id
=
f
"{tabname}_{page.
extra_networks_tabnam
e}_prompts"
,
elem_classes
=
[
"extra-page-prompts"
]):
pass
pass
elem_id
=
f
"{tabname}_{page.
id_pag
e}_cards_html"
elem_id
=
f
"{tabname}_{page.
extra_networks_tabnam
e}_cards_html"
page_elem
=
gr
.
HTML
(
'Loading...'
,
elem_id
=
elem_id
)
page_elem
=
gr
.
HTML
(
'Loading...'
,
elem_id
=
elem_id
)
ui
.
pages
.
append
(
page_elem
)
ui
.
pages
.
append
(
page_elem
)
page_elem
.
change
(
page_elem
.
change
(
fn
=
lambda
:
None
,
fn
=
lambda
:
None
,
_js
=
f
"function(){{applyExtraNetworkFilter({tabname}_{page.
id_pag
e}_extra_search); return []}}"
,
_js
=
f
"function(){{applyExtraNetworkFilter({tabname}_{page.
extra_networks_tabnam
e}_extra_search); return []}}"
,
inputs
=
[],
inputs
=
[],
outputs
=
[],
outputs
=
[],
)
)
...
...
modules/ui_extra_networks_user_metadata.py
View file @
4f962670
...
@@ -14,7 +14,7 @@ class UserMetadataEditor:
...
@@ -14,7 +14,7 @@ class UserMetadataEditor:
self
.
ui
=
ui
self
.
ui
=
ui
self
.
tabname
=
tabname
self
.
tabname
=
tabname
self
.
page
=
page
self
.
page
=
page
self
.
id_part
=
f
"{self.tabname}_{self.page.
id_pag
e}_edit_user_metadata"
self
.
id_part
=
f
"{self.tabname}_{self.page.
extra_networks_tabnam
e}_edit_user_metadata"
self
.
box
=
None
self
.
box
=
None
...
...
style.css
View file @
4f962670
...
@@ -879,13 +879,6 @@ footer {
...
@@ -879,13 +879,6 @@ footer {
margin-bottom
:
1em
;
margin-bottom
:
1em
;
}
}
.extra-network-pane
{
height
:
calc
(
100vh
-
24rem
);
overflow
:
clip
scroll
;
resize
:
vertical
;
min-height
:
52rem
;
}
.extra-networks
>
div
.tab-nav
{
.extra-networks
>
div
.tab-nav
{
min-height
:
3.4rem
;
min-height
:
3.4rem
;
}
}
...
@@ -1182,23 +1175,63 @@ body.resizing .resize-handle {
...
@@ -1182,23 +1175,63 @@ body.resizing .resize-handle {
/* ========================= */
/* ========================= */
.extra-network-pane
{
.extra-network-pane
{
display
:
flex
;
display
:
flex
;
}
height
:
calc
(
100vh
-
24rem
);
resize
:
vertical
;
.extra-network-pane
.extra-network-cards
{
min-height
:
52rem
;
display
:
block
;
}
}
.extra-network-pane
.extra-network-tree
{
.extra-network-pane
.extra-network-tree
{
display
:
block
;
flex
:
1
;
flex-direction
:
column
;
display
:
flex
;
font-size
:
1rem
;
font-size
:
1rem
;
min-width
:
25%
;
border
:
1px
solid
var
(
--block-border-color
);
border
:
1px
solid
var
(
--block-border-color
);
overflow
:
hidden
;
}
}
.extra-network-tree
.tree-list
{
.extra-network-pane
.extra-network-cards
{
margin
:
0
0.25rem
;
flex
:
3
;
overflow
:
clip
auto
!important
;
border
:
1px
solid
var
(
--block-border-color
);
}
.extra-network-pane
.extra-network-tree
.tree-list
{
flex
:
1
;
display
:
flex
;
flex-direction
:
column
;
padding
:
0
;
padding
:
0
;
width
:
100%
;
overflow
:
hidden
;
}
.extra-network-pane
.extra-network-tree
.tree-list
.tree-list-container
{
flex
:
1
;
overflow
:
clip
auto
!important
;
width
:
100%
;
}
.extra-network-pane
.extra-network-cards
::-webkit-scrollbar
,
.extra-network-pane
.tree-list-container
::-webkit-scrollbar
{
background-color
:
transparent
;
width
:
16px
;
}
.extra-network-pane
.extra-network-cards
::-webkit-scrollbar-track
,
.extra-network-pane
.tree-list-container
::-webkit-scrollbar-track
{
background-color
:
transparent
;
background-clip
:
content-box
;
}
.extra-network-pane
.extra-network-cards
::-webkit-scrollbar-thumb
,
.extra-network-pane
.tree-list-container
::-webkit-scrollbar-thumb
{
background-color
:
var
(
--border-color-primary
);
border-radius
:
16px
;
border
:
4px
solid
var
(
--background-fill-primary
);
}
.extra-network-pane
.extra-network-cards
::-webkit-scrollbar-button
,
.extra-network-pane
.tree-list-container
::-webkit-scrollbar-button
{
display
:
none
;
}
}
.extra-network-tree
.tree-list
.tree-list-controls
{
.extra-network-tree
.tree-list
.tree-list-controls
{
...
@@ -1244,17 +1277,15 @@ body.resizing .resize-handle {
...
@@ -1244,17 +1277,15 @@ body.resizing .resize-handle {
background-color
:
transparent
;
background-color
:
transparent
;
}
}
/* Directory <ul> visibility based on expanded attribute. */
/* Directory <ul> visibility based on
data-
expanded attribute. */
.extra-network-tree
.tree-list-content
[
expanded
=
false
]
+
.tree-list--subgroup
{
.extra-network-tree
.tree-list-content
+
.tree-list--subgroup
{
height
:
0
;
height
:
0
;
overflow
:
hidden
;
visibility
:
hidden
;
visibility
:
hidden
;
opacity
:
0
;
opacity
:
0
;
}
}
.extra-network-tree
.tree-list-content
[
expanded
=
true
]+
.tree-list--subgroup
{
.extra-network-tree
.tree-list-content
[
data-expanded
]+
.tree-list--subgroup
{
height
:
auto
;
height
:
auto
;
overflow
:
visible
;
visibility
:
visible
;
visibility
:
visible
;
opacity
:
1
;
opacity
:
1
;
}
}
...
@@ -1307,7 +1338,7 @@ body.resizing .resize-handle {
...
@@ -1307,7 +1338,7 @@ body.resizing .resize-handle {
background-color
:
var
(
--neutral-800
);
background-color
:
var
(
--neutral-800
);
}
}
.dark
.extra-network-tree
div
.tree-list-content
[
selected
]
{
.dark
.extra-network-tree
div
.tree-list-content
[
data-
selected
]
{
background-color
:
var
(
--neutral-700
);
background-color
:
var
(
--neutral-700
);
}
}
...
@@ -1317,20 +1348,20 @@ body.resizing .resize-handle {
...
@@ -1317,20 +1348,20 @@ body.resizing .resize-handle {
background-color
:
var
(
--neutral-200
);
background-color
:
var
(
--neutral-200
);
}
}
.extra-network-tree
div
.tree-list-content
[
selected
]
{
.extra-network-tree
div
.tree-list-content
[
data-
selected
]
{
background-color
:
var
(
--neutral-300
);
background-color
:
var
(
--neutral-300
);
}
}
/* ==== CHEVRON ICON ACTIONS ==== */
/* ==== CHEVRON ICON ACTIONS ==== */
/* Define the animation for the arrow when it is clicked. */
/* Define the animation for the arrow when it is clicked. */
.extra-network-tree
.tree-list-content-dir
[
expanded
=
false
]
.tree-list-item-action-chevron
{
.extra-network-tree
.tree-list-content-dir
.tree-list-item-action-chevron
{
-ms-transform
:
rotate
(
135deg
);
-ms-transform
:
rotate
(
135deg
);
-webkit-transform
:
rotate
(
135deg
);
-webkit-transform
:
rotate
(
135deg
);
transform
:
rotate
(
135deg
);
transform
:
rotate
(
135deg
);
transition
:
transform
0.2s
;
transition
:
transform
0.2s
;
}
}
.extra-network-tree
.tree-list-content-dir
[
expanded
=
true
]
.tree-list-item-action-chevron
{
.extra-network-tree
.tree-list-content-dir
[
data-expanded
]
.tree-list-item-action-chevron
{
-ms-transform
:
rotate
(
225deg
);
-ms-transform
:
rotate
(
225deg
);
-webkit-transform
:
rotate
(
225deg
);
-webkit-transform
:
rotate
(
225deg
);
transform
:
rotate
(
225deg
);
transform
:
rotate
(
225deg
);
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment