From d673c58c10fbf026a8a77fb802d04b7c7e2630e8 Mon Sep 17 00:00:00 2001 From: Vladimir Mandic Date: Mon, 8 Sep 2025 09:42:22 -0400 Subject: [PATCH] fix drop image to prompt in modernui Signed-off-by: Vladimir Mandic --- extensions-builtin/sdnext-modernui | 2 +- javascript/dragDrop.js | 6 +++--- javascript/imageParams.js | 10 +++------- javascript/ui.js | 1 + modules/api/middleware.py | 8 +++++++- modules/generation_parameters_copypaste.py | 2 ++ modules/infotext.py | 2 +- modules/ui_control.py | 4 ++-- modules/ui_img2img.py | 2 +- modules/ui_sections.py | 1 - modules/ui_txt2img.py | 4 ++-- 11 files changed, 23 insertions(+), 19 deletions(-) diff --git a/extensions-builtin/sdnext-modernui b/extensions-builtin/sdnext-modernui index 976d8fb1a..4d107f686 160000 --- a/extensions-builtin/sdnext-modernui +++ b/extensions-builtin/sdnext-modernui @@ -1 +1 @@ -Subproject commit 976d8fb1a39710cc800a635a270b6ff0b69d7a45 +Subproject commit 4d107f68698975876a8ad9c581f3c212a8abee15 diff --git a/javascript/dragDrop.js b/javascript/dragDrop.js index 73c0c33c3..009263081 100644 --- a/javascript/dragDrop.js +++ b/javascript/dragDrop.js @@ -1,10 +1,9 @@ -// allows drag-dropping files into gradio image elements, and also pasting images from clipboard - function isValidImageList(files) { return files && files?.length === 1 && ['image/png', 'image/gif', 'image/jpeg'].includes(files[0].type); } function dropReplaceImage(imgWrap, files) { + log('dropReplaceImage', imgWrap, files); if (!isValidImageList(files)) return; const tmpFile = files[0]; imgWrap.querySelector('.modify-upload button + button, .touch-none + div button + button')?.click(); @@ -23,7 +22,6 @@ function dropReplaceImage(imgWrap, files) { }; if (imgWrap.closest('#pnginfo_image')) { - // special treatment for PNG Info tab, wait for fetch request to finish const oldFetch = window.fetch; window.fetch = async (input, options) => { const response = await oldFetch(input, options); @@ -57,6 +55,7 @@ window.document.addEventListener('dragover', (e) => { window.document.addEventListener('drop', (e) => { const target = e.composedPath()[0]; + log('dropEvent', e, target); if (!target.placeholder) return; if (target.placeholder.indexOf('Prompt') === -1) return; const imgWrap = target.closest('[data-testid="image"]'); @@ -69,6 +68,7 @@ window.document.addEventListener('drop', (e) => { }); window.addEventListener('paste', (e) => { + log('pasteEvent', e); const { files } = e.clipboardData; if (!isValidImageList(files)) return; const visibleImageFields = [...gradioApp().querySelectorAll('[data-testid="image"]')] diff --git a/javascript/imageParams.js b/javascript/imageParams.js index 69057ba5e..ba8568a94 100644 --- a/javascript/imageParams.js +++ b/javascript/imageParams.js @@ -4,14 +4,10 @@ async function initDragDrop() { const target = e.composedPath()[0]; if (!target.placeholder) return; if (target.placeholder.indexOf('Prompt') === -1) return; - const tab = get_tab_index('tabs'); - let promptTarget = ''; - if (tab === 0) promptTarget = 'txt2img_prompt_image'; - else if (tab === 1) promptTarget = 'img2img_prompt_image'; - else if (tab === 2) promptTarget = 'control_prompt_image'; - else if (tab === 3) promptTarget = 'video_prompt_image'; - else return; + const tabName = getENActiveTab(); + const promptTarget = `${tabName}_prompt_image`; const imgParent = gradioApp().getElementById(promptTarget); + log('dropEvent', target, promptTarget, imgParent); const fileInput = imgParent.querySelector('input[type="file"]'); if (!imgParent || !fileInput) return; if ((e.dataTransfer?.files?.length || 0) > 0) { diff --git a/javascript/ui.js b/javascript/ui.js index 6fe2f954b..66416d0d5 100644 --- a/javascript/ui.js +++ b/javascript/ui.js @@ -189,6 +189,7 @@ function get_tab_index(tabId) { .forEach((button, i) => { if (button.className.indexOf('selected') !== -1) res = i; }); + console.log('get_tab_index', tabId, res); return res; } diff --git a/modules/api/middleware.py b/modules/api/middleware.py index d276bd46b..6270a9ff2 100644 --- a/modules/api/middleware.py +++ b/modules/api/middleware.py @@ -15,7 +15,13 @@ import modules.errors as errors errors.install() -ignore_endpoints = ['/sdapi/v1/log', '/sdapi/v1/browser', '/sdapi/v1/gpu', '/sdapi/v1/network/thumb'] +ignore_endpoints = [ + '/sdapi/v1/log', + '/sdapi/v1/browser', + '/sdapi/v1/gpu', + '/sdapi/v1/network/thumb', + '/sdapi/v1/progress', +] def setup_middleware(app: FastAPI, cmd_opts): diff --git a/modules/generation_parameters_copypaste.py b/modules/generation_parameters_copypaste.py index 3d667d8d4..a2f38b94e 100644 --- a/modules/generation_parameters_copypaste.py +++ b/modules/generation_parameters_copypaste.py @@ -95,6 +95,8 @@ def add_paste_fields(tabname, init_img, fields, override_settings_component=None modules.ui.img2img_paste_fields = fields # compatibility elif tabname == 'control': modules.ui.control_paste_fields = fields + elif tabname == 'video': + modules.ui.video_paste_fields = fields def get_all_fields(): diff --git a/modules/infotext.py b/modules/infotext.py index 4a348a776..efcd18345 100644 --- a/modules/infotext.py +++ b/modules/infotext.py @@ -79,7 +79,7 @@ def parse(infotext): params[f"{key}-2"] = int(size.group(2)) elif isinstance(params[key], str): params[key] = val - debug(f'Param parsed: type={type(params[key])} "{key}"={params[key]} raw="{val}"') + debug(f'Param parsed: type={type(params[key])} "{key}"="{params[key]}" raw="{val}"') return params diff --git a/modules/ui_control.py b/modules/ui_control.py index deb812779..673e82d80 100644 --- a/modules/ui_control.py +++ b/modules/ui_control.py @@ -121,8 +121,8 @@ def create_ui(_blocks: gr.Blocks=None): with gr.Blocks(analytics_enabled = False) as control_ui: prompt, styles, negative, btn_generate, btn_reprocess, btn_paste, btn_extra, prompt_counter, btn_prompt_counter, negative_counter, btn_negative_counter = ui_sections.create_toprow(is_img2img=False, id_part='control') - txt_prompt_img = gr.File(label="", elem_id="control_prompt_image", file_count="single", type="binary", visible=False) - txt_prompt_img.change(fn=images.image_data, inputs=[txt_prompt_img], outputs=[prompt, txt_prompt_img]) + prompt_img = gr.File(label="", elem_id="control_prompt_image", file_count="single", type="binary", visible=False) + prompt_img.change(fn=images.image_data, inputs=[prompt_img], outputs=[prompt, prompt_img]) with gr.Group(elem_id="control_interface"): diff --git a/modules/ui_img2img.py b/modules/ui_img2img.py index 66b770c69..402a3edc1 100644 --- a/modules/ui_img2img.py +++ b/modules/ui_img2img.py @@ -40,6 +40,7 @@ def create_ui(): with gr.Blocks(analytics_enabled=False) as _img2img_interface: 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) + img2img_prompt_img.change(fn=modules.images.image_data, inputs=[img2img_prompt_img], outputs=[img2img_prompt, img2img_prompt_img]) 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 @@ -162,7 +163,6 @@ def create_ui(): ui_common.reuse_seed(seed, reuse_seed, subseed=False) ui_common.reuse_seed(subseed, reuse_subseed, subseed=True) - img2img_prompt_img.change(fn=modules.images.image_data, inputs=[img2img_prompt_img], outputs=[img2img_prompt, img2img_prompt_img]) dummy_component1 = gr.Textbox(visible=False, value='dummy') dummy_component2 = gr.Number(visible=False, value=0) img2img_args = [ diff --git a/modules/ui_sections.py b/modules/ui_sections.py index 2042f896d..5dd635ab9 100644 --- a/modules/ui_sections.py +++ b/modules/ui_sections.py @@ -10,7 +10,6 @@ def create_toprow(is_img2img: bool = False, id_part: str = None, generate_visibl prompt_neg = shared.prompt_styles.apply_negative_styles_to_prompt(prompt_neg, styles, wildcards=not shared.opts.extra_networks_apply_unparsed) return [gr.Textbox.update(value=prompt), gr.Textbox.update(value=prompt_neg), gr.Dropdown.update(value=[])] - def parse_style(styles): return styles.split('|') if styles is not None else None diff --git a/modules/ui_txt2img.py b/modules/ui_txt2img.py index 7fb672562..8e888a122 100644 --- a/modules/ui_txt2img.py +++ b/modules/ui_txt2img.py @@ -12,8 +12,8 @@ def create_ui(): with gr.Blocks(analytics_enabled=False) as _txt2img_interface: txt2img_prompt, txt2img_prompt_styles, txt2img_negative_prompt, txt2img_submit, txt2img_reprocess, txt2img_paste, txt2img_extra_networks_button, txt2img_token_counter, txt2img_token_button, txt2img_negative_token_counter, txt2img_negative_token_button = ui_sections.create_toprow(is_img2img=False, id_part="txt2img") - txt_prompt_img = gr.File(label="", elem_id="txt2img_prompt_image", file_count="single", type="binary", visible=False) - txt_prompt_img.change(fn=images.image_data, inputs=[txt_prompt_img], outputs=[txt2img_prompt, txt_prompt_img]) + txt2img_prompt_img = gr.File(label="", elem_id="txt2img_prompt_image", file_count="single", type="binary", visible=False) + txt2img_prompt_img.change(fn=images.image_data, inputs=[txt2img_prompt_img], outputs=[txt2img_prompt, txt2img_prompt_img]) 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