separate & optimize logics

main
Haoming 2024-07-11 17:13:26 +08:00
parent 91b39272ad
commit a5473abcfe
7 changed files with 129 additions and 81 deletions

1
.gitignore vendored Normal file
View File

@ -0,0 +1 @@
__pycache__

View File

@ -1,6 +1,6 @@
MIT License MIT License
Copyright (c) 2023 Haoming Copyright (c) 2024 Haoming
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal

View File

@ -25,6 +25,7 @@ Sometimes, when you type too fast or copy prompts from all over the places, you
- In `Auto`: The process is ran whenever you press **Generate** - In `Auto`: The process is ran whenever you press **Generate**
- In `Manual`: The process is only ran when you press the **Format** button - In `Manual`: The process is only ran when you press the **Format** button
- [x] Toggle which above features is enabled/disabled by default in `System` section of the **Settings** tab - [x] Toggle which above features is enabled/disabled by default in `System` section of the **Settings** tab
- [x] Pressing `Alt` + `Shift` + `F` can also trigger formatting
## Note ## Note
1. Since the formatting in `Auto` mode is triggered at the same time as the generation, 1. Since the formatting in `Auto` mode is triggered at the same time as the generation,

View File

@ -25,6 +25,7 @@
- `自動`: 每次按下 **生成 (Generate)** 時處裡 - `自動`: 每次按下 **生成 (Generate)** 時處裡
- `手動`: 手動按下 **Format** 時才處裡 - `手動`: 手動按下 **Format** 時才處裡
- [x] 在 **Settings** 頁面的 `System` 區 開啟/關閉 上述預設功能 - [x] 在 **Settings** 頁面的 `System` 區 開啟/關閉 上述預設功能
- [x] 按下 `Alt` + `Shift` + `F` 亦可觸發格式化
## 注意 ## 注意
1. 由於`自動`校正和生成是同時觸發,除非有先用過`手動`校正,不然當下所產的第一張圖片之內部資料並不會被更新。 1. 由於`自動`校正和生成是同時觸發,除非有先用過`手動`校正,不然當下所產的第一張圖片之內部資料並不會被更新。

View File

