Adding in the functionality for the extension
parent
3f8299d89f
commit
8095929f1f
|
|
@ -0,0 +1,16 @@
|
|||
# A simple history slider.
|
||||
|
||||
Similarly to that have DrawThings.ai but for AUTOMATIC 1111 Stable Diffusion Webui.
|
||||
|
||||
### Example
|
||||

|
||||
|
||||
## What can it do?
|
||||
|
||||
- It will track both prompt and negative prompt history for txt2img and img2img.
|
||||
- It will allow a user to load the history stored on local storage.
|
||||
- It will allow a user to clear the prompt history.
|
||||
|
||||
## TODO
|
||||
- Change the formatting of the local history to a singular instance using JSON to track steps.
|
||||
- Put a max threshold on the prompt's history.
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 5.5 MiB |
|
|
@ -0,0 +1,168 @@
|
|||
const LOADED_STORAGE_KEY = "_history_is_loaded";
|
||||
const TEXT_TO_IMAGE = "txt2img"
|
||||
const IMAGE_TO_IMAGE = "img2img"
|
||||
const HISTORY_TOP_ROW_POSTFIX = "_history_top_row"
|
||||
|
||||
function init() {
|
||||
// Dynamically obtained from the objects being loaded into Gradio
|
||||
txt2img_prompt.addEventListener("input", () => watchPrompts(TEXT_TO_IMAGE));
|
||||
txt2img_neg_prompt.addEventListener("input", () => watchPrompts(TEXT_TO_IMAGE));
|
||||
img2img_neg_prompt.addEventListener("input", () => watchPrompts(IMAGE_TO_IMAGE));
|
||||
img2img_prompt.addEventListener("input", () => watchPrompts(IMAGE_TO_IMAGE));
|
||||
}
|
||||
|
||||
function swapThem() {
|
||||
// Swap from the lower end of the GUI to where we want them to, below the prompts
|
||||
const tab = (get_uiCurrentTab()).innerHTML.trim();
|
||||
if (tab == TEXT_TO_IMAGE || tab == IMAGE_TO_IMAGE) {
|
||||
const top_row = document.getElementById(tab + "_toprow");
|
||||
const history_top_row = document.getElementById(tab + HISTORY_TOP_ROW_POSTFIX);
|
||||
top_row.after(history_top_row);
|
||||
}
|
||||
}
|
||||
|
||||
function changingTabs() {
|
||||
// Listen for changing tabs.
|
||||
const tab = (get_uiCurrentTab()).innerHTML.trim();
|
||||
if (tab == TEXT_TO_IMAGE || tab == IMAGE_TO_IMAGE) {
|
||||
// if (isLoaded(tab)) {
|
||||
// load_history(tab);
|
||||
// }
|
||||
swapThem();
|
||||
}
|
||||
}
|
||||
|
||||
function isLoaded(tab) {
|
||||
// This might be good for when we create a auto load checkbox.
|
||||
console.log("is loaded?");
|
||||
const t = window.localStorage.getItem(tab + LOADED_STORAGE_KEY) || false;
|
||||
console.log(t);
|
||||
return t;
|
||||
}
|
||||
|
||||
function buildKey(a, b) {
|
||||
return a + "_" + b;
|
||||
}
|
||||
|
||||
function capturePrompts(tabname) {
|
||||
const value = {};
|
||||
value.negative_prompt = gradioApp().querySelector(
|
||||
"#" + tabname + "_neg_prompt textarea"
|
||||
).value;
|
||||
value.prompt = gradioApp().querySelector(
|
||||
"#" + tabname + "_prompt textarea"
|
||||
).value;
|
||||
return value;
|
||||
}
|
||||
|
||||
function updatePromptHistory(tabname) {
|
||||
const slider = gradioApp().querySelector(
|
||||
"#" + tabname + "_prompt_history_slider> input"
|
||||
);
|
||||
const prompt = gradioApp().querySelector("#" + tabname + "_prompt textarea");
|
||||
const negprompt = gradioApp().querySelector(
|
||||
"#" + tabname + "_neg_prompt textarea"
|
||||
);
|
||||
const key = buildKey(tabname, slider.value);
|
||||
const value = JSON.parse(window.localStorage.getItem(key));
|
||||
|
||||
prompt.value = value.prompt;
|
||||
negprompt.value = value.negative_prompt;
|
||||
}
|
||||
|
||||
function watchPrompts(tabname) {
|
||||
const input = gradioApp().querySelector(
|
||||
"#" + tabname + "_prompt_history_slider> div input"
|
||||
);
|
||||
const slider = gradioApp().querySelector(
|
||||
"#" + tabname + "_prompt_history_slider> input"
|
||||
);
|
||||
|
||||
slider.max = parseInt(slider.max) + 1;
|
||||
slider.value = parseInt(slider.max);
|
||||
input.value = parseInt(slider.value);
|
||||
|
||||
|
||||
let value = capturePrompts(tabname);
|
||||
let key = buildKey(tabname, slider.value);
|
||||
|
||||
|
||||
window.localStorage.setItem(key, JSON.stringify(value));
|
||||
}
|
||||
|
||||
function load_history(tabname) {
|
||||
if (!isLoaded(tabname)) {
|
||||
window.localStorage.setItem(buildKey(tabname, LOADED_STORAGE_KEY), true)
|
||||
}
|
||||
const slider = gradioApp().querySelector(
|
||||
"#" + tabname + "_prompt_history_slider> input"
|
||||
);
|
||||
const input = gradioApp().querySelector(
|
||||
"#" + tabname + "_prompt_history_slider> div input"
|
||||
);
|
||||
|
||||
const items = {...window.localStorage};
|
||||
|
||||
let count = 0;
|
||||
let last_prompt = "";
|
||||
let last_neg_prompt = "";
|
||||
for (let key in items) {
|
||||
const re = new RegExp(tabname + "_[0-9]+", "g");
|
||||
if (key.match(re)) {
|
||||
count++;
|
||||
}
|
||||
}
|
||||
|
||||
if (count > 0) {
|
||||
const value = JSON.parse(items[tabname + "_" + count]);
|
||||
last_prompt = value.prompt;
|
||||
last_neg_prompt = value.negative_prompt;
|
||||
slider.max = parseInt(count);
|
||||
slider.value = parseInt(count);
|
||||
input.value = parseInt(count);
|
||||
document.cookie = "isInit=true";
|
||||
|
||||
const prompt = gradioApp().querySelector(
|
||||
"#" + tabname + "_prompt textarea"
|
||||
);
|
||||
const negprompt = gradioApp().querySelector(
|
||||
"#" + tabname + "_neg_prompt textarea"
|
||||
);
|
||||
prompt.value = last_prompt;
|
||||
negprompt.value = last_neg_prompt;
|
||||
}
|
||||
}
|
||||
|
||||
function confirm_clear_history(tabname) {
|
||||
const slider = gradioApp().querySelector(
|
||||
"#" + tabname + "_prompt_history_slider> input"
|
||||
);
|
||||
const input = gradioApp().querySelector(
|
||||
"#" + tabname + "_prompt_history_slider> div input"
|
||||
);
|
||||
|
||||
if (confirm("Clear " + tabname + " prompt history?")) {
|
||||
slider.max = 1;
|
||||
slider.value = 1;
|
||||
input.value = 1;
|
||||
const items = {...window.localStorage};
|
||||
for (let key in items) {
|
||||
const re = new RegExp(tabname + "_[0-9]+", "g");
|
||||
if (key.match(re)) {
|
||||
window.localStorage.removeItem(key);
|
||||
}
|
||||
}
|
||||
|
||||
window.localStorage.setItem(
|
||||
buildKey(tabname, slider.value),
|
||||
JSON.stringify(capturePrompts(tabname))
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
onUiLoaded(async () => {
|
||||
swapThem();
|
||||
init();
|
||||
});
|
||||
onUiTabChange(async () => { changingTabs() });
|
||||
Binary file not shown.
|
|
@ -0,0 +1,62 @@
|
|||
import gradio as gr
|
||||
from modules import scripts
|
||||
from modules.ui_components import FormGroup
|
||||
|
||||
|
||||
def create_history_slider(tabname):
|
||||
with FormGroup(elem_id=f"prompt_history_slider_{tabname}"):
|
||||
history = gr.Slider(
|
||||
minimum=1,
|
||||
maximum=1,
|
||||
step=1,
|
||||
elem_id=f"{tabname}_prompt_history_slider",
|
||||
label="Prompt History",
|
||||
value=1,
|
||||
)
|
||||
history.input(
|
||||
fn=lambda *x: x,
|
||||
_js="function(){updatePromptHistory('" + tabname + "')}",
|
||||
inputs=None,
|
||||
outputs=None,
|
||||
)
|
||||
history.release( #this is for the case where the user goes too fast or off the page.
|
||||
fn=lambda *x: x,
|
||||
_js="function(){updatePromptHistory('" + tabname + "')}",
|
||||
inputs=None,
|
||||
outputs=None,
|
||||
)
|
||||
|
||||
return history
|
||||
|
||||
class HistoryScript(scripts.Script):
|
||||
def __init__(self) -> None:
|
||||
super().__init__()
|
||||
|
||||
def title(self):
|
||||
return "History"
|
||||
|
||||
def show(self, is_img2img):
|
||||
return scripts.AlwaysVisible
|
||||
|
||||
def ui(self, is_img2img):
|
||||
id_part = "img2img" if is_img2img else "txt2img"
|
||||
with gr.Row(elem_id=f"{id_part}_history_top_row", variant="compact", scale=100):
|
||||
with gr.Column(elem_id="history_col", scale=11):
|
||||
history_slider = create_history_slider(id_part)
|
||||
with gr.Column(elem_id="history_col", scale=1):
|
||||
with gr.Row(elem_id="history_button_row", variant="compact"):
|
||||
clear_history = gr.Button("Clear", visible=True, label="Clear history")
|
||||
clear_history.click(
|
||||
fn=lambda *x: x,
|
||||
_js="function(){confirm_clear_history('" + id_part + "')}",
|
||||
inputs=None,
|
||||
outputs=None,
|
||||
)
|
||||
load_history = gr.Button("Load", visible=True, label="Load history")
|
||||
load_history.click(
|
||||
fn=lambda *x: x,
|
||||
_js="function(){load_history('" + id_part + "')}",
|
||||
inputs=None,
|
||||
outputs=None,
|
||||
)
|
||||
return [history_slider, clear_history, load_history]
|
||||
Loading…
Reference in New Issue