Gradio 4.0 Compatibility - Forge lag, icons, and download status (#341)

* Create text proxies for HTML input changes

* Fix icons, download status, and filter click outside

* undo aria change

* Compat for gradio 3
pull/348/head
Channel Cat 2024-10-10 13:06:56 -07:00 committed by GitHub
parent 0b97a482ad
commit aa32745e64
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 90 additions and 38 deletions

View File

@ -277,15 +277,23 @@ function updateSVGIcons() {
background: url('${filterIconUrl}') no-repeat center center;
background-size: contain;
}
#refreshBtn > img,
#refreshBtnL > img {
content: url('${searchIconUrl}');
}
/* Gradio 4 */
#filterBox > button:nth-child(2),
#filterBoxL > button:nth-child(2) {
background: url('${filterIconUrl}') no-repeat center center !important;
background-size: 22px !important;
}
#filterBox > button:nth-child(2) > span,
#filterBoxL > button:nth-child(2) > span {
visibility: hidden;
}
`;
document.head.appendChild(style);
const refreshBtn = document.querySelector("#refreshBtn, #refreshBtnL");
const targetSearchElement = refreshBtn?.firstChild || refreshBtnL?.firstChild;
if (targetSearchElement) {
targetSearchElement.src = searchIconUrl;
}
}
// Creates a tooltip if the user wants to filter liked models without a personal API key
@ -309,7 +317,7 @@ function createTooltip(element, hover_element, insertText) {
// Function that closes filter dropdown if clicked outside the dropdown
function setupClickOutsideListener() {
var filterBox = document.getElementById("filterBoxL") || document.getElementById("filterBox");
var filterButton = filterBox.getElementsByTagName("div")[1];
var filterButton = filterBox.children[1];
var dropDown = filterBox.getElementsByTagName("div")[2];
function clickOutsideHandler(event) {

View File

@ -211,7 +211,7 @@ def selected_to_queue(model_list, subfolder, download_start, create_json, curren
total_count += 1
html = download_manager_html(current_html)
return (
gr.Button.update(interactive=False, visible=False), # Download Button
gr.Button.update(interactive=True, visible=True), # Cancel Button
@ -220,6 +220,41 @@ def selected_to_queue(model_list, subfolder, download_start, create_json, curren
gr.HTML.update(value='<div style="min-height: 100px;"></div>'), # Download Progress
gr.HTML.update(value=html) # Download Manager HTML
)
def gr_progress_threadable():
"""
Gradio progress bars can no longer be updated from a separate thread,
so we need to use this to update them from the main thread.
"""
# Gradio 3 does not need a wrapper
if not hasattr(gr, "__version__") or int(gr.__version__.split(".")[0]) <= 3:
return gr.Progress()
gr_progress=gr.Progress()
value = [0, None, False] # progress, desc, has_update
def progress(p, desc=None):
value[0] = p
value[1] = desc
value[2] = True
def _update_progress():
if value[2]:
gr_progress(value[0], desc=value[1])
value[2] = False
def join(thread):
_update_progress()
while thread.is_alive():
thread.join(timeout=0.1)
_update_progress()
progress.join = join
return progress
def download_start(download_start, dl_url, model_filename, install_path, model_string, version_name, model_sha256, model_id, create_json, current_html):
global total_count, current_count
@ -238,7 +273,7 @@ def download_start(download_start, dl_url, model_filename, install_path, model_s
current_count = 0
html = download_manager_html(current_html)
return (
gr.Button.update(interactive=False, visible=True), # Download Button
gr.Button.update(interactive=True, visible=True), # Cancel Button
@ -289,6 +324,8 @@ def download_cancel():
gl.download_fail = True
if gl.download_queue:
item = gl.download_queue[0]
else:
item = None
while True:
if not gl.isDownloading:
@ -622,7 +659,7 @@ def download_file_old(url, file_path, model_id, progress=gr.Progress() if queue
os.remove(file_path)
time.sleep(5)
def download_create_thread(download_finish, queue_trigger, progress=gr.Progress() if queue else None):
def download_create_thread(download_finish, queue_trigger, progress=gr_progress_threadable() if queue else None):
global current_count
current_count += 1
if not gl.download_queue:
@ -654,7 +691,10 @@ def download_create_thread(download_finish, queue_trigger, progress=gr.Progress(
else:
thread = threading.Thread(target=download_file_old, args=(item['dl_url'], path_to_new_file, item['model_id'], progress))
thread.start()
thread.join()
if progress is not None and hasattr(progress, "join"):
progress.join(thread)
else:
thread.join()
if not gl.cancel_status or gl.download_fail:
if os.path.exists(path_to_new_file):

View File

@ -511,7 +511,7 @@ def send_to_browser(model_name, content_type, click_first_item):
number = _download.random_number(click_first_item)
return (
gr.HTML.update(output_html), # Card HTML
gr.Textbox.update(output_html), # Card HTML
gr.Button.update(interactive=False), # Prev Button
gr.Button.update(interactive=False), # Next Button
gr.Slider.update(value=1, maximum=1), # Page Slider

View File

@ -89,6 +89,9 @@ def saveSettings(ust, ct, pt, st, bf, cj, td, ol, hi, sn, ss, ts):
def all_visible(html_check):
return gr.Button.update(visible="model-checkbox" in html_check)
def HTMLChange(input):
return gr.HTML.update(value=input)
def show_multi_buttons(model_list, type_list, version_value):
model_list = json.loads(model_list)
@ -201,7 +204,7 @@ def on_ui_tabs():
with gr.Row(elem_id="save_set_box"):
save_settings = gr.Button(value="Save settings as default", elem_id="save_set_btn")
search_term = gr.Textbox(label="", placeholder="Search CivitAI", elem_id="searchBox")
refresh = gr.Button(label="", value="", elem_id=refreshbtn, icon="placeholder")
refresh = gr.Button(value="", elem_id=refreshbtn, icon="placeholder")
with gr.Row(elem_id=header):
with gr.Row(elem_id="pageBox"):
get_prev_page = gr.Button(value="Prev page", interactive=False, elem_id="pageBtn1")
@ -300,7 +303,7 @@ def on_ui_tabs():
#Invisible triggers/variables
#Yes, there is probably a much better way of passing variables/triggering functions
model_id = gr.Textbox(visible=False)
queue_trigger = gr.Textbox(visible=False)
dl_url = gr.Textbox(visible=False)
@ -311,6 +314,8 @@ def on_ui_tabs():
selected_type_list = gr.Textbox(elem_id="selected_type_list", visible=False)
html_cancel_input = gr.Textbox(elem_id="html_cancel_input", visible=False)
queue_html_input = gr.Textbox(elem_id="queue_html_input", visible=False)
list_html_input = gr.Textbox(elem_id="list_html_input", visible=False)
preview_html_input = gr.Textbox(elem_id="preview_html_input", visible=False)
send_to_browser = gr.Textbox(elem_id="send_to_browser", visible=False)
arrange_dl_id = gr.Textbox(elem_id="arrange_dl_id", visible=False)
remove_dl_id = gr.Textbox(elem_id="remove_dl_id", visible=False)
@ -334,7 +339,7 @@ def on_ui_tabs():
delete_finish = gr.Textbox(visible=False)
current_model = gr.Textbox(visible=False)
current_sha256 = gr.Textbox(visible=False)
model_preview_html = gr.Textbox(visible=False)
model_preview_html_input = gr.Textbox(visible=False)
def ToggleDate(toggle_date):
gl.sortNewest = toggle_date
@ -348,7 +353,7 @@ def on_ui_tabs():
# Javascript Functions #
list_html.change(fn=None, inputs=hide_installed, _js="(toggleValue) => hideInstalled(toggleValue)")
list_html_input.change(fn=None, inputs=hide_installed, _js="(toggleValue) => hideInstalled(toggleValue)")
hide_installed.input(fn=None, inputs=hide_installed, _js="(toggleValue) => hideInstalled(toggleValue)")
civitai_text2img_output.change(fn=None, inputs=civitai_text2img_output, _js="(genInfo) => genInfo_to_txt2img(genInfo)")
@ -359,8 +364,8 @@ def on_ui_tabs():
list_models.select(fn=None, inputs=list_models, _js="(list_models) => select_model(list_models)")
preview_html.change(fn=None, _js="() => adjustFilterBoxAndButtons()")
preview_html.change(fn=None, _js="() => setDescriptionToggle()")
preview_html_input.change(fn=None, _js="() => adjustFilterBoxAndButtons()")
preview_html_input.change(fn=None, _js="() => setDescriptionToggle()")
back_to_top.click(fn=None, _js="() => BackToTop()")
@ -370,24 +375,23 @@ def on_ui_tabs():
for func in card_updates:
func.change(fn=None, inputs=current_model, _js="(modelName) => updateCard(modelName)")
list_html.change(fn=None, inputs=show_nsfw, _js="(hideAndBlur) => toggleNSFWContent(hideAndBlur)")
list_html_input.change(fn=None, inputs=show_nsfw, _js="(hideAndBlur) => toggleNSFWContent(hideAndBlur)")
show_nsfw.change(fn=None, inputs=show_nsfw, _js="(hideAndBlur) => toggleNSFWContent(hideAndBlur)")
list_html.change(fn=None, inputs=size_slider, _js="(size) => updateCardSize(size, size * 1.5)")
list_html_input.change(fn=None, inputs=size_slider, _js="(size) => updateCardSize(size, size * 1.5)")
size_slider.change(fn=None, inputs=size_slider, _js="(size) => updateCardSize(size, size * 1.5)")
model_preview_html.change(fn=None, inputs=model_preview_html, _js="(html_input) => inputHTMLPreviewContent(html_input)")
model_preview_html_input.change(fn=None, inputs=model_preview_html_input, _js="(html_input) => inputHTMLPreviewContent(html_input)")
download_manager_html.change(fn=None, _js="() => setSortable()")
queue_html_input.change(fn=None, _js="() => setSortable()")
click_first_item.change(fn=None, _js="() => clickFirstFigureInColumn()")
# Filter button Functions #
def HTMLChange(input):
return gr.HTML.update(value=input)
queue_html_input.change(fn=HTMLChange, inputs=[queue_html_input], outputs=download_manager_html)
list_html_input.change(fn=HTMLChange, inputs=[list_html_input], outputs=list_html)
preview_html_input.change(fn=HTMLChange, inputs=[preview_html_input], outputs=preview_html)
remove_dl_id.change(
fn=_download.remove_from_queue,
@ -432,14 +436,14 @@ def on_ui_tabs():
civitai_text2img_input.change(fn=txt2img_output,inputs=civitai_text2img_input,outputs=civitai_text2img_output)
list_html.change(fn=all_visible,inputs=list_html,outputs=select_all)
list_html_input.change(fn=all_visible, inputs=list_html, outputs=select_all)
def update_models_dropdown(input):
if not gl.json_data:
return (
gr.Dropdown.update(value=None, choices=[], interactive=False), # List models
gr.Dropdown.update(value=None, choices=[], interactive=False), # List version
gr.HTML.update(value=None), # Preview HTML
gr.Textbox.update(value=None), # Preview HTML
gr.Textbox.update(value=None, interactive=False), # Trained Tags
gr.Textbox.update(value=None, interactive=False), # Base Model
gr.Textbox.update(value=None, interactive=False), # Model filename
@ -453,7 +457,7 @@ def on_ui_tabs():
gr.Textbox.update(value=None), # Model ID
gr.Textbox.update(value=None), # Current sha256
gr.Button.update(interactive=False), # Save model info
gr.HTML.update(value='<div style="font-size: 24px; text-align: center; margin: 50px;">Click the search icon to load models.<br>Use the filter icon to filter results.</div>') # Model list
gr.Textbox.update(value='<div style="font-size: 24px; text-align: center; margin: 50px;">Click the search icon to load models.<br>Use the filter icon to filter results.</div>') # Model list
)
model_string = re.sub(r'\.\d{3}$', '', input)
@ -463,7 +467,7 @@ def on_ui_tabs():
return (gr.Dropdown.update(value=model_string, interactive=True),
model_versions,html,tags,base_mdl,filename,install_path,sub_folder,DwnButton,SaveImages,DelButton,filelist,dl_url,id,current_sha256,
gr.Button.update(interactive=True),
gr.HTML.update()
gr.Textbox.update()
)
model_select.change(
@ -486,20 +490,20 @@ def on_ui_tabs():
model_id,
current_sha256,
save_info,
list_html
list_html_input
]
)
model_sent.change(
fn=_file.model_from_sent,
inputs=[model_sent, type_sent],
outputs=[model_preview_html]
outputs=[model_preview_html_input]
)
send_to_browser.change(
fn=_file.send_to_browser,
inputs=[send_to_browser, type_sent, click_first_item],
outputs=[list_html, get_prev_page , get_next_page, page_slider, click_first_item]
outputs=[list_html_input, get_prev_page , get_next_page, page_slider, click_first_item]
)
sub_folder.select(
@ -515,7 +519,7 @@ def on_ui_tabs():
list_versions
],
outputs=[
preview_html,
preview_html_input,
trained_tags,
base_model,
download_model,
@ -672,7 +676,7 @@ def on_ui_tabs():
model_filename,
sub_folder,
current_sha256,
preview_html
preview_html_input
],
outputs=[]
)
@ -680,7 +684,7 @@ def on_ui_tabs():
save_images.click(
fn=_file.save_images,
inputs=[
preview_html,
preview_html_input,
model_filename,
install_path,
sub_folder
@ -708,7 +712,7 @@ def on_ui_tabs():
page_outputs = [
list_models,
list_versions,
list_html,
list_html_input,
get_prev_page,
get_next_page,
page_slider,
@ -719,7 +723,7 @@ def on_ui_tabs():
install_path,
sub_folder,
file_list,
preview_html,
preview_html_input,
trained_tags,
base_model,
model_filename