├── .gitignore ├── .DS_Store ├── README.md ├── javascript └── images_history.js └── scripts └── images_history.py /.gitignore: -------------------------------------------------------------------------------- 1 | path_recorder.txt 2 | -------------------------------------------------------------------------------- /.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yfszzx/stable-diffusion-webui-images-browser/HEAD/.DS_Store -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # stable-diffusion-webui-images-browser 2 | 3 | This an extension for [stable-diffusion-webui](https://github.com/AUTOMATIC1111/stable-diffusion-webui) 4 | 5 | This an images browser for browsing past generated pictures, view their generated infomations,send the prompt to txt2img or img2img, collect images to your "faveries" fold, delete the images you no longer need, and you can also browse images in any folds in your computer 6 | ![image](https://s6.jpg.cm/2022/10/24/PJjuZt.png) 7 | 8 | go to the directory \/extensions and run command to install: 9 | 10 | `git clone https://github.com/yfszzx/stable-diffusion-webui-images-browser ` 11 | 12 | and restart your stable-diffusion-webui, then you can see the new tab "Images Browser" 13 | 14 | [See here for more install details](https://github.com/AUTOMATIC1111/stable-diffusion-webui/wiki/Extensions) 15 | -------------------------------------------------------------------------------- /javascript/images_history.js: -------------------------------------------------------------------------------- 1 | var images_history_click_image = function(){ 2 | console.log("in images_history_click_image !") 3 | console.log(this.classList) 4 | if (!this.classList.contains("transform")){ 5 | var gallery = images_history_get_parent_by_class(this, "images_history_cantainor"); 6 | var buttons = gallery.querySelectorAll(".gallery-item"); 7 | var i = 0; 8 | var hidden_list = []; 9 | buttons.forEach(function(e){ 10 | if (e.style.display == "none"){ 11 | hidden_list.push(i); 12 | } 13 | i += 1; 14 | }) 15 | if (hidden_list.length > 0){ 16 | setTimeout(images_history_hide_buttons, 10, hidden_list, gallery); 17 | } 18 | } 19 | images_history_set_image_info(this); 20 | } 21 | 22 | function images_history_get_parent_by_class(item, class_name){ 23 | var parent = item.parentElement; 24 | while(!parent.classList.contains(class_name)){ 25 | parent = parent.parentElement; 26 | } 27 | return parent; 28 | } 29 | 30 | function images_history_get_parent_by_tagname(item, tagname){ 31 | var parent = item.parentElement; 32 | tagname = tagname.toUpperCase() 33 | while(parent.tagName != tagname){ 34 | parent = parent.parentElement; 35 | } 36 | return parent; 37 | } 38 | 39 | function images_history_hide_buttons(hidden_list, gallery){ 40 | var buttons = gallery.querySelectorAll(".gallery-item"); 41 | var num = 0; 42 | buttons.forEach(function(e){ 43 | if (e.style.display == "none"){ 44 | num += 1; 45 | } 46 | }); 47 | if (num == hidden_list.length){ 48 | setTimeout(images_history_hide_buttons, 10, hidden_list, gallery); 49 | } 50 | for( i in hidden_list){ 51 | buttons[hidden_list[i]].style.display = "none"; 52 | } 53 | } 54 | 55 | function images_history_set_image_info(button){ 56 | var buttons = images_history_get_parent_by_tagname(button, "DIV").querySelectorAll(".gallery-item"); 57 | var index = -1; 58 | var i = 0; 59 | buttons.forEach(function(e){ 60 | if(e == button){ 61 | index = i; 62 | } 63 | if(e.style.display != "none"){ 64 | i += 1; 65 | } 66 | }); 67 | var gallery = images_history_get_parent_by_class(button, "images_history_cantainor"); 68 | var set_btn = gallery.querySelector(".images_history_set_index"); 69 | var curr_idx = set_btn.getAttribute("img_index", index); 70 | if (curr_idx != index) { 71 | set_btn.setAttribute("img_index", index); 72 | } 73 | set_btn.click(); 74 | 75 | } 76 | 77 | function images_history_get_current_img(tabname, img_index, page_index){ 78 | console.log("tabName",tabname) 79 | console.log("img_index",img_index) 80 | console.log(tabname + '_images_history_set_index') 81 | return [ 82 | tabname, 83 | gradioApp().getElementById(tabname + '_images_history_set_index').getAttribute("img_index"), 84 | page_index 85 | ]; 86 | } 87 | 88 | function images_history_delete(del_num, tabname, image_index){ 89 | image_index = parseInt(image_index); 90 | var tab = gradioApp().getElementById(tabname + '_images_history'); 91 | var set_btn = tab.querySelector(".images_history_set_index"); 92 | var buttons = []; 93 | tab.querySelectorAll(".gallery-item").forEach(function(e){ 94 | if (e.style.display != 'none'){ 95 | buttons.push(e); 96 | } 97 | }); 98 | var img_num = buttons.length / 2; 99 | del_num = Math.min(img_num - image_index, del_num) 100 | if (img_num <= del_num){ 101 | setTimeout(function(tabname){ 102 | gradioApp().getElementById(tabname + '_images_history_renew_page').click(); 103 | }, 30, tabname); 104 | } else { 105 | var next_img 106 | for (var i = 0; i < del_num; i++){ 107 | buttons[image_index + i].style.display = 'none'; 108 | buttons[image_index + i + img_num].style.display = 'none'; 109 | next_img = image_index + i + 1 110 | } 111 | var bnt; 112 | if (next_img >= img_num){ 113 | btn = buttons[image_index - 1]; 114 | } else { 115 | btn = buttons[next_img]; 116 | } 117 | setTimeout(function(btn){btn.click()}, 30, btn); 118 | } 119 | 120 | } 121 | 122 | function images_history_turnpage(tabname){ 123 | var buttons = gradioApp().getElementById(tabname + '_images_history').querySelectorAll(".gallery-item"); 124 | buttons.forEach(function(elem) { 125 | elem.style.display = 'block'; 126 | }); 127 | } 128 | 129 | 130 | function images_history_init(){ 131 | var tabnames = gradioApp().getElementById("images_history_tabnames_list") 132 | if (tabnames){ 133 | images_history_tab_list = tabnames.querySelector("textarea").value.split(",") 134 | for (var i in images_history_tab_list ){ 135 | var tab = images_history_tab_list[i]; 136 | gradioApp().getElementById(tab + '_images_history').classList.add("images_history_cantainor"); 137 | gradioApp().getElementById(tab + '_images_history_set_index').classList.add("images_history_set_index"); 138 | gradioApp().getElementById(tab + '_images_history_del_button').classList.add("images_history_del_button"); 139 | gradioApp().getElementById(tab + '_images_history_gallery').classList.add("images_history_gallery"); 140 | } 141 | 142 | //preload 143 | var tab_btns = gradioApp().getElementById("images_history_tab").querySelector("div").querySelectorAll("button"); 144 | for (var i in images_history_tab_list){ 145 | var tabname = images_history_tab_list[i] 146 | tab_btns[i].setAttribute("tabname", tabname); 147 | tab_btns[i].addEventListener('click', function(){ 148 | var tabs_box = gradioApp().getElementById("images_history_tab"); 149 | if (!tabs_box.classList.contains(this.getAttribute("tabname"))) { 150 | gradioApp().getElementById(this.getAttribute("tabname") + "_images_history_renew_page").click(); 151 | tabs_box.classList.add(this.getAttribute("tabname")) 152 | } 153 | }); 154 | } 155 | if (gradioApp().getElementById("images_history_preload").querySelector("input").checked ){ 156 | setTimeout(function(){tab_btns[0].click()}, 100); 157 | } 158 | 159 | } else { 160 | setTimeout(images_history_init, 500); 161 | } 162 | } 163 | 164 | let timer 165 | var images_history_tab_list = ""; 166 | setTimeout(images_history_init, 500); 167 | document.addEventListener("DOMContentLoaded", function() { 168 | var mutationObserver = new MutationObserver(function(m){ 169 | if (images_history_tab_list != ""){ 170 | 171 | for (var i in images_history_tab_list ){ 172 | let tabname = images_history_tab_list[i] 173 | var buttons = gradioApp().querySelectorAll('#' + tabname + '_images_history .gallery-item'); 174 | buttons.forEach(function(bnt){ 175 | bnt.addEventListener('click', images_history_click_image, true); 176 | document.onkeyup = function(e){ 177 | clearTimeout(timer) 178 | timer = setTimeout(() => { 179 | let tab = gradioApp().getElementById("tab_images_history").getElementsByClassName("bg-white px-4 pb-2 pt-1.5 rounded-t-lg border-gray-200 -mb-[2px] border-2 border-b-0")[0].innerText 180 | bnt = gradioApp().getElementById(tab+"_images_history_gallery").getElementsByClassName('gallery-item !flex-none !h-9 !w-9 transition-all duration-75 !ring-2 !ring-orange-500 hover:!ring-orange-500 svelte-1g9btlg')[0] 181 | images_history_click_image.call(bnt) 182 | },500) 183 | 184 | } 185 | }); 186 | 187 | var cls_btn = gradioApp().getElementById(tabname + '_images_history_gallery').querySelector("svg"); 188 | if (cls_btn){ 189 | cls_btn.addEventListener('click', function(){ 190 | gradioApp().getElementById(tabname + '_images_history_renew_page').click(); 191 | }, false); 192 | } 193 | 194 | } 195 | } 196 | }); 197 | mutationObserver.observe(gradioApp(), { childList:true, subtree:true }); 198 | }); 199 | 200 | 201 | 202 | 203 | 204 | -------------------------------------------------------------------------------- /scripts/images_history.py: -------------------------------------------------------------------------------- 1 | import os 2 | import shutil 3 | import time 4 | import stat 5 | import gradio as gr 6 | import modules.extras 7 | import modules.ui 8 | from modules.shared import opts, cmd_opts 9 | from modules import shared, scripts 10 | from modules import script_callbacks 11 | from pathlib import Path 12 | from typing import List, Tuple 13 | 14 | faverate_tab_name = "Favorites" 15 | tabs_list = ["txt2img", "img2img", "txt2img-grids", "img2img-grids", "Extras", faverate_tab_name, "Others"] #txt2img-grids and img2img-grids added by HaylockGrant 16 | num_of_imgs_per_page = 0 17 | loads_files_num = 0 18 | path_recorder_filename = os.path.join(scripts.basedir(), "path_recorder.txt") 19 | image_ext_list = [".png", ".jpg", ".jpeg", ".bmp", ".gif", ".webp"] 20 | 21 | def reduplicative_file_move(src, dst): 22 | def same_name_file(basename, path): 23 | name, ext = os.path.splitext(basename) 24 | f_list = os.listdir(path) 25 | max_num = 0 26 | for f in f_list: 27 | if len(f) <= len(basename): 28 | continue 29 | f_ext = f[-len(ext):] if len(ext) > 0 else "" 30 | if f[:len(name)] == name and f_ext == ext: 31 | if f[len(name)] == "(" and f[-len(ext)-1] == ")": 32 | number = f[len(name)+1:-len(ext)-1] 33 | if number.isdigit(): 34 | if int(number) > max_num: 35 | max_num = int(number) 36 | return f"{name}({max_num + 1}){ext}" 37 | name = os.path.basename(src) 38 | save_name = os.path.join(dst, name) 39 | if not os.path.exists(save_name): 40 | shutil.move(src, dst) 41 | else: 42 | name = same_name_file(name, dst) 43 | shutil.move(src, os.path.join(dst, name)) 44 | 45 | def save_image(file_name): 46 | if file_name is not None and os.path.exists(file_name): 47 | reduplicative_file_move(file_name, opts.outdir_save) 48 | return "
Moved to favorites
" 49 | else: 50 | return "
Image not found (may have been already moved)
" 51 | 52 | def delete_image(delete_num, name, filenames, image_index, visible_num): 53 | if name == "": 54 | return filenames, delete_num 55 | else: 56 | delete_num = int(delete_num) 57 | visible_num = int(visible_num) 58 | image_index = int(image_index) 59 | index = list(filenames).index(name) 60 | i = 0 61 | new_file_list = [] 62 | for name in filenames: 63 | if i >= index and i < index + delete_num: 64 | if os.path.exists(name): 65 | if visible_num == image_index: 66 | new_file_list.append(name) 67 | i += 1 68 | continue 69 | if opts.images_delete_message: 70 | print(f"Deleting file {name}") 71 | os.remove(name) 72 | visible_num -= 1 73 | txt_file = os.path.splitext(name)[0] + ".txt" 74 | if os.path.exists(txt_file): 75 | os.remove(txt_file) 76 | else: 77 | print(f"File does not exist {name}") 78 | else: 79 | new_file_list.append(name) 80 | i += 1 81 | return new_file_list, 1, visible_num 82 | 83 | def traverse_all_files(curr_path, image_list) -> List[Tuple[str, os.stat_result]]: 84 | if curr_path == "": 85 | return image_list 86 | f_list = [(os.path.join(curr_path, entry.name), entry.stat()) for entry in os.scandir(curr_path)] 87 | for f_info in f_list: 88 | fname, fstat = f_info 89 | if os.path.splitext(fname)[1] in image_ext_list: 90 | image_list.append(f_info) 91 | elif stat.S_ISDIR(fstat.st_mode): 92 | image_list = traverse_all_files(fname, image_list) 93 | return image_list 94 | 95 | 96 | def get_all_images(dir_name, sort_by, keyword): 97 | fileinfos = traverse_all_files(dir_name, []) 98 | keyword = keyword.strip(" ") 99 | if len(keyword) != 0: 100 | fileinfos = [x for x in fileinfos if keyword.lower() in x[0].lower()] 101 | if sort_by == "date": 102 | fileinfos = sorted(fileinfos, key=lambda x: -x[1].st_mtime) 103 | elif sort_by == "path name": 104 | fileinfos = sorted(fileinfos) 105 | 106 | filenames = [finfo[0] for finfo in fileinfos] 107 | return filenames 108 | 109 | def get_image_page(img_path, page_index, filenames, keyword, sort_by): 110 | if page_index == 1 or page_index == 0 or len(filenames) == 0: 111 | filenames = get_all_images(img_path, sort_by, keyword) 112 | page_index = int(page_index) 113 | length = len(filenames) 114 | max_page_index = length // num_of_imgs_per_page + 1 115 | page_index = max_page_index if page_index == -1 else page_index 116 | page_index = 1 if page_index < 1 else page_index 117 | page_index = max_page_index if page_index > max_page_index else page_index 118 | idx_frm = (page_index - 1) * num_of_imgs_per_page 119 | image_list = filenames[idx_frm:idx_frm + num_of_imgs_per_page] 120 | 121 | visible_num = num_of_imgs_per_page if idx_frm + num_of_imgs_per_page < length else length % num_of_imgs_per_page 122 | visible_num = num_of_imgs_per_page if visible_num == 0 else visible_num 123 | 124 | load_info = "
" 125 | load_info += f"{length} images in this directory, divided into {int((length + 1) // num_of_imgs_per_page + 1)} pages" 126 | load_info += "
" 127 | return filenames, page_index, image_list, "", "", "", visible_num, load_info 128 | 129 | def show_image_info(tabname_box, num, page_index, filenames): 130 | file = filenames[int(num) + int((page_index - 1) * num_of_imgs_per_page)] 131 | tm = "
" + time.strftime("%Y-%m-%d %H:%M:%S",time.localtime(os.path.getmtime(file))) + "
" 132 | return file, tm, num, file, "" 133 | 134 | def change_dir(img_dir, path_recorder, load_switch, img_path_history): 135 | warning = None 136 | try: 137 | if not cmd_opts.administrator: 138 | head = os.path.realpath(".") 139 | real_path = os.path.realpath(img_dir) 140 | if len(real_path) < len(head) or real_path[:len(head)] != head: 141 | warning = f"You have not permission to visit {img_dir}. If you want visit all directories, add command line argument option '--administrator', More detail here" 142 | except: 143 | pass 144 | if warning is None: 145 | try: 146 | if os.path.exists(img_dir): 147 | try: 148 | f = os.listdir(img_dir) 149 | except: 150 | warning = f"'{img_dir} is not a directory" 151 | else: 152 | warning = "The directory does not exist" 153 | except: 154 | warning = "The format of the directory is incorrect" 155 | 156 | if warning is None: 157 | if img_dir not in path_recorder: 158 | path_recorder.append(img_dir) 159 | if os.path.exists(path_recorder_filename): 160 | os.remove(path_recorder_filename) 161 | if opts.images_record_paths: 162 | with open(path_recorder_filename, "a") as f: 163 | for x in path_recorder: 164 | f.write(x + "\n") 165 | return "", gr.update(visible=True), gr.Dropdown.update(choices=path_recorder, value=img_dir), path_recorder, img_dir 166 | else: 167 | return warning, gr.update(visible=False), img_path_history, path_recorder, load_switch 168 | 169 | def create_tab(tabname): 170 | custom_dir = False 171 | path_recorder = [] 172 | if tabname == "txt2img": 173 | dir_name = opts.outdir_txt2img_samples 174 | elif tabname == "img2img": 175 | dir_name = opts.outdir_img2img_samples 176 | elif tabname == "txt2img-grids": #added by HaylockGrant to add a new tab for grid images 177 | dir_name = opts.outdir_txt2img_grids 178 | elif tabname == "img2img-grids": #added by HaylockGrant to add a new tab for grid images 179 | dir_name = opts.outdir_img2img_grids 180 | elif tabname == "Extras": 181 | dir_name = opts.outdir_extras_samples 182 | elif tabname == faverate_tab_name: 183 | dir_name = opts.outdir_save 184 | else: 185 | custom_dir = True 186 | dir_name = None 187 | if os.path.exists(path_recorder_filename): 188 | with open(path_recorder_filename) as f: 189 | path = f.readline().rstrip("\n") 190 | while len(path) > 0: 191 | path_recorder.append(path) 192 | path = f.readline().rstrip("\n") 193 | 194 | if not custom_dir: 195 | dir_name = str(Path(dir_name)) 196 | if not os.path.exists(dir_name): 197 | os.makedirs(dir_name) 198 | 199 | with gr.Row(visible= custom_dir): 200 | img_path = gr.Textbox(dir_name, label="Images directory", placeholder="Input images directory", interactive=custom_dir) 201 | img_path_history = gr.Dropdown(path_recorder) 202 | path_recorder = gr.State(path_recorder) 203 | 204 | with gr.Row(visible= not custom_dir, elem_id=tabname + "_images_history") as main_panel: 205 | with gr.Column(): 206 | with gr.Row(): 207 | with gr.Column(scale=2): 208 | with gr.Row(): 209 | first_page = gr.Button('First Page') 210 | prev_page = gr.Button('Prev Page') 211 | page_index = gr.Number(value=1, label="Page Index") 212 | next_page = gr.Button('Next Page') 213 | end_page = gr.Button('End Page') 214 | history_gallery = gr.Gallery(show_label=False, elem_id=tabname + "_images_history_gallery").style(grid=opts.images_history_page_columns) 215 | with gr.Row() as delete_panel: 216 | with gr.Column(scale=1): 217 | delete_num = gr.Number(value=1, interactive=True, label="delete next") 218 | with gr.Column(scale=3): 219 | delete = gr.Button('Delete', elem_id=tabname + "_images_history_del_button") 220 | 221 | with gr.Column(): 222 | with gr.Row(): 223 | sort_by = gr.Radio(value="date", choices=["path name", "date"], label="sort by") 224 | keyword = gr.Textbox(value="", label="keyword") 225 | with gr.Row(): 226 | with gr.Column(): 227 | img_file_info = gr.Textbox(label="Generate Info", interactive=False, lines=6) 228 | img_file_name = gr.Textbox(value="", label="File Name", interactive=False) 229 | img_file_time= gr.HTML() 230 | with gr.Row(elem_id=tabname + "_images_history_button_panel") as button_panel: 231 | if tabname != faverate_tab_name: 232 | save_btn = gr.Button('Move to favorites') 233 | try: 234 | send_to_buttons = modules.generation_parameters_copypaste.create_buttons(["txt2img", "img2img", "inpaint", "extras"]) 235 | except: 236 | pass 237 | with gr.Row(): 238 | collected_warning = gr.HTML() 239 | 240 | # hiden items 241 | with gr.Row(visible=False): 242 | renew_page = gr.Button("Renew Page", elem_id=tabname + "_images_history_renew_page") 243 | visible_img_num = gr.Number() 244 | tabname_box = gr.Textbox(tabname) 245 | image_index = gr.Textbox(value=-1) 246 | set_index = gr.Button('set_index', elem_id=tabname + "_images_history_set_index") 247 | filenames = gr.State([]) 248 | all_images_list = gr.State() 249 | hidden = gr.Image(type="pil") 250 | info1 = gr.Textbox() 251 | info2 = gr.Textbox() 252 | load_switch = gr.Textbox(value="load_switch", label="load_switch") 253 | turn_page_switch = gr.Number(value=1, label="turn_page_switch") 254 | with gr.Row(): 255 | warning_box = gr.HTML() 256 | 257 | change_dir_outputs = [warning_box, main_panel, img_path_history, path_recorder, load_switch] 258 | img_path.submit(change_dir, inputs=[img_path, path_recorder, load_switch, img_path_history], outputs=change_dir_outputs) 259 | img_path_history.change(change_dir, inputs=[img_path_history, path_recorder, load_switch, img_path_history], outputs=change_dir_outputs) 260 | img_path_history.change(lambda x:x, inputs=[img_path_history], outputs=[img_path]) 261 | 262 | #delete 263 | delete.click(delete_image, inputs=[delete_num, img_file_name, filenames, image_index, visible_img_num], outputs=[filenames, delete_num, visible_img_num]) 264 | delete.click(fn=None, _js="images_history_delete", inputs=[delete_num, tabname_box, image_index], outputs=None) 265 | if tabname != faverate_tab_name: 266 | save_btn.click(save_image, inputs=[img_file_name], outputs=[collected_warning]) 267 | 268 | #turn page 269 | first_page.click(lambda s:(1, -s) , inputs=[turn_page_switch], outputs=[page_index, turn_page_switch]) 270 | next_page.click(lambda p, s: (p + 1, -s), inputs=[page_index, turn_page_switch], outputs=[page_index, turn_page_switch]) 271 | prev_page.click(lambda p, s: (p - 1, -s), inputs=[page_index, turn_page_switch], outputs=[page_index, turn_page_switch]) 272 | end_page.click(lambda s: (-1, -s), inputs=[turn_page_switch], outputs=[page_index, turn_page_switch]) 273 | load_switch.change(lambda s:(1, -s), inputs=[turn_page_switch], outputs=[page_index, turn_page_switch]) 274 | keyword.submit(lambda s:(1, -s), inputs=[turn_page_switch], outputs=[page_index, turn_page_switch]) 275 | sort_by.change(lambda s:(1, -s), inputs=[turn_page_switch], outputs=[page_index, turn_page_switch]) 276 | page_index.submit(lambda s: -s, inputs=[turn_page_switch], outputs=[turn_page_switch]) 277 | renew_page.click(lambda s: -s, inputs=[turn_page_switch], outputs=[turn_page_switch]) 278 | 279 | turn_page_switch.change( 280 | fn=get_image_page, 281 | inputs=[img_path, page_index, filenames, keyword, sort_by], 282 | outputs=[filenames, page_index, history_gallery, img_file_name, img_file_time, img_file_info, visible_img_num, warning_box] 283 | ) 284 | turn_page_switch.change(fn=None, inputs=[tabname_box], outputs=None, _js="images_history_turnpage") 285 | turn_page_switch.change(fn=lambda:(gr.update(visible=False), gr.update(visible=False)), inputs=None, outputs=[delete_panel, button_panel]) 286 | 287 | # other funcitons 288 | set_index.click(show_image_info, _js="images_history_get_current_img", inputs=[tabname_box, image_index, page_index, filenames], outputs=[img_file_name, img_file_time, image_index, hidden]) 289 | set_index.click(fn=lambda:(gr.update(visible=True), gr.update(visible=True)), inputs=None, outputs=[delete_panel, button_panel]) 290 | img_file_name.change(fn=lambda : "", inputs=None, outputs=[collected_warning]) 291 | 292 | hidden.change(fn=modules.extras.run_pnginfo, inputs=[hidden], outputs=[info1, img_file_info, info2]) 293 | 294 | try: 295 | modules.generation_parameters_copypaste.bind_buttons(send_to_buttons, img_file_name, img_file_info) 296 | except: 297 | pass 298 | 299 | def on_ui_tabs(): 300 | global num_of_imgs_per_page 301 | global loads_files_num 302 | num_of_imgs_per_page = int(opts.images_history_page_columns * opts.images_history_page_rows) 303 | loads_files_num = int(opts.images_history_pages_perload * num_of_imgs_per_page) 304 | with gr.Blocks(analytics_enabled=False) as images_history: 305 | with gr.Tabs(elem_id="images_history_tab") as tabs: 306 | for tab in tabs_list: 307 | with gr.Tab(tab): 308 | with gr.Blocks(analytics_enabled=False) : 309 | create_tab(tab) 310 | gr.Checkbox(opts.images_history_preload, elem_id="images_history_preload", visible=False) 311 | gr.Textbox(",".join(tabs_list), elem_id="images_history_tabnames_list", visible=False) 312 | return (images_history , "Image Browser", "images_history"), 313 | 314 | def on_ui_settings(): 315 | section = ('images-history', "Images Browser") 316 | shared.opts.add_option("images_history_preload", shared.OptionInfo(False, "Preload images at startup", section=section)) 317 | shared.opts.add_option("images_record_paths", shared.OptionInfo(True, "Record accessable images directories", section=section)) 318 | shared.opts.add_option("images_delete_message", shared.OptionInfo(True, "Print image deletion messages to the console", section=section)) 319 | shared.opts.add_option("images_history_page_columns", shared.OptionInfo(6, "Number of columns on the page", section=section)) 320 | shared.opts.add_option("images_history_page_rows", shared.OptionInfo(6, "Number of rows on the page", section=section)) 321 | shared.opts.add_option("images_history_pages_perload", shared.OptionInfo(20, "Minimum number of pages per load", section=section)) 322 | 323 | 324 | script_callbacks.on_ui_settings(on_ui_settings) 325 | script_callbacks.on_ui_tabs(on_ui_tabs) 326 | 327 | #TODO: 328 | #recycle bin 329 | #move by arrow key 330 | #generate info in txt 331 | --------------------------------------------------------------------------------