@ -16,42 +16,6 @@ class LeFormatter {
}); });
} }
// ===== UI Related =====
static button({ onClick }) {
const button = document.createElement('button');
button.id = 'manual-format';
button.classList.add(['lg', 'secondary', 'gradio-button']);
button.textContent = 'Format';
button.style.padding = '2px 8px';
button.style.borderRadius = '0.2em';
button.style.border = 'var(--button-border-width) solid var(--button-secondary-border-color)';
button.style.background = 'var(--button-secondary-background-fill)';
button.addEventListener('click', onClick);
return button;
}
static checkbox(text, default_value, { onChange }) {
const label = gradioApp().getElementById('tab_settings').querySelector('input[type=checkbox]').parentNode.cloneNode(true);
label.removeAttribute('id');
const checkbox = label.children[0];
checkbox.checked = default_value;
checkbox.addEventListener('change', (event) => {
onChange(event.target.checked);
});
const span = label.children[1];
span.textContent = text;
label.style.display = 'flex';
label.style.alignItems = 'center';
label.style.margin = '2px 8px';
return label;
}
// ===== Main Format Logics ===== // ===== Main Format Logics =====
static formatPipeline(textArea, dedupe, removeUnderscore, autoRefresh) { static formatPipeline(textArea, dedupe, removeUnderscore, autoRefresh) {
const lines = textArea.value.split('\n'); const lines = textArea.value.split('\n');
@ -138,33 +102,44 @@ class LeFormatter {
} }
// ===== Load Settings ===== // ===== Load Settings =====
/** @returns {boolean} */
static shouldRefresh() { static shouldRefresh() {
const config = gradioApp().getElementById('setting_pf_disableupdateinput').querySelector('input[type=checkbox]'); const config = gradioApp().getElementById('setting_pf_disableupdateinput').querySelector('input[type=checkbox]');
return !config.checked; return !config.checked;
} }
/** @returns {boolean} */
static defaultAuto() { static defaultAuto() {
const config = gradioApp().getElementById('setting_pf_startinauto').querySelector('input[type=checkbox]'); const config = gradioApp().getElementById('setting_pf_startinauto').querySelector('input[type=checkbox]');
return config.checked; return config.checked;
} }
/** @returns {boolean} */
static defaultDedupe() { static defaultDedupe() {
const config = gradioApp().getElementById('setting_pf_startwithdedupe').querySelector('input[type=checkbox]'); const config = gradioApp().getElementById('setting_pf_startwithdedupe').querySelector('input[type=checkbox]');
return config.checked; return config.checked;
} }
/** @returns {boolean} */
static defaultRemoveUnderscore() { static defaultRemoveUnderscore() {
const config = gradioApp().getElementById('setting_pf_startwithrmudscr').querySelector('input[type=checkbox]'); const config = gradioApp().getElementById('setting_pf_startwithrmudscr').querySelector('input[type=checkbox]');
return config.checked; return config.checked;
} }
// ===== Cache All Prompt Fields ===== // ===== Cache All Prompt Fields =====
/** @returns {Array<Element>} */
static getPromptFields() { static getPromptFields() {
// Expandable ID List in 1 place
const ids = ['txt2img_prompt', 'txt2img_neg_prompt', 'img2img_prompt', 'img2img_neg_prompt', 'hires_prompt', 'hires_neg_prompt'];
const textareas = []; const textareas = [];
ids.forEach((id) => { // Expandable ID List in 1 place
[
'txt2img_prompt',
'txt2img_neg_prompt',
'img2img_prompt',
'img2img_neg_prompt',
'hires_prompt',
'hires_neg_prompt'
].forEach((id) => {
const textArea = gradioApp().getElementById(id)?.querySelector('textarea'); const textArea = gradioApp().getElementById(id)?.querySelector('textarea');
if (textArea != null) if (textArea != null)
textareas.push(textArea); textareas.push(textArea);
@ -176,11 +151,11 @@ class LeFormatter {
onUiLoaded(async () => { onUiLoaded(async () => {
const promptFields = LeFormatter.getPromptFields(); const promptFields = LeFormatter.getPromptFields();
const refresh = LeFormatter.shouldRefresh();
var autoRun = LeFormatter.defaultAuto(); var autoRun = LeFormatter.defaultAuto();
var dedupe = LeFormatter.defaultDedupe(); var dedupe = LeFormatter.defaultDedupe();
var removeUnderscore = LeFormatter.defaultRemoveUnderscore(); var removeUnderscore = LeFormatter.defaultRemoveUnderscore();
const refresh = LeFormatter.shouldRefresh();
document.addEventListener('keydown', (e) => { document.addEventListener('keydown', (e) => {
if (e.altKey && e.shiftKey && e.code === 'KeyF') { if (e.altKey && e.shiftKey && e.code === 'KeyF') {
@ -189,39 +164,26 @@ onUiLoaded(async () => {
} }
}); });
const manualBtn = LeFormatter.button({ const formatter = LeFormatterUI.setupUIs(
onClick: () => { () => {
promptFields.forEach((field) => LeFormatter.formatPipeline(field, dedupe, removeUnderscore, true)); promptFields.forEach((field) => LeFormatter.formatPipeline(field, dedupe, removeUnderscore, true));
} },
autoRun, dedupe, removeUnderscore
);
formatter.checkboxs[0].addEventListener("change", (e) => {
autoRun = e.target.checked;
formatter.btn.style.display = autoRun ? 'none' : 'flex';
}); });
manualBtn.style.display = autoRun ? 'none' : 'block'; formatter.checkboxs[1].addEventListener("change", (e) => {
dedupe = e.target.checked;
const autoCB = LeFormatter.checkbox('Auto Format', autoRun, {
onChange: (checked) => {
autoRun = checked;
manualBtn.style.display = autoRun ? 'none' : 'block';
}
}); });
const dedupeCB = LeFormatter.checkbox('Remove Duplicates', dedupe, { formatter.checkboxs[2].addEventListener("change", (e) => {
onChange: (checked) => { dedupe = checked; } removeUnderscore = e.target.checked;
}); });
const underlineCB = LeFormatter.checkbox('Remove Underscores', removeUnderscore, {
onChange: (checked) => { removeUnderscore = checked; }
});
const formatter = document.createElement('div');
formatter.id = 'le-formatter';
formatter.style.display = 'flex';
formatter.style.flex.direction = 'row';
formatter.appendChild(autoCB);
formatter.appendChild(manualBtn);
formatter.appendChild(dedupeCB);
formatter.appendChild(underlineCB);
const tools = document.getElementById('quicksettings'); const tools = document.getElementById('quicksettings');
tools.after(formatter); tools.after(formatter);
@ -229,15 +191,14 @@ onUiLoaded(async () => {
const generateButton = gradioApp().getElementById(`${mode}2img_generate`); const generateButton = gradioApp().getElementById(`${mode}2img_generate`);
const enqueueButton = gradioApp().getElementById(`${mode}2img_enqueue`); const enqueueButton = gradioApp().getElementById(`${mode}2img_enqueue`);
const handleClick = () => { generateButton?.addEventListener('click', () => {
if (autoRun) { if (autoRun)
promptFields.forEach((field) => LeFormatter.formatPipeline(field, dedupe, removeUnderscore, refresh)); promptFields.forEach((field) => LeFormatter.formatPipeline(field, dedupe, removeUnderscore, refresh));
} });
};
generateButton.addEventListener('click', handleClick); enqueueButton?.addEventListener('click', () => {
if (enqueueButton) { if (autoRun)
enqueueButton.addEventListener('click', handleClick); promptFields.forEach((field) => LeFormatter.formatPipeline(field, dedupe, removeUnderscore, refresh));
} });
}); });
}); });

View File

@ -0,0 +1,61 @@
class LeFormatterUI {
/** @param {Function} onClick @returns {Element} */
static #button(onClick) {
const button = document.createElement('button');
button.textContent = 'Format';
button.id = 'manual-format';
button.classList.add(['lg', 'secondary', 'gradio-button']);
button.addEventListener('click', onClick);
return button;
}
/** @param {boolean} default_value @param {string} text @returns {Element} */
static #checkbox(default_value, text) {
const label = gradioApp().getElementById('tab_settings').querySelector('input[type=checkbox]').parentNode.cloneNode(true);
label.removeAttribute('id');
label.classList.add("pf-checkbox");
const checkbox = label.children[0];
checkbox.checked = default_value;
const span = label.children[1];
span.textContent = text;
return label;
}
/**
* @param {Function} onManual
* @param {boolean} autoRun @param {boolean} dedupe @param {boolean} removeUnderscore
* @returns {Element}
* */
static setupUIs(onManual, autoRun, dedupe, removeUnderscore) {
const formatter = document.createElement('div');
formatter.id = 'le-formatter';
const manualBtn = this.#button(onManual);
manualBtn.style.display = autoRun ? 'none' : 'flex';
const autoCB = this.#checkbox(autoRun, 'Auto Format');
const dedupeCB = this.#checkbox(dedupe, 'Remove Duplicates');
const underscoreCB = this.#checkbox(removeUnderscore, 'Remove Underscores');
formatter.appendChild(autoCB);
formatter.appendChild(manualBtn);
formatter.appendChild(dedupeCB);
formatter.appendChild(underscoreCB);
formatter.btn = manualBtn;
formatter.checkboxs = [
autoCB.children[0],
dedupeCB.children[0],
underscoreCB.children[0]
];
return formatter;
}
}

23
style.css Normal file
View File

@ -0,0 +1,23 @@
#le-formatter {
display: flex;
flex-direction: row;
user-select: none;
}
#manual-format {
height: 24px;
padding: 2px 8px;
border-radius: 0.2em;
border: var(--button-border-width) solid var(--button-secondary-border-color);
background: var(--button-secondary-background-fill);
display: flex;
justify-content: center;
align-items: center;
}
.pf-checkbox {
display: flex;
align-items: center;
margin: 2px 8px;
}